SecMap - SSRF

本文最后更新于:1 个月前

SecMap - SSRF,在内外网边界上打个洞

SecMap - SSRF

简介

SSRF,服务端请求伪造(Server-side Request Forge)的缩写。产生的原因是服务端提供了从其他服务器获取数据的功能,但没有对地址和协议等做过滤与限制。常见的一个场景就是:服务器通过用户输入的 URL 来获取图片。这个功能如果被恶意使用,可以利用存在缺陷的 Web 应用作为跳板来攻击远程和本地的服务器。

分类

ssrf 主要分为:

  1. 回显型 ssrf
  2. 无回显型 ssrf

有回显型的 ssrf 就是会将访问到的信息返回给攻击者,而无回显的 ssrf 则不会,但是可以通过带外通道(比如 dnslog)或者访问开放/未开放的端口导致的延时来判断。

危害

ssrf 危害的本质是穿透了访问控制,这个访问控制一般来说是内外网边界,但其实也可以是相互信任的公网服务器之间的访问控制。

我们可以这么考虑,作为攻击者,在外网想攻击位于内网的服务,这个时候如果有个未授权的 socks 代理可以直通内网,那是最好的,因为可以转发很多协议;那如果只有未授权的 HTTP 代理呢?存在 ssrf 漏洞就相当于对外开放了一个比较难用的未授权的 HTTP 代理。

如果真的是有一个 HTTP 代理,那我们还方便进行渗透测试;如果是 ssrf,无法直接配置给浏览器或者是类似 Burp Suite 这种工具使用;就算可以用来探测端口,那又能怎么样呢?这么看来 ssrf 的用处只限于攻击内部完全没有认证的页面(数据泄露)/接口(可能造成 RCE);

好在我们还有其他协议的支持,让 ssrf 从只能发出 HTTP 请求变成可以发出更多协议类型的请求。

常用协议

在 ssrf 里常用的有:

  1. http://: 这个是我们最熟悉的,可用于浏览未授权页面、调用未授权接口、存在漏洞的 Web 组件直接上 exp、探测内网主机存活、端口开放情况,低配版 HTTP 代理。
  2. gopher://: “万金油” 协议。利用此协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求,极大拓宽了 SSRF 的攻击面。
  3. dict://: 无法插入 \r\n 并且前后均有垃圾数据。
  4. file://: 读取本地文件,这个没啥好说的。
  5. ldap://: 有垃圾数据,可以插入 \r\n

上一篇已经仔细讨论过各种协议,这里就不再展开说了,详见:

https://www.tr0y.wang/2021/05/17/SecMap-非常见协议大礼包/

漏洞点

一句话,能够对外发起网络请求的地方,就有可能有 ssrf:

  1. 在线识图
  2. 在线翻译:百度翻译,有道翻译
  3. 图片的加载/下载/收藏/分享
  4. 文章的订阅/收藏/分享/转载
  5. 接收邮件服务器地址的邮件系统
  6. 可以收取其他邮箱邮件的 Web Mail(POP3/IMAP/SMTP)
  7. 文件处理,如 FFmpeg(concat:http://tr0y.wang/a.m3u8|file:///etc/passwd)、ImageMagick(fill 'url(http://127.0.0.1)')、XML(XXE 漏洞)…
  8. 请求远程服务器资源,远程 URL 上传,静态资源图片文件等
  9. 数据库内置功能,比如 MongoDB 的 copyDatabase 函数(mongo <= v4.0),将未授权的 MongoDB 变成一个无回显 ssrf(db.copyDatabase('\r\nset key Tr0y\r\nquit\r\n', 'test', '127.1:6379')
  10. 主从任务:master 节点(攻击者)可以派发给 slave 节点任务;
  11. Webhooks
  12. 其他:从 URL 关键字中寻找:share、url、link、src、source、target、sourceURl、imageURL、domain 等等,这些关键字可以配合 Google 的搜索语法去寻找 ssrf 漏洞
  13. 与 CRLF 组合

攻击技巧

  1. 利用非常见协议,dict、gopher 等
  2. 添加端口可能绕过匹配正则:http://127.0.0.1/ 改为 http://127.0.0.1:80/
  3. 127.0.0.1 与 localhost 在大部分情况下都是等价的,取决于 hosts 配置
  4. 利用 IPv6:http://[::]:80/ 相当于 http://127.0.0.1
  5. 利用 @/# 可能绕过域名限定的正则:http://[email protected] 相当于 http://127.0.0.1http://127.0.0.1#tr0y.wang 也是 http://127.0.0.1
  6. 利用进制:以 127.0.0.1 为例,首先,ip 可以没 .,比如 2130706433(十进制),0x7F000001(十六进制);也可以有 .,比如 0x7F.0x000.0x001(十六进制)、0177.0000.0001(八进制),甚至可以混用,比如 0x7F.000.0x001(十六进制 加 十进制);还可以合并,127.0.0.1 == 127.0.1 == 127.1127.3.2.1 == 127.3.513 == 127.3.513 == 127.197121,注意这个合并注意只能从前到后合并,具体的计算方式,可以按照 . 分割,分别先转为 8 位二进制,然后从左到右每段直接拼在一起,最后再转为十进制或者十六进制即可,有一个比较特殊的是 00.0.0.0 == 0.0.0 == 0.0 == 0,即目标服务器监听了 0.0.0.0 的服务都可以用此方法访问到。以上这几种方式可以随意组合搭配,而且其实各个进制的补 0 可以填很多个:127.0.0000000000000000000000000000000000.1
  7. 利用跳转:比如,利用短链,http://dlj.bz/kA47FD 相当于 http://127.0.0.1,本质上是利用 301 跳转,所以完全可以自己打一个 301 跳转,想怎么跳就怎么跳,别忘记同时还可以转换协议:Location: file:///etc/passwd。状态码可以是 301、302、307
  8. 利用域名 A 记录:http://localhost.tr0y.wang/ ,在域名上设置 A 记录,指向 127.0.0.1。如果你实在懒,可以用 xip.io/xip.name,它的子域名前缀就是解析的 ip 地址,比如 127.0.0.1.xip.io 的 A 记录就是 127.0.0.1
  9. 利用 IDN,详见:https://www.tr0y.wang/2020/08/18/IDN/ⓉⓇ⓪ⓨ.ⓦⓐⓝⓖ 等于 tr0y.wang127。0。0。1 相当于 127.0.0.1
  10. 与 CRLF 组合:比较经典的就是 Python 的 CVE(CVE-2016-5699、CVE-2019-9740、CVE-2019-9947、CVE-2019-9948),其实也是由于允许 \r\n 的存在,大大提升了通过 http:// 协议来利用的 ssrf 的杀伤力:



  11. DNS 重绑定攻击:可见:https://www.tr0y.wang/2020/11/02/DNS-3-attack-by-dns/#DNS-重绑定攻击

防御

ssrf 的修复比较复杂,需要根据业务实际场景来采取不同的方案。

首先明确此类功能的流程:

  1. 提取 URL 的域名
  2. 解析 Host 的 ip
  3. 发出请求
  4. 如果有跳转,取出 Location URL,回到第 1 步;否则继续下一步
  5. 发出最终的请求,实现业务逻辑

那么自然就需要注意:

  1. 限制请求的 ip 和端口:一般的业务禁掉私有 ip 完全可行;限制端口可有效降低攻击面
  2. 只允许 HTTP/HTTPS 协议,如果可以的话只允许 HTTPS 协议:防止攻击者用其他协议绕过,减少攻击场景到只能打 web 服务(但对于 HTTPS 协议存在骚操作,请参考 资料 2)。只允许 HTTPS 有两个作用,一个是 SSRF 一般是为了打内网应用,而内网应用很少上 HTTPS 的,所以没法利用;另一方面是可以解决 DNS 重绑定攻击的问题。
  3. 解析/跳转(没必要就别跟随跳转了)后一定要进行检查:防止利用各种形式的 ip、跳转绕过
  4. 完善正则表达式:这个没啥通用的技巧,根据具体的业务需求定,需要经过完善测试(限制 @ 的使用、防止用子域名前缀绕过等等)
  5. 去除 URL 中的特殊字符:防止因为 url 解析模块对 host 的提取解析结果存在歧义而造成的安全问题(强烈建议阅读 资料 1
  6. 过滤返回的信息/统一错误信息:将有回显变成无回显,提升利用难度(比如 file:// 就直接废掉了)
  7. 只解析一次 ip:最后真正发起请求去获取资源的时候,可以把域名替换成之前就已经解析好的 ip,这样来避免重复解析带来的 DNS 重绑定攻击问题。
  8. 可以考虑建立一个发起请求的代理集群。外网代理集群专门用于业务对外网发起请求;另一个代理集群专门用于业务对内网发起请求。然后在网络层面上保证外网代理集群无法与内网直接互通。

资料

  1. ssrf 利用新纪元:
  2. ssrf 遇到 TLS 的利用方式:
  3. 猪猪侠在乌云大会上关于 ssrf 的分享:


本来下周要随公司回西电做宣讲的
议题与内容都准备好了
奈何内部沟通到出了点问题
没法通过公司的出差去了
嗯确实挺糟心的

然后最近一直在规划未来的发展
有很多想不明白的地方
这段时间确实颇有压力
所以虽然没法去参加宣讲和会议
但我还是决定下周回趟西电
散散心顺便找挚友聊聊天
等这段时间过去了
我再和大家聊聊最近的思考与决策