欢迎新同学的光临
… …
人若无名,便可专心练剑
我不是一条咸鱼,而是一条死鱼啊!
文件上传漏洞
文件上传漏洞是一个危害巨大的漏洞,通过上传WebShell更是将这种漏洞的危害无限扩大。攻击者在受影响系统放置或者插入WebShell后,可通过该WebShell更轻松,更隐蔽的在服务中为所欲为。
简介
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。 文件上传漏洞大多是没有限制上传的文件格式,导致可以直接上传危险文件,并且部分文件上传漏洞的利用技术门槛非常的低,对于攻击者来说很容易实施。
PHP文件上传相关函数
move_uploaded_file(file,newloc)
move_uploaded_file() 函数将上传的文件移动到新位置, 若成功,则返回 true,否则返回 false
参数 | 描述 |
---|---|
file | 必需,规定要移动的文件 |
newloc | 必需,规定文件的新位置 |
实例
未对上传文件格式进行限制,则可以上传危险文件
upload.php
<!DOCTYPE html>
<html>
<head>
<title>文件上传</title>
</head>
<meta charset="utf-8">
<body>
<form action="" enctype="multipart/form-data" method="POST" name="uploadfile">
请上传图片: <input type="file" name="upfile" />
<input type="submit" value="上传" name="submit">
</form>
<br />
</body>
</html>
<?php
if (isset($_POST['submit'])) {
echo "文件名:".$_FILES['upfile']['name']."<br />";
if ($_FILES['upfile']['error'] == 0) {
$dir = "./upload/".$_FILES['upfile']['name'];
move_uploaded_file($_FILES['upfile']['tmp_name'],$dir);
echo "文件保存路径:".$dir."<br />";
echo "上传成功...<br />";
}
}
?>
主要关键代码:
可以看到未对用户上传的文件做任何校验。
注意:这里需要先给upload文件分配权限(命令:chmod 755 upload)
http://192.168.161.133/fileupload/upload.php
成功打开页面尝试上传其他文件。 新建文件phpinfo.php,并输入内容:
<?php
phpinfo();
?>
上传phpinfo.php 文件
成功看到.php格式的文件被上传
根据页面返回的路径,尝试执行phpinfo.php: 输入url:192.168.161.133/fileupload/upload/phpinfo.php :
成功执行了phpinfo.php文件中的代码,这就是一次常见的文件上传漏洞利用实例
文件上传漏洞防御
文件上传漏洞攻击要实现,一般来说需要满足以下条件:
-
上传的文件能够被Web容器解释执行
-
用户能够从Web上访问这个文件
-
用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功
根据上述的条件来防御,如下:
1、文件上传的目录设置为不可执行
只要web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此这一点至关重要
2、判断文件类型
- 在判断文件类型时,可以结合使用MIMEType、后缀检查等方式
- 在文件类型检查中,强烈推荐白名单方式,黑名单的方式已经无数次被证明是不可靠的
- 此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码
3、使用随机数改写文件名和文件路径
- 文件上传如果要执行代码,则需要用户能够访问到这个文件
- 在某些环境中,用户能上传,但不能访问
- 如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本
- 再来就是像shell.php.rar.rar和crossdomain.xml这种文件,都将因为重命名而无法攻击。
4、单独设置文件服务器的域名
由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含Javascript的文件上传利用等问题将得到解决
文章里面的实例之所以会造成文件上传漏洞,究其原因还是未对用户的输入文件进行过滤。 像上个页面中,如果限制用户输入文件为图片类型,就可以避免这种攻击的发生。
查看修改之后的代码 upload_filter.php关键代码
使用switch函数对上传文件格式做了判断
<?php
if (isset($_POST['submit'])) {
echo "文件名:".$_FILES['upfile']['name']."<br />";
switch ($_FILES['upfile']['type']) {
case 'image/jpeg':
$flag = 1;
break;
default:
die("上传失败,请确保文件格式为图片.....");
break;
}
if ($_FILES['upfile']['error'] == 0) {
$dir = "./upload/".$_FILES['upfile']['name'];
move_uploaded_file($_FILES['upfile']['tmp_name'],$dir);
echo "文件保存路径:".$dir."<br />";
echo "上传成功...<br />";
}
}
?>
再上传phpinfo.php,发现上传不成功:
再来试试修改目录权限的方法: 到Web相应目录下执行以下命令:sudo chmod -x upload
将upload目录设置为不可执行,再尝试加载之前上传的phpinfo.php:
提示没有执行权限,所以这也是一种有效防御文件上传漏洞的方法。 当然,攻击与防御总是相对的,我们这里做了简单的过滤,攻击者也会有很多上传绕过的方法
参考链接:https://www.shiyanlou.com/courses/895
我自横刀向天笑,去留肝胆两昆仑