viernes, 26 de julio de 2019

Ataque Man in the Middle en APT < 1.4.9




Buenas lectores! 

En esta primera entrada, quiero mostrar un tipo de ataque que se basa en Man in the Middle APT, el cual descubrí realizando una de las máquinas de la plataforma Hackthebox. 

Para ponernos un poco en contexto, se trata de una vulnerabilidad en el gestor de paquetes de alto nivel en los sistemas GNU/Linux, que se encuentra en versiones inferiores a la 1.4.9 de APT, esta vulnerabilidad nos permite saltarnos el proceso de verificación de los paquetes que son solicitados para actualizarse o instalarse.

La vulnerabilidad en cuestión se trata de: CVE-2019-3462 , esta nos permite redireccionar las peticiones de APT a un servidor atacante en el cual podremos gestionar los paquetes que tratará de solicitar la máquina vulnerable al ejecutar "apt-get update && apt-get upgrade", estos paquetes estarán manipulados aumentado su versión y añadiendo en los scripts de instalación el código de la shell inversa.

Como veréis a continuación, he intentado replicar el escenario que me encontré al realizar el CTF, sinceramente me gustó la manera de manipular paquetes Debian el cual me trajo bastante dolor de cabeza, hasta que al final se obtiene la querida inverse shell root y el dolor se convierte en satisfacción.

Punto importante a comentar: este tipo de ataque se realiza una vez se ha obtenido usuario en la máquina vulnerable y nos disponemos a realizar Privesc (escalada de privilegios). 

Sin más dilación, vamos allá:

Direcciones IP:
- Kali Linux 2019.2: 192.168.17.142
- Debian Server 7.10: 192.168.17.143

Lo primero que me encontré fue que el user obtenido, poseía permisos de SUDO NOPASSWD para "apt-get update && apt-get upgrade" y permisos para poder cambiar redirecciones de tráfico "ftp_proxy, http_proxy y https_proxy", a partir de aquí empieza la diversión.

Realizamos redirección sobre la variable "http_proxy" hacia nuestra máquina y puerto:

Modificación de variable "http_proxy"

Podemos comprobar que funciona ejecutando un servidor web temporal con PHP y ejecutar el comando "sudo apt-get update" en la máquina vulnerable.

Prueba de conexiones entrantes al servidor web temporal.

Como vemos, al no encontrar archivos de los cuales realizar llamada, nos muestra error 404 en todas las peticiones.

Como ya tenemos la redirección aplicada en la variable de entorno, lo siguiente que se me pasó por la cabeza fue...si tengo que "engañar" al servidor para que actualice un paquete manipulado, tendré que tener un paquete real ¿no?. 

Listamos los paquetes que tiene el servidor y elegimos uno, en este caso elegí el paquete "tar" y mostramos detalles del paquete instalado en el servidor:

Búsqueda del paquete "tar" y detalles de este.

Creamos los directorios temporales donde estará nuestro pequeño repositorio y descargamos el paquete "tar" del repositorio oficial.

Creación de directorios y descarga de paquete "tar" original.

Una vez tengamos el paquete ya en nuestra posesión, vamos a desempaquetarlo para poder listar y manipular:

Desempaquetado de archivo .deb descargado.

El primer archivo que tendremos que modificar, será "control", este archivo lleva como su propio nombre indica, un control sobre el paquete que lo tiene: versión, arquitectura, paquete, paquetes sugeridos, etc. A nosotros nos interesa modificar la versión del paquete para aumentarla y que el servidor vulnerable crea que hay una versión nueva de este y realice la petición para actualizar e instalar.

Archivo control sin modificar versión
Archivo control con versión modificada

En este punto vamos a realizar un pequeño inciso. Cuando tenemos que manipular paquetes de tipo .deb y añadir nuestro pequeño código para la shell inversa, nos tenemos que centrar en 2 tipos de scripts que contienen estos paquetes (puede contenerlo si lo requiere o no), los cuales son: "preinst y postinst"

  • PREINST: Este script se ejecuta antes de que el paquete al que pertenece se descomprima.
  • POSTINST: Este script se ejecuta después de la instalación del paquete.

Una vez entendido esto, vamos a modificar el archivo "postinst" para añadir nuestra shell-inversa. En el caso de que hayáis elegido un paquete que no contenga un archivo de "preinst" o "postinst", se puede crear manualmente y otorgarle permisos de ejecución (755).

Cambiar tipo de shell a utilizar (bash) y añadir código de reverse shell

Cuando ya tenemos manipulado el paquete,  volvemos a empaquetar y aumentar la versión en el nombre:

Importante: la versión del paquete DPKG en la máquina de Kali y en Debian, son distintas, por lo tanto pueden surgir problemas a la hora de intentar desempaquetar al realizar "upgrade" y que no reconozca el formato de compresión (gz y xz) o permisos con los cuales se ha empaquetado, por eso tenemos que engañar el empaquetado con fakeroot.

Empaquetado con fakeroot

Una vez empaquetado, podemos eliminar el directorio "modif_tar" y el paquete tar con la versión anterior.

Otro de los archivos importantes a la hora de realizar una actualización a través de APT, es el archivo "Packages", este contiene la ruta de donde se encuentra el paquete a instalar y los hashes (md5, sha1, sha256 y sha512), los cuales verifican que ningún archivo ha sido manipulado...o si =P.

Es importante obtener los hashes del paquete manipulado, para ello utilizamos las herramientas de generación de hashes de Kali:

Obtención de Hashes para paquete "deb" manipulado.

Podemos crear el archivo y almacenar la salida que hemos obtenido en uno de los pasos anteriores con el comando de "apt-cache show tar", recordar añadir los checksum del paso anterior, cambiar la versión y el tamaño del paquete .deb, si no muestra como he comentado en el paso anterior los campos de Filename (Ubicación del archivo a instalar), Size (tamaño del archivo a instalar) y Hashes, lo podemos introducir manualmente:

Creación de archivo "Packages"

Comprimimos el archivo Packages y también tenemos que obtener los hashes de estos dos archivos... sé lo que estás pensando, pesado no? Al final obtendremos la recompensa 😜

Obtención de Hashes de archivos "Packages" y "Packages.gz"

En este punto, tendremos que crear otro archivo más, que es el "Release"... no desesperes! Este archivo contiene la información y ubicación los archivos "Packages" y "Packages.gz", así como sus hashes y tamaño de estos. 

Importante que la Versión del servidor Debian, Arquitectura, Tamaño y Hashes sean los correctos.

Creación de archivo "Release"

Hasta el momento, nuestro pequeño repositorio contendrá estos archivos:

Listado de archivos hasta el momento.

Como estáis pensando y si no, ya lo digo yo, los archivos creados no están en sus ubicaciones correctas, así que tendremos que crear las rutas de los directorios temporales del repositorio, en las cuales tendrá que buscar la máquina vulnerable al realizar la petición a través de APT. 

Los directorios temporales, se han dejado por defecto, pero en los archivos de Release y Packages, podemos indicarle directorios distintos para que sea más llevadero. 

Nos podemos basar en las peticiones que ha realizado la máquina Debian al ejecutar el comando "apt-get update" y que hemos podido observar en nuestro servidor web temporal.

Las peticiones estaban realizando la solicitud de los archivos creados pero en rutas distintas, estas rutas serán las que tendremos que crear:

  •     http://192.168.17.142/dists/wheezy/Release
  •     http://192.168.17.142/dists/wheezy/main/binary-amd64/Packages
  •     http://192.168.17.142/dists/wheezy/main/binary-amd64/Packages.gz
  •     http://192.168.17.142/pool/main/t/tar/tar_1.27+dfsg-0.1_amd64.deb
Dejo por aquí un esquema que he creado para que se entienda mejor:

Esquema de directorios

Y pasamos a crear los directorios con sus rutas correctas y mover los archivos:

Creamos directorios y nos movemos a carpeta "debian".

Ya tenemos todo lo necesario, ahora nos falta lo más importante:

  • Ejecutamos servidor Web con PHP por si no lo hemos dejado ejecutándose en la carpeta padre, que es "debian".
    • php -S 0.0.0.0:666
  • Ejecutamos netcat para escuchar la conexión inversa de la máquina Debian, acordarse el puerto que hemos indicado al añadir el código de la shell en el archivo "Postinst" (9999)
    • nc -lvp 9999
  • Ejecutar "sudo apt-get update && sudo apt-get upgrade" en la máquina Debian y cuando nos indique si estamos de acuerdo en saltar la verificación/autenticación...presionamos "Y".

Dejo por aquí un pequeño vídeo con el resultado final y las solicitudes que realiza la máquina Debian solicitando la nueva versión del paquete "tar" para actualizar:



Y aquí la imagen con las solicitudes y los códigos 200 del servidor web temporal:

Solicitudes entrantes

Como opinión personal, es cierto que se tienen que dar algunas coincidencias para poder realizar este tipo de ataque, pero sabemos que existen usuarios que no tienen permisos 100% y solo se le otorgan permisos "mínimos" para llevar a cabo ciertas acciones en los sistemas que manejan. 

También conocemos compañeros, amigos, familiares, etc, que siguen obcecados con versiones anteriores de alguna distribución por su sencillez o simplemente por que es la versión de distribución que mejor conoce.

Recordar actualizar el paquete APT a la última versión para corregir de este tipo de vulnerabilidades.

Nos vemos en el próximo artículo.

Saludos!

rekkatz

0 comentarios:

Publicar un comentario