如何通过 DNS 重绑定窃取你的以太坊
字数 1455 2025-08-22 12:22:30
DNS重绑定攻击窃取以太坊钱包教学文档
1. 攻击背景与原理
1.1 以太坊JSON-RPC服务漏洞
- 大多数以太坊客户端(Geth、Mist和Parity)默认在localhost:8545运行JSON-RPC服务
- 该服务通常未经身份验证,仅依赖同源策略(SOP)保护
- 虽然Geth的JSON-RPC没有CORS头部,但仍存在DNS重绑定风险
1.2 DNS重绑定攻击定义
DNS重绑定是一种攻击技术,攻击者通过控制DNS解析结果,使浏览器在单次会话中访问不同IP地址(先合法服务器IP,后改为127.0.0.1),绕过同源策略限制。
2. 攻击实施步骤
2.1 准备工作
- 注册一个域名(如attacker.com)
- 搭建DNS服务器(可使用Python的dnslib库)
- 配置Web服务器(Apache)监听80和8545端口
- 准备JavaScript攻击代码
2.2 攻击流程
- 受害者访问attacker.com
- DNS服务器返回真实服务器IP(如87.87.87.87)
- 页面加载后创建iframe指向randomsub.attacker.com:8545
- 初始DNS解析仍返回真实IP(87.87.87.87)
- JavaScript等待60秒(浏览器DNS缓存过期)
- 发送请求到randomsub.attacker.com:8545/test
- DNS服务器此时返回127.0.0.1
- 请求实际发送到localhost:8545,可读取JSON-RPC响应
2.3 多用户处理
- 为每个用户生成唯一随机子域名作为标识
- 每个子域名独立进行DNS重绑定过程
3. 技术细节
3.1 DNS服务器实现要点
- 使用Python dnslib库简化开发
- 设置TTL<5秒(但浏览器仍会缓存60秒)
- 根据请求阶段返回不同IP(先真实IP后127.0.0.1)
3.2 JavaScript关键代码
-
min.js:
- 生成随机子域名
- 创建隐藏iframe指向子域名:8545
-
main.js:
- 执行DNS重绑定核心逻辑
- 等待DNS缓存过期
- 发送恶意请求并处理响应
3.3 Web服务器配置
- Apache设置两个虚拟主机:
- 端口80: 主攻击页面
- 端口8545: 包含攻击JS代码
4. 攻击效果
4.1 可获取的信息
- 受害者的以太坊地址
- 账户余额
- 交易历史
4.2 可执行的操作
- 调用eth_sendTransaction发送交易
- 转移以太币(若账户未锁定)
- 与存储型XSS结合实现持久化攻击
5. 防御措施
5.1 服务端防护
- 为JSON-RPC服务添加身份验证
- 限制访问IP(仅允许127.0.0.1)
- 修改默认端口
5.2 客户端防护
- 使用浏览器扩展阻止DNS重绑定
- 禁用不必要的JSON-RPC服务
- 及时更新以太坊客户端
6. 漏洞现状
- 该漏洞已报告给以太坊基金会并修复
- 修复方案包括添加适当的身份验证机制
7. 学习资源
- DNS重绑定维基百科: https://en.wikipedia.org/wiki/DNS_rebinding
- 原始研究博客: https://blog.hacker.af/how-your-ethereum-can-be-stolen-using-dns-rebinding
- 示例代码可在研究者GitHub获取
8. 法律与道德声明
本教学文档仅用于安全研究和技术学习目的。未经授权对他人系统进行测试或攻击是违法行为。请在法律允许范围内进行安全研究,并遵循负责任的漏洞披露原则。