前 言
CORS漏洞其中已经存在很久了,但是国内了解的人不是很多,文章更是少只有少,漏洞平台也没有此分类。
在DefConChina中,陈建军分享的议题中解释的更清楚,有意向的可以找PPT或者视频
owasp内的详细介绍
http://blog.securelayer7.net/owasp-top-10-security-misconfiguration-5-cors-vulnerability-patch/
漏洞描述CORS,Cross-OriginResource Sharing,跨源资源共享。
CORS是W3C出的一个标准,其思想是使用自定义的HTTP头部让浏览器与服务器进行沟通。因为开发者需要进行跨域进行获取资源,应用场景,在a.com,想获取b.com中的数据,常用的2种方法进行跨域一种为JSONP,一种为CORS.还有html标签也能跨域,有以下几种img, iframe,ink, script等。
cors跨域访问资源示意图:
假设用户登陆一个含有CORS配置网站vuln.com,同时又访问了攻击者提供的一个链接evil.com。evil.com的网站向vuln.com这个网站发起请求获取敏感数据,浏览器能否接收信息取决于vuln.com的配置。
如果vuln.com配置了Access-Control-Allow-Origin头且为预期,那么允许接收,否则浏览器会因为同源策略而不接收。
漏洞产生原因前面说了,设置了orgin就能进行跨域访问。而如果配置cors不当的话,如Access-Control-Allow-Orgin:的话,就有可能存在问题。
Access-Control-Allow-Origin这个字段的意思是允许跨域访问的网站,配置为的话,默认就能跨域访问所有网站,也就是说orgin这个字段是可控的。当然仅仅有一个orgin字段还不行,这里要说下Access-Control-Allow-Origin-Credentials这个字段。这个字段的意思是是否带cookie跨域访问网站,如果为true的话,就是允许带着cookie跨域访问b网站。所以说,如果攻击者把orgin:设置成自己搭建的网站,功能为接收受害者的cookie。而Access-Control-Allow-Origin-Credentials又设置成true,这时候我们就可以说存在漏洞了。
看到前面漏洞产生原因,主要是Access-Control-Allow-Orgin:kissing_heart:和Access-Control-Allow-Origin-Credentials:true这两个问题。有人可能要问了,这两个成立的话就会存在漏洞?答案是否定的。因为当你跨域的时候,浏览器看到你这两个的设置,会认为是不安全的,就是会拦截你的操作。而Access-Control-Allow-Orgin绑定了一个网站,但是对值没进行一个校验,也就是攻击者抓包把orgin改了,而网站没进行校验,就存在漏洞。
所以
Access-Control-Allow-Orgin:XXXXX.com
Access-Control-Allow-Origin-Credentials: true
---可能存在漏洞
Access-Control-Allow-Orgin:*
Access-Control-Allow-Origin-Credentials: true
--- 不存在漏洞
常见测试点1.互联网厂商的api接口
2.聊天的程序的api接口
3.app的api(不过有一些请求需要带有一些额外的请求头,利用起来比较困难)
4.区块链厂商
漏洞检测方法第一种:
curlhttps://test.net -H “Origin: https://evil.com” -I
当你看到的返回结果包括
Access-Control-Allow-Credentials:true Access-Control-Allow-Origin: https://evil.com
则可能存在cors漏洞
第二种:
github上提供了一个关于扫描CORS配置漏洞的脚本,https://github.com/chenjj/CORScanner
一些简单用法:
root@kali:~/Desktop/CORScanner# python cors_scan.py -husage: cors_scan.py [-h] [-u URL] [-i INPUT] [-t THREADS] [-o OUTPUT] [-v [VERBOSE]] [-d [HEADERS [HEADERS ...]]]OPTIONS: -h, --help show this help message and exit -u URL, --url URL URL/domain to check it's CORS policy -i INPUT, --input INPUT URL/domain list file to check their CORS policy -t THREADS, --threads THREADS Number of threads to use for CORS scan -o OUTPUT, --output OUTPUT Save the results to text file -v [VERBOSE], --verbose [VERBOSE] Enable Verbosity and display results in realtime -d [HEADERS [HEADERS ...]], --headers [HEADERS [HEADERS ...]] Add headers to the request.Example: python cors_scan.py -u google.com
第三种:
使用burp进行自动化检测
在burp下做如下设置
然后我们便可以使用过滤器查看是否存在cors漏洞
实战案例首先是一个这样的界面,然后我们抓包,发现有Orgin字段
我们把orgin改为其他地址试试
发现Access-Control-Allow-Orgin已经为我的博客地址并且Access-Control-Allow-Origin-Credentials:true。说明存在这个漏洞,此时我们便可以使用pocbox来获取他人的信息了。
将生成的poc发送给别人即可获取他人的信息。
当然,如果有兴趣的也可以去看一下hackerone上的一个案例:
https://bugbountypoc.com/exploiting-cross-origin-resource-sharing/
其他攻击手段客户端缓存中毒
这种配置允许攻击者利用其他的漏洞。
比如,一个应用返回数据报文头部中包含“X-User”这个字段,这个字段的值没有经过验证就直接输出到返回页面上。
GET /login HTTP/1.1Host: www.target.localOrigin: https://attacker.domain/X-User:
返回报文(注意:“Access-Control-Allow-Origin”已经被设置,但是“Access-Control-Allow-Credentials:true”并且“Vary:Origin”头没有被设置)
HTTP/1.1 200 OKAccess-Control-Allow-Origin: https://attacker.domain/…Content-Type: text/html…Invalid user: <svg/onload=alert(1)
攻击者可以把xss的exp放在自己控制的服务器中的JavaScript代码里面然后等待受害者去触发它。
var req = new XMLHttpRequest();req.onload = reqListener;req.open('get','http://www.target.local/login',true);req.setRequestHeader('X-User', '');req.send();function reqListener() {location='http://www.target.local/login';}
如果在返回报文中头部没有设置“Vary:Origin”,那么可以利用上面展示的例子,可以让受害者浏览器中的缓存中存储返回数据报文(这要基于浏览器的行为)并且当浏览器访问到相关URL的时候就会直接显示出来。(通过重定向来实现,可以用“reqListener()”这个方法)
如果没有CORS的话,上面的缺陷就没法利用,因为没有办法让受害者浏览器发送自定义头部,但是如果有了CORS,就可以用“XMLHttpRequest”做这个事情。
绕过姿势NULL源
CORS的规范中还提到了“NULL”源。触发这个源是为了网页跳转或者是来自本地HTML文件。目标应用可能会接收“null"源,并且这个可能被测试者(或者攻击者)利用,意外任何网站很容易使用沙盒iframe来获取”null“源
<script>**CORSrequest here**script>’>iframe>
使用上面的iframe产生一个请求类似于下面这样
GET /handler
Host: target.local
Origin: null
如果目标应用接收”null"源,那么服务器将返回类似下面的数据报文
HTTP/1.1 200 OK
Acess-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
使用目标域名作为子域名
如果目标应用只检查只检查“Origin”中的字符串是否包含“target.local”,那么就可以在自己控制的服务器上创建一个子域名。用这样的方式,请求一般产生自JavaScript代码,并且请求中的“Origin”会像下面这样
Origin: https://target.local.attacker.domain
注册一个同名的域名
假设,目标应用实现是基于下面的正则表达式去检测“Origin”头部的话:
^https?:\/\/.*.?target.local$
这个?只影响".“这个字符串,因此在“target.local”前面的任何字符串都是被允许的,而不管是否有”."把他们分开。因此,只需要在“origin”末尾包含目标域名就可以绕过上面的限制(这个场景的的目标域名是“target.local”),比如:
Origin: https://nottarget.local
攻击者只需要注册一个末尾包含目标域名的新域名就可以利用这样的漏洞了。
漏洞修复方案(1)如果没有必要就不要开启CORS
(2)严格限制域白名单,而不是使用*
(3)尽量避免使用Access-Control-Allow-Credentials
(4)对于orgin域名进行严格限制,可信域名限制,详细限制,如信任子域名*.test.com 如果检查域名后缀方式请采用.test.com
(5)配置“VARY”头部
(6)如果可能的话避免使用“CREDENTIALS”
(7)限制缓存的时间
(8)限制使用的方法
原创文章未经授权禁止转载,谢谢合作
● 云众可信征稿进行时
● 原创干货 | 记一次拟真环境的模拟渗透测试
● 原创干货 | 从手工去除花指令到Get Key
● 原创干货 | 浅谈被动探测思路
·END·
云众可信原创·干货·一起玩
微信号:yunzhongkexin好看的人才能点