【问题标题】:SQL injection against quote()?针对quote()的SQL注入?
【发布时间】:2012-03-22 13:31:00
【问题描述】:

注意:这是一个在虚拟机内有一个虚构站点的项目。这是我正在从事的一个高级大学项目。我并不是想利用一个真实的、真实的网站。这是出于教育目的,以了解此类漏洞利用的强大程度,即使具有给定的功能。

我目前正在从事一个涉及利用网站漏洞的项目(在安全和受控的环境下,在 VM 内)。一部分涉及利用 SQL 语句。目标是能够只输入用户名和不正确的密码并仍然能够登录。我已经为此工作了几个小时,但没有这样的运气,我已经做了很多研究看看有哪些漏洞可用。

当一个人提交他们的用户名和密码(在这种情况下,它可以是任何东西),一个函数将使用以下准备好的 SQL 语句运行:

$query = "SELECT Salt FROM Accounts WHERE Username = '$quoted'";

$quoted 在哪里:

$quoted = $this->db->quote($user);

这实质上为每个提供的单/双引号添加了一个额外的单/双引号。尽管尝试了其他可能性(例如' OR 1=1' 等),但我想出的最接近的是:

SELECT Salt FROM Accounts WHERE Username = '\'' OR 1=1 -- '

$user 变量最初是 \' OR 1=1 --。第一个和最后一个引号是通过 quote() 函数自动添加的,以及转义单引号之后的附加引号。然而,这似乎不是正确的 SQL 语法,可能是因为它将整个 $user 输入解释为用户名。

在此之后还有另一个准备好的语句,但它依赖于与盐连接的密码的 md5 哈希,我认为一旦 md5 返回,我认为真的没有任何方法可以在语句中注入任何内容哈希。出于好奇,声明是这样的:

$query = "SELECT * FROM Accounts WHERE Username = '$user' AND Password = '$hash';

$hash = md5($pass.$salt)

有人想阐明任何可能性吗?也许我只是真的忽略了它,但我觉得我已经尝试了一切。

编辑:我解决了这个问题。它与解决另一个函数来利用注入有关。它最终添加了一个带有注入代码的用户名(二阶注入),然后它会进行登录。登录过程引用了第一个查询的用户名,但第二个查询没有;因此,用户会自动登录。

【问题讨论】:

  • “我想到的最接近的注射方法是:” --- 我不相信。 \' OR 1=1 -- 这应该并且将被引用,没有任何问题
  • @zerkms 糟糕,我忘了解释我也尝试过其他注射。但它们似乎都是通过引用函数引用的。
  • 那你期望得到什么?他们被引用是因为这就是引用的用途
  • @zerkms 当然可以。我明白这一点。我正在尝试利用该功能进行任何可能的注入。我只是征求意见。
  • 1.我们不知道 quote() 到底是什么 - 你没有解释 2. 如果有任何公开的已知漏洞 - 它们将在几天内修复

标签: sql sql-injection


【解决方案1】:

SQL 中的反斜杠是一个令人头疼的话题,它取决于所使用的 DBMS。

标准 SQL 没有赋予它们任何意义。要转义字符串中的引号,请将引号加倍。您使用的quote 方法似乎遵循该原则:

  • 输入:\' OR 1=1 --
  • 输出:'\'' OR 1=1 --'

某些 DBMS 可能实际上定义了反斜杠的含义。然而,更复杂的是,您通常拥有不确定数量的中间语言(PHP、ODBC 等),这些语言也可能会修改字符串,并且可能会将含义应用于纯 SQL 所不具备的反斜杠。

如果您输入 X' OR 1=1 --,(用 X 代替反斜杠),您将得到相同的映射字符串,其中反斜杠被 X 替换。因此,如果攻击要成功,您需要 @987654326 @ 方法会混淆 DBMS 将如何处理反斜杠,但这相当于 quote() 方法中的错误。

如果您设法嵌入 Unicode 转义序列,您可能会获得更大的吸引力。例如,U+0027(十进制 39)是单引号。这种诡计可能会让你通过quote(),但它可能不会。 quote()-like 方法背后的想法是,您不应该能够将文本扭过它们,这意味着与预期不同的东西。由于服务器中的错误,字符的非最小 UTF-8 编码可能会触发问题,但这并不是那么可能。 Unicode 标准很明确,不应接受无效的 UTF-8 编码——在任何接近安全信息的地方都是如此。

你说得对,用引号括起来的哈希输出不会被有效地注入,尤其是如果攻击者永远看不到盐。

【讨论】:

  • 我尝试使用十六进制实体 (') 和十进制 (') 作为单引号。我回显了查询,它看起来肯定是注入,但是当它被 DBMS 读取时,它呈现不正确。不过,我会继续搞砸它。我觉得我在正确的轨道上;真是郁闷,哈哈。
  • 所以看了下源码,发现quote()函数使用的是SQLite 3的escapeString()方法,它唯一做的就是转义单引号,而不是双引号.不幸的是,引用的用户名用单引号括起来。
  • @SpacePyro:当然,它可以正常工作。您可能想要更微妙地使用SQL smuggling
猜你喜欢
  • 2019-12-06
  • 1970-01-01
  • 2018-06-30
  • 2016-05-19
  • 2018-07-05
  • 2021-07-07
  • 2010-11-18
相关资源
最近更新 更多