Web#

babyphp#

点击scan后提示Google源码。
Google找到源码https://github.com/xl7dev/WebShell/blob/master/Php/scanner.php。
除了端口扫描功能外还有一个基于curl的内网代理功能。
getCss函数对使用curl获取的query参数url内容中的link标签进行了提取,并使用file_get_contents包含文件并输出。
这里在自己的服务器上构造一个link标签,使用file协议读文件,并满足含有http://以及正则表达式中的.css。指定url为自己服务器,即可实现任意文件读。
访问/flag.php发现有文件,读取flag.php得到flag。
payload:

1
<link href="file:///var/http://.css/../../www/html/flag.php">

cloudstorage#

app.js中可以得知题目要求ssrf访问本地/flag地址获得flag。
panel.js中/admin路径使用request.get访问了给定地址fileUrl,访问前使用check对地址进行了校验。
utils.js中的check要求地址是一个http地址,并验证地址dns解析后是否是公网地址且是服务器地址,且端口号为非80和8080端口,所以我们无法直接一次访问ssrf本地地址,考虑跳转访问。
dnslookup使用的ip-api.com的服务查询指定域名的dns记录,而执行request时会重新通过本机再次解析dns。并且在request前还sleep了5s,考虑DNS Rebinding。
在自己服务器上使用 https://github.com/nopernik/mpDNS 搭建一个简易的dns服务器,并设置为一个子域名的NS记录。
先尝试远端调用check函数使用ip-api.com解析域名,服务器上得到ip-api.com的ip地址。编写程序,当访问者为ip-api.com的ip地址时返回题目公网地址,其他地址返回我们自己服务器的地址。
此时在自己服务器非80和8080端口上用nginx监听,并rewrite到 http://127.0.0.1/flag 上,跳转实现对服务的本地访问,得到 flag。
mpdns.py修改:

1
2
3
4
5
6
7
8
def checkMacro(q,query,peer):
...
if macroType == 'custom':
if peer[0] == '108.162.244.180' or peer[0] == '162.158.162.5':
return '121.37.175.154'
else:
return 'xxx.xxx.xxx.xxx' # Server IP
...

names.db:

1
11.hw.ncat.xyz      A   {{custom}}