注:本文是一篇翻译文章,原文链接:https://medium.com/@vickieli/bypassing-ssrf-protection-e111ae70727b

当在Web应用程序中找到一个可以获取的外部资源的功能。你可以从各种外部站点读取内容,并且可以请求的文件类型不会有任何限制,应用程序会立即显示所有内容。这个现象告诉你,接下来该尝试一下是否存在SSRF漏洞了。所以你开始输入:127.0.0.1。但是仅过了一秒钟,服务器返回了一个意想不到的响应:

Error. Requests to this address are not allowed. Please try again.

所以现在该做什么?

SSRF保护机制

企业确实意识到了SSRF攻击的风险。所以大多数人已经在他们的Web应用程序中实现了某种形式的SSRF保护。SSRF保护机制基本上分两种:黑名单和白名单。

黑名单指的是如果接收到的输入为列在黑名单上的地址,那么不允许这些地址且阻止请求的处理。大多数SSRF是采用的黑名单来保护不允许探测内网IP地址段。

另一方面,白名单指的是服务器只允许接收处理在预先设定好的白名单列表里包含的URL的请求,并使得其他请求处理失败。

绕过白名单

白名单通常更难绕过,因为默认情况下相对于黑名单而言,白名单更加严格。但是如果白名单中的域中存在开放的重定向漏洞,则可能存在SSRF漏洞。

如果您可以找到可利用的重定向漏洞,则可以请求重定向到内部IP地址段的白名单中的域。

如果没有正确利用白名单(例如,使用了设计不好的正则表达式),那么也可以通过使用子域名或目录的形式作为列入白名单的域名来绕过(例如,victime.com.attacker.com或attacker.com/victim.com )。

绕过黑名单

但是由于应用程序本身的需要(获取外部资源),大多数SSRF保护机制都是以黑名单形式出现。如果遇到黑名单,有很多种方法可以欺骗服务器:

利用重定向漏洞欺骗

使服务器请求你所控制的URL重定向到黑名单地址。例如可以在自己可控的Web服务器上托管如下内容的文件:

<?php header(“location:http://127.0.0.1”);?>

假设此文件位于http://attakcer.com/redirect.php ,这样当你的目标服务器请求http://attakcer.com/redirect.php ,目标服务器实际上被重定向到http://127.0.0.1 ,这是一个受限制的内部地址。

利用DNS欺骗

修改可控的域的A记录或者AAAA记录,并使其指向受害者网络的内部地址。例如,假设http://attacker.com 是你可控的子域名。你可以创建自定义主机名到IP地址映射,使得http://subdomain.attacker.com 解析到127.0.0.1。现在当目标服务器请求http://attacker.com ,它会认为你的域位于127.0.0.1,并从改地址请求数据。

使用IPv6地址

尝试使用IPv6地址而不是IPv4地址,因为服务器可能尚未针对IPv6实施而实施了针对IPv4的保护机制。

切换编码

有很多不同的编码URL或地址可以使服务器正常解析,但是可以绕过黑名单的限制。这些编码包括十六进制编码,八进制编码,双字编码,URL编码和混合编码。

  • 十六进制编码

    十六进制编码是一种表示通过以16为基底的字符表现形式(字符从0到F),而不是以10为基底(字符从0到9)。说明服务器可以理解hex编码后的IP地址。将10进制IP地址转为16进制的IP地址,你需要计算每个段,例如

    127.0.0.1 -> 0x7f.0x0.0x0.0x1

    以0x开始说明这是一个hex编码后的数字。

  • 八进制编码

    八进制编码是一种以8为基底表现字符的形式。和转hex编码差不多,你可以将IP地址转为8进制的IP地址形式。例如

    127.0.0.1 -> 0177.0.0.01

    这样的情况下,0开头的数字基本就是8进制格式下的数字。

  • 双字符编码

    dword代表双字符,是一个32位整数。IP地址基本上是32位数,分为4个八位字节,并以10进制写入。例如127.0.0.1实际上就是01111111.00000000.00000000.00000001。所以当我们01111111000000000000000000000001转为一个10进制数时,也就是得到了双字符形式下的IP地址。

    那么如果将127.0.0.1转为双字符形式?即127*256³+0*256²+0*256¹+1*256⁰,计算得到2130706433。意味着如果输入为http://2130706433 而不是http://127.0.0.1 ,仍然可以正常解析。

  • URL编码

    URL中的每个单独字符可以用其指定的十六进制数表示,如果它们前面带有%符号。例如,单词“localhost”可以用其URL编码来表示,“%6c%6f%63%61%6c%68%6f%73%74”。因此,当服务器阻止对内部主机名(例如“localhost”)的请求时,请尝试使用URL编码的等效命令。

  • 混合编码

    这是混搭时间!你也可以使用编码技术的组合来试图欺骗服务器:也许这会起作用?

    127.0.0.1 -> 0177.0.0.0x1

结论

这只是攻击者在他们的武器库中可能拥有的绕过方法的一小部分。而且我很明确的是有更多创造性的方法可以绕过防御利用SSRF漏洞。

如果找不到有效的绕过,需要切换思路并思考:如果为这个功能设置SSRF保护?设计然后记住这个防御逻辑。然后尝试绕过你自己设计的保护机制。有没有可能在设计时错过某些细节?该应用程序的开发人员也同时错过了某些细节?

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖