LOADING

宽字节注入

网络安全

宽字节注入

name=1%df' union select version(),database() --+
# 用burpsuite抓包,这个payload直接放入name参数即可

原理: %df'

  • 在URL编码中,代表一个特定的字节,当与后面的单引号结合时,可能会形成一个有效的宽字节字符。
  • 在 GBK 编码中,%df 后面跟着一个单引号可能会被解释为一个合法的中文字符

从而绕过对单引号的过滤

# 宽字节注入原代码:
if(isset($_POST['submit']) && $_POST['name']!=null){

    $name = escape($link,$_POST['name']);
    $query="select id,email from member where username='$name'";//这里的变量是字符型,需要考虑闭合
    //设置mysql客户端来源编码是gbk,这个设置导致出现宽字节注入问题
    $set = "set character_set_client=gbk";
    execute($link,$set);

    //mysqi_query不打印错误描述
    $result=mysqli_query($link, $query);
    if(mysqli_num_rows($result) >= 1){
        while ($data=mysqli_fetch_assoc($result)){
            $id=$data['id'];
            $email=$data['email'];
            $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
        }
    }else{
        $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
    }
}

我们最好对比一下字符型注入宽字节注入的代码

if(isset($_GET['submit']) && $_GET['name']!=null){
    //这里没有做任何处理,直接拼到select里面去了
    $name=$_GET['name'];
    //这里的变量是字符型,需要考虑闭合
    $query="select id,email from member where username='$name'";
    $result=execute($link, $query);
    if(mysqli_num_rows($result)>=1){
        while($data=mysqli_fetch_assoc($result)){
            $id=$data['id'];
            $email=$data['email'];
            $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
        }
    }else{

        $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
    }
}

需要重点关注的是

# 宽字节注入
$name = escape($link,$_POST['name']);
# 字符型注入
$name=$_GET['name'];

escape 函数,它可以用于转义 SQL 查询中的字符串,防止 SQL 注入。
escape 函数被调用时,它会将输入字符串中的特殊字符替换为它们的转义版本,
例如将单引号'替换为两个单引号'',双引号"替换为两个双引号""等。
但是不能防止宽字节注入,如果服务器使用 GBK 编码,并且没有正确地处理转义字符,%df' 可能会被解释为一个有效的宽字节字符,从而绕过对单引号的过滤