本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.
描述
很多 web 应用都提供了从其他的服务器上获取数据的功能.使用用户指定的 URL,web 应用可以获取图片,下载文件,读取文件内容等.这个功能如果被恶意使用,可以利用存在缺陷的 web 应用作为代理攻击远程和本地的服务器.这种形式的攻击称为服务端请求伪造攻击(Server-side Request Forgery).
一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
相关文章
相关案例
https://github.com/httpvoid/writeups/blob/main/Hacking-Google-Drive-Integrations.md
相关工具
相关靶场
payload
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery
相关资源
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery#
writeup
内部端口扫描
攻击内网服务 (例如: redis,memcache,或存在 log4j rce 的服务)
攻击 Kubelet API : 在云环境中,可通过 Kubelet API 查询集群 pod 和 node 的信息,也可通过其执行命令。为了安全考虑,此服务一般不对外开放。但是,攻击者可以通过 SSRF 去访问 Kubelet API,获取信息和执行命令。
攻击 Docker Remote API:Docker Remote API 是一个取代远程命令行界面(rcli)的 REST API,默认开放端口为 2375。此 API 如果存在未授权访问,则攻击者可以利用其执行 docker 命令,获取敏感信息,并获取服务器 root 权限。因此为了安全考虑,一般不会在外网开放,此时我们就可以通过 SSRF 去尝试攻击那些不对外开放的 Docker Remote API。其过程与攻击 Kubelet API 类似。
越权攻击云平台内其他组件或服务:由于云上各组件相互信任,当云平台内某个组件或服务存在 SSRF 漏洞时,就可通过此漏洞越权攻击其他组件或者服务。例如用户正常请求服务 A 时,云 API 层会对请求进行校验,其中包括身份、权限等。如果服务 A 存在 SSRF 漏洞,则可构造请求使服务 A 访问服务 B,因为服务 A 与服务 B 互相信任,所以服务 B 未校验服务 A 的请求,从而越权操作服务 B 的资源。
绕过 cdn 获取真实ip
https://webhook.site/
利用 ssrf 进行访问,产生 dos 的效果
Cloud Metadata
在云环境中,元数据即表示实例的相关数据,可以用来配置或管理正在运行中的实例。攻击通过 SSRF 去访问元数据中存储的临时密钥或者用于自启动实例的启动脚本,这些脚本可能会包含 AK、密码、源码等等,然后根据从元数据服务获取的信息,攻击者可尝试获取到受害者账户下 COS、CVM、集群等服务的权限。
metadata 泄露
java ssrf
php ssrf
在 Python 中,常用的函数有 urllib(urllib2) 和 requests 库。
CVE-2019-9740 & CVE-2019-9947
以 urllib(urllib2) 为例, urllib 并不支持 gopher,dict 协议,但 urllib 曾爆出 CVE-2019-9740、CVE-2019-9947 两个漏洞,这两个漏洞都是 urllib(urllib2) 的 CRLF 漏洞,触发点不同,其影响范围都在 urllib2 in Python 2.x through 2.7.16 and urllib in Python 3.x through 3.7.3 之间.
漏洞示例
通过 CLRF漏洞,实现换行对redis的攻击
CVE-2019-9948
该漏洞只影响 urllib,范围在 Python 2.x 到 2.7.16,这个版本间的 urllib 支持 local_file/local-file 协议,可以读取任意文件
解析差异
已目标为例 http://baidu.com@qq.com
urllib3 取到的 host 是 baidu.com
urllib 取到的 host 是 qq.com
当我们需要通过 URL 发送用户名和密码时,可以使用 http://username:password@www.xxx.com,此时 @前的字符会被当作用户名密码处理,@后面的字符才是我们请求的地址,即 http://test.com@127.0.0.1/
与 http://127.0.0.1/
请求时是相同的,而这种方法有时可以绕过系统对地址的检测。
不同进制
开发人员在提取或者过滤域名或者 IP 时,未考虑到 IP 的进制转换的影响,则存在被利用进制转换绕过的可能。浏览器不仅可以识别正常的 IP 地址,也可以识别八进制、十进制、十六进制等其他进制的 IP 地址,但是有时候开发人员会忽视这一点,因此有时,我们可以通过这一点去绕过防护。
http://www.subnetmask.info/
利用别名绕过
不规范格式
IPv6
封闭式字母数字(Enclosed Alphanumerics)字符是一个Unicode块,其中包含圆形,支架或其他非封闭外壳内的字母数字印刷符号,或以句号结尾。封闭的字母数字块包含一个表情符号,封闭的M用作掩码工作的符号。它默认为文本显示,并且定义了两个标准化变体,用于指定表情符号样式或文本表示。这些字符也是可以被浏览器识别的,而开发人员有时会忽略这一点。
jar:// 协议能从远程获取 jar 文件及解压得到其中的内容,其格式如下:
实例如下,!
符号后面就是其需要从中解压出的文件:
jar:// 协议分类:
也使用 jar 协议进行 Blind SSRF
利用
描述
dict 协议有一个功能:dict://serverip:port/name:data 向服务器的端口请求 name data,并在末尾自动补上 rn(CRLF)。也就是如果我们发出 dict://serverip:port/config:set:dir:/var/spool/cron/ 的请求,redis 就执行了 config set dir /var/spool/cron/ . 用这种方式可以一步步执行 redis getshell 的 exp,执行完就能达到和 gopher 一样的效果。原理一样,但是 gopher 只需要一个 url 请求即可,dict 需要步步构造。
对内网 redis 的利用
gopher 协议支持发出 GET、POST 请求:可以先截获 get 请求包和 post 请求包,在构成符合 gopher 协议的请求。
gopher 协议是 ssrf 利用中最强大的协议
相关文章
相关工具
格式
gopher 的默认端口是70
如果发起 post 请求,回车换行需要使用 %0d%0a,如果多个参数,参数之间的 & 也需要进行 URL 编码
发送 get 请求
如果要发送如下 payload
那么需要变为如下格式
在 HTTP 包的最后要加 %0d%0a,代表消息结束
发送 post 请求
那么需要变为如下格式
ssrf 中的利用
URL中的/不能进行两次编码,端口号不可以两次编码,协议名称不可两次转码
配合 Redis 未授权访问漏洞进行攻击
我们可以利用 Gopher 协议远程操纵目标主机上的 Redis,可以利用 Redis 自身的提供的 config 命令像目标主机写 WebShell、写 SSH 公钥、创建计划任务反弹 Shell 等,其思路都是一样的,就是先将 Redis 的本地数据库存放目录设置为 web 目录、~/.ssh 目录或 /var/spool/cron 目录等,然后将 dbfilename(本地数据库文件名)设置为文件名你想要写入的文件名称,最后再执行 save 或 bgsave 保存,则我们就指定的目录里写入指定的文件了。
绝对路径写 WebShell
redis命令
利用 Gopherus
这里将生成的 payload 要进行 url 二次编码(因为我们发送 payload 用的是 GET 方法),然后利用服务器上的 SSRF 漏洞,将二次编码后的 payload 打过去就行了:
Redis 主从复制
以 [网鼎杯 2020 玄武组]SSRFMe 这一题为例, buuoj 上有环境,方便复现
题目信息:
通过 http://0.0.0.0/ 访问本机绕过对内网IP的检测
Redis 配置了密码,为 root
利用主从复制进行 rce
利用脚本 https://github.com/xmsec/redis-ssrf
修改脚本
生成 payload,记得 URL 编码一下
rogue-server 使用这个项目的 https://github.com/Dliv3/redis-rogue-server.git
访问
相关文章
利用
开发人员在构建 SSRF 防护时,只考虑到了域名,没有考虑到域名解析后的 IP,则存在被利用域名解析服务来绕过的可能。
http://xip.io
http://nip.io
当防御方限制只允许 http(s) 访问或者对请求的 host 做了正确的校验后,可以通过 30x 方式跳转进行绕过。
比如,我们可以搭建一个服务,在收到目标服务器的请求后添加一个 Location 响应头重定向至内网服务器
开发人员在进行 SSRF 防护时,未考虑到短网址的影响,则存在被利用短网址绕过的可能。
https://a.f8x.io/
DNS重绑定
描述
DNS 重绑定攻击的原理是当我们设置恶意域名 TTL 为非常小的值时,DNS 记录仅在短时间内有效,目标服务第一次解析域名后,第二次重新请求 DNS 服务器获取新的 ip,两次 DNS 解析是有时间差的,我们可以使用这个时间差进行绕过,利用服务器两次解析同一域名的短暂间隙,更换域名背后的 ip 进行 ssrf。
利用方法如下:
在网站 SSRF 漏洞处访问精心构造的域名。网站第一次解析域名,获取到的 IP 地址为 A;
经过网站后端服务器的检查,判定此 IP 为合法 IP。
网站获取 URL 对应的资源(在一次网络请求中,先根据域名服务器获取 IP 地址,再向 IP 地址请求资源),第二次解析域名。此时已经过了 ttl 的时间,解析记录缓存 IP 被删除。第二次解析到的域名为被修改后的 IP 即为内网 IP B;
攻击者访问到了内网 IP。
注意点
java 中 DNS 请求成功的话默认缓存 30s(字段为 networkaddress.cache.ttl,默认情况下没有设置),失败的默认缓存 10s。(缓存时间在 /Library/Java/JavaVirtualMachines/jdk /Contents/Home/jre/lib/security/java.security 中配置)所以一般认为 java 不存在 DNS rebinding 问题。
在 php 中则默认没有缓存。
Linux 默认不会进行 DNS 缓存,mac 和 windows 会缓存 (所以复现的时候不要在 mac、windows 上尝试)
有些公共 DNS 服务器,比如 114.114.114.114 还是会把记录进行缓存,但是 8.8.8.8 是严格按照 DNS 协议去管理缓存的,如果设置 TTL 为 0,则不会进行缓存。
相关文章/案例
相关工具
http://ceye.io/dns-rebinding
利用方法
Dns rebinding 常见方案除了自建 dns 服务器之外,还可以通过绑定两个 A 记录,一个绑定外网 ip,一个绑定内网 ip。这种情况访问顺序是随机的,无法保证成功率。
自建 dns 服务器需要配置将域名的 dns 服务指向自己的 vps,然后在 vps 上运行域名解析脚本,内容如下
当第一次访问时,解析为外网 ip 通过 ssrf 检测,
第二次访问时,也即业务访问时,ip 会指向 127.0.0.1,从而达到了绕过目的。
修复方案
在 Check 时获取 IP 地址,后面的请求绑定此 IP
TLS Poison
过滤 url 中的特殊字符
禁用不需要的协议,只允许 HTTP 和 HTTPS 请求,可以防止类似于 file://, gopher://, ftp:// 等引起的问题。
白名单的方式限制访问的目标地址,禁止对内网发起请求。
过滤或屏蔽请求返回的详细信息,验证远程服务器对请求的响应是比较容易的方法。如果 web 应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
验证请求的文件格式,禁止跟随 301、302 跳转。
限制请求的端口为 http 常用的端口,比如 80、443、8080、8000 等。
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
- 通过对 ssrf 访问 Google Cloud Metadata,直至 RCE
- excel 中的 ssrf+xxe 读文件
- google cloud ssrf + bypass
- python 写的 ssrf 参数扫描工具
- 自动化 Fuzz SSRF 开发工具
- An automated SSRF finder. Just give the domain name and your server and chill! ;) Also has options to find XSS and open redirects
- SSRF to TCP Port Scanning, Banner and Private IP Disclosure by abusing the FTP protocol/clients
- SSRF plugin for burp Automates SSRF Detection in all of the Request
- This Lab contain the sample codes which are vulnerable to Server-Side Request Forgery attack
- SSRF (Server Side Request Forgery) testing resources
- An exhaustive list of all the possible ways you can chain your Blind SSRF vulnerability
- 该工具生成 gopher payload ,以利用 SSRF 并在各种服务器中获得 RCE
- redis ssrf gopher generater && redis ssrf to rce by master-slave-sync
- DNS rebinding toolkit
- A DNS rebinding attack framework.
- ssrf、ssrfIntranetFuzz、dnsRebinding、recordEncode、dnsPoisoning、Support ipv4/ipv6