IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 宽字节注入 -> 正文阅读

[PHP知识库]宽字节注入

宽字节注入

宽字节注入是由于不同编码中中英文所占字符的不同所导致的。通常来说,在GBK编码当中,一个汉字占用2个字节。而在UTF-8编码中,一个汉字占用3个字节。在php中,我们可以通过输入 echo strlen(“中”) 来测试。当为GBK编码时,输出2。当为UTF-8编码时,输出3。除了GBK编码以外,所有的ANSI编码都是中文占用两个字节。

在说之前,我们先说一下php中对于sql注入的过滤,这里就不得不提到几个函数了。

addslashes()函数

这个函数在预定义字符前添加反斜杠\。预定义字符:单引号'双引号"反斜杠\NULL。但是这个函数有一个特点就是虽然会添加\进行转义,但是\并不会插入到数据库中。这个函数的功能和魔术引号完全相同,所以当打开了魔术引号时,不应使用这个函数,因为这样会导致双层转义。默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行addslashes()。遇到这种情况时可以使用函数get_magic_quotes_gpc()进行检测。

PHP addslashes() 函数

mysql_real_escape_string()函数

这个函数用来转义SQL语句中使用的字符串中的特殊字符。下列字符受其影响:\x00\n\r\'"\x1a。如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

PHP mysql_real_escape_string() 函数

魔术引号

当打开时,所有的单引号'双引号"反斜杠\NULL字符都会被自动加上一个反斜杠\来进行转义,这个和addslashes()函数的作用完全相同。所以,如果魔术引号打开了,就不要使用addslashes()函数了。如下,一共有三个魔术引号指令。

  1. magic_quotes_gpc 影响到 HTTP 请求数据(GET,POST 和 COOKIE)。不能在运行时改变。在 PHP 中默认值为 on。 参见get_magic_quotes_gpc()
  2. magic_quotes_runtime 如果打开的话,大部份从外部来源取得数据并返回的函数,包括从数据库和文本文件所返回的数据都会被反斜线转义。该选项可在运行时改变,在 PHP 中的默认值为 off。 参见set_magic_quotes_runtime()get_magic_quotes_runtime()
  3. magic_quotes_sybase 如果打开的话,将会使用单引号对单引号进行转义而非反斜杠。此选项会完全覆盖magic_quotes_gpc。如果同时打开两个选项的话,单引号将会被转义成"。而双引号"反斜杠\NULL字符将不会进行转义。 如何取得其值参见ini_get()

php中什么是魔术引号-php教程-PHP中文网

测试代码

<?php
// 设置GBK编码,解决php中文乱码
header("content-type:text/html;charset=GBK");

echo "SQL宽字节注入环境"."<hr>";

// 连接mysql
$conn = mysqli_connect('192.168.202.128', 'root', 'root');

// 判断连接是否成功
if(!$conn){
   die ("连接MySQL发生错误:" . mysqli_connect_error($conn));
}

// 选择库 test
mysqli_select_db($conn, 'test') or die ("无法正确连接到数据库!");

// 设置GBK编码,解决mysql中文乱码
mysqli_set_charset($conn,"GBK");

// 取消报错显示
error_reporting(0);

// 接收参数id
if(isset($_GET['id'])){
    $id=$_GET['id'];
    // addslashes()函数,在预定义符号前添加反斜杠
    $id=addslashes($id);
    // 执行sql语句并返回结果
    $sql = "SELECT * FROM user WHERE id='$id' LIMIT 0,1";
    $result = mysqli_query($conn, $sql);
    $row = mysqli_fetch_array($result, MYSQLI_BOTH);
    if($row) { 	
	    echo 'Your username:'.$row['username'] . '<br>';
	    echo 'Your password:'.$row['password'] . '<hr>';
    }else{
        echo mysqli_connect_error($conn) . "<hr>";
    }
}
else{ echo "Please input the ID as parameter with numeric value" . "<hr>";}

echo '执行的SQL语句:'. $sql;
?>

对应页面如下:
img
我们要想绕过这个转义,就得把\'\给去掉,那么怎么去掉呢?

1.在转义之后,想办法让\前面再加一个\,或者是凑成偶数个\,这样就变成了\\'\被转义了,而'逃出了限制。
2. 在转义之后,想办法把\吃掉,只留下一个'

这里我们利用第2中方法,即宽字节注入。宽字节注入利用的是MySQL的一个特性:MySQL在使用GBK编码的时候,会认为两个字符是一个汉字,前提是前一个字符的 ASCII 值大于128。

注入语句:

/?id=-1%df' union select 1,(select @@datadir),(select @@version_compile_os)--+

注入结果:
在这里插入图片描述
防御措施:

addslashes() 函数换成mysql_real_escape_string() 函数,因为php官方文档说了这个函数会考虑到连接的当前字符集。
img
所以防止宽字节注入的第一个方法就是在调用mysql_real_escape_string()函数之前,先设置连接所使用的字符集为GBK :

mysql_set_charset=('gbk',$conn) 

这个方法虽然可行,但是还有很多网站是使用addslashes()函数进行过滤的,我们不可能把所有的addslashes()函数都换成mysql_real_escape_string()

所以防止宽字节注入的另一个方法就是在所有SQL语句前将character_set_client指定连接的形式设置为binary(二进制)。

mysql_query("SET character_set_connection=gbk, character_set_results=gbk,character_set_client=binary", $conn); 

当我们的MySQL收到客户端的请求数据后,会认为他的编码是character_set_client所对应的编码,也就是二进制。然后再将它转换成character_set_connection所对应的编码。然后进入具体表和字段后,再转换成字段对应的编码。当查询结果产生后,会将查询表和字段的编码转换成character_set_results所对应的编码,返回给客户端。所以,如果我们将character_set_client编码设置成了binary,就不存在宽字节注入的问题了,数据将以二进制的形式传递。

SQL注入的防御

代码方向

  1. 对用户输入数据进行转义,例如addslashes() 函数在指定的预定义字符前添加反斜杠,把'转义为\'
  2. 对特定的关键词进行匹配过滤。如可以检测selectfromunion等关键词,将其过滤。
  3. 对数据类型及数据长度进行严格限定,防止用户输入过多的无用数据。
  4. 采用sql语句预编译,SQL引擎会预先进行语法分析,产生语法树,生成执行计划,也就是说,后面无论输入的是什么,都不会影响该SQL语句的语法结构。
  5. 使用正则表达式过滤传入的参数。

服务器方向

  1. 对数据库采用最小权限分配,如普通用户与系统管理员用户的权限进行严格的区分,这样即使可以拿到权限也不会造成更大的损失。
  2. 避免显示SQL执行报错的信息,防止报错信息被利用。
  3. 数据层的编码统一,防止过滤模型被绕过。
  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章           查看所有文章
加:2021-08-10 13:12:35  更:2021-08-10 13:14:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 15:33:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码