多字节字符漏洞利用 - PHP/MySQL

信息安全 php sql注入 mysql
2021-08-29 14:47:52

有人可以指出一个链接,其中包含有关 MySQL 多字节字符攻击的一些信息?一个朋友让我注意到了它们,但我在互联网上找不到太多信息。

2个回答

概括。是的,问题在于,在某些字符编码(如 UTF-8)中,单个字符表示为多个字节。一些程序员试图阻止 SQL 注入的一种方法是在将不受信任的输入中的所有单引号插入到他们的 SQL 查询之前对其进行转义。但是,许多标准的引号转义函数不知道数据库将使用的字符编码并将其输入作为字节序列处理,而忽略了单个字符可能会填满多个字节的事实。这意味着引号转义函数对字符串的解释与数据库不同。因此,在某些情况下,引号转义函数可能无法转义数据库将解释为单引号的多字节编码的字符串部分;或者可能会无意中以引入单引号的方式分解多字节字符编码,而该单引号以前不存在。因此,多字节字符攻击为攻击者提供了一种进行 SQL 注入攻击的方法,即使程序员认为他们已经充分地将输入转义到数据库中。

影响。如果您使用准备好的/参数化语句来形成所有数据库连接,那么您是安全的。多字节攻击将失败。(当然,除了数据库和库中的错误。但根据经验,这些似乎很少见。)

但是,如果您尝试转义不受信任的输入,然后使用字符串连接动态形成 SQL 查询,您可能容易受到多字节攻击。您是否真的易受攻击取决于您使用的转义函数、您使用的数据库、您在数据库中使用的字符编码以及可能的其他因素的具体细节。很难预测多字节攻击是否会成功。因此,使用字符串连接形成 SQL 查询很脆弱,不推荐使用。

技术细节。如果您想了解攻击的详细信息,我可以为您提供一些详细解释攻击的链接。有几种攻击方式:

  • 通过消耗引用功能引入的额外反斜杠/引号来对 UTF-8 和其他字符编码进行基本攻击:参见,例如,here

  • 对例如 GBK 的偷偷摸摸的攻击,通过欺骗引用功能为您引入额外的引用来工作:例如,请参见Chris Shiflett 的博客此处此处

  • 攻击,例如,UTF-8,通过使用单引号的无效非规范(过长)编码来隐藏引号的存在:参见,例如,here基本上,对单引号进行编码的正常方式是使其适合单字节序列(即0x27)。但是,也有数据库可能将多字节序列解码为单引号,并且不包含该0x27字节或任何其他可疑字节值。因此,标准的引号转义函数可能无法转义这些引号。

多字节攻击不仅限于 SQL 注入。一般来说,多字节攻击会导致攻击者删除控制字符的“字节消耗”情况。这与经典的相反 ' or 1=1--,其中攻击者引入了单引号控制字符。对于 mysql ,mysql_real_escape_string()它旨在处理字符编码问题。PDO 等参数化查询库将自动使用此功能。MySQLi 实际上将查询的参数作为结构中的一个单独元素发送,这完全避免了这个问题。

如果通过 Shift-JIS 呈现 HTML 页面,则可以使用控制字符来获取 XSS。在第 207 页的“ A Tangled Web ”(神奇的书!)中提供了一个很好的例子:

<img src="http://fuzzybunnies.com/[0xE0]">
...this is still a part of the mkarup...
...but the srever dosn't know...
" onload="alert('this will execute!')"
<div>
...page content continues...
</div>

在这种情况下,0xE0是一个特殊字节,表示 3 字节符号的开始。当浏览器呈现此 html 时,流">将被消耗并变成单个 Shift-JIS 符号。如果攻击者通过另一个变量来控制以下输入,那么他可以引入事件处理程序来获取代码执行。