PG: Twiggy
| ターゲット // Twiggy | |
|---|---|
| Platform | OffSec Proving Grounds |
| OS | Linux |
| Difficulty | Easy |
| IP | 192.168.192.62 |
Recon#
Nmap#
| |
▶ Full nmap output
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
53/tcp open domain
80/tcp open http nginx 1.16.1
|_http-title: Home | Mezzanine
4505/tcp open zmtp ZeroMQ ZMTP 2.0
4506/tcp open zmtp ZeroMQ ZMTP 2.0
8000/tcp open http nginx 1.16.1
Enumeration#
Port 80 - Mezzanine CMS#
A blog running Mezzanine CMS with an admin login page. No weak credentials, no version info exposed. Moving on.
Port 8000 - Salt API#
Sending a POST request to port 8000 reveals the service identity in the response headers:

The header shows salt-api/3000-1 running on CherryPy 5.6.0. SaltStack has well-known critical vulnerabilities.
Ports 4505/4506 - ZeroMQ#
These are SaltStack’s ZeroMQ message bus ports, confirming we’re dealing with a full Salt deployment.
Foothold#
SaltStack Salt API RCE (CVE-2020-11651)#
Found the exploit on ExploitDB.
First, validate RCE with a ping:
| |
Confirmed – we have code execution.
Getting a Shell via Empire#
The exploit behaves inconsistently with standard reverse shells, so I used PowerShell Empire (works on Linux targets too):
- Launch Empire server & client
- Create and start an HTTP listener

- Generate a
multi_bashstager and download the shell script - Serve it via Python HTTP server
- Trigger via the Salt API exploit:
| |
Agent calls back – we’re in as root. No privesc needed.
Proof#
proof
local.txt: [redacted]
proof.txt: [redacted]

Key Takeaways#
[ ノート ]
- Always inspect HTTP response headers – they can reveal service versions that aren’t shown in the page content
- SaltStack CVE-2020-11651 is an authentication bypass leading to RCE – extremely critical
- When standard reverse shells don’t work, C2 frameworks like Empire provide reliable alternatives
- Ports 4505/4506 (ZeroMQ) are a dead giveaway for SaltStack deployments