Web 漏洞靶场练习(第二弹)
字数 4590 2025-11-08 10:04:01
XSS漏洞靶场攻关教学文档:xss-labs全解析
一、XSS漏洞核心原理
跨站脚本攻击(XSS) 的核心原理是:攻击者通过向网页中注入恶意脚本,利用网站对用户输入过滤不严的漏洞,使浏览器执行这些非预期的脚本,从而盗取用户信息、劫持会话或实施其他攻击。
根据脚本是否存储在服务器上,XSS主要分为三类:
- 反射型XSS:恶意脚本来自当前HTTP请求(如URL参数),由服务器直接返回并立即执行。
- 存储型XSS:恶意脚本被永久存储在服务器端(如数据库),当其他用户访问包含此脚本的页面时触发。
- DOM型XSS:漏洞完全在客户端处理,不经过服务器,由页面的JavaScript代码不当处理用户输入导致。
本靶场(xss-labs)主要针对反射型XSS进行练习。
二、关卡详解与Payload构造技巧
Level 1:直接注入
- 漏洞点:
keyword参数值直接被输出到页面中,未经过任何过滤。 - 源码分析:
$str = $_GET["keyword"]; echo "<h2 align=center>没有找到和".$str."相关的结果.</h2>"; - Payload:
<script>alert(1)</script> - 教学要点:这是最基础的XSS形式。当用户输入被直接拼接进HTML时,浏览器会将其解析为HTML代码而非普通文本。
Level 2:">闭合标签绕过
- 漏洞点:用户输入被放入一个
<input>标签的value属性中。 - 源码分析:
$str = $_GET["keyword"]; echo "<input name=keyword value='".$str."'>"; - 挑战:直接输入
<script>alert(1)</script>会被当作value的值,脚本不会执行。 - Payload:
"><script>alert(1)</script> - 构造原理:
">用于闭合当前的value属性值和<input>标签。- 随后注入的
<script>标签成为独立的HTML元素,从而被浏览器执行。
- 最终HTML:
<input name=keyword value=""><script>alert(1)</script>">
Level 3 & Level 4:单/双引号闭合与事件处理器
- 漏洞点:输入被
htmlspecialchars()函数处理,但引号处理策略不同。输入被放入<input>标签的value属性。 - 源码分析(Level 3):
$str = $_GET["keyword"]; $str2 = htmlspecialchars($str, ENT_QUOTES); // 同时转换单引号和双引号 echo "<input name=keyword value='".$str2."'>"; // 属性由单引号包裹 - 挑战:
<,>,",'等符号被转义为HTML实体(如'变为'),无法使用<script>标签或简单的引号闭合。 - 绕过技巧:利用HTML标签的事件属性,如
onclick(点击时触发)、onfocus(获得焦点时触发)、onmouseover(鼠标悬停时触发)等。 - Payload(Level 3 - 单引号包裹):
' onfocus=javascript:alert(1) '' onclick='alert(1)
- Payload(Level 4 - 双引号包裹):
" onfocus=javascript:alert(1) "" onclick="alert(1)
- 教学要点:
htmlspecialchars()函数在未设置ENT_QUOTES时默认不转义单引号,这是Level 3的关键。- 事件处理器(如
onclick)的值可以是JavaScript代码,无需显式使用<script>标签。
Level 5:脚本关键字过滤与超链接伪协议
- 漏洞点:代码对
<script>和on等关键字进行了过滤替换。 - 源码分析:
$str = strtolower($_GET["keyword"]); // 先转为小写 $str2 = str_replace("<script", "<scr_ipt", $str); // 替换<script $str3 = str_replace("on", "o_n", $str2); // 替换on - 挑战:无法使用
<script>标签和onxxx事件处理器。 - 绕过技巧:使用
<a>标签的href属性结合javascript:伪协议。 - Payload:
"> <a href=javascript:alert(1)>点击</a> <" - 构造原理:
">闭合前面的<input>标签。- 插入一个超链接,其
href属性值为javascript:alert(1)。当用户点击此链接时,会执行其中的JavaScript代码。 <"是为了平衡标签,避免语法错误(非必需,但更规范)。
Level 6:大写绕过
- 漏洞点:过滤函数(如
str_replace)对关键字进行替换,但未进行大小写统一处理。 - 源码分析:过滤了
script,on,src等,但都是小写。 - Payload:
"><SCRIPT>alert(1)</SCRIPT>或" OnClick="alert(1) - 教学要点:HTML对标签和属性名不区分大小写,但PHP的字符串处理函数默认是区分大小写的。这是一种非常经典的“黑名单”绕过方式。
Level 9:Unicode解码
- 挑战:页面会检查输入中是否包含
http://,如果没有,则不会正常输出。这要求Payload中必须包含该字符串,但又不能破坏JavaScript代码。 - 绕过技巧:利用JavaScript对Unicode转义字符的支持。
- Payload:
" onclick="alert(1)//http:// - Payload(使用Unicode):
" onclick="eval('\u0061\u006c\u0065\u0072\u0074(1)')//http:// - 教学要点:
\u0061是字母a的Unicode转义形式。eval()函数会将这些转义字符解码并执行。//用于注释掉后面的http://,避免其引发语法错误。
Level 10:隐藏输入与onfocus事件
- 挑战:用户输入不会被直接显示在页面的可见位置,而是被赋给了一个
type="hidden"的隐藏输入框。 - 技巧:通过URL参数
?keyword=test&t_link=1&t_history=2&t_sort=3发现,可能存在其他参数(如t_sort)被输出。需要将隐藏输入框的type属性改为text,使其可见,然后才能触发事件。 - Payload:
" onclick="alert(1) type="text - 最终HTML:
<input name="t_sort" value="" onclick="alert(1)" type="text"> - 教学要点:一个标签可以有多个属性。通过注入
type="text"属性,覆盖了原有的type="hidden",使输入框可见,从而可以点击触发onclick事件。
Level 11 & 12 & 13:HTTP请求头注入
- 漏洞点:XSS漏洞不仅存在于URL参数,还可能存在于HTTP请求头中,如
Referer,User-Agent,Cookie。如果服务器端代码将这些头信息不加过滤地输出到页面上,就可能造成XSS。 - 攻击方法:使用工具(如Burp Suite)拦截HTTP请求,修改对应的请求头。
- Payload(以Referer为例):
GET /level11.php HTTP/1.1 Host: target.com Referer: " onmouseover="alert(1) ... - 教学要点:永远不要信任任何来自客户端的输入,包括但不限于URL参数、POST数据、以及所有的HTTP头部信息。
Level 15:ng-include文件包含
- 背景:此关卡引入了AngularJS框架。
- 漏洞点:使用
ng-include指令动态包含文件,其值是一个AngularJS表达式。 - 原理:在AngularJS 1.x版本中,如果未对
ng-include的值进行严格处理,攻击者可以通过构造表达式来包含恶意代码或执行函数。 - Payload:需要构造一个指向包含XSS Payload的文件的AngularJS表达式(具体Payload依赖于靶场环境设置)。
- 教学要点:引入了客户端模板注入的概念。现代前端框架(如Angular, Vue, React)如果使用不当,同样可能产生XSS漏洞。
Level 16:空格/换行符实体转义绕过
- 漏洞点:代码将空格(
)和换行符(/)替换为HTML实体 和<br>。 - 源码分析:
str_replace(" ", " ", $str)和str_replace("/", "<br>", $str) - 挑战:普通的Payload中的空格会被破坏。
- 绕过技巧:使用其他空白符或标签属性分隔符。
- Payload:
">(使用/代替空格)"onmouseover=alert(1)(属性之间可以紧挨着,浏览器能正确解析)
- 教学要点:HTML解析器非常“宽容”,标签属性之间可以用空格、换行、制表符等多种空白符分隔,甚至在某些情况下可以没有分隔符。
Level 17 & 18:embed标签与事件绑定
- 漏洞点:用户输入被插入到
<embed>标签的src属性中。 - 源码分析:
echo '<embed src="xsf01.php?arg=' . $str . '">'; - 挑战:需要在
embed标签的上下文中执行脚本。 - 技巧:
<embed>标签支持事件处理器,如onmouseover。 - Payload:
1" onmouseover=alert(1) type="application/x-shockwave-flash" width=100 height=100 - 构造原理:
1"用于闭合src属性值的前半部分。- 然后注入
onmouseover事件。 - 添加
type等属性让embed标签更完整,提高触发成功率(尤其是在现代浏览器中,embed标签需要正确的MIME类型才能被正常处理)。
三、防御建议总结
根据以上攻击手法,可以总结出有效的XSS防御策略:
-
严格输出编码:
- 原则:根据数据输出的上下文,进行相应的编码。
- HTML正文:使用
htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8'),将<,>,",',&等字符转义。 - HTML属性:同上,必须使用
ENT_QUOTES同时转义单双引号。 - JavaScript代码:使用
json_encode($input)将数据安全地嵌入到JS中。 - URL参数:使用
urlencode($input)。
-
实施内容安全策略(CSP):通过HTTP头
Content-Security-Policy告诉浏览器只允许加载指定源的脚本、样式等资源,可以极大程度地缓解XSS攻击。 -
避免使用黑名单:如Level 6所示,黑名单很容易被绕过(大小写、编码、罕见标签等)。应采用白名单机制,只允许已知安全的字符或格式。
-
使用安全框架/库:现代前端框架(如React, Vue, Angular)默认有较好的XSS防护机制。后端模板引擎也应选择具备自动转义功能的。
-
设置HttpOnly Cookie:为敏感的Cookie标记
HttpOnly属性,防止被JavaScript窃取。
这份文档详尽地覆盖了xss-labs靶场中的核心知识点和攻击技巧,是学习反射型XSS原理和绕过手法的优秀教材。