编码技术

一、编码基础概述

1.1 为什么需要编码

在计算机系统中,不同系统、协议和应用程序对数据的表示和处理方式存在差异。编码技术解决了以下问题:

  • 字符表示:将人类可读的字符转换为计算机可处理的二进制数据
  • 数据传输:确保特殊字符在传输过程中不被误解或破坏
  • 安全过滤:绕过基于特定字符集的过滤机制
  • 数据压缩:在某些情况下提高传输效率

1.2 编码与加密的区别

  • 编码:数据格式的转换,是可逆的、公开的转换过程,不提供保密性
  • 加密:通过密钥将数据转换为密文,提供保密性和完整性保护

1.3 编码在网络安全中的重要性

渗透测试中,攻击者常利用编码技术:

  • 绕过WAF(Web应用防火墙)和输入过滤
  • 隐藏恶意负载
  • 规避安全检测机制
  • 利用解析差异实施攻击

二、基础字符编码

2.1 ASCII编码

ASCII编码背景

  • 历史:1963年由美国国家标准协会(ANSI)制定,最初用于电报通信
  • 标准范围:0-127(7位),共128个字符
  • 扩展ASCII:8位编码,范围0-255,包含特殊符号和非英语字符
  • 渗透测试意义:作为大多数现代编码的基础,理解ASCII对于分析编码绕过至关重要

完整ASCII表

十进制 十六进制 二进制 字符 名称/说明
控制字符 (0-31, 127)
0 0x00 00000000 NUL 空字符 (Null)
7 0x07 00000111 BEL 响铃 (Bell)
8 0x08 00001000 BS 退格 (Backspace)
9 0x09 00001001 HT 水平制表符 (Horizontal Tab)
10 0x0A 00001010 LF 换行 (Line Feed)
13 0x0D 00001101 CR 回车 (Carriage Return)
27 0x1B 00011011 ESC 转义 (Escape)
127 0x7F 01111111 DEL 删除 (Delete)
可打印字符 (32-126)
32 0x20 00100000 [空格] 空格 (Space)
33 0x21 00100001 ! 感叹号
34 0x22 00100010 双引号
39 0x27 00100111 单引号
40-41 0x28-0x29 00101000-00101001 () 括号
42 0x2A 00101010 * 星号
43 0x2B 00101011 + 加号
44 0x2C 00101100 , 逗号
45 0x2D 00101101 - 连字符
46 0x2E 00101110 . 句点
47 0x2F 00101111 / 斜杠
58-59 0x3A-0x3B 00111010-00111011 :; 冒号、分号
60-62 0x3C-0x3E 00111100-00111110 <> 小于号、大于号
63 0x3F 00111111 ? 问号
64 0x40 01000000 @ at符号
65-90 0x41-0x5A 01000001-01011010 A-Z 大写字母
91-96 0x5B-0x60 01011011-01100000 []^_` 特殊符号
97-122 0x61-0x7A 01100001-01111010 a-z 小写字母
123-126 0x7B-0x7E 01111011-01111110 { }~

渗透测试中的ASCII特殊字符应用

  • 空格(0x20):SQL注入中替代空格的常用字符(如%09%0A
  • 单引号(0x27):SQL注入关键字符,常需编码绕过
  • 双引号(0x22):XSS攻击中常用于闭合属性
  • 尖括号(0x3C, 0x3E):HTML标签标识符,XSS攻击核心
  • 斜杠(0x2F):路径分隔符,目录遍历攻击关键
  • 反斜杠(0x5C):在某些语言中作为转义字符

2.2 Unicode编码体系

  • UTF-8

    • 可变长度编码(1-4字节)
    • 向后兼容ASCII
    • 互联网标准(RFC 3629),现代Web应用首选
    • 优势:节省空间(ASCII字符仅需1字节),支持全球语言
  • UTF-16

    • 固定2字节或可变4字节编码
    • Windows系统内部常用
    • BOM(Byte Order Mark)问题可能导致解析异常
  • UTF-32

    • 固定4字节编码
    • 处理简单但空间效率低
    • 较少用于网络传输
  • 渗透测试应用

    • 利用不同系统对Unicode解析的差异
    • BOM头注入绕过文件类型检测
    • 混合编码导致的解析漏洞

2.3 ISO-8859系列编码

  • ISO-8859-1 (Latin-1):西欧语言
  • ISO-8859-2:中欧语言
  • ISO-8859-5:西里尔字母
  • 渗透测试应用:在未指定编码的Web应用中引发乱码问题,可能导致安全漏洞

三、Web相关编码技术

3.1 页面编码

  • 设置方式

    1
    <meta charset="utf-8" />

    或HTTP响应头:

    1
    Content-Type: text/html; charset=utf-8
  • 常用编码

    • UTF-8:现代Web标准
    • GBK/GB2312:中文环境常用
    • ISO-8859-1:早期Web应用
  • 渗透测试应用

    • 利用编码不一致导致的XSS漏洞
    • 混合编码绕过过滤
    • 通过修改响应头欺骗客户端解析

3.2 HTML编码

  • 命名实体&nbsp;&lt;&gt;

  • 十进制实体&#160;&#60;&#62;

  • 十六进制实体&#xA0;&#x3C;&#x3E;

  • HTML5新增实体:更多特殊字符支持

  • 渗透测试应用

    1
    <img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;" />
    • 多层编码绕过过滤器
    • 混合使用不同编码方式
    • 利用浏览器解析差异
  • 注意事项

    • 仅在属性值和文本内容中有效
    • 不能对标签名、属性名进行HTML编码

3.3 URL编码

  • 标准:RFC 3986

  • 编码规则

    • 保留字符(如!, *, ', (, ), ;, :, @, &, =, +, $, ,, /, ?, #, [, ])需要编码
    • 非ASCII字符必须编码
    • 空格编码为+%20
  • 渗透测试应用

    1
    http://example.com/index.php?keyword=aa%20union%20select
    • 绕过基于关键字的过滤
    • 多次URL编码绕过WAF
    • 混合编码技术(如先Base64再URL编码)

3.4 JavaScript编码

  • 十六进制编码

    1
    \x3C\x73\x63\x72\x69\x70\x74\x3Ealert(1)\x3C\x2F\x73\x63\x72\x69\x70\x74\x3E
  • 八进制编码

    1
    \74\163\143\162\151\160\164\76alert(1)\74\57\163\143\162\151\160\164\76
  • Unicode编码

    1
    \u003c\u0073\u0063\u0072\u0069\u0070\u0074\u003ealert(1)\u003c\u002f\u0073\u0063\u0072\u0069\u0070\u0074\u003e
  • 渗透测试应用

    • 绕过基于关键字的JS过滤
    • 混合编码实现高级XSS
    • 利用<script>标签的编码绕过

3.5 CSS编码

  • Unicode编码\0000格式
  • 十六进制编码\0000\x0000
  • 渗透测试应用
    1
    body { background: url('\x68\x74\x74\x70\x3a\x2f\x2f\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d'); }
    • CSS注入攻击
    • 绕过内容安全策略(CSP)

四、数据传输编码

4.1 Base64编码

  • 原理:将二进制数据转换为64个可打印ASCII字符

  • 标准:RFC 4648

  • 特点

    • 编码后数据量增加约33%
    • 末尾可能有1-2个=作为填充
    • URL安全变种使用-_代替+/
  • 渗透测试应用

    1
    <iframe src='data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=='></iframe>
    • 隐藏恶意脚本
    • 绕过基于关键字的过滤
    • 多层编码(Base64 + URL编码)

4.2 Hex编码

  • 原理:将每个字节转换为两位十六进制数

  • 数据库应用:MySQL中使用0x前缀

    1
    SELECT 0x48656C6C6F; -- 输出Hello
  • 渗透测试应用

    • SQL注入绕过
    • 文件内容十六进制表示
    • 混合编码绕过过滤

4.3 UUEncode

  • 历史:早期用于Unix系统间邮件传输
  • 特点:将3字节转换为4个可打印字符
  • 渗透测试应用:在遗留系统中可能发现的编码方式

4.4 Quoted-Printable

  • 标准:RFC 2045,用于MIME编码

  • 特点

    • 保留可打印ASCII字符
    • 非ASCII字符和特殊字符编码为=后跟两位十六进制
    • 每行不超过76字符
  • 渗透测试应用

    • 邮件系统漏洞利用
    • 绕过基于内容的过滤

五、数据结构编码

5.1 JSON编码

  • 标准:RFC 8259

  • 特点

    • 轻量级数据交换格式
    • 支持对象、数组、字符串、数字、布尔值和null
    • 严格的语法要求
  • 渗透测试应用

    1
    [{"Name":"a1","Number":"123","Contno":"000","QQNo":""}]
    • JSON注入攻击
    • 利用解析差异实施攻击
    • 通过编码绕过JSON验证

5.2 XML编码

  • 实体编码&lt;, &gt;, &amp;
  • CDATA<![CDATA[...]]>区域
  • 渗透测试应用
    • XXE(XML External Entity)攻击
    • 利用编码绕过XML解析器
    • 混合编码实现高级攻击

5.3 序列化

  • PHP序列化

    1
    a:3:{i:0;s:3:"Moe";i:1;s:5:"Larry";i:2;s:5:"Curly";}
    • a表示数组,i表示整数,s表示字符串
  • Java序列化:二进制格式,易受反序列化漏洞影响

  • Python Pickle:类似Java序列化,存在安全风险

  • 渗透测试应用

    • 反序列化漏洞利用
    • 操作序列化数据实现远程代码执行
    • 绕过基于结构的过滤

六、特殊编码技术

6.1 UTF-7编码

  • 历史:设计用于在7位传输通道中传输Unicode
  • 特点:使用+开头的编码序列
  • 渗透测试应用
    1
    <img src="moonsec +AG0AbwBv-n+AHM-e+AGM-" />
    • 绕过基于ASCII的过滤器
    • XSS攻击中的经典绕过技术
    • 现代浏览器已逐渐弃用,但在旧系统中仍有效

6.2 Punycode

  • 标准:RFC 3492
  • 用途:将国际化域名转换为ASCII兼容格式
  • 渗透测试应用
    • IDN欺骗(同形异义字攻击)
    • 钓鱼网站构造
    • 例如:xn--80ak6aa92e.com 可能显示为 “аpple.com”(使用西里尔字母а)

6.3 Double Encoding(双重编码)

  • 原理:对同一数据进行两次相同或不同的编码
  • 渗透测试应用
    1
    %253Cscript%253Ealert(1)%253C/script%253E
    • 第一次解码:%3Cscript%3Ealert(1)%3C/script%3E
    • 第二次解码:<script>alert(1)</script>
    • 绕过仅进行单次解码的WAF

6.4 Mixed Encoding(混合编码)

  • 原理:结合多种编码方式
  • 渗透测试应用
    1
    %25%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E
    • URL编码 + HTML编码混合
    • 绕过多层过滤系统

七、编码在渗透测试中的实际应用

7.1 绕过WAF

  • 多层编码:对同一内容进行多次编码
  • 混合编码:结合URL、HTML、JS等多种编码
  • 大小写混淆:利用WAF大小写敏感性
  • 空格替换:用%09(TAB)、%0A(换行)等代替空格

7.2 XSS攻击

  • HTML编码绕过
    1
    <img src=x onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;">
  • JS编码绕过
    1
    \u0061\u006c\u0065\u0072\u0074(1)
  • 混合编码
    1
    <img src=x onerror="eval('\x61\x6c\x65\x72\x74\x28\x31\x29')">

7.3 SQL注入

  • Hex编码绕过
    1
    SELECT * FROM users WHERE username = 0x61646D696E
  • URL编码绕过
    1
    UNION%20SELECT%201,2,3
  • 双重编码绕过
    1
    %2527%20OR%201%3D1--

7.4 文件包含漏洞

  • 编码路径遍历
    1
    ?file=..%2f..%2fetc%2fpasswd
  • 混合编码绕过
    1
    ?file=%252e%252e%252fetc%252fpasswd

八、编码工具推荐

8.1 在线工具

  • CyberChef:多功能编码/解码工具,支持超过200种操作
  • URLDecoder:专门用于URL编码解码
  • Base64decode:Base64编码解码
  • Unicode Escape:Unicode编码转换
  • XSS Encoder:专门用于XSS测试的编码工具

8.2 浏览器插件

  • HackBar:多功能安全测试工具,包含编码功能
  • Burp Suite Encoder:集成在Burp Suite中的编码工具
  • XSStrike:XSS检测工具,包含编码绕过功能

8.3 命令行工具

  • Python
    1
    2
    import urllib.parse
    urllib.parse.quote("test string")
  • JavaScript (Node.js)
    1
    encodeURIComponent("test string")
  • Linux命令
    1
    echo "Hello" | base64

九、防御建议

9.1 安全编码实践

  • 输入规范化:在处理前将输入转换为标准格式
  • 多层解码检查:避免仅进行单次解码
  • 白名单过滤:允许已知安全的字符,拒绝其他所有
  • 内容安全策略(CSP):限制脚本执行来源

9.2 WAF配置建议

  • 多层解码:确保WAF能够处理多层编码
  • 正则表达式优化:使用更智能的模式匹配
  • 上下文感知:根据不同输入位置应用不同规则
  • 定期更新规则:跟上新的编码绕过技术

9.3 安全开发建议

  • 使用安全API:避免手动处理编码/解码
  • 输出编码:在输出到不同上下文时使用适当编码
  • 安全库使用:使用经过验证的安全库处理用户输入
  • 安全测试:包括对编码绕过技术的测试

十、编码绕过案例研究

10.1 经典XSS双重编码绕过

  • 原始payload<script>alert(1)</script>
  • 双重URL编码
    1
    %253Cscript%253Ealert(1)%253C%252Fscript%253E
  • WAF行为:仅进行一次URL解码,得到<script>alert(1)</script>,仍然被过滤
  • 浏览器行为:进行两次URL解码,最终执行脚本

10.2 SQL注入Hex编码绕过

  • 原始payload' OR 1=1 --
  • Hex编码0x27204F5220313D31202D2D
  • 绕过原理:某些WAF无法识别Hex编码的SQL注入

10.3 UTF-7 XSS攻击

  • payload+ADw-script+AD4-alert(1)+ADw-/script+AD4-
  • 绕过原理:旧版IE将UTF-7内容视为脚本执行
  • 现代影响:虽然现代浏览器已弃用UTF-7,但某些中间件可能仍存在风险