探究:宽字节注入中gbk编码到底是指谁的?

前言

想必师傅们都知道宽字节注入的前提必须要目标使用了GBK编码,才能够加上一些字符结合转义字符构造成汉字,吞掉了转义字符,使得引号逃逸出来,导致注入。但是这里的"使用了GBK编码"具体指的是谁的编码呢?数据库的编码(数据库服务器的默认字符集、数据库的字符集、数据表的字符集、列的字符集)吗,网站的编码吗,还是什么编码?还是这两个都是?或者是其他的什么编码呢?

既然不知道,那么我先查查网上其他师傅怎么说吧:

资料查询

查文章

先是查了大量的有关宽字节注入的文章,发现都没有得到想要的答案:

image-20241020165148510

image-20241020164709440

image-20241020165109918

image-20241020165214528

image-20241020165309713

发现绝大多数文章,要么没有提到宽字节的利用前提,文章重心一直放在怎么利用上,要么文章的相关措辞都是"mysql使用了GBK编码",也就是说这个编码前提是指的数据库的gbk编码,但是都没有指明该gbk编码具体到底在哪里,因为mysql配置编码的地方很多

拷打ChatGPT

image-20241020170539840

ok,首先GPT排除了网站编码的可能性,它也认为是数据库的编码影响的,继续拷打

image-20241020170705776

image-20241020170725536

啊嘞?GPT给我说这四个配置项共同决定了数据库在处理字符时的编码行为,咋越来越离谱了呢,有点懵圈……

没事我直接写个宽字节注入的Demo自己做实验,看看到底是哪个编码影响的,不就行了吗?

动手实验

Demo

<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "security";
$conn = new mysqli($servername, $username, $password, $dbname);
$conn->set_charset("gbk"); 
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$db_encoding = $conn->character_set_name();
$website_encoding = ini_get("default_charset");
echo "<p>Debug: Database Encoding - <strong>" . htmlspecialchars($db_encoding) . "</strong></p>";
$id = addslashes($_GET['id']);
$sql = "SELECT * FROM users WHERE id = '$id'";
echo "<p>Debug: Executing SQL Query - <strong>" . htmlspecialchars($sql) . "</strong></p>";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "ID: " . $row["id"] . " - Username: " . $row["username"] . " - Password: " . $row["password"] . "<br>
";
    }
} else {
    echo "0 results";
}
$conn->close();
?>

这段demo实现了宽字节注入的场景,并且添加了一些调试输出,打印了执行的sql语句,打印了数据库连接时采用的字符集编码

image-20241021085941477

实验变量-各种gbk编码

首先看看有哪些地方能配置gbk编码,也就是首先找出所有的影响实验结论的变量,再逐一控制变量实验,就能找到到底哪一个才是宽字节注入的真正前提

1. 网站编码

image-20241021090120356

网站编码(如<meta charset="UTF-8">)主要用于控制前端显示,这个编码定义了网页上显示内容的字符编码方式,比如是 UTF-8、GBK 等。但它还会影响浏览器向服务器发送数据时的编码

比如,当用户在网页上填写表单并提交时,浏览器会根据网页的编码(如 GBK)对数据进行编码后,再发送到服务器。这意味着网页编码决定了浏览器如何对用户输入进行编码。

服务器收到数据后,会根据约定的编码方式对数据进行解码。如果服务器预期收到的数据是 UTF-8 编码,而前端传过来的实际是 GBK 编码的数据,那么解码可能会失败。

关键点在于:无论前端数据传输使用的是什么编码,服务器端应用在接收到数据后可以根据需要进行重新编码和转换。所以,前端编码的影响主要是在数据进入服务器的那一刻,之后数据的编码转换完全由服务器端控制。

image-20241021094429428

那么,从这里就已经可以看出,网站编码影响的是网站前端到服务器端之间传输的数据编码,并没有真正影响到数据库,因为和数据库直接交互的是服务器端,那么由此推测:网站编码不是宽字节注入的真正前提

我使用这个谷歌插件修改网站编码

2. 数据库字符集

image-20241021090526505

这个gbk编码又是干什么的呢?这是数据库整理字符集编码:

数据存储设置数据库(整理)字符集编码会影响存储的数据的实际编码方式。例如,如果表的字符集是utf8mb4,插入数据时会按照utf8mb4编码存储,读取时也会按utf8mb4解码。

查询和排序整理规则影响查询时的比较和排序方式。例如,如果表的整理规则是utf8_general_ci,那么查询时会忽略大小写进行比较。

image-20241021094846097

也就是这个数据库编码是纯只在数据库中的,只影响数据库中的数据存储、排序、整理的,也和网站编码一样,没有与服务器直接交互,仅仅影响数据库本身,那么推测:数据库编码也不是宽字节注入的真正前提

3. 表字符集

如果上述推测正确,那么同理可得,表的字符集仅仅影响表中数据以什么编码进行存储和读取,并不会直接影响与服务器的交互或者导致宽字节注入

image-20241021095615598

4. 列字符集

如果推测正确,同上

image-20241021095729850

# SQL注入 # web安全 # 宽字节
已在FreeBuf发表 0 篇文章
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
原始链接: https://www.freebuf.com/articles/web/413549.html
侵权请联系站方: [email protected]

相关推荐

换一批