Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文
随着 Tavis Ormandy 发现本地主机上利用未经身份验证的 JSON-RPC 服务的讨论兴起,我想到的第一件事就是以太坊客户端(Geth,Mist 和 Parity)。/ _& m- Z9 W* b% N1 w) \+ S
大多数以太坊客户端在 localhost 上的端口 8545 上运行 JSON-RPC 服务,但由于它位于 localhost 上,因此我们无法直接从用户的浏览器访问它。电子钱包中的这个问题利用 CORS 标头通过 localhost 上的 JSON-RPC 控制用户的电子钱包。3 @. t- w: u& M$ D- Y& i. K5 u! P) D
Geth 的 JSON-RPC 看起来非常安全,因为它没有返回任何 CORS 头部,但随后 cpacia 在电子钱包的半补丁上发表了评论,这引起了我的兴趣。这是他具体评论的内容:
) s( t5 \( L" ~/ Q: kJust disabling CORS is still vulnerable to a DNS rebinding attack. It needs to be authenticated. ~ cpacia
5 {# q9 D' V" x& g5 ^2 Y( M我听说过 DNS 重新绑定但从未尝试深入研究过它。由于 Geth 的 JSON-RPC 也未经过身份验证,它也可能存在 DNS 重绑定攻击。
- \8 M$ p/ M7 E0 H5 W) N) u我开始研究 DNS 重绑定,但所有文章都非常古老。然后我在 Bug Bounty 论坛上询问了这个问题,Luke Young 将他在 Defcon 会议上关于现今 DNS 重绑定利用的 演讲链接 发给了我。它包括一个自动化工具,可以在大多数现代浏览器上实现 DNS 重新绑定。( i- y* t. U" X4 a6 `' _& \  H
但是我有一颗非常好奇的心,我不想使用任何预先制作的工具,所以我开始编写自己的 DNS 服务器。Python 有一个非常好的库,名为 dnslib,它为我处理了大部分的 DNS 底层的内容。我注册了一个域名,设置了一些指向我的服务器的记录,并将它们用作名称服务器。
1 @. E/ [9 _4 ^' z7 t/ G/ B# N我想看看不同的浏览器如何在 TTL 很小的情况下做出响应的,所以我让我的 DNS 服务器返回 TTL , C% {3 p+ H2 A- q) A
使用–rpc 标志运行 geth (当然是在测试网络中)8 {! x& [6 m$ j. {& V4 p
geth --rpc --testnet
' }  M+ U9 x- x: A现在是一些需要解决 javascript 问题的时间,这是最难的部分。我不是一个很好的网络开发人员,每次 Javascript 行为时都使我很难理解。我在 3 小时内一起破解了一个非常糟糕但工作正常的 javascript。初步结果是成功的。
1 s6 h+ @  r* y" ^. r# v* F现在为了使它与 geth 一起使用,我必须在端口 8545 上运行我的 Web 服务器和域,因为 SOP 也使用这个端口。但如果我将链接发送给任何端口 8545 的人会显得有些低级。3 N8 M; A6 d  `& P: `
解决方案是 iframe。我让 apache 监听 8545 和 80 端口,并为每个端口设置一个虚拟主机。现在我编写一个 i 访问 8545 端口的 frame 并在隐藏的 iframe 中运行所有的 javascript。
' B, p6 a3 w/ u) F8 X1 l" O另一个问题是关于多个用户,如果多个用户同时访问了我的域,该怎么办?因为我使用的是一一个基于计数的操作系统,DNS 服务器会无法区分请求来自哪个用户。最终解决我的困惑是想到了使用子域名。
2 l/ j7 |; f  y+ U4 m- T/ o每次用户访问主域我都可以生成一个指向随机子域名的 iframe,将其作为这个用户的标识。我知道我可能没有清楚地解释这种攻击方式,下面有个例子。
: i  v% m: H3 n3 t1 J0 n我们假设我的域名是 attacker.com,我的服务器的 IP 是 87.87.87.87,以下攻击方式的步骤:# @, J% {! A* h8 C2 O& O+ [$ m) s
受害者在他的浏览器中打开 attacker.com。
- y: \1 s5 l  r; Z* a3 B( |首先,针对 attacker.com 的 DNS 请求被发送到我的服务器并且我的 DNS 服务器使用真实的 IP 地址 87.87.87.87 响应。
# k- u+ ?- t5 C- i4 w+ T' O6 Q* x接下来,用户的浏览器加载 attacker.com,然后创建一个指向 randomrsub.attacker.com:8545 的 iframe,并将其添加到页面 body 部分。. W+ {0 H. Z4 z6 u* G
现在,一个获取子域 randomrsub.attacker.com 地址的 DNS 请求发送到我的服务器,DNS 服务器再次使用真实 IP 87.87.87.87 进行响应。但这次,由于它位于端口 8545 上,因此 apache 会使用不同的虚拟主机进行响应,从而开始我们的 DNS 重绑定攻击利用。
$ F; _' L* J& x在 randomrsub.attacker.com:8545 上的 javascript 会先等待 60 秒,然后发送一个请求 randomsub.attacker.com:8545/test 的 XmlHttpRequest。
* A+ k$ m9 j. G& e: `由于浏览器的 DNS 缓存已过期,浏览器会再次解析 DNS。这次,我的 DNS 服务器响应 IP 为 127.0.0.1。
; o/ v% J/ o* B! @现在请求实际上发送到 127.0.0.1:8545/test 而不是我的服务器,因为它在 randomrr.attacker.com:8545 的源下,我们可以读取响应。% t0 r$ l" b0 c" p0 D
由于我们每次都会生成一个随机子域,因此我们甚至可以处理对多个用户的攻击,因为子域可以作为其标识令牌。
- I, \  L! K- m. C/ r我还必须优化一下 javascript,以保证 95% 的时间都能正常工作。我在真正的 DNS 查询之前添加了一些虚假的 DNS 查询,以便它在错误的时候不会响应成错误的 IP 地址。
& ~5 h( g8 I9 R- Q: ~* b这个漏洞也可以结合存储型 XSS 攻击。只需将资源请求指向一个 js 文件,即可添加 iframe 和 TADA !!3 X6 w) i, I; ^" c- q
所以现在我们可以读取 JSON-RPC 服务的响应,这意味着我们可以读取他们的以太坊地址,他们的账目,甚至会窃取他们的以太(如果他们的账户未上锁)。 JSON-RPC API 有一个相当不错的方法,称为 eth_sendTransaction,它基本上可用于从用户的帐户发送以太坊。
4 l) e# ^2 A( @1 s" K我将我的 POC 放到了 http://rebinddns.ml 网站上。如果您使用 JSON-RPC 运行 Geth (或任何其他以太坊客户端)超过 60 秒,您将看到一个 alert(),其中包含您的以太坊地址及其余额。. x2 O; T& @! f$ x5 g- }

! B. Q. A2 x" j8 `' [$ y1 `1 Y2 k0 ]PoC 中使用的所有文件都可以在我的 github 上找到。& I% V/ Y8 @8 l! N
min.js  - 在端口 8545 上生成子域的隐藏 iframe 的 Js 文件8 b+ F. W( Z4 p7 f4 R
main.js  - 执行 DNS 重新绑定的 Js 文件! a3 F$ W% j0 A
server.py  - 用 python 编写的 DNS 服务器
1 N% M8 K  T4 D我已经验证了 Geth,C ++以太坊客户端以及 python 客户端都存在漏洞。 PoC 已经在 Firefox,Chrome 和 Safari 上进行了测试。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

牙忍喊适索 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    9