微信又改版了,为了我们能一直相见
你的加星和在看对我们非常重要
点击“长亭安全课堂”——主页右上角——设为星标🌟
期待与你的每次见面~
在浏览器场景下的 DNS 重绑定攻击有什么不一样?
最近 Chrome 的正在推广(https://developer.chrome.com/blog/private-network-access-preflight/)的PNA(Private Network Access) :https://wicg.github.io/private-network-access/策略真的能完全防御吗?
这里不过多介绍,不了解的师傅可以先看一下下面的文章:《从 0 到 1 认识 DNS 重绑定攻击》(https://xz.aliyun.com/t/7495)
DNS 重绑定本质上是欺骗客户端请求的 IP 地址。
这个客户端可以在服务器上,就是 SSRF,攻击对象一般是各种后端语言的网络库,或者是无头浏览器。
SSRF 安全指北:https://security.tencent.com/index.php/blog/msg/179
这个客户端也可以在个人 PC 上,就是 CSRF,攻击对象一般是浏览器。
在浏览器中使用 DNS 重绑定技术一般是服务于 CSRF 攻击,实现绕过同源策略,实现访问本机服务,或者内网服务。如果服务没有对 host 进行校验,那么就可以进行攻击。
在GitHub 上有个项目: https://github.com/nccgroup/singularity 实现了一个 DNS 重绑定的攻击框架,核心亮点在于实现多种 DNS 重绑定攻击策略,并有很多Bypass 技巧,在PPT 中:https://bit.ly/Singularity_Defcon27有比较完整的技术细节,这里我挑几个我认为很酷的技术点介绍一下:
还有其他的比如缓存覆盖刷新,websocket 远控都很酷,感兴趣的师傅可以看代码。
Multiple answers
使用这个重绑定策略能实现全平台全浏览器 3 秒内完成攻击。
Multiple answers
简称 ma
,这个策略利用 DNS Multiple Answers,查询 dns 的时候响应两个 IP 地址,一个是真实的服务器 IP,另一个是内网 IP,比如 127.0.0.1
,官方 PPT 上有一个很棒的图。
浏览器在拿到多个 dns 响应时,会尝试用第一个连接,失败之后就会尝试另一个,这时就实现了 DNS 重绑定。这个其实算是一个正常功能,也非常常见,可以说是 DNS 层面的负载均衡技术。
ma策略下还有些小问题:
ma
策略在使用某些 dns 服务器时有一定概率失败。原始响应
8.8.8.8
查询多次尝试一致
1.1.1.1
查询存在排序混乱
119.29.29.29
失败
223.5.5.5
存在排序混乱,强制 TTL
114.114.114.114
首次查询正常,后续查询强制 TTL,并存在排序混乱
所以… 一些不规范的 DNS 服务器一定程度上能缓解攻击…
0.0.0.0
Bypass在 Linux 和 macOS 中 0.0.0.0
实际上是 127.0.0.1
,如果一个程序监听 127.0.0.1
,使用 0.0.0.0
也能访问到。
而在 Windows 中,0.0.0.0
就不是一个有效地址。
PNA (Private Network Access) 是目前 Chrome 正在推广的一个安全策略,目标就是缓解 CSRF 对本地或者内网服务的攻击利用。
https://wicg.github.io/private-network-access/
https://developer.chrome.com/blog/private-network-access-update/
https://developer.chrome.com/blog/private-network-access-preflight/
在 Chrome 94 版本中,开始拦截公网 http 网站对私有网络的请求。
在未来的 Chrome 98 版本中,在访问私有网络前会尝试 CORS preflight,纯测试警告提醒开发者,并不会拦截,和常规的跨域类似,只是响应头为 Access-Control-Request-Private-Network: true
,后续预计在 Chrome 101 版本中将会严格执行安全策略,拦截 preflight 失败的请求。
目前 Chrome 是 97 版本,已经会拦截 http 网站的内网请求了,可以简单尝试一下。
The request client is not a secure context and the resource is in more-private address space
private
. 请求客户端不是安全上下文,资源位于更私密的地址空间 “private” 中。
这里多了一个概念 more-private address space
,可以在 DevTools 中 Network 右键打开一列。
可以看到 http://rebind.it/
网站属于 Public
,如果打开一个内网或者本地服务,可以看到是 Private。
可以猜到浏览器是根据远程地址进行空间划分,分为 Public,Private,Local 等,然后限制 Public 到 Private 或者 Local 的请求。
script 或者 img 自带跨域的标签加载也会被拦截。 |
PNA 一共 3 个判定条件,一个个看。在 CSRF 攻击场景中,目标服务一般都是 http,意味着攻击请求是 http 的,而且对于 DNS 重绑定来说,只能攻击 http 服务,https 服务直接就会因为证书错误而失败。同时 Chrome 又拦截了混合内容,意味着我们的服务也得是 http 的。
第一个条件 isFromHTTP==true
,没法绕了,后两个条件似乎是类似的,问题都在于 Chrome 是如何给地址分类的?
还记得前面提到的 0.0.0.0
吗?Chrome 认为 0.0.0.0
是 Public。
同时在 Linux 和 macOS 上 0.0.0.0
是指 127.0.0.1,
isToPrivateOrLocal==false
这样就绕过了 PNA,当然这个 Bypass 不适用于 Windows。
除了Chrome对IP的分类错误,还有一种情况让Chrome直接 “跳过” 分类。
如果有师傅按照上面自己操作一下,应该就能发现,在 Chrome 使用代理的时候,Remote Address Space
永远都是一样的,实际上都是代理服务器的 Address Space。
因为浏览器配置代理后,浏览器就不解析 DNS 了,所有的请求直接转发给代理服务器,实际产生连接的也是代理服务器,这里标记的 Remote Address Space
自然也就是代理服务器了,isFromPublic==false
,实现绕过 PNA。但是,此时发生 DNS 重绑定攻击就不是在浏览器中,而是在代理服务器中,因为实际客户端是代理软件,DNS Rebinding in Proxy Server 这就是另一个话题了。
在 Linux 和 macOS 中,利用 0.0.0.0
还是可以使用 DNS 重绑定攻击本地服务。在代理场景中,PNA 策略直接失效,DNS 重绑定如旧。PNA 还是很棒的,继 SameSite 之后 CSRF 漏洞又遭一锤,有认证的外部服务无了,无认证的内部服务也无了。
说起 SameSite,前几天发布的 Firefox 96 版本(https://www.mozilla.org/en-US/firefox/96.0/releasenotes/)
也开始默认设置 SameSite=lax了,现在好像就差 Safari 了。
(https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite#%E6%B5%8F%E8%A7%88%E5%99%A8%E5%85%BC%E5%AE%B9%E6%80%A7)
SameSite 的可以看这篇 《CSRF 漏洞的末日?关于 Cookie SameSite 那些你不得不知道的事》。
对于 CSRF 来说,在浏览器层面做防御,和服务端的修修补补比,可以说是降维打击了。
这让我想起了 NAT Slipstream ,Chrome 直接把相关端口都给 Block 了 ,简单粗暴。