一、文件上传
1. 什么是文件上传?
文件上传就是:
用户把自己电脑上的文件发送给服务器,服务器接收这个文件。
例如网站有:选择文件 → 上传
整个过程:本地文件 →浏览器 →HTTP请求 →服务器 →PHP处理 →保存文件
2. PHP 如何接收上传文件?
PHP 使用预定义变量:$_FILES
例如前端:
<input type="file" name="file">PHP:
$_FILES['file']3.$_FILES中有什么?
例如:$_FILES['file']里面常见的数据:
$_FILES['file']['name'] $_FILES['file']['type'] $_FILES['file']['tmp_name'] $_FILES['file']['error'] $_FILES['file']['size']分别表示:
name:用户上传时的文件名
type:文件的MIME类型信息
tmp_name:PHP暂时保存上传文件的位置
error:上传过程中产生的错误代码
size:文件大小
其中最重要的是:$_FILES['file']['tmp_name']。它表示:服务器暂时保存这个上传文件的位置。
二、文件上传是怎么保存的?
PHP 常使用:move_uploaded_file()函数将上传的临时文件移动到指定的目录中,从而将上传的文件保存下来。
例如:
move_uploaded_file( $_FILES['file']['tmp_name'], 'uploads/test.jpg' );这个函数有两个参数:
第一个参数:上传文件当前的临时位置
第二个参数:文件最终保存的位置
执行过程:
用户上传 test.jpg ↓ PHP接收 ↓ 临时保存 ↓ $_FILES['file']['tmp_name'] ↓ move_uploaded_file() ↓ uploads/test.jpg三、什么是文件上传漏洞?
正常的网站不会什么文件都接受。
例如只允许:.jpg .png .gif
并且还应该检查:文件大小,文件类型、文件内容、文件扩展名、保存位置、文件名
如果程序对这些检查存在问题,就可能产生文件上传漏洞。
所以文件上传漏洞的核心不是:网站有上传功能。
而是:用户能够上传服务器本来不应该接受或处理的文件。
也就是说:如果服务器端代码未对客户端上传的文件进行严格的验证和过滤,就容易造成可以上传任意文件的情况,包括上传脚本 文件
产生的危害
恶意用户可以利用上传的恶意脚本文件控制整个文件,甚至控制整服务器,这个恶意脚本文件又被称为webshell
可将webshell称为一直网页的后门,webshell脚本具有非常强大的功能,如查看服务器中的目录,文件,执行系统命令等。
JavaScript检测绕过
常用于用户选择文件上传的场景,如果上传的文件的后缀不被允许,则会弹窗告知。此时上传文件的数据包并没有发送到服务器端,只是在客户端浏览器中使用JavaScript对数据包进行检测。
上传了非jpg的格式
绕过客户端JavaScript检测的方式:
1)使用浏览器插件,删除检测文件后缀的JavaScript代码,然后上传文件即可绕过。
2)先把需要上传的文件的后缀改成允许上传的格式,即可绕过JavaScript的检测,然后抓包,再把后缀名改成可执行文件的后缀即刻上传成功。
客户端上传文件的HTML部分代码:函数作用:先将文件名转换为小写,再通过substr函数获取文件名的最后一个点号后面的后缀。如果不是.jpg则弹框提示。
服务端处理上传文件的代码:
如果上传文件没错,在通过file_exists函数判断在upload目录下文件是否存在,不存在就通过move_uploaded_file函数将文件保存到upload。此代码并没有对文件后缀做任何判断,所以只需绕过前端JavaScript的校验就可以上传webshell。
文件后缀/黑名单绕过
原理:虽然服务器代码中限制了某些后缀的文件上传,但是有些版本的apache允许解析其他文件的后缀。
例如:在httpd.conf中,如果配置了 Addtype application/x-httpd-php .php .phtml,则能解析php和.phtml文件。
网站管理员可以在配置文件中添加任意扩展名,从而让网站去解析,配置这些扩展名是因为,这些扩展名曾经使用过,在某些情况下需要对这些文件进行解析,因此可以这样绕过。
通常有phtml、phps、php3、php5、pht等
apache是从右向左解析文件后缀的,如果最右侧的扩展 名不可识别,就继续往左解析,直到遇到可以接卸的文件后缀为止。因此,如果上传的文件名类似1.php.xxxxx,由于xxxxx后缀不能被解析,所以继续向左解析,从而触发后门。
第五行:定义一个数组,数组中的元素就是被列入黑名单的扩展名
第八行:截取扩展名
第13行:检测后缀名是否在黑名单中。
在这里上传文件后,对文件重命名了
文件Content-Type绕过
如果服务器端的代码时通过Content-Type的值来判断文件的类型,就存在被绕过的可能,因为Content-Type的值时通过客户端传递的,可以修改,当上传一个php文件时,在Burp中将Content-Type修改为image/jpeg,就可以绕过。
竞争条件攻击
由于网站上传文件的逻辑是先允许上传任意文件,然后检查上传文件中是否包含webshell脚本,如果包含则删除该文件。但是,文件上传成功和删除文件这两个操作之间会存在一个时间差。攻击者可以利用这个时间差来完成竞争条件的上传漏洞攻击。
思路:先上传一个webshell脚本,这个脚本的内容是生成一个新的webshell脚本。然后客户端立即访问上传的脚本,就会在服务端自动生成webshell。
<?php fputs(fopen('../shell.php','w'),'<?php @eval($_POST[a]) ?>'); ?>fopen('../shell.php','w'):打开(创建)上层目录下shell.php,w代表写入模式;如果文件不存在就新建,存在就覆盖。fputs(文件句柄,内容):把一句话木马代码写入shell.php文件。- 写入的木马:
<?php @eval($_POST[a]) ?>
eval()执行 POST 参数a传过来的 PHP 代码;@用来屏蔽报错。
攻击者使用蚁剑 / 菜刀连接shell.php,参数密码为a,获取网站权限。
黑名单绕过
文件上传漏洞修复建议
通过白名单的方式判断文件后缀名是否合法
对上传的文件进行重命名。