Web 漏洞靶场练习(第二弹)
字数 4590 2025-11-08 10:04:01

XSS漏洞靶场攻关教学文档:xss-labs全解析

一、XSS漏洞核心原理

跨站脚本攻击(XSS) 的核心原理是:攻击者通过向网页中注入恶意脚本,利用网站对用户输入过滤不严的漏洞,使浏览器执行这些非预期的脚本,从而盗取用户信息、劫持会话或实施其他攻击。

根据脚本是否存储在服务器上,XSS主要分为三类:

  1. 反射型XSS:恶意脚本来自当前HTTP请求(如URL参数),由服务器直接返回并立即执行。
  2. 存储型XSS:恶意脚本被永久存储在服务器端(如数据库),当其他用户访问包含此脚本的页面时触发。
  3. 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>
  • 构造原理
    1. "> 用于闭合当前的value属性值和<input>标签。
    2. 随后注入的<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实体(如'变为&#x27;),无法使用<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)
  • 教学要点
    1. htmlspecialchars()函数在未设置ENT_QUOTES时默认不转义单引号,这是Level 3的关键。
    2. 事件处理器(如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> <"
  • 构造原理
    1. "> 闭合前面的<input>标签。
    2. 插入一个超链接,其href属性值为javascript:alert(1)。当用户点击此链接时,会执行其中的JavaScript代码。
    3. <" 是为了平衡标签,避免语法错误(非必需,但更规范)。

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实体&nbsp;<br>
  • 源码分析str_replace(" ", "&nbsp;", $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
  • Payload1" onmouseover=alert(1) type="application/x-shockwave-flash" width=100 height=100
  • 构造原理
    1. 1" 用于闭合src属性值的前半部分。
    2. 然后注入onmouseover事件。
    3. 添加type等属性让embed标签更完整,提高触发成功率(尤其是在现代浏览器中,embed标签需要正确的MIME类型才能被正常处理)。

三、防御建议总结

根据以上攻击手法,可以总结出有效的XSS防御策略:

  1. 严格输出编码

    • 原则:根据数据输出的上下文,进行相应的编码。
    • HTML正文:使用htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8'),将<, >, ", ', &等字符转义。
    • HTML属性:同上,必须使用ENT_QUOTES同时转义单双引号。
    • JavaScript代码:使用json_encode($input)将数据安全地嵌入到JS中。
    • URL参数:使用urlencode($input)
  2. 实施内容安全策略(CSP):通过HTTP头Content-Security-Policy告诉浏览器只允许加载指定源的脚本、样式等资源,可以极大程度地缓解XSS攻击。

  3. 避免使用黑名单:如Level 6所示,黑名单很容易被绕过(大小写、编码、罕见标签等)。应采用白名单机制,只允许已知安全的字符或格式。

  4. 使用安全框架/库:现代前端框架(如React, Vue, Angular)默认有较好的XSS防护机制。后端模板引擎也应选择具备自动转义功能的。

  5. 设置HttpOnly Cookie:为敏感的Cookie标记HttpOnly属性,防止被JavaScript窃取。


这份文档详尽地覆盖了xss-labs靶场中的核心知识点和攻击技巧,是学习反射型XSS原理和绕过手法的优秀教材。

XSS漏洞靶场攻关教学文档:xss-labs全解析 一、XSS漏洞核心原理 跨站脚本攻击(XSS) 的核心原理是: 攻击者通过向网页中注入恶意脚本,利用网站对用户输入过滤不严的漏洞,使浏览器执行这些非预期的脚本,从而盗取用户信息、劫持会话或实施其他攻击。 根据脚本是否存储在服务器上,XSS主要分为三类: 反射型XSS :恶意脚本来自当前HTTP请求(如URL参数),由服务器直接返回并立即执行。 存储型XSS :恶意脚本被永久存储在服务器端(如数据库),当其他用户访问包含此脚本的页面时触发。 DOM型XSS :漏洞完全在客户端处理,不经过服务器,由页面的JavaScript代码不当处理用户输入导致。 本靶场(xss-labs)主要针对反射型XSS进行练习。 二、关卡详解与Payload构造技巧 Level 1:直接注入 漏洞点 : keyword 参数值直接被输出到页面中,未经过任何过滤。 源码分析 : Payload : <script>alert(1)</script> 教学要点 :这是最基础的XSS形式。当用户输入被直接拼接进HTML时,浏览器会将其解析为HTML代码而非普通文本。 Level 2:">闭合标签绕过 漏洞点 :用户输入被放入一个 <input> 标签的 value 属性中。 源码分析 : 挑战 :直接输入 <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) : 挑战 : < , > , " , ' 等符号被转义为HTML实体(如 ' 变为 &#x27; ),无法使用 <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 等关键字进行了过滤替换。 源码分析 : 挑战 :无法使用 <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为例) : 教学要点 :永远不要信任任何来自客户端的输入,包括但不限于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实体 &nbsp; 和 <br> 。 源码分析 : str_replace(" ", "&nbsp;", $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原理和绕过手法的优秀教材。