Privilege Escalation

Una vez que obtenemos acceso inicial a una caja, queremos enumerarla minuciosamente para encontrar posibles vulnerabilidades que podamos explotar para lograr un nivel de privilegios más alto. Podemos encontrar muchas listas de verificación y hojas de trucos en línea que tienen una colección de verificaciones que podemos ejecutar y los comandos para ejecutar estas verificaciones. Un excelente recurso es HackTricks , que tiene una excelente lista de verificación para la escalada de privilegios locales tanto en Linux como en Windows . Otro excelente repositorio es PayloadsAllTheThings , que también tiene listas de verificación tanto para Linux como para Windows . Debemos comenzar a experimentar con varios comandos y técnicas y familiarizarnos con ellos para comprender las múltiples debilidades que pueden llevar a la escalada de nuestros privilegios.

Scripts de enumeración

Muchos de los comandos anteriores se pueden ejecutar automáticamente con un script para revisar el informe y buscar cualquier punto débil. Podemos ejecutar muchos scripts para enumerar automáticamente el servidor ejecutando comandos comunes que devuelvan cualquier hallazgo interesante. Algunos de los scripts de enumeración comunes de Linux incluyen LinEnum y linuxprivchecker , y para Windows incluyen Seatbelt y JAWS .

Otra herramienta útil que podemos utilizar para la enumeración de servidores es Privilege Escalation Awesome Scripts SUITE (PEASS) , ya que está bien mantenida para permanecer actualizada e incluye scripts para enumerar tanto Linux como Windows.

Nota: Estos scripts ejecutarán muchos comandos conocidos por identificar vulnerabilidades y crearán mucho "ruido" que puede activar el software antivirus o el software de monitoreo de seguridad que busca este tipo de eventos. Esto puede evitar que los scripts se ejecuten o incluso activar una alarma que indique que el sistema ha sido comprometido. En algunos casos, es posible que queramos hacer una enumeración manual en lugar de ejecutar scripts.

Exploits del kernel

Siempre que nos encontramos con un servidor que ejecuta un sistema operativo antiguo, debemos comenzar por buscar posibles vulnerabilidades del kernel que puedan existir. Supongamos que el servidor no se mantiene con las últimas actualizaciones y parches. En ese caso, es probable que sea vulnerable a vulnerabilidades específicas del kernel que se encuentran en versiones sin parches de Linux y Windows.

Por ejemplo, el script anterior nos mostró que la versión de Linux es 3.9.0-73-generic. Si buscamos exploits para esta versión o usamos searchsploit, encontraremos un CVE-2016-5195, también conocido como DirtyCow. Podemos buscar y descargar el exploit DirtyCow y ejecutarlo en el servidor para obtener acceso root.

El mismo concepto se aplica también a Windows, ya que existen muchas vulnerabilidades en versiones de Windows que no han sido parcheadas o que son más antiguas, y que pueden utilizarse para escalar privilegios. Debemos tener en cuenta que los exploits del kernel pueden provocar inestabilidad en el sistema y debemos tener mucho cuidado antes de ejecutarlos en sistemas de producción. Es mejor probarlos en un entorno de laboratorio y ejecutarlos en sistemas de producción únicamente con la aprobación explícita y la coordinación con nuestro cliente.

Software vulnerable

Otra cosa que debemos buscar es el software instalado. Por ejemplo, podemos usar el dpkg -lcomando en Linux o mirar C:\Program Filesen Windows para ver qué software está instalado en el sistema. Debemos buscar exploits públicos para cualquier software instalado, especialmente si se utilizan versiones anteriores que contengan vulnerabilidades sin parchear.

Privilegios de Usuario

Un aspecto crítico a considerar después de obtener acceso a un servidor es los privilegios disponibles para el usuario con el que hemos accedido. Si se nos permite ejecutar comandos específicos como root (o como otro usuario), podríamos tener la oportunidad de escalar nuestros privilegios a usuario root/sistema o acceder como otro usuario. A continuación, se presentan algunas formas comunes de explotar ciertos privilegios de usuario:

Sudo

El comando sudo en Linux permite a un usuario ejecutar comandos como un usuario diferente. Generalmente, se usa para permitir que usuarios con menores privilegios ejecuten comandos como root sin darles acceso completo al usuario root. Esto se hace permitiendo la ejecución de comandos específicos que solo pueden ser ejecutados por root (como tcpdump) o accediendo a ciertos directorios exclusivos para root. Podemos verificar los privilegios de sudo disponibles con el comando:

sudo -l

Salida esperada:

[sudo] password for user1:
...SNIP...

User user1 may run the following commands on ExampleServer:
    (ALL : ALL) ALL

La salida anterior indica que podemos ejecutar todos los comandos con sudo, lo que nos otorga acceso completo. Podemos usar el comando su con sudo para cambiar al usuario root:

sudo su -

Verificación del usuario:

whoami

Salida esperada:

root

En algunos casos, es posible que se nos permita ejecutar ciertos comandos, o todos los comandos, sin proporcionar una contraseña:

sudo -l

Salida esperada:

(user : user) NOPASSWD: /bin/echo

La entrada NOPASSWD indica que el comando /bin/echo puede ejecutarse sin una contraseña. Esto es útil si obtuvimos acceso al servidor a través de una vulnerabilidad y no tenemos la contraseña del usuario. Como indica user, podemos ejecutar sudo como ese usuario y no como root. Para hacerlo, podemos especificar el usuario con -u user:

sudo -u user /bin/echo Hello World!

Salida esperada:

Hello World!

Una vez que encontramos una aplicación específica que podemos ejecutar con sudo, podemos buscar formas de explotarla para obtener un shell como usuario root. GTFOBins contiene una lista de comandos y cómo pueden ser explotados a través de sudo. Podemos buscar la aplicación sobre la cual tenemos privilegios de sudo, y si existe, podría indicarnos el comando exacto que debemos ejecutar para obtener acceso root.

Para sistemas Windows, LOLBAS contiene una lista de aplicaciones de Windows que podríamos utilizar para realizar ciertas funciones, como descargar archivos o ejecutar comandos en el contexto de un usuario con privilegios.

Tareas programadas

Tanto en Linux como en Windows, existen métodos para ejecutar scripts a intervalos específicos para llevar a cabo una tarea. Algunos ejemplos son ejecutar un análisis antivirus cada hora o ejecutar un script de copia de seguridad cada 30 minutos. Normalmente, hay dos formas de aprovechar las tareas programadas (Windows) o los trabajos cron (Linux) para aumentar nuestros privilegios:

  1. Agregar nuevas tareas programadas/trabajos cron

  2. Engañarlos para que ejecuten un software malicioso

La forma más sencilla es comprobar si tenemos permiso para añadir nuevas tareas programadas. En Linux, una forma habitual de mantener las tareas programadas es mediante Cron Jobs. Hay directorios específicos que podemos utilizar para añadir nuevos trabajos cron si tenemos los writepermisos necesarios sobre ellos. Entre ellos se incluyen:

  1. /etc/crontab

  2. /etc/cron.d

  3. /var/spool/cron/crontabs/root

Si podemos escribir en un directorio llamado por un trabajo cron, podemos escribir un script bash con un comando de shell inverso, que debería enviarnos un shell inverso cuando se ejecute.

Credenciales Expuestas

Una vez que hemos ganado acceso a un servidor, un paso importante es buscar archivos que podamos leer para ver si contienen credenciales expuestas. Es bastante común encontrar contraseñas en archivos de configuración, archivos de log y archivos de historial de usuario (como bash_history en Linux y PSReadLine en Windows). Los scripts de enumeración que mencionamos anteriormente suelen buscar posibles contraseñas en estos archivos y proporcionarnos los resultados.

Ejemplo de salida de un script de enumeración:

[+] Searching passwords in config PHP files
[+] Finding passwords inside logs (limit 70)

Resultado encontrado en un archivo de configuración:

/var/www/html/config.php: $conn = new mysqli(localhost, 'db_user', 'password123');

En este caso, la contraseña de la base de datos es password123, lo que nos permitiría iniciar sesión en las bases de datos MySQL locales y buscar información interesante.

Reutilización de Contraseñas

Además, podemos verificar la reutilización de contraseñas. Es posible que el usuario del sistema haya utilizado la misma contraseña para su cuenta y para las bases de datos. Esto puede permitirnos cambiar al usuario si la contraseña coincide. Para hacerlo, usamos el siguiente comando:

su -

Ingreso de contraseña:

Password: password123

Verificación del usuario:

whoami

Salida esperada:

root

Esto indica que hemos cambiado al usuario root utilizando la contraseña expuesta. También podemos usar estas credenciales para iniciar sesión en el servidor a través de SSH como el usuario correspondiente.

Claves SSH

Finalmente, veamos cómo trabajar con claves SSH. Si tenemos acceso de lectura al directorio .ssh de un usuario específico, podemos leer sus claves SSH privadas, que generalmente se encuentran en /home/user/.ssh/id_rsa o /root/.ssh/id_rsa, y usarlas para iniciar sesión en el servidor. Si podemos leer el directorio /root/.ssh/ y el archivo id_rsa, podemos copiarlo a nuestra máquina y usar la bandera -i para iniciar sesión con él.

Pasos para usar la clave SSH:

  1. Copiar la clave privada a nuestra máquina:

    vim id_rsa
  2. Cambiar los permisos del archivo para que sean más restrictivos:

    chmod 600 id_rsa
  3. Iniciar sesión en el servidor usando la clave privada:

    ssh root@10.10.10.10 -i id_rsa

    Salida esperada:

    root@10.10.10.10#

    Aquí, utilizamos el comando chmod 600 id_rsa para ajustar los permisos del archivo de clave privada, ya que las claves SSH requieren permisos restrictivos para funcionar correctamente. Si los permisos de las claves SSH son demasiado permisivos, el servidor SSH las rechazará.

Agregar Nuestra Clave Pública

Si tenemos acceso de escritura al directorio .ssh de un usuario, podemos agregar nuestra clave pública al archivo authorized_keys en el directorio /home/user/.ssh/ del usuario. Esta técnica se usa para obtener acceso SSH después de haber obtenido un shell como ese usuario.

  1. Generar una nueva clave SSH:

    ssh-keygen -f key

    Salida esperada:

    Generating public/private rsa key pair.
    Enter passphrase (empty for no passphrase): *******
    Enter same passphrase again: *******
    
    Your identification has been saved in key
    Your public key has been saved in key.pub
    The key fingerprint is:
    SHA256:...SNIP... user@parrot
    The key's randomart image is:
    +---[RSA 3072]----+
    |   ..o.++.+      |
    ...SNIP...
    |     . ..oo+.    |
    +----[SHA256]-----+

    Esto generará dos archivos: key (la clave privada) y key.pub (la clave pública). Usaremos key con ssh -i y copiaremos key.pub a la máquina remota.

  2. Copiar la clave pública a la máquina remota y agregarla a authorized_keys:

    echo "ssh-rsa AAAAB...SNIP...M= user@parrot" >> /root/.ssh/authorized_keys
  3. Iniciar sesión en el servidor remoto usando nuestra clave privada:

    ssh root@10.10.10.10 -i key

    Salida esperada:

    root@remotehost#

    Ahora deberíamos poder iniciar sesión mediante SSH como usuario root utilizando nuestra clave privada.

Last updated