本篇对文件上传的学习做了记录。
UploadLabs
Pass1
这关使用文件后缀白名单的方式,在前端检测了文件类型。
直接用burp修改请求绕过就行。
其间WindowsDefender报毒file: C:\Windows\php7CC0.tmp,经过搜索发现这个是php上传文件的缓存。加入wd的排除项就可以了。
Pass2
这关是在后端进行了检查,使用的Content-Type白名单,包括image/jpeg,image/png,image/gif
绕过方式同Less1
Pass3
在后端做了黑名单检查。提示不允许上传asp,jsp,php后缀的文件。
经过搜索发现可以传phtml,phm,phs,ph5等。不过这些后缀需要在对应的web服务器中进行配置才能用php解析。在网上搜到的博客基本都是说
需要在apache/conf/httpd.conf配置文件中有:
AddType application/x-httpd-php .php .phtml .phps .php5 .pht
但是经过测试发现并没有用。恶补了一下apache和php相关的知识,发现这种方式只在php是module运行模式下起作用(upload-labs官方说明了环境搭建时使用module方式连接,当时没有注意)。而我用的是phpstudy,默认使用的fastcgi模式,所以并不起作用。
如果想在fcgi模式下用php解析特定后缀,需要修改fcgi解析后缀,但是不建议这么修改。建议使用伪静态的方式把来自不同后缀的请求定位到php文件。
Pass4
黑名单了phtml,phm,等。但是可以使用.htaccess
Pass5
上传.user.ini
其中写auto_prepend_file=01.gif,其它所有php都会预加载01.gif
然后再上传名为01.gif的一句话木马
只要是以fastcgi运行的php都可以用这个方法
Pass6
大小写绕过
Pass7
加空格绕过
Pass8
加.绕过
windows会自动删除最后一个点
Pass9
::$data绕过
Pass10
. .绕过
代码规则是:
- 首位去空
- 末尾删点
- 取第一个点后的字符串
- 转为小写
- 删去::$DATA
- 首尾去空
php. .
Pass11
把特定后缀替换为空,直接双写绕过
Pass12
因为这关传输了文件的保存路径,在路径里面增加%00进行截断字符串。文件名就没意义了。
Pass13
还是00截断,GET方式变为POST方式
POST不会像GET对%00进行自动解码
需要用burp在二进制中进行修改
将70 68 70后面的2b改为00
Pass14
只读前两字节判断文件是否合法
制作图片马:
- cmd
copy 1.jpg/b 1.php/a 2.jpg
,把1.jpg(二进制)和2.php(ASCII)先后写入2.jpg - powershell
echo <?php echo(exec($_GET['cmd']));?>|out-file -append -encoding ascii 1.jpg
,直接追加ASCII格式的内容到1.jpg - 直接上传,文件包含执行。
Pass15
getimagesize获取文件信息,判断是否是jpeg png gif
Pass16
exif_imagetype模块检测,同样是检测前两个字节
Pass17
图片被二次渲染
gif
将渲染后的图片下载,用winhex和原图片对比。直接修改二进制,将payload添加在原图片没有变的位置。
png
Pass18
代码逻辑有问题,先把文件上传,再判断文件是否合法。不合法删除,合法重命名。
直接用burp intruder,在文件被删前访问。
1 |
|
burp上传抓包,然后用nullpayload
写python脚本,一直访问,直到html.status_code==200
Pass19 条件竞争
同样是代码逻辑问题,先把文件上传,再判断是否需要处理。
用burp intruder上传图片马,写python在被(重命名+重新渲染+移动)之前用文件包含访问。
这道题的文件上传路径是根目录下,upload1.png。看起来是路径中少了一个斜杠。
应该是作者代码出现了错误,看了下代码,找到了问题= =。修复后在github提了个pull request。
Pass20
在文件名后面加/.
绕过
点绕过 空格绕过
apache解析漏洞 a.php.adsfg
Pass21
看代码,发现步骤是这样的
- 检查了Content-Type和POST 参数中的save_name。
- 如果save_name不是数组,则用
.
explode成数组 - 先检查end(save_name)是否是 jpg png gif
- 然后save_name=reset(save_name).’.’.save_name(count(svae_name)-1),也就是如果save_name是a.b.c.d,就重命名成a.d
最关键的一点是,它判断了save_name是不是数组,如果正常上传肯定不是,所以会用.
来分割成数组,然后再进行后面的判断。
那我们直接用burp,传个save_name的数组
save_name[0]=’a.php’
save_name[2]=’jpg’
这里是利用了php的特性,在这种情况下count(save_name)=2
那么count(save_name)-1=1,但savename[1]为空,所以第四步拼接完成后结果是a.php
总结
了解了文件上传思路,图片马和文件包含的结合利用方式,各种绕过方法。之后需要熟悉下各种解析漏洞。