自动探测
自动化探测利用脚本正在完善优化中,欢迎各位师傅试用交流:https://github.com/Echocipher/Subdomain-Takeover
如果您在使用中遇到了一些Bug,或者建议,期待您的交流:echocipher@163.com
0x00 What is Subdomain Takeover?
子域名接管是由于错误配置等原因,对应主机指向了一个当前未在使用或已经删除的特定服务(例如:Github pages,Heroku等),攻击者可以通过接管子域来获取对另一个域的控制权的风险点。通常情形如下:
- 域名使用
CNAME
记录到了另一个域(例如,sub.example.com
CNAMEanotherdomain.com
)
- anotherdomain`到期并可以被任何人注册
- 由于未
example.com
DNS区域删除CNAME
记录,因此攻击者注册anotherdomain.com
后可以控制sub.example.com
如果上述存在的话,任何注册anotherdomain.com
的人都可以控制sub.example.com
直到DNS记录失效,攻击者可以利用这一点构造钓鱼页面、执行跨站脚本攻击(XSS)等等
子域名接管不仅仅限于CNAME
记录,NS
,MX
甚至A
记录也会受到影响。
0x02 How does it come about?
Transparency To Browser
上图记录了涉及CNAME
的DNS解析,在第7步中,浏览器请求sub.example.com
而不是anotherdomain
,即使是使用了CNAME
记录,浏览器中的URL栏目中扔包含sub.example.com
, Web浏览器会信任DNS解析后返回的内容,这也就导致当攻击者能控制DNS记录的时候,当我们请求sub.example.com
时,浏览器接收到攻击者设置的A
记录的值,浏览器认为这是合法的,就会显示从该服务器接收到的所有内容,通过这一点攻击者就可以绕过Web浏览器的安全性检测(例如:同源策略),而且由于子域接管不是常规的中间人攻击,所以TLS/SSL并不能解决该问题,甚至通过生成有效的SSL证书还可以使得攻击场景更加完善。
SSL证书
例如Let’s Encrypt等证书机构允许通过内容自动验证域名所有权:
攻击者由于可以控制子域内容,因此按照Let’s Encrypt的要求在特定的URL路径上放置特定内容之后,Let’s Encrypt 将会自动完成证书的验证,然后批准为给定域发放证书,这大大降低了用户对网络钓鱼的识别度。
0x03 What will it lead to?
由于子域名接管导致的问题,很多漏洞赏金厂商已经开始接收子域名接管的漏洞,从赏金方面我们可以推测出厂商对问题的重视程度:
那么子域名接管都会导致哪些问题呢?
Cookie窃取
浏览器实施了很多安全策略从而保证用户不受恶意网站伤害,其中包括同源策略等内容,浏览器主要安全职责之一就是保护已经存在的Cookie,由于虽然HTTP是无状态协议,但是为了方便用户登录,所以会采用Cookie充当登录令牌,浏览器识别过后验证用户身份,而Cookie可以跨子域共享,例如当网站使用基于Cookie的单点登录系统时,用户可以使用一个子域登录,并且在各种子域中共享相同的会话令牌,设置常规Cookie的语法如下:
HTTP/1.1 200 OK
Set-Cookie: name=value
如果这个Cookie是由example.com
所在的web服务器发出的,那么只有这个服务器才可以访问到这个Cookie,但是可以通过以下方式为通配符域发布Cookie:
HTTP/1.1 200 OK
Set-Cookie: name=value; domain=example.com
这样Cookie可以存在于对example.com
的HTTP请求中,也可以包含在任何其他子域里面(例如:subdomain.example.com),这样导致使用子域名接管来进行攻击,例如某个特定的域使用Cookie用于通配符域,那么如果有一个子域遭受到攻击者子域接管,如果用户访问了该子域,Cookie会随HTTP请求自动发送,这样会导致HttpOnly cookie
被绕过,
HttpOnly cookie - 默认情况下,Cookie可以通过在创建cookie的网站上下文中运行的Javascript代码访问。Javascript可以读取,更新和删除cookie。HttpOnly cookie标志(由Web服务器设置)表示Javascript代码无法访问特定cookie。获取它的唯一方法是通过HTTP请求和响应标头。
而上文我们又介绍了攻击者可以生成SSL证书,因此浏览器的另一安全机制Secure cookie
也会被绕过
Secure cookie - 当cookie具有由Web服务器设置的安全标志时,只有在使用HTTPS时才能将其传送回Web服务器。
当子域接管被利用后,攻击者通过欺骗用户访问自己控制的子域,由于没有使用JavaScript访问Cookie,又可以生成SSL证书,所以可以绕过这两个安全机制来窃取用户Cookie
Arne Swinnen在hackerone的报告中详细的介绍了攻击过程:https://hackerone.com/reports/172137
而且由于JavaScript脚本是攻击者可以控制的,因此攻击者接管后可以进行更多其他的攻击。
但是有一种办法可以保护浏览器中JavaScript脚本的完整性,Subresource Integrity提出了一种机制,将加密哈希添加到script
中,
<script src="https://example.com/example-framework.js"
integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
crossorigin="anonymous"></script>
当提供的加密哈希与下载文件不匹配时,浏览器将会拒绝执行它。
电子邮件
当可以进行CNAME
子域接管的时候。攻击者可以将MX
设置为任意Web服务器,这会允许接收电子邮件到某个子域中,攻击者通常会使用欺骗Return-Path
header的方法接收电子邮件的回复。在网络钓鱼攻击中经常大范围使用,同时,由于SPF
将配置存储在DNS TXT
记录中,当子域被接管的时候,攻击者同样可以控制TXT
记录,就可以绕过SPF
检查来发送邮件
Rojan Rijal曾发现了Uber基于SendGrid服务的某个可劫持子域名,之后,利用该子域名,他成功拦截了Uber内部的公司电邮通信,获取了Uber官方$10,000美金的奖励。
漏洞详情(内附POC视频):https://www.arneswinnen.net/2017/06/authentication-bypass-on-ubers-sso-via-subdomain-takeover/
网络钓鱼
由于攻击者对相应子域有控制权限,他可以构造钓鱼页面来进行网络钓鱼攻击,例如一个银行的某个子域存在接管风险时,攻击者可以通过伪造表单来诱骗用户输入银行卡号、密码等敏感信息
CORS跨域资源共享
跨域资源共享,Cross-Origin Resource Sharing (CORS), 允许 Web 应用服务器进行跨域的网页访问控制。在Web应用创建的某个域中,按照一组规则来允许某些网站可以访问提取包括认证数据在内的数据信息。以某些子域名是可信域名的前提下,一些Web应用还允许子域名执行跨域的HTTP请求。当你挖掘子域名劫持漏洞时,可以留意一下COSR头信息,在BurpSuite Pro专业版中就有这个检测功能,另外可以看看Web应用是否将子域名列入了白名单,这些设置都可能实现对Web授权用户的数据窃取。
Oauth 授权白名单化
与跨域资源共享,Oauth 授权过程同样具备一个白名单机制,藉此,Web开发者可以指定指定哪个回调URIs是可以接受的。这里的风险在于,当存在劫持漏洞的子域名被列入这个白名单中时,攻击者可以在Oauth授权过程中把用户会话重定向到先前那个存在劫持漏洞的子域名中,以此窃取用户的
Oauth 授权信息。
内容安全策略(Content-Security Policies)
内容安全策略是Web应用信任的另一个主机列表,CSP的目的在于限制哪些主机可以在应用中执行客户端代码。如果希望尽量减少跨站脚本的影响,这种方式非常有用。如果你可以劫持控制的子域名包含在白名单中,你就可以绕过CSP限制,在Web应用中执行恶意的客户端代码。
<pre>curl -sI https://hackerone.com | grep -i "content-security-policy"
content-security-policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; child-src www.youtube-nocookie.co
m; connect-src 'self' www.google-analytics.com errors.hackerone.net; font-src 'self'; form-action 'self'; frame-ancestor
s 'none'; img-src 'self' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com profi
le-photos.hackerone-user-content.com hackerone-us-west-2-production-attachments.s3-us-west-2.amazonaws.com; media-src 's
elf' hackerone-us-west-2-production-attachments.s3-us-west-2.amazonaws.com; script-src 'self' www.google-analytics.com;
style-src 'self' 'unsafe-inline'; report-uri https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c
97a071737701f598
点击劫持(ClickJacking)
在browser-security-whitepaper中提到,在X-Frame-Options标头中,IE、Edge和Safari都支持ALLOW-FROM uri机制,表示该页面可以在指定来源的 frame 中展示,也就是说,如果你可劫持控制的子域名在该机制的白名单中,那么就可以在目标网页应用中构建欺骗页面,执行点击劫持(ClickJacking)攻击。
密码管理器的密码信息泄露
某些密码管理器,如LastPass会在一些主网站所属的子域名网站中执行自动密码填充功能,这相当于让网站设置了一个包含明文密码的非httponly类cookie,可以方便子域名劫持之后的深入利用。
Broken Link Hijacking
这种情况下的子域名,并不属于目标网站所有,但却是用来运行目标网站的网页内容的。也就是说,如目标网站网页内容中某个资源需要从外部导入的第三方资源,举例来说,像js文件一样,那么,攻击者就可以通过JavaScript的Blob对象类型进行导入,从而声明对目标网站相关子域名的控制权限。
这种在网页页面的主机劫持可以导致存储型跨站漏洞,攻击者可以针对目标网站页面,利用这种模式来加载任意的客户端代码。我在此提出这种威胁,就是希望我们不要把想像力只限制在子域名身上,还可以延伸到代码审查和目标网站的主机映射等方面。
0x04 Where does it come from?
CNAME子域名接管
如果域名通过CNAME
记录解析到的第三方服务可以被注册,那么攻击者就可以声明对子域的接管,检测流程如下:
像是Amazon S3
、Github pages
、Heroku
、Readme.io
都是存在被接管风险的
NS子域名接管
同样,如果NS
记录解析到的域名可以被接管,源域名也是会受到子域影响的。使用NS记录的子域名接管中存在着一个问题是源域名为了冗余和负载均衡,通常会具有多个NS
记录,假设sub.example.com
具有两个NS
记录,分别是ns.vulnerable.com
和ns.nonvulnerable.com
,这时如果攻击者接管了ns.vulnerable.com
,那么如果有用户请求sub.example.com
时,由于有两个ns记录,所以有两种情况:
- 用户DNS解析选择了
ns.nonvulnerable.com
,由于是合法的DNS,所以用户会得到正确的结果,并且可能会缓存6到24小时 - 用户DNS解析选择了
ns.vulnerable.com
,由于被攻击者接管,用户会得到攻击者设定好的结果,该结果同样也会被缓存,而且由于攻击者拥有控制权限,因此可以对TTL设置,例如一周
每次缓存条目到期时,都会重复上述过程。当攻击者选择使用具有高值的TTL时,错误结果将保留在该时段的DNS缓存中。在此期间,对sub.example.com
的所有请求都将使用攻击者缓存的虚假DNS结果。当使用公共DNS解析器(例如,Google DNS)时,甚至会放大这个攻击程度。在这种情况下,公共解析器可能会缓存错误结果,这意味着使用相同DNS解析程序的所有用户将获得错误结果,直到缓存到期。
除了控制源域名外,还可以控制源域名的所有更高级别的域。这是因为拥有NS记录的规范域名意味着拥有源域名的完整DNS区域。
2016年,Matthew Bryant 在maris.int上展示了使用NS
进行子域名接管:
他还展示了如何控制所有.io
域名的响应
更多内容详细参考:https://0xpatrik.com/subdomain-takeover-ns/
MX子域名接管
与NS
和CNAME
子域名接管相比,MX
子域名接管相对影响较小,因为MX
记录仅用于接收电子邮件,因此在MX
子域名接管仅允许攻击者接收发往原域名的电子邮件,可能会造成网络钓鱼攻击或者窃取相关信息
云服务厂商
随着云服务的推广,很多公司组织选择了云平台来进行存储等功能,云服务厂商大多数情况下回生成一个唯一的域名来用于访问用户创建的资源,由于用户数量众多,云服务上通常选取使用子域来进行表示,一般格式为name-of-customer.cloudprovider.com
,其中cloudprovider.com
是云服务提供商的主域。
而如果公司组织注册的云服务是公开的(例如:电商平台),通常为了便于用户记忆,公司会注册自己的子域名进行链接,有两种方式进行链接,
- HTTP 301/302重定向 - 301和302是HTTP响应代码,用于触发Web浏览器将当前URL重定向到另一个URL。在云服务的上下文中,第一个请求是对组织的域名(例如,shop.organization.com),然后重定向到云提供商的域名(例如,organization.ecommerceprovider.com)
- HTTP 301/302重定向 - 301和302是HTTP响应代码,用于触发Web浏览器将当前URL重定向到另一个URL。在云服务的上下文中,第一个请求是对组织的域名(例如,shop.organization.com),然后重定向到云提供商的域名(例如,organization.ecommerceprovider.com)。
如果使用CNAME记录方法,子域名接管的可能性就会发挥作用。即使云提供商拥有规范域名的基本域,仍然可以进行子域接管。
那么我们如何去寻找能被接管的云服务商呢?我们应该尽可能寻找符合如下条件的服务商。
- 普遍性 - 基于CNAME记录的统计信息,优先考虑CNAME记录中使用率最高的云提供商域。
- 支持CNAME记录 - 如上所述,云提供商需要支持CNAME。
- 域所有权验证 - 所选的云提供商未验证源域名的所有权。由于所有者不需要经过验证,因此任何人都可以使用过期的云配置来实现子域名接管。
例如:Amazon S3
、Heroku
、Shopify
、GitHub
、Microsoft Azure
等,在can-i-take-over-xyz项目中提供了可接管的列表
0x05 How to exploit this vulnerability?
测试子域接管的流程如下:
- 设定范围
- 收集子域名
- 子域名接管验证
- 报告输出
这里我以Github Pages
为例:
假设我们有一个这样的域名test.djmag.club
,我们将CNAME
解析到myh4ck1ife.github.io
我们访问一下试试
假如因为各种原因,我们的仓库被删除了,但是DNS记录忘了修改,当攻击者访问的时候就会发现:
那么接下来就可以进行接管了:
我们假设攻击者是Ecocipher:
这时候我们首先新建一个仓库,
我们新建一个主页来验证是否接管成功:
接下来我们创建CNAME文件,并将其指向test.djmag.club
此时我们再访问test.djmag.club
可以发现,我们已经成功接管了该子域:
同样的,如果我们编写主页插入JavaScript脚本,我们同样会触发脚本:
0x06 How to Solve the Problem
- 删除受影响的DNS记录 - 最简单的解决方案是从DNS区域中删除受影响的记录。如果组织确定不再需要受影响的源域名,则通常使用此步骤。
- 声明域名 - 这意味着在特定云提供商或常规互联网域的情况下注册资源,重新购买过期域名。
0x07 What should we pay attention to when reporting vulnerabilities?
- 请确保在你可劫持控制的子域名上部署了属于你自己的Web内容
- 部署的Web内容尽量简单干净
- 最佳方法就是在你部署的Web内容HTML文件注释中包含了某个隐秘消息即可,在与厂商联系协调时,这就足以证明漏洞问题
- 如果厂商给你授权,为了说明整体的威胁影响,你可以进一步对这种子域名劫持漏洞做出测试
- 大多数情况下,如果你的漏洞报告中包含了子域名劫持漏洞的利用步骤,厂商都会都会认可这种漏洞
- 子域名劫持漏洞属于高危漏洞,在编写漏洞报告时,请认真一点