pikachu靶场通关笔记12 XSS关卡08-XSS之htmlspecialchars(四种技巧渗透)
目录
本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合,通过对XSS关卡源码的代码审计找到安全风险的真实原因,讲解XSS的原理并进行渗透实践,本文为XSS第08关卡XSS之htmlspecialchars关卡的渗透部分。

一、htmlspecialchars
PHP 的 htmlspecialchars ()函数 用于将特殊字符转换为 HTML 实体,防止 XSS 攻击。函数的基本语法如下所示。
string htmlspecialchars( string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ?string $encoding = null, bool $double_encode = true)
htmlspecialchars 函数的主要参数含义如下所示。
| 参数 | 可选值/示例 | 作用 |
|---|---|---|
$flags | ENT_QUOTES | 转义单双引号(推荐) |
ENT_COMPAT | 仅转义双引号 | |
ENT_NOQUOTES | 不转义任何引号 | |
$encoding | 'UTF-8'(推荐) | 指定字符编码,避免乱码 |
$double_encode | true(默认) | 是否对已转义的字符再次转义 |
htmlspecialchars函数主要转义以下 5 个字符,具体如下所示。
| 原始字符 | 转义后实体 | 用途说明 |
|---|---|---|
& | & | 避免混淆 HTML 实体 |
" | " | 转义双引号(属性值用) |
' | ' | 转义单引号(属性值用) |
< | < | 避免标签被解析 |
> | > | 避免标签被解析 |
尽管htmlspecialchars 函数对用户输入进行处理,可以防范XSS安全风险,它并非能抵御所有类型的 XSS 攻击,以下是它无法有效防御的几类情况::
事件处理属性:在 HTML 标签里,很多属性可用于触发 JavaScript 代码,例如
onclick、onload、onmouseover等。要是攻击者把恶意脚本注入到这些事件处理属性中,htmlspecialchars就可能无法有效防御。协议攻击:攻击者可通过构造包含恶意协议(如 javascript:、data:)的 URL 来实施攻击。htmlspecialchars 虽然会对特殊字符进行编码,但无法阻止恶意协议的使用。
单引号绕过情况:htmlspecialchars 默认不会对单引号进行编码(除非指定 ENT_QUOTES 或 ENT_COMPAT 标志)。攻击者可利用单引号来绕过过滤,注入恶意脚本。
二、源码分析
1、进入靶场
打开pikachu靶场第08关XSS之htmlspecialchars,完整URL地址如下所示,这是一个输入框页面,如下所示。
http://127.0.0.1/pikachu/vul/xss/xss_02.php

2、代码审计
查看xss_02.php源码内容,如下所示使用htmlspecialchars函数对输入参数进行了过滤处理,具体如下所示。

这段 PHP 代码的主要功能是处理用户通过 GET 请求提交的 message 参数。当用户提交表单(即 submit 参数存在)时,会进行如下操作:
- 检查
message是否为空,如果为空,提示用户输入内容。 - 如果
message不为空,使用htmlspecialchars函数对其进行处理,将特殊字符转换为 HTML 实体。 - 提示用户输入内容已被记录,并将处理后的内容以超链接的形式展示在页面上。
对源码进行详细注释,具体如下所示。
输入点啥吧!"; } else { // 如果 'message' 不为空,使用 htmlspecialchars 函数对用户输入的 'message' 内容进行处理 // htmlspecialchars 函数会将特殊字符转换为 HTML 实体,如将 转换为 > 等 // 但默认情况下,单引号 ' 不会被处理 $message = htmlspecialchars($_GET['message']); // 向 $html1 变量中追加一段提示信息 // 告知用户输入的内容已经被记录 $html1 .= "你的输入已经被记录:"; // 实际使用的代码,将处理后的内容作为超链接的 href 属性和显示文本 // 即创建一个超链接,链接地址和显示文本都是用户输入的内容 $html2 .= "{$message}"; }}?>
3、渗透思路
虽然代码使用了 htmlspecialchars 函数对用户输入进行处理,但仍然有XSS安全风险,渗透思路如下:
(1)利用单引号绕过
由于 htmlspecialchars 默认不对单引号 ' 进行处理,攻击者可以构造包含单引号的恶意输入。例如,当用户输入 ' οnclick='alert('XSS') 时,最终生成的 HTML 代码会变成:
' onclick='alert('XSS')
当用户点击这个超链接时,就会触发 onclick 事件,执行其中的 JavaScript 代码,弹出包含 XSS 的警告框。
(2)利用协议绕过
攻击者可以构造包含恶意协议的输入,如 javascript:alert('XSS')。当用户输入该内容时,最终生成的 HTML 代码为:
javascript:alert('XSS')
当用户点击这个超链接时,浏览器会执行 javascript 协议指定的代码,从而触发 XSS 攻击。
三、渗透实战
1、探测是否有过滤
进入pikachu靶场的第08关卡xss之htmlspecialchars,注意这是一个带有输入框的页面,如下所示。
http://127.0.0.1/pikachu/vul/xss/xss_02.php

接下来输入关键字判断是否有过滤,关键字包括:单引号、双引号、左右尖括号、问号、&、字符串与数字'"<>'ljn'"20141019"%#?,具体如下所示。
'"<>'ljn'"20141019"%#?

发现<a>标签内还是href属性内,左右尖括号被编码,双引号被替编码为了",但是单引号居然没有被html编码,可以利用<a>标签。
2、注入payload1
ljn' οnfοcus='alert(1019)'

3、注入payload2
ljn' οnclick='alert(1019)'

4、注入payload3
ljn' οnclick='alert(document.cookie)'

5、注入payload4
javascript:alert(1019)

浙公网安备 33010602011771号