SSRF 攻击
SSRF攻击(Server-Side Request Forgery,服务器端请求伪造),伪造服务器端发起的请求,从而获取客户端获取不到的数据。SSRF漏洞形成的原因主要是服务器端所提供的接口中包含了所要请求的内容的URL参数,并且未对客户端所传输过来的URL参数进行过滤。
漏洞危害
- 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息;
- 攻击运行在内网或本地的应用程序(比如溢出);
- 对内网Web应用进行指纹识别,通过访问默认文件实现;
- 攻击内外网的Web应用,主要是使用Get参数就可以实现的攻击(比如Struts2漏洞利用,SQL注入等);
- 当请求方法允许其他协议的时候,将可能利用gophar、file等协议进行第三方服务利用,如利用内网的redis获取权限、利用fastcgi进行getshell等
SSRF防御
目前,针对SSRF的防御思路主要是检查一下请求url的host不为内网IP,即
- 如何检查IP是否为内网IP
- 如何获取真正请求的host
而针对这两点检测思路,衍生出很多相应的绕过方法
SSRF攻击
SSRF主要利用地址绕过、302跳转、dns rebinding进行攻击
ip地址检测绕过
通常所用的内网地址段如下:
对于一般的黑名单检测,存在进制绕过
P师傅利用python对ip进行检测:
host获取绕过
如何获取”真正请求”的Host,这里需要考虑三个问题:
- 如何正确的获取用户输入的URL的Host?
- 只要Host只要不是内网IP即可吗?
- 只要Host指向的IP不是内网IP即可吗?
参考orange大佬的文章,A New Era of SSRF - Exploiting URL Parser in
Trending Programming Languages!
,
谈到了多个php中url parser的函数及原理,若parser函数与后台处理逻辑不统一,则可能存在问题。
附上P师傅用python获取host的方法:
利用http://xip.io
可以绕过一部分防护,这个域名能将包含某个IP地址的子域名解析到该IP,如127.0.0.1.xip.io
,将会自动解析到127.0.0.1
302跳转
然而,做好了对ip和host的检查,并不能完全防御ssrf漏洞。当我们请求的目标返回30X状态的时候,如果没有禁止跳转的设置,大部分HTTP库会自动跟进跳转。此时如果跳转的地址是内网地址,将会造成SSRF漏洞。
DNS rebinding
正常服务器防御ssrf时,都会至少发起2次对DNS的请求,即获取host的ip判断一次,最后访问url一次
而dns rebinding则是利用服务器访问url时多次请求dns的特点,将某域名额外绑定内网ip,使得服务器在第二次访问url时dns解析到内网ip造成ssrf.
DNS请求过程
- 查询本地DNS服务器(/etc/resolv.conf)
- 如果有缓存,返回缓存的结果,不继续往下执行
- 如果没有缓存,请求远程DNS服务器,并返回结果
本地DNS缓存机制
windows和mac系统都会对dns进行缓存,而Linux则默认不会进行DNS缓存
DNS TTL
TTL(Time to live),TTL表示DNS里面域名和IP绑定关系的Cache在DNS上存活的最长时间。假如一个域名的TTL为10s,当我们在这10s内,对该域名进行多次DNS请求,DNS服务器,只会收到一次请求,其他的直接请求本地dns缓存
PHP中默认ttl为0,而JAVA中默认为10
实现方式
- 特定域名,即可以直接设置ttl=0,绑定一个外网一个内网,使得第一次解析为外网,第二次为内网ip
- 暴力撞概率,设置两条A记录(一外网,一内网),使得第一次解析为外网,第二次为内网ip
- 自建DNS服务器(最靠谱)
其中自建DNS服务器,需要先添加一条ns记录和一条a记录,ns记录表示域名test.test.site这个子域名指定由ns.test.site这个域名服务器来解析,然后a记录表示我的这个ns.test.site的位置在ip地址104.160.43.154上。
记录类型 | 主机记录 | 解析线路 | 记录值 | MAX优先值 | TTL |
---|---|---|---|---|---|
NS | test | 默认 | ns.test.site | - | 10分钟 |
A | NS | 默认 | 104.160.43.154 | - | 10分钟 |
然后在上述地址104.160.43.154搭建一个dns服务器即可:
|
|