跳转至

宽字节注入

情景一

在PHP中使用mysql_query(“set names GBK”);指定三个字符集(客户端、连接层、结果集)都是GBK编码。 情景代码:

mysql_query(“set names GBK”); 
$bar = addslashes($_GET[‘bar’]) ;    <== addslashes() 加\进行转义,可以对'进行转义\'
$sql = “select password from user where bar=’{$bar}’”; 
$res = mysql_query($sql) ; 

提交:http://127.0.0.1/foo.php?bar=admin%df%27 (%27是') 这时,发生如下转换:

%df%27=====(addslashes)======>%df%5c%27======(GBK)======>運'

带入sql为:

Select password from user where bar='運'

成功将单引号闭合。为了避免漏洞,网站一般会设置UTF-8编码,然后进行转义过滤。但是由于一些不经意的字符集转换,又会导致漏洞。

情景二:

使用set names UTF-8指定了UTF-8字符集,并且也使用转义函数进行转义。有时候,为了避免乱码,会将一些用户提交的GBK字符使用iconv函数(或者mb_convert_encoding)先转为UTF-8,然后再拼接入SQL语句。 情景代码:

mysql_query(“set names UTF-8”) ; 
$bar =iconv(“GBK”,”UTF-8”, addslashes($_GET[‘’bar])) ;  

$sql = “select password from user where bar=’{$bar}’” ; 
$res = mysql_query($sql) ; 

我们可以看到,为了使得SQL语句中的字符集保持一致,一般都会使用iconv等字符集转换函数进行字符集转换,问题就是出在了GBKUTF-8转换的过程中。 提交:http://127.0.0.1/foo.php?bar=%e5%5c%27 变换过程:(e55c转为UTF-8e98ca6

e55c27====(addslashes)====>e55c5c5c27====(iconv)====>e98ca65c5c27

可以看到,多出了一个5c,将转义符(反斜杠)本身转义,使得后面的%27发挥了作用。 测试如下:

情景三:

使用iconv进行字符集转换,将UTF-8转为GBK,同时,set names字符集为GBK。提交%e9%8c%a6即可。 这个情景的大前提是先编码后转义:

e98ca6====(iconv)=====>e55c=====(addslashes)====>e55c5c

同样可以多出一个反斜杠进行利用,在此不再详述,因为漏洞条件比较苛刻。​