【问题标题】:Php & Sql Injection - UTF8 POCPHP & Sql 注入 - UTF8 POC
【发布时间】:2011-07-05 13:52:36
【问题描述】:

有很多关于 addlashes 和 mysql_real_escape 函数如何不安全地防止注入的讨论。事实上,即使是像 Wordpress 这样的大型框架或 CMS 也在使用这些功能,而且到目前为止它们做得非常好。

我知道在使用GBK字符集时有一些特殊的场景,或者utf8_decode可以用来注入一些sql代码,或者一些简单的例子比如1' OR 1 --可以在涉及到简单的地方时使用。

但是,经过一番研究,如果字符集是 UTF-8,则似乎很难将某些内容注入到使用 addlashes 或 mysql_real_escape 的简单查询中,让我们承认,这是最常见的情况。

所以,鉴于这个新手脚本,请提供一个 sql 注入 POC(记住 UTF-8 字符集)

$mysql['username'] = addslashes($_POST['username']);
$mysql['password'] = addslashes($_POST['password']);

$sql = "SELECT *
FROM users
WHERE username = '{$mysql['username']}'
AND password = '{$mysql['password']}'";

更新 - 我只需要一个简单的示例,而不是完整披露该过程。即使是来自谷歌的链接也可能有效。

【问题讨论】:

  • 2 个书签和 2 个关闭投票?有什么原因吗?
  • 好问题,但我想知道的是:为什么 简单地使用 mysql_real_escape_string 如果甚至有一个遥远的理论可能性 addslashes 不够好(更不用说准备好的陈述等)?
  • 我告诉过你,对于此类问题,这是完全错误的网站。不开玩笑。那是因为大多数人从不考虑问题(更不用说问题背后的问题),而是倾向于发布他们认为与问题相关的某种知识。看,这家伙问了类似的问题,但没有得到很好的答案:stackoverflow.com/questions/3448441 但是,它也包含对您问题的某种答案
  • 我明白你的意见,弹片上校,但上次你给了我正确的答案:)
  • 哈哈,就像我说的!这家伙因为他无用的咆哮而获得了赏金:)

标签: php sql code-injection


【解决方案1】:

更新 2

After further research5.0.77 之前的 MySQL 版本在单独与 SET NAMES 结合使用时可能容易受到 GBK 问题的影响。早先认为只有 5.0.22 及更早版本易受攻击。

这意味着,如果您使用的 PHP 版本 到 5.2,其中引入了 mysql_set_charset / mysqli_set_charset,那么您的代码可能在特定的、精心设计的条件下容易受到攻击。 p>

如果您卡在 PHP 5.1 上,请确保您使用的是 MySQL 5.0.77 或更高版本。 5.0.77“只有”两年的历史,但已被推送到 RHEL/CentOS 5.x 的存储库中,更流行的发行版停留在 MySQL 的 5.0.x 系列和 PHP 的 5.1.x 系列。

进行升级,伙计们!


更新 1Another recent question 发现了 GBK 的来源:A bugfix in MySQL 5.0.22。在使用 mysql_real_escape_string 以外的任何内容 mysql_set_charset 而不是 仅使用 SET NAMES 时,早于此的版本严重易受攻击。 mysqli 等效项被命名为mysqli_set_charset

在 PDO 中似乎没有 mysql_set_charset 的等价物。这可能是因为它可以使用 MySQL 本机准备好的语句,这可能不会出现问题,或者SET NAMES 是否足以使其底层转义机制按预期工作。

无论如何,如果您使用的是 5.0.22 5.0.77 之前的任何 MySQL 版本,并且没有特别注意确保您只传递已知字符串中的字符串字符集,你可能会发现自己容易受到攻击。

我不修改原始帖子的其余部分,但我已经更新了 tldr。


关于 addlashes 和 mysql_real_escape 函数如何不安全地防止注入的讨论很多

这是对的。 addslashes 用于防止 SQL 注入是完全错误的,因为它不能保证为所有数据库提供正确的转义方法,主要是因为它添加了反斜杠,有时转义机制完全不同。

如果您被困在被称为“mysql”扩展(而不是使用 PDO 或 mysqli)的史前垃圾堆中,mysql_real_escape_string 是您在需要时获得的最佳保护之一将一些 SQL 连接在一起。

我知道在使用GBK字符集的时候有一些特殊的场景,或者utf8_decode可以用来注入一些sql代码

您可能正在考虑创建格式错误的 UTF-8 序列,但我只将其视为XSS 机制,从未将其视为 SQL 注入机制。通过iconv//IGNORE//TRANSLIT 运行字符串应该是足够好的保护(通常通过在坏序列点截断字符串,这是一种可接受的故障模式当你受到攻击时--格式错误的序列绝不应该出现在合法请求中)。

此外,虽然在非拉丁语言中有很多“引号”字符,但 MySQL 在实际上只遵守标识符的反引号和双引号以及字符串值的单引号方面相当不错。

再想一想,如果将其视为不同的字符集,也许另一个字符集中的某些字符序列可能在中间包含一个单引号。但是,addslashes 很可能完全不了解字符集,并且仅适用于原始字节。它会在一个序列的中间加上一个反斜杠,然后把它炸掉。但是,这应该只会在某处引起关于错误字符集信息的抱怨。

另一方面,mysql_real_escape_string 的设计考虑了内置的连接字符集,因此如果它看到的是序列而不是引号,它就不会转义序列。但是,因为它会将其识别为序列而不是引用,所以完全没有危险。

最终,如果您认为这是一个问题,您有责任确保仅接受预期字符集的输入,并在出现不匹配时将所有输入转换为所需字符集。这很少会触发合法请求。


tl;dr: 除非您使用的是非常旧的 MySQL 版本和/或无法确保您的数据采用已知良好的字符集,否则这不是问题。始终使用特定于数据库的转义机制以获得最大的安全性,并始终假设用户是在找你。

【讨论】:

  • 您所说的“假设用户是来找你的”是什么意思。他! ;)
  • mres 仅在您还调用 mysql_set_charset 时才会 100% 保护输入。否则它很容易受到与addslashes() 相同的基于字符集的攻击。但是如果你将字符集设置为连接字符集,你就可以了......
  • 嗯,在那里的文档中,他们建议使用该函数而不是 SET NAMES ...。我想知道为什么。
  • 我已经更新了我的帖子,提供了有关 GBK 事物来源的更多信息——MySQL 5.0.22 及更早版本中的一个错误。
  • 你能举一个这个漏洞的例子吗?我尝试使用 UTF 的可变长度编码以多种不同方式编码 ",但 MySQL 从未将其解码为 " 以便能够将其用于 SQL 注入。
猜你喜欢
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 2016-12-11
相关资源
最近更新 更多