← back to writeups
Vulnhub

Vulnhub: Matrix 3

Matrix 3 stacks two puzzles: a patience-testing web crawl that ends in a crackable hash, and a Windows binary reversed in Ghidra to leak SSH credentials — then a tidy two-step sudo chain to root. It is a good exercise in automation (letting DirBuster walk a generated directory maze) and in static analysis.

Attack chain at a glance

  • Recon — HTTP on 80 and 7331, SSH on the non-standard 6466; the site says “follow the white rabbit.”
  • Web crawl — a rabbit image names the next path, which opens into a maze of generated directories; DirBuster finds a secret file deep inside holding a hash.
  • Crack — an online cracker resolves the hash to passwd, which unlocks the basic-auth prompt on port 7331.
  • Reversing — a robots.txt disallow leads to a Windows binary (data); Ghidra static analysis reveals embedded SSH credentials.
  • Root — SSH in as guest; a passwordless sudo /bin/cp is used to plant an SSH key for trinity; a second passwordless sudo rule (as oracle) drops a root shell.
Techniques in play: directory brute-forcing at scale (DirBuster), offline/online hash cracking, static binary analysis with Ghidra, and chaining sudo file-write primitives — a passwordless cp is enough to bootstrap full access by writing an authorized_keys file. (One credential-recovery screenshot in this writeup is from a public walkthrough, noted inline.)

Matrix 3 is a breadcrumb hunt: a rabbit-hole of generated directories hides a crackable hash, a Windows binary analysed in Ghidra leaks SSH credentials, and two chained sudo rules (cp then a passwordless shell) walk the way to root.

Reconnaissance

Matrix 3 VM booted from Vulnhub
The Matrix 3 VM running.

netdiscover finds the target.

netdiscover locating the target host
Scanning for the target with netdiscover.

The host is 192.168.0.119. nmap shows HTTP on 80 and 7331, and SSH on the non-standard port 6466.

nmap showing ports 80, 7331 (http) and 6466 (ssh)
HTTP on 80 and 7331, SSH on 6466.

Following the white rabbit

Port 80 tells us to “follow the white rabbit.”

Web page instructing to follow the white rabbit
The landing page's hint.

A dirb scan reveals an assets folder.

dirb finding an assets directory
An assets directory surfaces.

It contains an img subdirectory with a PNG.

PNG file inside the img subdirectory
A lone PNG under img.

The image is a white rabbit, and its filename contains “matrix” — visiting a path built from that name works.

White rabbit image whose name hints at the next path
The rabbit's filename points at the next directory.

That path is full of randomly named folders, each holding another set of random names.

Directory of randomly named folders
A maze of generated directories.

Walking it by hand would take forever, so DirBuster is pointed at it to brute-force the tree.

DirBuster configured against the directory tree
Letting DirBuster do the walking.

With a wordlist and a few extensions it finds a file called secret at /Matrix/n/e/o/6/4/.

DirBuster locating a secret file deep in the tree
secret found at /Matrix/n/e/o/6/4/.

Cracking the hash

Downloading the secret file
Pulling the secret file down.

It contains a hash.

The secret file revealed as a hash
The file holds a single hash.

An online cracker resolves it quickly.

Online cracker returning the plaintext 'passwd'
The hash cracks to passwd.

Reversing the binary for SSH creds

That password opens the basic-auth prompt on port 7331.

Logging in on port 7331 with the cracked password
Authenticated on port 7331.

A dirb scan of this service is run next.

dirb scan against port 7331
Enumerating port 7331.

It finds a robots.txt that disallows /data/.

robots.txt disallowing /data/
robots.txt points at /data/.

That directory holds a data file — a Windows executable.

A Windows binary named data
The data file is a Windows binary.

It is loaded into Ghidra for static analysis.

Opening the binary in Ghidra
Analysing data in Ghidra.
I was unable to recover the credentials from the binary myself despite several attempts; the following screenshot is from a published walkthrough, included for completeness.
Walkthrough screenshot of the located credentials
Where the credentials sit in the binary (from a walkthrough).

The binary hides a username and password that can now be used.

Username and password extracted from the binary
The embedded SSH credentials.

Privilege escalation

Those credentials log in over SSH on port 6466 as guest.

SSH login as guest on port 6466
A shell as guest.

sudo -l shows guest may run /bin/cp without a password.

sudo -l showing passwordless /bin/cp for guest
guest can run /bin/cp as root.

That write primitive is used to plant an SSH key: generate a keypair…

Generating an SSH keypair
Generating a fresh SSH keypair.

…then cp the public key into the next user's authorized_keys. Logging in with the private key lands a shell as trinity with no password.

SSH into trinity using the planted key
Key-based login as trinity.

sudo -l as trinity shows oracle can be run without a password; its /bin/sh escape gives a root shell.

Abusing a passwordless sudo rule to get root
The second sudo rule → root.

/root holds flag.txt.

root flag.txt completing the box
The root flag — box complete.
Matrix 3 is two puzzles stacked: a patience-testing web crawl to a binary, then a tidy privilege-escalation chain where a single passwordless cp is enough to bootstrap full access.

Defender's notes

  • Don't rely on obscure, unguessable paths — directory brute-forcing finds them; require real authentication.
  • Never ship secrets inside distributed binaries; strings and decompilers recover them in minutes.
  • A passwordless sudo on a file-copy utility (cp) is a write-anywhere-as-root primitive — scope sudo rules tightly and avoid file-manipulation binaries.
  • Use strong, salted password hashes.