Write-up地址:How I Discovered XSS that Affects around 20 Uber Subdomains
总算回家了,完全没想到这次要外出一个月,今天开始恢复更新。
前几天忘记在哪里看到了这个write up的中文翻译了,当时也没看,今天打算写总结的时候刚好发现了这篇write-up,决定就是这篇了。
这个在uber发现的漏洞实现上是由logout时重定向引起的反射型XSS,是作者在分析uber的SAML功能时发现的,本来作者是打算做bypass SAML authentication的,但是没有成功,之后才转向分析其他可能的漏洞。
什么是SAML
在说SAML(Security Assertion Markup Language)之前,要先说一下什么是SSO(Single Sign-On),SAML是SSO的一种解决方案。
所有使用互联网的用户应该都知道登录是怎么回事,通过注册并登录一个网站应用,你就可以享受专门针对你个人的网站应用服务了。由于HTTP的无状态性,为了避免对一个网站应用的多次登录,网站应用会使用session ID(例如cookies)来标识用户,这样你只要登录一次该网站应用,在session ID有效期间就不需要再次登录了。但存在一个问题——cookies只在同一个domain下才有效。对于一个大型的网站,它可能有多个应用,而不同应用有不用的domain,这个时候使用cookies就不合适了。
于是就出现了一个解决办法,网站单独建立一个身份提供者(Identity Provider),该应用创建、维护并管理用户认证,而不同的应用作为服务提供者(Service Provider),当用户登录一个应用时,应用会根据用户的origin将其重定向到身份提供者那里,身份提供者验证用户身份,返回一个响应,告诉服务提供者用户是否验证通过,若验证通过,用户就可以使用该应用了。提供一个典型的应用场景,打开淘宝(https://www.taobao.com/)和天猫(https://www.tmall.com/)页面,这时候两个都是未登录状态,如果你这时候登陆淘宝,再刷新天猫页面,会发现天猫页面也是登陆状态。
实现SSO有多重方式,OpenID、Oauth和SAML等,这里要说的就是SAML,顾名思义,SAML是一个基于XML的开源标准数据格式,它规定了身份提供者和服务提供者之间交换认证信息等数据的数据格式,也就是说使用SAML,在应用向身份提供者请求验证用户时,两者之间是通过xml传递信息的。
漏洞发现过程
在作者对uber的子域名进行扫描收集时,发现很多内部域名都会被重定向到uber.onelogin.com
进行身份验证,onelogin是一个统一访问管理平台,提供基于SAML的SSO,而之前在使用SAML的应用中已经存在一些身份认证绕过的漏洞,所以作者尝试寻找uber中是否存在这些漏洞,但是发现已经有人提交过了。
根据上面对于SSO的介绍,我们知道当用户访问一个uber的内部网站(https://carbon-prototype.uberinternal.com:443/)时,会被重定向到uber.onelogin.com
,即有一个请求发向uber.onelogin.com
,而登陆后uber.onelogin.com
又会向内部网站返回一个响应,作者观察了发向uber.onelogin.com
的请求,里面有一个使用base64编码SAMLRequest的参数,通过解码可以获得接收响应的URL(https://carbon-prototype.uberinternal.com:443/oidauth/saml_consume),这时作者再一次试图绕过身份认证,但是失败了,因此作者对oidauth/这个目录进行扫描,想看一下有没有其他有趣的文件或目录
./dirsearch.py -u https://carbon-prototype.uberinternal.com:443/oidauth/ -ejson
然后
https://carbon-prototype.uberinternal.com:443/oidauth/logout
这个页面吸引了作者的注意力,因为logout功能通常会伴随着一个重定向,而这个过程中可能存在XSS漏洞。
打开上面的页面,会被重定向到
https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1
注意里面的base参数,是一个URL,当作者把它修改为javascript:alert(123);
后,成功实现了反射型的XSS。
最后作者通过脚本,找到所有接收SAML响应的网址,然后请求该域名下的oidauth/prompt
目录,看是否存在该反射型XSS漏洞
1. 对一个新的应用进行测试时,可以看是否存在在其他应用中已经发现的漏洞
2. 为什么会想到目录扫描:在请求包的数据中发现一个oidauth/目录
3. logout功能可能存在XSS漏洞,值得进一步测试