Recientemente, mientras verificamos la seguridad de los recursos web del banco, encontramos una vulnerabilidad en el servidor de correo Exim 4.89, que podr铆a conducir a la ejecuci贸n remota de c贸digo. La vulnerabilidad se conoce como CVE-2018-6789. Usando el exploit de PoC, obtuvimos el Reverse Shell en la m谩quina remota y luego accedemos al sitio web del banco.
Naturalmente, nos preguntamos por qu茅 se hizo posible tal explotaci贸n de la vulnerabilidad.
驴De d贸nde vino CVE-2018-6789?
En resumen, la vulnerabilidad se debe a un error al calcular la longitud del b煤fer en la funci贸n base64.c: b64decode utilizada por Exim. Puede leer m谩s sobre esto aqu铆 (en ingl茅s).
Si ingresa una cadena de longitud especial, puede sobrescribir un byte de informaci贸n y, usando acciones simples, cambiar los comandos del servidor, ejecutando as铆 c贸digo arbitrario (RCE).
Exim asigna un b煤fer de 3 * (len / 4) +1 bytes para contener los datos decodificados. Sin embargo, si se alimenta una cadena base64 incorrecta a la entrada de la funci贸n, por ejemplo, 4n + 3 de largo, Exim asignar谩 3n + 1 bytes para el b煤fer. Pero al mismo tiempo, escribir谩 3n + 2 bytes de datos en el b煤fer. Esto hace que se sobrescriba un byte en el mont贸n.
Exim proporciona store_malloc_3 y store_free_3, que son envoltorios para malloc y funciones gratuitas de Glibc. Glibc asigna un gran bloque de datos, luego almacena sus metadatos en los primeros 0x10 bytes y devuelve un puntero a la memoria donde el usuario puede escribir sus datos. As铆 es como se ve: Los
metadatos incluyen el tama帽o del bloque anterior (el que est谩 en la memoria arriba), el tama帽o del bloque actual y algunas banderas. Los primeros tres bits del tama帽o se utilizan para almacenar banderas. En el ejemplo, el tama帽o 0x81 implica que el fragmento actual es 0x80 bytes y el fragmento anterior ya est谩 en uso.
Los bloques liberados, una vez utilizados por Exim, se colocan en una lista doblemente enlazada. Glibc lo mantiene de acuerdo con las banderas y fusiona los trozos liberados contiguos en un trozo m谩s grande para evitar la fragmentaci贸n. Para cada solicitud de asignaci贸n de memoria, Glibc examina estos fragmentos en orden FIFO y los reutiliza.
Para mejorar el rendimiento, Exim utiliza su propio complemento de administraci贸n de memoria; se basa en la estructura del bloque de tiendas. La caracter铆stica principal de storeblock es que cada uno de ellos tiene un tama帽o m铆nimo de 0x2000 bytes, lo que se convierte en una limitaci贸n para la explotaci贸n. Tenga en cuenta que storeblock tambi茅n es un bloque de datos. As铆 es como se ve en la memoria:
Comandos admitidos por el servidor de correo para organizar los datos en el mont贸n:
- EHLO hostname. EHLO hostname sender_host_name. , store_free store_malloc .
- . , , Exim .
- AUTH. Exim base64 . , store_get (). store_get().
- Reset EHLO/HELO, MAIL, RCPT. , Exim smtp_reset. store_reset , 芦 禄. , storeblock- store_get .
Para usar un desbordamiento de pila de un solo byte, debemos poder liberar el bloque de datos que est谩 debajo de la cadena decodificada en base64. Sender_host_name es adecuado para esto.
El mont贸n debe formarse de tal manera que deje el bloque de datos libre sobre el bloque que contiene sender_host_name.
Para hacer esto, necesita:
1. Poner un bloque grande en un contenedor sin clasificar. En primer lugar, enviamos un mensaje EHLO con un nombre de host de gran tama帽o para que asigne y libere un trozo de longitud 0x6060 en un contenedor sin clasificar.
2. Seleccione el primer bloque de tienda. Luego enviamos un comando no reconocido para llamar a store_get () y asignamos el bloque de tienda dentro del fragmento liberado.
3. Seleccione el segundo bloque y suelte el primero. Enviamos EHLO para recibir el segundo bloque. El primer bloque se libera secuencialmente debido a que se llama a smtp_reset despu茅s de que se completa EHLO.
Una vez que el mont贸n est谩 preparado, podemos usarlo para sobrescribir el tama帽o del bloque original. Modificamos 0x2021 a 0x20f1, lo que expande ligeramente el bloque.
4. Env铆e datos base64 y desborde 1 byte en el mont贸n. Ejecute el comando AUTH para enviar datos base64.
5. Cree y env铆e una cadena de tama帽o adecuado. Dado que expandimos el bloque de datos, el comienzo del siguiente fragmento ahora estar谩 en alg煤n lugar dentro. Ahora tenemos que arreglarlo para pasar la verificaci贸n de integridad de Glibc. Estamos enviando otra cadena base64 aqu铆.
6. Libere el bloque extendido. Para controlar el contenido del bloque extendido, primero debemos liberar el bloque, porque no podemos editarlo directamente. Es decir, debemos enviar un nuevo mensaje EHLO para liberar el antiguo nombre de host. Sin embargo, el procesamiento del comando EHLO llama a smtp_reset tras una ejecuci贸n exitosa. Esto puede provocar la interrupci贸n del programa o una terminaci贸n anormal. Para evitar esto, estamos enviando un nombre de host no v谩lido como +.
7. Sobrescriba el siguiente puntero del bloque de tienda superpuesto.
Una vez liberado el fragmento, podemos obtenerlo con AUTH y sobrescribir parte del bloque de almacenamiento superpuesto. Aqu铆 utilizamos una t茅cnica llamada "grabaci贸n parcial". Esto nos permite cambiar el puntero sin romper ASLR. Hemos cambiado parcialmente el siguiente puntero a un bloque que contiene l铆neas ACL. Las l铆neas de ACL se especifican mediante un conjunto de globales, como uschar * acl_smtp_helo;
Estos punteros se inicializan al comienzo del proceso de Exim y se establecen de acuerdo con la configuraci贸n. Por ejemplo, si la configuraci贸n contiene la l铆nea acl_smtp_mail = acl_check_mail, el puntero acl_smtp_mail apunta a la l铆nea acl_check_mail.
Cada vez que el servidor recibe un comando MAIL FROM, Exim realiza una verificaci贸n de ACL, que primero expande acl_check_mail. En la expansi贸n, si Exim encuentra la l铆nea $ {run {cmd}}, intentar谩 ejecutar el comando cmd, por lo que un atacante remoto puede hacer que se ejecute el c贸digo.
8. Restablezca el bloque de almacenamiento y obtenga el bloque de almacenamiento que contenga ACL. El bloque ACL ahora est谩 en la cadena de bloques. Se liberar谩 despu茅s de que se haga smtp_reset (), y luego podremos recuperarlo nuevamente asignando algunos bloques.
9. Sobrescriba las l铆neas de ACL y ejecute la comprobaci贸n de ACL. Finalmente, reescribimos todo el bloque que contiene las l铆neas ACL. Ahora enviamos comandos como EHLO, MAIL, RCPT para ejecutar la comprobaci贸n de ACL.
Por cierto, la explotaci贸n de la vulnerabilidad fue facilitada por el ASLR desactivado por alguna raz贸n desconocida para nosotros.
驴Qu茅 problemas tuvo el cliente?
El primero es la falta de gesti贸n de actualizaciones. Debido al hecho de que se utiliz贸 la versi贸n antigua de Exim, fue posible organizar un compromiso del sistema. Para evitar esto, le recomendamos que organice la verificaci贸n e instalaci贸n peri贸dicas de las actualizaciones de seguridad en los componentes de la infraestructura de la informaci贸n.
Recomendamos comprobar la existencia de nuevas actualizaciones cr铆ticas y de seguridad al menos una vez al mes. Para buscar actualizaciones, es mejor utilizar los sitios / listas de correo de los fabricantes de equipos o la informaci贸n de los repositorios.
El banco tambi茅n carec铆a de un proceso de gesti贸n de vulnerabilidades, por lo que la vulnerabilidad no se detect贸 a tiempo. El uso de esc谩neres de vulnerabilidades especializados - por ejemplo, OpenVAS, Nessus, xSpider, etc. - ayudar铆a a rectificar la situaci贸n. Las pruebas de penetraci贸n regulares y el monitoreo del tiempo de eliminaci贸n de vulnerabilidades tambi茅n ayudar铆an.
Y por 煤ltimo pero no menos importante. El banco carec铆a de un proceso de gesti贸n de cambios. Todos los cambios fueron realizados por administradores en el entorno de producci贸n. En consecuencia, nadie control贸 ni supervis贸 esto. Esto llev贸 al hecho de que ASLR estaba deshabilitado en el servidor.
Salida
Varias infracciones aparentemente no relacionadas dieron como resultado que el sitio web del banco se viera comprometido. Los atacantes podr铆an utilizarlo para, por ejemplo, cambiar los datos bancarios por los suyos.
La historia termin贸 bien. Despu茅s del compromiso, notificamos inmediatamente al cliente de la situaci贸n. El banco actualiz贸 urgentemente el servidor Exim a la versi贸n actual, para la cual la vulnerabilidad ya no es relevante. Sin embargo, si la vulnerabilidad no hubiera sido identificada durante la prueba de penetraci贸n, sino por atacantes reales, el resultado podr铆a haber sido diferente.