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() --+

其实也算联合查询里面的知识,只不过是由于数据库宽字节引起的漏洞,所以还是可以利用的