SSRF(Server-Side Request Forgery:服务器端请求伪造)
严正声明:本文仅限于技术讨论,严禁用于其他用途。
文章目录
ssrf漏洞原理
- 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞
- SSRF漏洞形成的原因主要是服务端提供了从其他服务器应用获取数据的功能,并且未对客户端所传输过来的URL参数进行严格过滤与限制,导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
- 数据流:攻击者----->服务器---->目标地址
绕过方案
- 一般情况下利用URL解析导致SSRF过滤被绕过基本上都是因为后端通过不正确的正则表达式对URL进行了解析。而在2017年的Blackhat大会上,Orange Thai 在blackhat中发表的演讲《A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages! 》中介绍了SSRF攻击的一个新的角度———利用不同编程语言对URL的处理标准来绕过SSRF过滤,从而实施攻击。该方式主要是利用URL解析器和URL请求器之间的差异性发起攻击,由于不同的编程语言实现URL解析和请求是不一样的,所以很难验证一个URL是否合法。
很难验证一个URL是否合法的原因在于:
1.在 RFC2396/RFC3986 中进行了说明,但是也仅仅是说明。2.WHATWG(网页超文本应用技术工作小组)定义了一个基于RFC协议的具体实现,但是不同的编程语言仍然使用他们自己的实现。
下图展示了cURL请求函数与其他语言解析函数结合使用时,由于差异性造成的漏洞。
可以得知,NodeJS url、Perl URI、Go net/url、PHP parser_url以及Ruby addressable解析函数与cURL libcurl请求函数差异性都可能造成漏洞的产生
下图的实例中,我们看到上述所述编程语言的解析函数得到的IP是google.com,而cURL请求得到的却是evil.com:80
curl—命令行工具
- 命令行工具,可以从shell或者脚本中运行该工具。
- 提供了130多种不同的“flags”
- 通常被用来模拟浏览器的行为
- 跨平台
libcurl—库
- 用作其他程序的开发库
- 可以与许多语言想结合,如PHP、C++
- 跨平台
- 提供了多种不同的使用它的APIs
相同点
- curl和libcurl都可以利用多种多样的协议来传输文件,包括HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE等。
不同点
- curl是命令行工具,可以通过shell或脚本来运行curl。curl底层所使用的库是libcurl。
- libcurl是一个库,通常与别的程序绑定在一起使用,如命令行工具curl就是封装了libcurl库。所以我们也可以在你自己的程序或项目中使用libcurl以获得类似CURL的强大功能。接下来将要介绍的PHP扩展就是对curl的一个封装。
①点分割符号替换
在浏览器中可以使用不同的分割符号来代替域名中的.
分割,可以使用。
、。
、.
来代替:
http://www。qq。com
http://www。qq。com
http://www.qq.com
无效的绕过方式
②本地回环地址
127.0.0.1,通常被称为本地回环地址(Loopback Address),指本机的虚拟接口,一些表示方法如下(ipv6的地址使用http访问需要加[]
):
http://127.0.0.1
http://localhost
http://127.255.255.254
127.0.0.1 - 127.255.255.254
http://[::1]
http://[::ffff:7f00:1]
http://[::ffff:127.0.0.1]
http://127.1
http://127.0.1
http://0:80
③IP的进制转换
IP地址是一个32位的二进制数,通常被分割为4个8位二进制数。通常用“点分十进制”表示成(a.b.c.d)的形式,所以IP地址的每一段可以用其他进制来转换。 IPFuscator 工具可实现IP地址的进制转换,包括了八进制、十进制、十六进制、混合进制。在这个工具的基础上添加了IPV6的转换和版本输出的优化。
在脚本对IP进行八进制转换时,一些情况下会在字符串末尾多加一个L。
④封闭式字母数字 (Enclosed Alphanumerics)字符
封闭式字母数字是一个由字母数字组成的Unicode印刷符号块,使用这些符号块替换域名中的字母也可以被浏览器接受。在浏览器测试中只有下列单圆圈的字符可用:
List:
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
ⓧⓘⓐⓝⓞⓤⓟⓔⓝⓖ.ⓒⓞⓜ
①⑦②.①⑥.⑥⓪.①⑥⑥
经测试,不可行,也许有其他方式
浏览器访问时会自动识别成拉丁英文字符:
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
⑤URL十六进制编码
URL十六进制编码可被浏览器正常识别,编码脚本:
#-*- coding:utf-8 -*-
data = "www.qq.com";
alist = []
fo