SQL宽字节注入


URL编码

①将需要进行编码的字符替换:为其对应的编码形式,使用 “%” 其后跟随两位的十六进制数来替换非 ASCII 字符。
②对于URL中的保留字符,也需要进行编码。
③URL 不能包含空格,通常使用加号(+)或 %20 替代空格。
④其他字符出现在 URL 之中都必须转义,规则是根据操作系统的默认编码,将每个字节转为百分号(%)加上两个大写的十六进制字

UTF-8编码

UTF-8是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无需或只进行少部分修改后,便可继续使用。
基本特征
UCS字符U+0000到U+007F(ASCII)被编码为字节0x00到0x7F(ASCII兼容)。这意味着只包含7位ASCII字符的文件在ASCII和UTF-8两种编码方式下是一样的。
所有大于0x007F的UCS字符被编码为一个有多个字节的串,每个字节都有标记位集。

因此,ASCII字节(0x00-0x7F)不可能作为任何其他字符的一部分。表示非ASCII字符的多字节串的第一个字节总是在0xC0到0XFD的范围里,并指出这个字符包含多少个字节。多字节串的其余字节都在0x80到0xBF范围里。这使得重新同步非常容易,并使编码无国界,且很少受丢失字节的影响。
UTF8分成单字节、双字节、三字节、四字节模式。
UTF-8编码字符理论上可以最多到4个字节长,然而16位BMP字符最多只用到3字节长, UCS-4字节串的排列顺序是预定的,字节0xFE和0xFF在UTF-8编码中从未用到。
编码字节数
UTF-8使用14字节为每个字符编码:
·一个US-ASCIl字符只需1字节编码(Unicode范围由U+0000
U+007F)。
·带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字母则需要2字节编码(Unicode范围由U+0080~U+07FF)。
·其他语言的字符(包括中日韩文字、东南亚文字、中东文字等)包含了大部分常用字,使用3字节编码。
·其他极少使用的语言字符使用4字节编码。
字符集
UTF-8编码规则:如果只有一个字节则取值为0x00-0x7F。其余字节按长度进行以下拓展:
UTF-8由4种编码方式实现,即UTF8-1/UTF8-2/UTF8-3/UTF8-4
其中:
UTF8, 16进制编码表
UTF8-1
0x00-0x7F
UTF8-2
0xC2-0xDF 0x80-0xBF
UTF8-3
0xE0 0xA0-0xBF 0x80-0xBF
0xE1-0xEC 0x80-0xBF 0x80-0xBF
0xED 0x80-0x9F 0x80-0xBF
0xEE-0xEF 0x80-0xBF 0x80-0xBF
UTF8-4
0xF0 0x90-0xBF 0x80-0xBF 0x80-0xBF
0xF1-0xF3 0x80-0xBF 0x80-0xBF 0x80-0xBF
0xF4 0x80-0x8F 0x80-0xBF 0x80-0xBF
每种编码可能有多个编码范围,每个编码范围间,以空格作为每个字节的分隔符。UTF8-3的第一个编码,其第一个字节取值必须为0xE0,第二个字节范围为0xA0-0xBF,第三个字节为0x80-0xBF

Unicode

‌Unicode编码‌是一种字符编码规范,旨在为世界上每一种文字系统的每一个字符分配一个唯一的整数编号,从而避免任何冲突。Unicode编码规则的核心在于其分配机制和编码格式。‌

Unicode编码规则的核心概念
①码点(Code Point)‌:每个字符都被分配一个唯一的码点,格式为U+[XX]XXXX,范围从U+0000到U+10FFFF,足以容纳超过100万个字符。
‌②字符平面:Unicode采用分组的方式存储字符,每个组称为一个平面,每个平面能容纳65536个字符。
Unicode编码的分配机制
Unicode通过两个主要的编码格式来存储字符:

‌UTF-16‌:这是Unicode的缺省编码格式,每个字符占用16位(两个字节)。对于一些扩展字符,UTF-16使用一对代用字符进行编码,高位代用字符在U+D800到U+DBFF之间,低位代用字符在U+DC00到U+DFFF之间。
‌UTF-8‌:这是一种变长的编码格式,适用于面向字节基于ASCII的应用程序和文件系统。UTF-8可以将Unicode字符转换为变长的ASCII安全的字节字符串,非补充字符最多占用3个字节,补充字符最多占用4个字节。

宽字节注入原理

宽字节注入是一种SQL注入攻击方式。在数据库使用GBK等宽字节编码(且必须是GBK编码时才可以用宽字节注入,其他不行)时,一个汉字占两个字节。

在PHP中,当开启 magic_quotes_gpc (该函数会对特殊字符转义)后,输入的单引号 ‘ 前自动加上转义符’ ' ,从而让单引号‘失效。
攻击者利用宽字节编码特性,通过输入特定字节序列,让转义符号 \ 与后面字节组成一个汉字,从而使单引号 ‘ 能发挥SQL注入作用,达到恶意攻击目的。
eg:

一个登录验证的SQL语句为select * from users where username=’𝑢𝑠𝑒𝑟𝑛𝑎𝑚𝑒′𝑎𝑛𝑑𝑝𝑎𝑠𝑠𝑤𝑜𝑟𝑑=′
password’ 。

正常情况下,若用户的输入包含单引号会被转义。
但攻击者在用户名输入框输入 %df’ or 1=1# (这里 %df 在GBK编码下与转义字符 \ 组成一个汉字),SQL语句就会变成 select * from users where username=’汉字’ or 1=1# and password=’$password’ ,这样就绕过了原本基于用户名的验证,使攻击者可能成功登录系统。


文章作者: wuk0Ng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wuk0Ng !
评论
  目录