解决方案-ssrf漏洞原理-小白信息安全入门教程

解决方案-ssrf漏洞原理-小白信息安全入门教程

漏洞英文bug_ssrf漏洞_ssrf漏洞原理

什么是SSRF

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

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

代码语言:

复制

const request = require('request-promise-native');2.module.exports = class extends think.Controller {3.  async indexAction() {4.    const { url } = this.get();5.    const ret = await request.get(url);6.    // 这里是处理抓取数据的逻辑7.    // ...8.    this.ctx.body = ret;9.  }10.}

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

SSRF的危害

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

1.可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 信息。

2.攻击运行在内网或本地的应用程序(比如溢出)。

3.对内网 Web 应用进行指纹识别,通过访问默认文件实现。

4.攻击内外网的 Web 应用,主要是使用 GET 参数就可以实现的攻击。

5.利用 file 协议读取本地文件。

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

防御方法

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

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

代码语言:

复制

const ip = require('ip');2.const dns = require('dns');3.const { parse } = require('url');4.5.const lookupAsync = think.promisify(dns.lookup, dns);6.module.exports = class extends think.Logic {7.  async indexAction() {8.    const { url } = this.get();9.    const { protocol, hostname } = parse(url);10.    // 判断协议11.    if( !/https?:/i.test(protocol) ) {12.        return this.fail();13.    }14.    // 判断内网IP15.    cost host = await lookupAsync(hostname);16.    if( ip.isPrivate(host) ) {17.      return this.fail();18.    }19.  }20.}

短链接绕过

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

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

1.直接根据请求返回的响应头中的 HOST 来做内网 IP 判断。

2.由于跳转后的地址也还是需要 DNS 解析的,所以只要在每次域名请求 DNS 解析处都做内网 IP 判断的逻辑即可。

DNS重新绑定绕过

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

DNS如何重新绑定的工作攻击者注册一个域名(如.com),并在攻击者控制下将其代理给DNS服务器。服务器配置为很短响应时间的TTL记录,防止响应被缓存。当受害者浏览到恶意域时,攻击者的DNS服务器首先用托管恶意客户端代码的服务器的IP地址作出响应。例如,他们可以将受害者的浏览器指向包含旨在在受害者计算机上执行的恶意或Flash脚本的网站。恶意客户端代码会对原始域名(例如.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');2.const request = require('request-promise-native');3.4.module.exports = class extends think.Controller {5.  async indexAction() {6.    const { url } = this.get();7.    try {8.      const ret = await request(url, {agent: ssrfAgent(url)});9.      this.ctx.body = ret;10.    } catch(e) {11.      return this.fail();12.    }13.  }14.}

结束语

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

1.能够对外发起网络请求的地方,就可能存在 SSRF 漏洞

2.从远程服务器请求资源( from URL, & RSS Feed)

3.数据库内置功能(、、MSSQL、、)

4. 收取其他邮箱邮件(POP3、IMAP、SMTP)

5.文件处理、编码处理、属性信息处理(、、DOCX、PDF、XML)

~

网络安全学习,我们一起交流

~

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值