跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】

写在前面

在开始之前,先要看看ajax的局限性和其他跨域资源共享的方式,这里简单说说。

下面提到大量的origin,注意区分refererorigin只说明请求发出的域。

浏览器的同源组策略:如果两个 URL 的 protocol、port 和 host 都相同的话,则这两个 URL 是同源。同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。最重要的是它通常允许域向其他域发出请求,但不允许访问响应。

ajax:作为最基础的前后台交互,无需刷新页面就可以发出xhr包到后台,但是它有一定的局限性,就是它只能同源发送。

cors:解决跨域问题,就是在服务器端给响应添加头信息

Access-Control-Allow-Origin 必填 允许请求的域
Access-Control-Allow-Methods 必填 允许请求的方法
Access-Control-Allow-Headers 可选 预检请求后,告知发送请求需要有的头部
Access-Control-Allow-Credentials 可选 表示是否允许发送cookie,默认false;
Access-Control-Max-Age 可选 本次预检的有效期,单位:秒;

由于是服务器自主选择相应域,就相对安全了。此时就可以访问这个相应了。

jsonp:动态创建标签,并使用回调函数对请求内容进行处理,核心是动态添加<-script->标签来调用服务器提供的js脚本。

基本原理与理解

cors主要是针对ajax和一些api的接口安全,其利用条件一般较为苛刻,也常常被人忽视。其关键就在于敏感的ajax请求需要经过权限和同源策略的限制,一旦限制有问题,就可以从任何地方请求这个小小的接口,例如,诱导点击之后的被动请求,结合 xss的被动访问。

因为外部的网络环境千变万化,暴露出去的请求端点,也是风险项。

通过cors,可以限制请求该接口的源点,必须是信任的地方请求才能进行响应,可以以较大限度保证接口安全。

该漏洞容易与csrf混淆,它有一个本质的区别在于,cors不能修改请求包,你需要管理员的身份验证头,就不能自己修改请求包,只能想办法让管理员从信任域发起请求。

CORS vulnerability with basic origin reflection

首先可以在这里看到有一个ajax请求
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第1张图片
捕获这个请求,可以看到是允许cookie的交换,但是还没看到允许的域
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第2张图片
加入Origin请求头,探测服务器允许域,可以看到没有限制,随便一个example.com就能够完成敏感信息请求。
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第3张图片
这时就可以搭建攻击者服务器,并放入如下恶意代码。这个代码的含义非常简单,就是一个原生的ajax请求。注意下面的的$url需要替换成你请求的网址。
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第4张图片
写好后有一个deliver to victim 。这是模拟将该恶意链接发送给管理员等可登录人员。一旦受害者点击该链接,就会返回他们的敏感信息
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第5张图片
注:为什么需要受害者点击才可以?因为登录仍然没有绕过,需要在登录人员登录后,利用他们的cookie来发起该攻击。

注意在这里,敏感数据就是该ajax返回的敏感api key,发出该攻击,可以伪造受害者发出该包,获得敏感数据

CORS vulnerability with trusted null origin

解析 Origin 标头时出错
一些支持从多个来源访问的应用程序通过使用允许来源的白名单来实现。当收到 CORS 请求时,将提供的来源与白名单进行比较。如果源出现在白名单上,则它会反映在Access-Control-Allow-Origin标头中,以便授予访问权限。
实施 CORS 源白名单时经常会出现错误。一些组织决定允许从其所有子域(包括未来不存在的子域)进行访问。一些应用程序允许从其他各种组织的域(包括它们的子域)进行访问。这些规则通常通过匹配 URL 前缀或后缀,或使用正则表达式来实现。实施中的任何错误都可能导致访问被授予意外的外部域。

例如,假设一个应用程序授予对以以下结尾的所有域的访问权限:

normal-website.com 攻击者可能能够通过注册域来获得访问权限:

hackersnormal-website.com 或者,假设应用程序授予对所有域的访问权限

normal-website.com 攻击者可能能够使用域获得访问权限:

normal-website.com.evil-user.net

列入白名单的 null 原始值
Origin 标头的规范支持 value null。浏览器可能会null在各种异常情况下发送 Origin 标头中的值:

跨域重定向。
来自序列化数据的请求。
file:使用协议 请求。
沙盒化的跨域请求。
某些应用程序可能会将null源列入白名单以支持应用程序的本地开发。例如,假设一个应用程序接收到以下跨域请求:

GET /sensitive-victim-data
Host: vulnerable-website.com
Origin: null
服务器响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

null在这种情况下,攻击者可以使用各种技巧来生成包含Origin 标头 中的值的跨域请求。这将满足白名单,导致跨域访问。例如,这可以使用以下iframe形式的沙盒跨域请求来完成:

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,">iframe>

同样的,捕获这个AJAX请求
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第6张图片
探测服务端返回头,这里是null
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第7张图片
在攻击者服务器写入攻击代码
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第8张图片
发送给受害者
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第9张图片

这里要稍微说说前面的几个问题:
为什么要使用沙箱而不能使用之前的脚本? 因为使用iframe可以产生空源请求。
为什么不能使用相对路径? 因为是从iframe进行请求,需要使用绝对路径将日志写入攻击者服务器

CORS vulnerability with trusted insecure protocols

或许你已经发现了,要完成这个攻击,最重要的就是受害者的cookiecors是否配置正确。前面的攻击都是由于cors的问题较为突出,我们只需要构造出链接让受害者访问即可(就可以带上cookie)。而这个即使是配置“正确”的情况下也可能产生这个漏洞的场景,非常有意思。

其原理就是使用xsscors进行结合,虽然也有攻击者服务器,但是受害者点击后先定向到xss漏洞点,在xss点调用原生ajax发出敏感请求,记录在攻击者服务器上。这样就既在白名单发出请求,又带上了cookie

同样捕获到ajax请求
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第10张图片
浏览网页检查到疑似xss漏洞点。跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第11张图片
探测。
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第12张图片
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第13张图片
模拟即得到敏感信息。
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第14张图片

除了利用xss将受害者的请求诱导至信任域,这里还提到了非TLS信任域的中间人攻击。

假设严格使用 HTTPS 的应用程序还将使用纯 HTTP 的受信任子域列入白名单。例如,当应用程序收到以下请求时:

GET /api/requestApiKey HTTP/1.1
Host: vulnerable-website.com
Origin: http://trusted-subdomain.vulnerable-website.com
Cookie: sessionid=…
应用程序响应:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com
Access-Control-Allow-Credentials: true
在这种情况下,能够拦截受害者用户流量的攻击者可以利用 CORS 配置来破坏受害者与应用程序的交互。此次攻击涉及以下步骤:

受害用户发出任何纯 HTTP 请求。
攻击者将重定向注入:
http://trusted-subdomain.vulnerable-website.com
受害者的浏览器遵循重定向。
攻击者拦截纯 HTTP 请求,并将包含 CORS 请求的欺骗响应返回到:
https://vulnerable-website.com
受害者的浏览器发出 CORS 请求,包括来源:
http://trusted-subdomain.vulnerable-website.com
应用程序允许该请求,因为这是列入白名单的来源。请求的敏感数据在响应中返回。
攻击者的欺骗页面可以读取敏感数据并将其传输到攻击者控制下的任何域。
即使易受攻击的网站在使用 HTTPS 方面表现良好、没有 HTTP 端点且所有 cookie 都标记为安全,这种攻击仍然有效。

事实上,这是一种中间人攻击,由于http是没有ca来验证发送者的身份,可以通过拦截流量来捕获敏感的cors问题,当然,这样的利用难度也是很大的。

CORS vulnerability with internal network pivot attack

资料引用:

大多数 CORS 攻击依赖于响应标头的存在:
Access-Control-Allow-Credentials: true
如果没有该标头,受害者用户的浏览器将拒绝发送其 cookie,这意味着攻击者只能访问未经身份验证的内容,而他们可以通过直接浏览目标网站来轻松访问这些内容。

但是,在一种常见情况下,攻击者无法直接访问网站:当网站属于组织 Intranet 的一部分且位于私有 IP 地址空间内时。内部网站的安全标准通常低于外部网站,这使得攻击者能够发现漏洞并获得进一步的访问权限。例如,私有网络内的跨域请求可能如下:

GET /reader?url=doc1.pdf
Host: intranet.normal-website.com
Origin: https://normal-website.com
服务器响应如下:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
应用程序服务器信任来自任何来源且无需凭据的资源请求。如果私有 IP 地址空间内的用户访问公共互联网,则可以从使用受害者的浏览器作为访问 Intranet 资源的代理的外部站点执行基于 CORS 的攻击。

这种情况,是指内网中对于cors的利用。内网默认为信任域,请求资源甚至不会带身份验证。如果此时内网的机器访问外网,就可以诱导点击恶意的访问请求,利用该内网主机作为跳板,攻击内网服务,获取敏感信息。

首先,诱导受害者点击,扫描内网服务


注意替换$collaboratorPayload 为你自己的url,这里就是对192.168.0.x:8080,进行探测,这里只是一个c段探测,且端口固定,最后依次请求。存储该代码,发送给受害者,最后查看日志。
跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第15张图片
探测到192.168.0.63是开启状态(需要根据你扫描到的实际情况来看哦)

xss探测


跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】_第16张图片
解读一下代码,这里,可以通过img标签外连出来就说明找到xss

找到xss点了

诱导返回管理员页面

替换攻击代码为:


xss关键payload,就在于">