The client requested a black box assessment of a single host, simulating an external attacker with no prior access, credentials, or application documentation. Only the assigned target IP was in scope. As with prior engagements, manual exploitation was prioritized before falling back to public tooling, and all findings were documented alongside the path taken to full compromise.
Two flags were defined as proof of successful exploitation:
User.txtRoot.txtThis assessment identified a critical, unauthenticated remote code execution vulnerability in the target's web application, followed by a trivial local privilege escalation to root. The application was running a version of Next.js affected by a publicly disclosed, actively exploited critical vulnerability in the React Server Components ("Flight") protocol, tracked as CVE-2025-55182. This flaw stems from insecure deserialization of attacker-controlled input in the RSC protocol and does not require authentication to exploit.
Exploitation of this vulnerability provided a reverse shell running as a low-privileged local user. Escalation from that foothold to root required no further technical exploitation at all — a misconfigured sudo rule granted the compromised account passwordless execution of the system Python interpreter, which trivially provides a full shell in the context of any user permitted to invoke it, in this case root.
Both flags were recovered. This chain is assessed as Critical severity: the initial vector requires no authentication and has a public proof-of-concept, and the escalation path requires no exploitation skill whatsoever — only a sudoers misconfiguration.
| Finding | Severity |
|---|---|
| Unauthenticated RCE via CVE-2025-55182 (unpatched Next.js / React Server Components) | Critical |
Passwordless sudo access to /usr/bin/python3 with no argument restrictions | Critical |
An Nmap scan of the assigned target IP identified a single web-facing service of note:
| Port | Service | Notes |
|---|---|---|
| 3000/tcp | HTTP | Node.js application, identified as Next.js |
Port 3000 is the default development/production port for Next.js applications, which made framework and version identification straightforward from response headers and framework-specific static asset paths.
The identified Next.js version fell within the range affected by CVE-2025-55182, a critical-severity, unauthenticated remote code execution vulnerability disclosed in late 2025. The flaw exists in how the React Server Components "Flight" protocol deserializes incoming requests — attacker-controlled input is expanded during deserialization without adequate validation, and under default configuration this can be leveraged to achieve arbitrary server-side code execution with no authentication and no user interaction required.
This vulnerability affects default configurations of a very widely used framework, meaning a huge share of real-world Next.js deployments were exposed without any custom code or misconfiguration on the developer's part. Given its severity (maximum CVSS rating) and the availability of public technical writeups, it was treated as the primary line of attack for this engagement rather than something to rule out.
A working public proof-of-concept for this CVE was located and used to confirm exploitability against the target rather than developing an exploit from scratch, consistent with the vulnerability being both critical and already well-documented in the security community.
The public proof-of-concept was adapted to the target and executed against the application on port 3000. The exploit leverages the insecure deserialization behavior in the RSC protocol to achieve code execution within the Node.js server process, without requiring any valid session or credentials.
Execution of the proof-of-concept confirmed remote code execution and was used to establish a reverse shell back to an attacker-controlled listener. The resulting shell returned as the local user daniel — the account under which the Next.js application process was running.
daniel account.
Standard local enumeration was performed from the resulting shell. Checking the current user's sudo permissions was one of the first steps taken, and immediately revealed the escalation path:
sudo -l
...
User daniel may run the following commands on this host:
(root) NOPASSWD: /usr/bin/python3
This entry permits the daniel account to run the system Python 3 interpreter as root, with no password prompt and no restriction on what Python is used to do once invoked. Since Python provides direct access to OS-level functionality via its standard library, this is functionally equivalent to an unrestricted root shell.
Granting sudo access to a general-purpose interpreter (Python, Perl, Ruby, etc.) without restricting arguments or using a wrapper script is one of the most common and most severe sudo misconfigurations. The interpreter itself is not the risk — the risk is that it can execute arbitrary instructions on the attacker's behalf, including spawning a full shell, all inheriting the privilege level sudo was granted at.
Escalation was achieved by using Python's os module to directly replace the current process with a shell, inheriting root privileges from the sudo context:
sudo /usr/bin/python3 -c 'import os; os.execl("/bin/sh", "sh")'
This returned an interactive shell confirmed to be running as root:
id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
NOPASSWD unless there is a specific operational justification.daniel) should not have had any sudo entitlements at all under normal operating conditions for a web application process.