宽字节注入

函数介绍

PHP mysql_real_escape_string() 函数
PHP addslashes() 函数

字符集

在了解宽字节注入之前,我们先来看一看字符集是什么。字符集也叫字符编码,是一种将符号转换为二进制数的映射关系。
几种常见的字符集:

ASCII编码:单字节编码
0x00 null
0x20
0x21 !
0x22 "
0x23 #
0x24 $
0x25 %
0x26 &
0x27 ’
0x28 (
0x29)
0x2A *
0x2B +
0x2C ,
0x2D -
0x2E .
0x2F /
0x3A :
0x3B ;
0x3C <
0x3D =
0x3E >
0x3F ?
0x40 @
0x5B [
0x5C
0x5D ]
0x5E ^
0x5F _
0x60 `
0x7B {
0x7C |
0x7D }
0x7E ~

latin1编码:单字节编码

gbk编码:使用一字节和双字节编码,0x00-0x7F范围内是一位,和 ASCII 保持一致。双字节的第一字节范围是0x81-0xFE

UTF-8编码:使用一至四字节编码,0x00–0x7F范围内是一位,和 ASCII 保持一致。其它字符用二至四个字节变长表示。
宽字节就是两个以上的字节,宽字节注入产生的原因就是各种字符编码的不当操作,使得攻击者可以通过宽字节编码绕过SQL注入防御。

MySQL字符转换

数据提交到MySQL数据库,需要进行字符集的转换,使得MySQL数据库可以对数据进行处理,这一过程一般有以下三个步骤:
收到请求,将请求数据从 character_set_client ->character_set_connection。
内部操作,将数据从character_set_connection-> 表创建的字符集。
结果输出,将数据从表创建的字符集 -> character_set_results。
当执行set names “charset”,相当于执行
set character_set_client = charset
set character_set_connection = charset
set character_set_results = charset

client 指的是PHP程序
connection 指的是PHP客户端与MySQL服务器之间连接层
results 指的是MySQL服务器返回给PHP客户端的结果

MySQL常见的乱码问题就是这三个字符集的设置不当所引起的。

宽字节注入

这里的演示环境为 sqli-labs\Less-32

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");

function check_addslashes($string)
{
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                               //escape double quote with a backslash
    return $string;
}

// take the variables 
if(isset($_GET['id']))
{
$id=check_addslashes($_GET['id']);
//echo "The filtered request is :" .$id . "<br>";

//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity 

mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

    if($row)
    {
    echo '<font color= "#00FF00">'; 
    echo 'Your Login name:'. $row['username'];
    echo "<br>";
    echo 'Your Password:' .$row['password'];
    echo "</font>";
    }
    else 
    {
    echo '<font color= "#FFFF00">';
    print_r(mysql_error());
    echo "</font>";  
    }
}
    else { echo "Please input the ID as parameter with numeric value";}
?>

普通注入

当用户提交
http://127.0.0.1/Less-32/?id=1’
此时,发生如下转换
第一步:'被 check_addslashes 函数转义为 ’

第二步:在执行sql查询之前,也即’代入MySQL服务器之前,mysql_query(“SET NAMES gbk”);将MySQL的三个字符集设置为 gbk 编码

第三步:character_set_client告诉MySQL Server,传入的是gbk编码,也就是’被当做了%5C%27传入

第四步:character_set_client -> character_set_connection编码完全一致,数据没有做任何转换,所以输入是%5C%27,输出的是%5C%27

第五步:character_set_connection-> table charset这里我们需要关注下所使用的表的字符集
在这里插入图片描述
table_charset

可以看到id参数没有设置编码方式,不会对%5C%27进行处理。在这里MySQL服务器将查询语句执行,并返回结果。
执行的SQL语句为:
$sql=“SELECT * FROM users WHERE id=‘1’’ LIMIT 0,1”;
'被转义无法进行注入

第六步:table charset -> character_set_results由于character_set_results字符集也设定为 gbk ,保证了输出内容没有乱码。

通过上面的分析,我们发现用户提交的数据实际上只被处理了两次,一次是check_addslashes对危险字符的处理,另一次是gbk编码。所以,我们可以将以上步骤简化为:

数据 ---->(check_addslashes)----XXX----(GBK)---->代入数据库执行的内容

宽字节get注入

提交:
http://127.0.0.1/Less-32/?id=1%df’(浏览器自动进行url编码%27)->%df%27
根据以上分析,发生如下转换:
%df%27—>(check_addslashes)—>%df%5c%27---->(GBK)---->運’
MySQL执行的语句为:
$sql=“SELECT * FROM users WHERE id=‘1運’ LIMIT 0,1”;成功将单引号闭合,可以进行SQL注入。
在这里插入图片描述
在这里插入图片描述

宽字节get注入2.0

为了避免漏洞,网站一般会设置UTF-8编码,然后进行转义过滤。但是由于一些不经意的字符集转换,又会导致漏洞。
使用set names UTF-8指定了UTF-8字符集,并且也使用转义函数进行转义。有时候,为了避免乱码,会将一些用户提交的GBK字符使用iconv函数先转为UTF-8,然后再拼接入SQL语句。

mysql_query("set names UTF-8") ;  
$id=iconv('GBK','UTF-8', addslashes($_GET['id'])) ; 

提交:
%5c \
%27 ’
http://127.0.0.1/Less-32/?id=1%e5%5c%27
转换:(%e5%5c转为UTF-8为e9%8c%a6)
%e5%5c%27---->(addslashes)---->%e5%5c%5c%5c%27----(iconv)---->%e9%8c%a6%5c%5c%27
可以看到,多出了一个%5c,将转义符(反斜杠)本身转义,使得后面的%27单引号发挥了作用
在这里插入图片描述

在这里插入图片描述

宽字节post注入

本关是 post 型的注入漏洞,同样的也是将 post 过来的内容进行了 '的处理。由上面的例
子可以看到我们的方法就是将过滤函数添加的 \ 给吃掉。而 get 型的方式我们是以 url 形式
提交的,因此数据会通过 URLencode,如何将方法用在 post 型的注入当中,我们此处介绍
一个新的方法。将 utf-8 转换为 utf-16 或 utf-32,例如将 ’ 转为 utf-16 为 � ’ 。我们就可以利用这个方式进行尝试。
我们用万能密码的方式的来突破这一关。
在这里插入图片描述

宽字节注入防御

对于宽字节编码,有一种最好的修补就是:

(1)使用mysql_set_charset(GBK)指定字符集

(2)使用mysql_real_escape_string进行转义

原理是,mysql_real_escape_string与addslashes的不同之处在于其会考虑当前设置的字符集,不会出现前面e5和5c拼接为一个宽字节的问题,但是这个“当前字符集”如何确定呢?

就是使用mysql_set_charset进行指定。

上述的两个条件是“与”运算的关系,少一条都不行。

测试;
在这里插入图片描述

输出:
在这里插入图片描述

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SQL注入和宽字节注入都是常见的安全漏洞类型。下面我将简要介绍这两种注入方式。 1. SQL注入: SQL注入是一种在应用程序中利用不正确处理用户输入的漏洞,攻击者可以通过在用户输入中插入恶意的SQL代码来执行非授权的数据库操作。这可能导致数据泄露、数据篡改、绕过认证、获取系统权限等问题。 预防SQL注入的措施包括: - 使用参数化查询或预编译语句来处理数据库查询,而不是直接拼接用户输入的数据。 - 对用户输入进行严格的验证和过滤,避免将未经处理的输入直接传递给数据库查询。 - 最小化数据库用户的权限,并且仅分配最低必要的权限。 2. 宽字节注入宽字节注入是一种特定于某些数据库和编码方式的注入攻击方法。它利用了某些编码方式对特殊字符的处理不当,从而绕过了应用程序对输入进行过滤和验证的机制。攻击者可以通过插入宽字节字符来篡改SQL语句或绕过认证。 预防宽字节注入的措施包括: - 使用合适的编码方式,例如UTF-8,以避免特殊字符被误解释。 - 进行输入验证和过滤,确保特殊字符被正确处理,不会导致SQL语句的非预期解析。 - 定期更新数据库和应用程序框架,以修复已知的宽字节注入漏洞。 总的来说,要防止SQL注入和宽字节注入等安全漏洞,应该采取综合性的安全措施,包括输入验证、参数化查询、最小权限原则、使用最新版本的软件以及定期进行安全审计和漏洞扫描。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值