近期看到了很多大佬的面经,都问到了gopher扩展攻击面的知识,之前使用gopher利用过ssrf漏洞,但也仅仅停留在会用,并不是很了解,(今天挂着网课来总结一下),也算是逃课专业户了。
什么是gopher协议
gopher协议是一个古老且强大的协议,可以理解为是http协议的前身,他可以实现多个数据包整合发送。通过gopher协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。
很多时候在SSRF下,我们无法通过HTTP协议来传递POST数据,这时候就需要用到gopher协议来发起POST请求了。
gopher的协议格式如下:
gopher://<host>:<port>/<gopher-path>_<TCP数据流>
<port>默认为70
发起多条请求每条要用回车换行去隔开使用%0d%0a隔开,如果多个参数,参数之间的&也需要进行URL编码
但是gopher协议在各个语言中是有使用限制的。
语言 | 支持情况 |
---|---|
PHP | --wite-curlwrappers且php版本至少为5.3 |
Java | 小于JDK1.7 |
Curl | 低版本不支持 |
Perl | 支持 |
ASP.NET | 小于版本3 |
gopher发送请求
curl
为了熟悉下gopher,我本机curl发送一下gopher请求到 我的虚拟机。
最后虚拟机启动nc监听来接收一下消息。
查看下curl版本,看看支不支持gopher协议
gopher协议传递HTTP的GET请求
gopher在发送请求时候,必须进行URL编码
我本地准备PHP代码如下
<?php
echo $_GET['name'];
?>
http访问并抓包
get型的http数据包如下
GET /testg.php?name=xxx HTTP/1.1
Host: 10.211.55.2
直接在Burpsuite 中将数据进行编码(比较方便)
编码的时候在最后一定要补%0d%0a代表结束。
Burpsuite编码后
%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32
结尾没有%0d%0a我们手动添加一下。
转换为gopher
curl gopher://10.211.55.2:80/_%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a
gopher协议传递HTTP的POST请求
修改本地代码如下
<?php
echo $_POST['name'];
?>
我们用gopher协议传递POST请求时,必须要包含这四个,还有一个post传参。
转换为gopher
curl gopher://10.211.55.2:80/_%50%4f%53%54%20%2f%74%65%73%74%67%2e%70%68%70%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%2d%77%77%77%2d%66%6f%72%6d%2d%75%72%6c%65%6e%63%6f%64%65%64%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%38%0d%0a%0d%0a%6e%61%6d%65%3d%78%78%78%0d%0a
关于gopher协议的SSRF攻击
这里找了一道ctfshow上面的题目,在有SSRF漏洞的场景下,利用gopher解题。
打开无密码的MySQL
关于MySQL无密码
https://paper.seebug.org/510/
MySQL客户端连接并登录服务器时存在两种情况:需要密码认证以及无需密码认证。当需要密码认证时使用挑战应答模式,服务器先发送salt然后客户端使用salt加密密码然后验证;当无需密码认证时直接发送TCP/IP数据包即可。所以在非交互模式下登录并操作MySQL只能在无需密码认证,未授权情况下进行,本文利用SSRF漏洞攻击MySQL也是在其未授权情况下进行的。
先说一下解题的过程。
一般 SSRF 打内网应用主要还是通过协议,比如用的比较多的是 gopher
无论是用 gopher 攻击 redis、mysql、还是 ftp,这些主要都是基于 tcp 协议为主。这和 gopher 协议的基本格式有关我们前面也提到了
想要打 MySQL 就需要知道 MySQL 通信时的 TCP 数据流,才能知道要怎么和 MySQL 通信,这里可以通过 Wireshark 抓包来分析。我们后面说。
https://github.com/tarunkant/Gopherus
直接用这个工具,他包含常见的应用 gopher 数据包的格式构造, 原理也是通过 Wireshark 抓包分析,然后写脚本。
这串payload粘贴到returl参数下面,生成的 POC 里,_ 字符后面的内容还要 进行url编码。因为 PHP接收到POST或GET请求数据,自解码一次。
接下来就是找flag的位置了。
wireshark抓取3306原始数据包
接下来在本地抓包,还原一下这个工具的原理。
抓包与MySQL通信时的TCP数据流,我们本地新建一个MySQL用户并且无密码
CREATE USER 'Sch0lar'@'localhost';
GRANT USAGE ON *.* TO 'Sch0lar'@'localhost';
GRANT ALL ON *.* TO 'Sch0lar'@'localhost';
接下来使用tcpdump来监听抓取3306认证的原始数据包:
# lo 回环接口网卡 -w 报错 pcapng 数据包
tcpdump -i lo port 3306 -w mysql.pcapng
紧接着本地连接一下MySQL来测试一下命令
然后中止 tcpdump 使用 Wireshark 打开 mysql.pcapng
数据包,追踪 TCP 流 然后过滤出发给 3306 的数据:
抓包这里有一个坑 我这边正常情况wireshrak抓不到包,查了一阵子资料发现,可能是默认使用了SSL安全链接模式才导致我们无法抓包,
--ssl-mode=disabled
表示禁用SSL安全连接模式
再次链接抓包。
(看了国光大佬的博客,和其他大佬的博客他们并没有加--ssl-mode=disabled
,就能抓到包)猜测原因可能是MySQL版本的问题 可能高版本默认就会采用SSL安全模式进行连接。
保存为原始数据,并生成gopher数据流
生成gopher数据流,采用如下脚本
import sys
def results(s):
a=[s[i:i+2] for i in range(0,len(s),2)]
return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)
if __name__=="__main__":
s=sys.argv[1]
print(results(s))
大致就是这么一个流程。
语言表达可能有点问题,哪里理解有误还请大佬们指出来