编码技术
一、编码基础概述
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编码
命名实体:
、<、>等十进制实体:
 、<、>十六进制实体:
 、<、>HTML5新增实体:更多特殊字符支持
渗透测试应用:
1
<img src="x" onerror="alert(1)" />
- 多层编码绕过过滤器
- 混合使用不同编码方式
- 利用浏览器解析差异
注意事项:
- 仅在属性值和文本内容中有效
- 不能对标签名、属性名进行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编码
- 实体编码:
<,>,&等 - 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="alert(1)">
- 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
2import 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,但某些中间件可能仍存在风险