De exploit N-day a Kerberos EoP en entornos Linux
Tabla de contenidos
Introducción
En una de sus operaciones, el Red Team logra la ejecución de comandos en una página web perimetral, como usuario no privilegiado. En este artículo describe el análisis y explotación de una vulnerabilidad (CVE-2018-1685) que permite la lectura arbitraria de ficheros, pero de la que no se conocen detalles públicos. Finalmente, se expondrá un método para convertir este tipo de vulnerabilidades (lectura de ficheros) en el compromiso total del sistema (ejecución de comandos), en caso de máquinas Linux integradas en Directorio Activo mediante Kerberos.
Vulnerabilidad de elevación de privilegios (EOP)
La máquina comprometida, se trata de un servidor Red Hat actualizado, por lo que se descarta la elevación de privilegios mediante un exploit de kernel. Tras las típicas comprobaciones rutinarias, se detectan varios ejecutables con SUID, propiedad del usuario “root”:
/home/db2test/sqllib/adm: total 5.3M drwxr-sr-x. 2 db2test db2test 112 Oct 8 10:29 . drwxrwsr-t. 19 db2test db2test 4.0K Oct 8 10:32 .. -r-sr-xr-x. 1 db2test db2test 152K Oct 8 10:29 db2audit -r-
s
r-xr-x. 1 root db2test 19K Oct 8 10:29
db2cacpy
-r-xr-xr-x. 1 db2test db2test 195K Oct 8 10:29 db2cap -r-
s
r-x---. 1 root db2test 32K Oct 8 10:29
db2iclean
-r-
s
r-x---. 1 root db2test 87K Oct 8 10:29
db2licm
-r-xr-xr-x. 1 db2test db2test 120K Oct 8 10:29 db2set -r-sr-sr-x. 1 db2test db2test 4.7M Oct 8 10:29 db2trc
El usuario “db2test” parece estar relacionado con una instalación de pruebas de DB2, un sistema de gestión de bases de datos de IBM. Tras una rápida búsqueda en Google, se encuentra un boletín de seguridad relacionado con uno de estos ejecutables (db2cacpy), publicado por el fabricante.
A pesar de que no se ofrecen detalles de la vulnerabilidad, se pueden destacar dos pistas interesantes:
- Permite a un usuario local leer cualquier fichero del sistema.
- En la sección de «Workarounds», se indica que al borrar este binario se perderá la capacidad de añadir nuevos puertos al fichero /etc/services, cuando se agregan nuevas bases de datos utilizando el «Asistente de configuración».
Con esta información en mano, el Red Team procede a la búsqueda del fallo.
CVE-2018-1685: en busca de la vulnerabilidad
Lo primero es descargar el ejecutable para poder analizarlo localmente. Además, es necesario descargar también unas 10 librerías de DB2, para poder hacer funcionar la herramienta.
Tras un análisis estático inicial, podemos desentrañar su funcionamiento. El binario recibe 2 argumentos por línea de comandos, sobre los que realiza una comprobación para cada uno de ellos, antes de que el programa continúe.
Primer check
Se comprueba, de forma un tanto ofuscada, que este primer argumento corresponda con una clave que podemos encontrar en texto claro en el segmento “.rodata”.
Segundo check
En este caso, se comprueba que el segundo argumento comience con la cadena /tmp/services.
, probablemente porque algún otro componente de DB2 genera archivos que siguen este patrón.
Vulnerabilidad
Si estas dos comprobaciones se cumplen, la herramienta copia el fichero indicado (en el segundo parámetro) a /etc/services, sobrescribiéndolo. Un posible pseudocódigo, simplificado, podría ser el siguiente:
func main(argc, argv[]) { init_db2() if (argc is 3) { if (argv[1] equals HARDCODED_KEY) { if (argv[2] startsWith "/tmp/services.") { copy_file(argv[2], "/etc/services") } } } }
¿Cómo aprovechar esto para leer ficheros arbitrarios? A través de path traversal. Si en /tmp creamos un directorio “services.” (o que comience así), podríamos por ejemplo desencadenar la copia del fichero /tmp/services./../../etc/shadow
, cumpliendo el segundo check.
En este repositorio podéis encontrar un exploit funcional, que además se encarga de restaurar el fichero /etc/services original tras la explotación. Es posible que la clave (primer check) varíe dependiendo de la versión o instalación de DB2 (no hemos podido comprobarlo).
De lectura arbitraria a ejecución como root
Al tratarse de un servidor Linux integrado en Directorio Activo mediante Kerberos, lo primero que se hace es comprobar si en /tmp hay TGTs (ficheros ccache) vigentes (para su reutilización), pero todos se encuentran caducados. Por tanto, se busca una vía que no depende de la interacción de los usuarios: el archivo keytab.
En el keytab siempre se encuentran las claves de la cuenta de máquina (por defecto /etc/krb5.keytab en Red Hat). Las claves de una cuenta de máquina, se pueden aprovechar para forjar tickets para sus servicios (TGS).
Para extraer las claves del keytab, se hace uso de un script conjuntamente con el exploit de DB2.
A continuación, mediante la utilidad ticketer.py de impacket se construye un TGS para el servicio SSH del propio servidor (SPN “host”) a nombre de un usuario del dominio que tenga privilegios de administración en la máquina.
Finalmente, se utiliza el ticket generado para conectar vía SSH, autenticando mediante Kerberos.
Conclusión
En este artículo, hemos visto cómo un atacante puede aprovecharse de un fallo conocido, para el cual no existe exploit o detalles públicos. Por ello, es importante incidir en la temprana aplicación de todo parche de seguridad y no sólo cuando el exploit sale a la luz (un ejemplo de esto es la publicación de Zerologon, donde las empresas no vieron la criticidad del mismo hasta que el exploit circulaba por GitHub, meses después).