什么是 SSRF

大家使用的服务中或多或少是不是都有以下的功能:

  • 通过 URL 地址分享内容
  • 通过 URL 地址把原地址的网页内容调优使其适合手机屏幕浏览,即所谓的转码功能
  • 通过 URL 地址翻译对应文本的内容,即类似 Google 的翻译网页功能
  • 通过 URL 地址加载或下载图片,即类似图片抓取功能
  • 以及图片、文章抓取收藏功能

简单的来说就是通过 URL 抓取其它服务器上数据然后做对应的操作的功能。以 ThinkJS 代码为例,我们的实现方法大概如下:

const request = require('request-promise-native');
module.exports = class extends think.Controller {async indexAction() {const { url } = this.get();const ret = await request.get(url);// 这里是处理抓取数据的逻辑// ...this.ctx.body = ret;}
}
复制代码

本来是个不错的功能,但是当用户输入一个服务器可访问的内网地址,这个情况下它就会把内网的内容抓取出来展现给外网的用户。大多数公司会在内网中放置一些与公司相关的资料和关键数据,如果应用程序对用户提供的URL和远端服务器返回的信息没有进行合适的验证和过滤,就可能存在这种服务端请求伪造的缺陷,即 Server-Side Request Forgery,简称 SSRF。

SSRF 的危害

简单来说如果你的这个功能存在 SSRF 漏洞的话,相当于在攻击者和内网之间牵了根线,透过该通能攻击者可以间接访问到内网。攻击者可以利用 SSRF 实现的攻击主要有 5 种:

  1. 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 Banner 信息
  2. 攻击运行在内网或本地的应用程序(比如溢出)
  3. 对内网 Web 应用进行指纹识别,通过访问默认文件实现
  4. 攻击内外网的 Web 应用,主要是使用 GET 参数就可以实现的攻击
  5. 利用 file 协议读取本地文件

其中最后一条的实现方式是用户输入 file:// 本地文件协议地址,如果不做判断,程序很可能就会把本地文件读取出来返回给用户,例如 file:///etc/password 服务器系统密码。

防御方法

首先我们需要禁用掉不需要的协议,仅允许 HTTP(s) 请求,防止最后一条使用 file:// 等其它协议引起的问题,然后我们需要对输出内容进行判断,例如我应该输出一张图片,如果抓取返回回来的是一段文本我们就不应该返回。以及如果抓取远端地址导致报错返回的情况,我们需要统一处理返回给用户的内容,而不是直接将远端服务器的内容返回给用户,这样让攻击者了解到了更多远端服务器的信息。

除了输出内容的处理,我们还要对输入地址进行限制,过滤内网 IP,限制访问内网行为。以之前的示例代码为例,正常我们会增加如下处理:

const ip = require('ip');
const dns = require('dns');
const { parse } = require('url');const lookupAsync = think.promisify(dns.lookup, dns);
module.exports = class extends think.Logic {async indexAction() {const { url } = this.get();const { protocol, hostname } = parse(url);// 判断协议if( !/https?:/i.test(protocol) ) {return this.fail();}// 判断内网IPcost host = await lookupAsync(hostname);if( ip.isPrivate(host) ) {return this.fail();}}
}
复制代码

短链接绕过

大部分情况下这样处理是没有问题的,不过攻击者可不是一般人。这里存在一个两个可以绕过的方式,首先是短链接,短链接是先到短链接服务的地址之后再302跳转到真实服务器上,如果攻击者对内网地址进行短链处理之后以上代码会判断短链服务的 IP 为合法 IP 而通过校验。

针对这种绕过方式,我们有两种方法来阻止:

  1. 直接根据请求返回的响应头中的 HOST 来做内网 IP 判断
  2. 由于跳转后的地址也还是需要 DNS 解析的,所以只要在每次域名请求 DNS 解析处都做内网 IP 判断的逻辑即可

DNS 重新绑定绕过

另外一种绕过方式是利用 DNS 重绑定攻击。

DNS如何重新绑定的工作

攻击者注册一个域名(如attacker.com),并在攻击者控制下将其代理给DNS服务器。 服务器配置为很短响应时间的TTL记录,防止响应被缓存。 当受害者浏览到恶意域时,攻击者的DNS服务器首先用托管恶意客户端代码的服务器的IP地址作出响应。 例如,他们可以将受害者的浏览器指向包含旨在在受害者计算机上执行的恶意JavaScript或Flash脚本的网站。

恶意客户端代码会对原始域名(例如attacker.com)进行额外访问。 这些都是由同源政策所允许的。 但是,当受害者的浏览器运行该脚本时,它会为该域创建一个新的DNS请求,并且攻击者会使用新的IP地址进行回复。 例如,他们可以使用内部IP地址或互联网上某个目标的IP地址进行回复。

via: 《DNS 重新绑定攻击》

简单来说就是利用 DNS 服务器来使得每次解析返回不同的 IP,当在校验 IP 的时候 DNS 解析返回合法的值,等后续重新请求内容的时候 DNS 解析返回内网 IP。这种利用了多次 DNS 解析的攻击方式就是 DNS 重新绑定攻击。

由于 DNS 重新绑定攻击是利用了多次解析,所以我们最好将校验和抓取两次 DNS 解析合并成一次,这里我们也有两种方法来阻止:

  1. 将第一次 DNS 解析得到的 IP 直接用于第二次请求的 DNS 解析,去除第二次解析的问题
  2. 在抓取请求发起的时候直接判断解析的 IP,如果不符合的话直接拒绝连接

针对以上解决方法,有开发者直接封装了 ssrf-agent 模块,使用的时候只要将其传入即可实现一次解析,多次判断的功能,下面是简单的使用示例:

const ssrfAgent = require('ssrf-agent');
const request = require('request-promise-native');module.exports = class extends think.Controller {async indexAction() {const { url } = this.get();try {const ret = await request(url, {agent: ssrfAgent(url)});this.ctx.body = ret;} catch(e) {return this.fail();}}
}
复制代码

后记

SSRF 可以说是经久不衰的漏洞攻击了,早些年百度、人人、360搜索等都有过相应的案例。一般以下场景会可能存在 SSRF 问题,我们需要多加注意:

  1. 能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
  2. 从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
  3. 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
  4. Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
  5. 文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)

参考资料:

  • 《[安全科普]SSRF攻击实例解析》

  • 《浅析SSRF原理及利用方式》

  • 《SSRF 服务端请求伪造》

  • 《360CERT——某游戏平台客户端DNS Rebinding攻击预警》

  • 《关于DNS-rebinding的总结》

  • 《DNS Rebind Toolkit - 用于创建DNS重绑定攻击的前端JavaScript工具包》

Web安全漏洞之SSRF相关推荐

  1. Web漏洞之SSRF攻击汇总

    目录 靶场拓扑设计 x.x.x.x:8080 - 判断 SSRF 是否存在 172.72.23.21 - SSRF 获取本地信息 FILE 协议获取本地信息 172.72.23.1/24 - SSRF ...

  2. Web漏洞之SSRF(服务器端请求伪造)

    文章目录 一.漏洞场景 二.漏洞描述 三.漏洞原理 四.漏洞危害 五.漏洞评级 六.漏洞验证 七.漏洞利用 八.漏洞防御 一.漏洞场景 服务器会根据用户提交的URL 发送一个HTTP 请求.使用用户指 ...

  3. 米斯特白帽培训讲义(v2)漏洞篇 SSRF

    米斯特白帽培训讲义 漏洞篇 SSRF 讲师:gh0stkey 整理:飞龙 协议:CC BY-NC-SA 4.0 很多 Web 应用都提供了从其他服务器上获取数据的功能.使用用户指定的 URL,web ...

  4. (43.1)【web应用漏洞发现】漏洞平台、开发框架、CMS漏扫工具

    目录 WEB应用漏洞探针 一.已知CMS 1.1.漏洞平台 1.1.1.cnvd 1.1.2.seebug 1.1.3.exploit-db 1.1.4.Github-offensive-securi ...

  5. Web安全漏洞及安全防护

    一.Web安全概述 搭建一个Web应用不仅要考虑其功能与性能的完善性,更要考虑其安全性.Web应用搭建好以后,在暴露于外网的情况下是否是安全的?是否会遭受攻击者的攻击?是否对敏感数据.敏感代码及敏感后 ...

  6. 网络安全笔记 -- CSRF漏洞、SSRF漏洞

    1. CSRF漏洞 1.1 CSRF漏洞原理 CSRF(Cross-Site Request Forgery:跨站点请求伪造) CSRF 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的 ...

  7. Web常见漏洞及修复建议

    目录 1.SQL注入 漏洞描述 Web程序中对于用户提交的参数未做过滤直接拼接到SQL语句中执行,导致参数中的特殊字符破坏了SQL语句原有逻辑,攻击者可以利用该漏洞执行任意SQL语句,如查询数据.下载 ...

  8. 渗透测试常用WEB安全漏洞扫描工具集合

    渗透测试阶段信息收集完成后,需根据所收集的信息,扫描目标站点可能存在的漏洞,包括SQL注入漏洞.跨站脚本漏洞.文件上传漏洞.文件包含漏洞及命令执行漏洞等,然后通过这些已知的漏洞,寻找目标站点存在攻击的 ...

  9. WEB编辑器漏洞手册.zip

    WEB编辑器漏洞手册.zip 点击进入高速下载通道 转载于:https://www.cnblogs.com/gwrjy/p/7157680.html

最新文章

  1. linux 修改java版本_Linux 有问必答:如何在 Linux 中改变默认的 Java 版本
  2. oracle常见表,ORACLE常见视图和表整理
  3. 多种负载均算法及其 Java 代码实现 --转
  4. GraphViz :1 安装和简单使用
  5. hp designiet 500_2020年HP学院壁纸
  6. mysql 下 计算 两点 经纬度 之间的距离 计算结果排序
  7. OracleOraDb11g_home1TNSListener服务启动立马自动关闭问题解决
  8. python 物联网开发板_物联网学什么开发板好?
  9. linux 安装tcl命令,TCL/TK Linux下安装 | 勤奋的小青蛙
  10. rocketmq 初探(五)
  11. 在XML文件中定义动画(1)
  12. Opencv——图像膨胀
  13. 7.1 pdo 宝塔面板php_大商创X2.0宝塔环境保姆式完整安装教程
  14. 刚刚!2020“中国高被引学者” 榜单发布:清华、北大、浙大位居内地前三!
  15. 关于“EXP-00056: ORACLE error 12154 encountered”的解决方法
  16. 初始化问题(其中含有盲区,{}和()的区别)
  17. python 包的使用 (二)——tesseract识别图片中的文字
  18. AndroidStudio与eclipse打包的时候报错。Error:(4) Error: ssdk_instapager_login_html is not translated in......
  19. j2me 关于MIDP 读取jad文件
  20. python课程设计汽车销售管理系统_汽车销售管理系统--课程设计

热门文章

  1. spl_autoload_register函数
  2. 05_视图控制器_1
  3. [Codeforces677B]Vanya and Food Processor(模拟,数学)
  4. LightOj_1030 Discovering Gold
  5. Js 对象添加属性
  6. python程序运行结果始终为0_Python:始终运行程序
  7. 现在想转行学习前端,该怎么学才能最快入门
  8. 整个行业都缺Web前端工程师,你还在问Web前端工作好找吗?
  9. P - C语言实验——某年某月的天数
  10. hbuilderx版本怎么更新到新版本_2.9版本快雪迎春更新公告