
一、XSS漏洞原理
XSS属于客户端攻击,最终受害者是用户,但需要特别注意的是,网站管理人员也属于用户之一。这意味着XSS可以进行“服务端”攻击,因为管理员通常拥有比普通用户大得多的权限,如文件管理、数据管理等操作。攻击者往往利用管理员身份作为“跳板”来实施进一步的攻击。
XSS的重点不在于“跨站点”,而在于“脚本的执行”。其核心原理是:恶意攻击者在Web页面中插入精心构造的恶意Script代码。当用户浏览该页面时,嵌入的脚本代码会被浏览器解析并执行,从而达到攻击用户的目的。
XSS攻击主要分为三类:反射型、存储型以及DOM-based型。其中,反射型和DOM-based型可归类为非持久性XSS攻击,而存储型则属于持久性XSS攻击。
1. XSS漏洞出现的原因
程序对用户的输入和输出控制不够严格,导致攻击者“精心构造”的脚本输入后,在输出到前端时被浏览器当作有效代码解析执行,从而产生危害。整个数据传输路径中的每个环节都可能成为不信任数据的来源。

2. XSS的分类
- 反射型XSS (Reflected XSS):或称非持久型XSS,通常被认为是中危漏洞。
- 储存型XSS (Stored XSS):或称持久型XSS,属于高危漏洞,杀伤力大。
- DOM型XSS (DOM-based XSS):攻击载荷在客户端DOM解析过程中触发,不依赖于服务端响应。
3. 测试方法
- 工具扫描:可使用AWVS、APPscan等自动化工具进行初步探测。
- 手工测试:更精准的方式是使用Burpsuite、Firefox的HackBar插件或专门的XSS测试工具(如XSSER)进行手工测试。
进行手工检测时,关键在于寻找用户输入点以及数据输出的位置。为了高效测试,建议使用有特殊意义的字符或语句来快速验证是否存在漏洞:
- 在目标站点上找到输入点,如查询接口、留言板等。
- 输入一组“特殊字符 + 唯一识别字符”,提交后查看返回的页面源码,观察是否有对应的过滤或编码处理。
- 在源码中搜索定位到“唯一识别字符”,结合其前后的HTML语法,判断是否可以构造执行JS的条件(如构造标签闭合)。
- 提交构造的脚本代码,观察是否可以成功执行。若能执行,则说明存在XSS漏洞。
二、反射型XSS
反射型XSS攻击是最常见的类型。漏洞产生的原因是攻击者注入的数据直接“反射”在服务器的响应中。它通常需要一个包含XSS攻击向量的链接诱使用户点击,因此也被称为非持久性攻击。
JavaScript是Web开发的核心脚本语言,它可以被插入到HTML页面中并由所有现代浏览器执行。一个基本的JavaScript示例如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
alert('第一个javascript程序');
</script>
</body>
</html>
在XSS攻击中,攻击者常利用以下JavaScript函数或HTML事件属性来执行恶意操作:
alert(): 用于弹出警告框,常作为漏洞验证的POC。
window.location / location.href: 用于重定向用户到恶意网站。
- HTML事件处理器:
onload: 页面或图像加载完成后触发。
onerror: 加载资源出错时触发。
onchange: HTML元素内容改变时触发。
onclick: 用户点击HTML元素时触发。
onmouseover: 鼠标悬停在元素上时触发。
onmouseout: 鼠标移出元素时触发。
onkeydown: 用户按下键盘按键时触发。
三、DOM型XSS
DOM(文档对象模型)为JavaScript提供了访问和操作HTML文档的接口。DOM型XSS的攻击过程完全在客户端浏览器中完成,恶意代码的执行不依赖于将数据发送到服务器端再返回。它的特征是:整个攻击链都是前端的DOM解析与操作,没有后端代码的直接参与。
四、存储型XSS
存储型XSS是指应用程序将攻击者提交的恶意代码直接存储到服务器端(如数据库),之后永久性地显示在其他用户的页面上。一个典型的例子是:黑客在一篇博客文章中写入恶意JavaScript代码,文章发表后,所有访问该博客的用户都会在他们的浏览器中执行这段代码。由于恶意脚本被“存储”在服务端,故而得名。
存储型XSS可能出现的位置非常广泛,包括但不限于:
- 用户注册信息
- 留言板、评论框
- 上传文件的文件名
- 管理员可见的错误信息页面
- 在线聊天、客服对话窗口
- 问题反馈区、邮件内容
通俗来说,就是“见框就插”,任何用户可以控制输入并会展示给其他用户的地方都可能存在风险。
满足存储型XSS需要两个条件:第一,能够成功插入数据;第二,插入的JS代码能够在受害者浏览器中被正常解析执行。
它的危害极大,通常可以用来窃取用户的Cookie、获取内网IP等敏感信息。攻击者获取Cookie后,可通过修改浏览器或代理工具(如Burp Suite)中的Cookie值,直接登录受害者账户。值得注意的是,在SRC(安全应急响应中心)漏洞评级中,存储型XSS通常被视为中高危漏洞,在实际企业项目中则属于高危漏洞,需立即修复。
五、XSS绕过实战技巧
1. 引号闭合绕过(第二关)
观察页面,发现输入被直接输出,但并未弹窗。

查看网页源码,发现服务端使用了htmlspecialchars()函数对输入进行了HTML实体编码。

但该函数默认只编码双引号等,如果属性值由单引号包裹,则可能绕过。查看前端HTML结构,发现value属性使用的是双引号,但可以尝试构造事件处理器并闭合前面的双引号。

构造payload:" onclick="alert(1),成功弹窗。

2. 利用HTML事件绕过(第三关 & 第四关)
在第三关,测试发现尖括号<>和单引号‘都被过滤或转义。

尝试使用onclick事件,但发现属性值被额外添加了单引号导致闭合困难。


换用onmouseover事件,成功触发。Payload:' onmouseover='alert(1)。

第四关直接过滤了尖括号<>。

继续使用事件处理器,Payload:" onmouseover="alert(1),成功绕过。

3. JavaScript伪协议绕过(第五关 & 第六关)
第五关过滤方式是在script字符串中插入下划线_。

尝试事件处理器,发现on关键词也被类似处理。

使用JavaScript伪协议构造一个可点击的链接。Payload:"><a href=javascript:alert(1)>你好</a>。

第六关同样过滤script和href。


尝试简单的大小写绕过。Payload:"><a Href=javascript:alert(1)>你好</a>,成功。

4. 双写绕过(第七关)
第七关的过滤策略是直接删除script字符串。


采用双写策略,Payload:"><scrscriptipt>alert(1)</scrscriptipt>,删除中间的script后,两边的残片恰好组合成新的<script>标签。

5. HTML/URL编码绕过(第八关 & 第九关)
第八关过滤了script和javascript:等关键词。


利用HTML实体编码。例如,将javascript:中的t编码为t(十进制)或t(十六进制)。首先需要了解编码转换。

构造Payload:javascriptt:alert(1),输入后成功形成可执行链接。


第九关增加了更严格的过滤,要求输入内容必须包含http://。




使用URL编码的换行符%0d来分隔语句,绕过关键字检测。构造Payload:javascript:%0dhttp://%0dalert(1),使其既包含http://,又能执行alert。

6. 隐藏表单字段利用(第十关 & 第十一关)
第十关页面没有明显输入框,查看源码发现参数通过隐藏表单域t_sort传递。


直接对t_sort参数注入事件,Payload:?keyword=test&t_sort=" onmousemove="alert(1) type="text。这里的关键是利用注入将type="hidden"覆盖为type="text",使隐藏字段变为可见并携带恶意事件。


第十一关的注入点转移到了HTTP请求头Referer。使用Burp Suite等工具拦截请求,修改Referer头的值为第十关的Payload即可。


7. 其他相关关卡思路
-
第十二关:注入点在User-Agent请求头。
-
第十三关:注入点在Cookie请求头。
-
第十五关(AngularJS ng-include):利用ng-include指令包含外部文件的功能。需要注意路径需用单引号包裹,且被包含文件中的script可能不执行,但可通过参数传递其他XSS向量。例如,包含第一关并传递一个img标签的onerror事件:http://127.0.0.1/xss-labs/level15.php?src='./level1.php?name=<img src="x" onerror=alert(1)>‘。



-
第十六关(过滤空格):当<script>和空格都被过滤时,可使用<img>标签,并用URL编码的换行符%0d或%0a代替空格。Payload:<img%0dsrc=x%0donerror=alert(1)>。



通过以上这些实战关卡,我们可以看到,XSS的防御与绕过是一场持续的博弈。开发者采用过滤、编码、WAF等多种手段,而攻击者则不断寻找规则中的疏漏,利用各种编码、特性、上下文差异来达成攻击目的。理解这些绕过技巧,对于从事安全/渗透/逆向的防御方和攻击方都至关重要。只有深入理解攻击原理,才能构建更有效的防御体系。
希望这篇结合原理与实战的XSS解析,能帮助你在云栈社区的Web安全学习之路上更进一步。