Skip to content

URL 编码

1. 原理与本质

URL 编码(百分号编码)是统一资源标志符 (URI) 的编码机制。由于 HTTP 协议在传输 URL 时,只能使用安全的 ASCII 字符集,部分具有特殊语法含义的字符(保留字符)或不可见字符,必须进行转义处理,以避免被底层解析器(Lexer/Parser)误识别为控制指令。

  • 编码规则: 将字符的 ASCII 码或 UTF-8 字节的十六进制表示,加上前缀 %。例如,空格的 ASCII 码是 32(十六进制 20),编码后为 %20。

  • 非保留字符 (Unreserved): A-Z, a-z, 0-9, -, _, ., ~。绝对不需要进行 URL 编码。

  • 保留字符 (Reserved): ! * ' ( ) ; : @ & = + $ , / ? % # [ ]。作为数据载荷传输时必须编码。

2. 常用 URL 编码

在 Web 安全方向的实战与靶机环境中,熟练掌握高频特殊字符的十六进制映射,是构造 Payload 的基础。

2.1 注入类与闭合高频字符 ([[SQL注入]], [[命令注入]], [[XSS]])

字符 URL 编码 攻击场景与作用说明
' (单引号) %27 SQL 注入闭合字符串;命令注入屏蔽解析;XSS 闭合属性。
" (双引号) %22 同上。
< %3C XSS 标签注入;命令注入中的输入重定向。
> %3E XSS 标签闭合;命令注入中的输出重定向(写 WebShell)。
# %23 SQL 注入截断/注释后续查询语句;URL 锚点(防截断)。
\ (反斜杠) %5C 路径穿越;转义符注入。

2.2 控制流与分隔符 ([[命令执行 RCE]], [[CRLF注入]])

字符 URL 编码 攻击场景与作用说明
\n (换行) %0A Unix/Linux 换行符,绕过正则;分割多条 Shell 命令。
\r (回车) %0D HTTP 响应拆分攻击 (CRLF Injection %0D%0A)。
; (分号) %3B Shell 顺序执行多条命令;PHP 代码单行语句结束符。
\| (管道符) %7C Shell 命令管道,将前一条命令输出作为后一条命令输入。
& %26 Shell 后台执行;URL 参数分隔符(需注意在传递 Payload 时可能被解析为参数分割,需提前编码)。

2.3 特殊占位符与绕过

字符 URL 编码 攻击场景与作用说明
空格 %20 或 + 参数分割。在应用层过滤 %20 时,常尝试使用 %09 (Tab)、%0A 替代空格绕过。
\0 (空字符) %00 Poison Null Byte(%00 截断)。在旧版 PHP 或 C 语言底层处理中,作为字符串终止符,截断 .php 后缀判断。
% %25 双重编码构造基础(见下文)。

3. 实战进阶:CTF 编码绕过策略

在业务逻辑与底层抽象存在信息差时,常通过以下方式绕过 WAF 或正则引擎。

3.1 双重 URL 编码 (Double Encoding)

  • 原理: 攻击者对 Payload 进行两次 URL 编码。

  • 场景: 当 WAF 或前端代理只进行一次 URL 解码并执行安全检查,而脆弱的后端业务逻辑(如二次代入 SQL 查询)会触发第二次 URL 解码时使用。

  • 构造示例:

    • 单引号 ' -> 一次编码 %27 -> 二次编码 %2527 (因为 % 的编码是 %25)。

    • Payload: 1 %2527 UNION SELECT...

3.2 罕见编码与 Unicode 欺骗

  • 当标准 ASCII 特殊字符被过滤时,利用目标系统底层解析库(如某些 Web 容器或数据库驱动)处理全角字符或宽字节时的降级特性。

  • 示例 (宽字节注入): 在 GBK 编码环境下,使用 %df%27。反斜杠转义符 %5C 会与 %df 结合成一个合法的中文字符(餟),从而让后续的单引号 %27 逃逸并生效。