Upload-labs
文章目录
- Upload-labs
- 环境
- Pass-01 前端绕过
- Pass-02 MIME检查,只查Content-Type,不查filename
- Pass-03 黑名单->名单不全绕过
- Pass-04 黑名单->.htaccess 绕过
- Pass-05 黑名单->后缀名大小写绕过
- Pass-06 黑名单->后缀名加空格绕过
- Pass-07 黑名单->后缀名加点绕过
- Pass-08 黑名单->后缀名加::$DATA绕过
- Pass-09 黑名单->后缀名点空绕过
- Pass-10 黑名单->后缀名循环绕过
- Pass-11 白名单->%00截断绕过
- Pass-12 白名单->%00截断绕过
- Pass-13 图片马,文件包含利用
- Pass-14 图片马,文件包含利用
- Pass-15 图片马,文件包含利用
- Pass-16 图片马,文件包含,二次渲染
- Pass-17 白名单,资源竞争
- Pass-18 白名单,条件竞争
- Pass-19 黑名单 名单不全
- Pass-20白名单 代码审计
- 畸形解析
环境
一开始装的小皮phpstudy8 的环境,各种过不了,怎么改都不行。
然后找了作者搭好的环境,各种秒过。 https://github.com/c0ny1/upload-labs/releases
踩坑环境 小皮phpstudy 8.1.1.3 php5.2.17 apache 2.4.39
作者环境 phpstudy php5.2.17 apache 2.2.25(win 32)
Pass-01 前端绕过
将html文件保存到本地,然后修改js代码验证,将form表单添加action提交到http://localhost/upload-labs/Pass-01/,浏览器打开html上传完成绕过。
也可以上传后缀名符合要求的文件然后burpsuite抓包修改上传完成绕过
Pass-02 MIME检查,只查Content-Type,不查filename
burpsuite抓包,改content-type上传
Pass-03 黑名单->名单不全绕过
deldot():删除文件名末尾的点,为了防止多后缀
strrchr():查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符
可能存在php5,phtml,php3,phps 等后缀可以解析成php从而绕过
需要appache 配置php5等相关解析
换了环境,过了。。。环境(https://github.com/c0ny1/upload-labs/releases)
Pass-04 黑名单->.htaccess 绕过
要求
- 服务器没将上传的文件没改名
- apache服务器配置 AllowOverride None 改为: AllowOverride All
- apache服务器配置 LoadModule rewrite_module modules/mod_rewrite.so前面的注释符号#删除
先上传.htaccess,在有.htaccess文件的目录下,appache会安装该文件的配置进行解析,可以将任意文件解析成为php代码执行
.htaccess
htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能
AddType application/x-httpd-php .jpg
将jpg解析为php
<FilesMatch "xigua">
SetHandler application/x-httpd-php
</FilesMatch>
将文件名带有Screenshot的文件解析为php
文件格式要求特别严格,一个符号都,别错,(嚎啕大哭
换了环境,过了。。。
Pass-05 黑名单->后缀名大小写绕过
将php文件后缀名修改成Php上传,完成绕过
Pass-06 黑名单->后缀名加空格绕过
需服务器为windows系统
但是我,上传出错。。。
换了环境,秒过!。。。
Pass-07 黑名单->后缀名加点绕过
需服务器为windows系统
但是我,还是上传出错。。。
换了环境,秒过!。。。
Pass-08 黑名单->后缀名加::$DATA绕过
需服务器为windows系统
Pass-09 黑名单->后缀名点空绕过
由于没有循环去空点,可以构造去空点之后是.php.
之类的后缀名
上传后缀名为.php. .
的文件,去空,去点,再去空后剩下.php.
,windows会转为.php
但是我,还是上传出错。。。
换了环境,秒过!。。。
Pass-10 黑名单->后缀名循环绕过
由于没有循环去后缀名,可以构造去关键词之后是.php
之类的后缀名
上传后缀名为.pphphp
的文件,去关键词之后是.php
Pass-11 白名单->%00截断绕过
需要php的版本号低于5.3.29,且magic_quotes_gpc为关闭状态。经过url编码的%00解码之后就是0x00截断的那个字符。这一关是用到%00截断。因为get会解码。
strrpos()函数查找字符串在另一字符串中最后一次出现的位置。
系统在对文件名的读取时,如果遇到0x00,就会认为读取已结束。%00在get请求的url中会被服务器解码成0x00,服务器认为,”已经结束了“。
在抓包上传数据中发现有save_path=../upload/
,在path后面添加3.php%00
,则拼接完的路径,服务器只认前半部分save_path=../upload/3.php
。从而完成绕过。
淦,换了环境,还是秒过!。。。原来的那个环境会检测get的参数,报400错误
Pass-12 白名单->%00截断绕过
相对于11关,就是提交方式从get换成了post,get会自动将%00解码成0x00,但是post不会,在抓包后修改完路径需要将%00
用url解码,再提交完成绕过。
Pass-13 图片马,文件包含利用
读取文件头2字节,通过判断文件识别码区分文件类型
copy
命令制作的图片马,将后门包含在文件尾
copy 1.jpg/b + 2.txt 3.jpg
上传,图片包含,过。
Pass-14 图片马,文件包含利用
**使用getimagesize()
**检查文件格式。
如果copy制作的图片马图像损坏,用winhex搞(我没遇到过,读取图片用/b没问题的)。
上传,图片包含,过。
Pass-15 图片马,文件包含利用
**使用exif_imagetype()
**检查文件格式。这个函数会读取图像的第1个字节判断, 还会对图片的签名做检查(???)。
上传,图片包含,过。
Pass-16 图片马,文件包含,二次渲染
检查mime类型与文件名后缀一致且白名单,将上传的图片二次渲染后保存
是不是可以竞争?有先保存后渲染的步骤
上传后原先嵌入的代码被清除。
gif二次渲染比较简单,随便改,二次渲染之后大部分内容不变
png找一张偏移地址19是03的照片,在PLTE后插入代码,然后计算CRC插入,完成图片马(直接拿别人写好的脚本就很好)
jpg 用jpgpayload去插入,可能要多尝试几遍
Pass-17 白名单,资源竞争
有时候上传,程序会将文件删除或者重命名,这个时候可以进行条件竞争。
源码中,先将文件移动到目标目录中,再校验确认是否需要将该文件删除,可以通过大量重复上传,期间读取文件从而运行该文件使得getShell。
但是运行结果出现Warning: Unknown: failed to open stream: No such file or directory in Unknown on line 0
不改也偶有能刷出来。
解决方案:在php.ini中加一行user_agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
改了也偶有刷不出来。
Pass-18 白名单,条件竞争
源码中,先checkExtension(),move(),然后renameFile()。
利用apache可以解析多后缀特性(如7.php.7z可以被解析成php),但是php会被改名改掉,所以尝试需要在它改名前,完成访问运行该php。
在7.php.7z
文件中加入<?php fputs(fopen('phpinfo.php','w'),'<?php phpinfo(); ?>');?>
一旦该文件成功执行,则可以生成phpinfo文件
源程序好像有bug,并不会上传到upload文件夹里,而是上传到根目录下,并且命名会带有uploadxxx字样,改了源码中的setdir函数,程序上传到upload中,实验正常进行。
Pass-19 黑名单 名单不全
- 上传命名后缀名为PHP即可完成上传访问解析执行。
- 使用0x00截断,(.php
0x00
不在黑名单中,而0x00
在保存文件时会自动去掉)抓包改保存名即可上传
Pass-20白名单 代码审计
代码白名单检测MIME,保存文件名的后缀名,都在白名单中则重组文件名(保存文件名数组中第一个字符串+保存文件后缀名,去掉. .
中间字符串)。然后移动文件同时重命名。
代码审计
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
代码中存在if判断,explode()
条件执行。可以让他不执行,则$ext = end($file)
会拿到数组最后一个字符串。
构造数据包save_name[0] = a.php; save_name[2]=jpg
拼接新的文件名是$file_name = reset($file) . '.' . $file[count($file) - 1];
count($file)会统计$file数组中的元素数量(不一定是最后一个)所以就可以是a.php.
,我的天。
总结:白名单检测拿到数组最后一个,拼接的后缀名的时候拿到一个空的。因为一个是end($file),而一个是$file[count($file) - 1]
explode('.',$s)
将字符串s按.切割,返回切割后的数组。 "nihao.jpg.php."
切割后返回4个字符串。“nihao”,“jpg”,“php”,""。
数据包部分修改为
-----------------------------3628888705307336180839174379
Content-Disposition: form-data; name="save_name[0]"
upload-20.php
-----------------------------3628888705307336180839174379
Content-Disposition: form-data; name="save_name[2]"
jpg
完成上传访问解析执行。
也可以构造,解析为upload-20.php/.jpg
这样的目录文件名,即
-----------------------------3628888705307336180839174379
Content-Disposition: form-data; name="save_name[0]"
upload-20.php/.
-----------------------------3628888705307336180839174379
Content-Disposition: form-data; name="save_name[2]"
1
-----------------------------3628888705307336180839174379
Content-Disposition: form-data; name="save_name[2]"
jpg
但是这个方案我遇到了 文件上传失败(可以绕过检测,但是保存失败)。
畸形解析
IIS 6.0解析利用方法有三种:
-
目录解析
文件目录为image.asp/qq.jpg 则qq.jpg会被当成asp执行(php同理)
-
文件解析
正常文件为 image.jpg但文件名为 image.asp;.jpg或 xxx.aps;xxx.jpg 会被当成asp执行(php同理)
-
默认解析
IIS6.0 默认的可执行文件除了asp还包含这三种
/wooyun.asa
/wooyun.cer
/wooyun.cdx
Apache
Apache将从右至左开始判断后缀,若x3非可识别后缀,再判断x2,直到找到可识别后缀为止,然后将该可识别后缀进解析
test.php.x1.x2.x3则会被解析为php
Nginx<8.03
解析漏洞
在正常图片访问(如http://localhost/upload/a.jpg
)后加上/1.php
(http://localhost/upload/a.jpg/1.php
),则图片马会被解析执行。