hacktricks/network-services-pentesting/pentesting-web/artifactory-hacking-guide.md

18 KiB
Raw Blame History

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Este contenido fue tomado de https://www.errno.fr/artifactory/Attacking_Artifactory

Conceptos básicos de Artifactory

Usuarios y contraseñas por defecto

Las cuentas por defecto de Artifactory son:

Cuenta Contraseña por defecto Notas
admin password cuenta común de administración
access-admin password (<6.8.0) o un valor aleatorio (>= 6.8.0) utilizada solo para operaciones de administración local
anonymous usuario anónimo para recuperar paquetes de forma remota, no habilitado por defecto

Por defecto, no hay una política de bloqueo de contraseñas, lo que convierte a Artifactory en un objetivo principal para ataques de relleno de credenciales y rociado de contraseñas.

Autorizaciones

Idealmente, esto es lo que deberías ver al conectarte a Artifactory:

Página de inicio de sesión

Por otro lado, si te encuentras con algo más parecido a esto:

Página por defecto

Significa que se ha habilitado el "Acceso anónimo" en el panel de administración, lo cual es una configuración común utilizada para permitir que las aplicaciones recuperen artefactos sin problemas, pero te permite, el atacante, ver más de lo preferible.

Verificación de derechos de cuenta

A veces, debido a una mala configuración, ¡se permite al usuario anónimo desplegar archivos en algunos repositorios!

Para verificar a qué repositorios el usuario anónimo puede desplegar, utiliza la siguiente solicitud:

curl http://localhost:8081/artifactory/ui/repodata?deploy=true
{"repoList":["artifactory-build-info","example-repo-local"]}

Si hay entradas de repoKey en la solicitud, el usuario anónimo puede desplegar en estos, lo cual es realmente muy malo. Definitivamente deberías estar autenticado para desplegar cualquier archivo.

Esto se puede generalizar a otras cuentas una vez que obtengas una contraseña o token para ellas.

Listado de usuarios

Por alguna razón, el listado de usuarios es un derecho reservado solo para administradores. Encontré una forma alternativa de listar usuarios (aquellos que están desplegando activamente al menos) que depende del valor “Desplegado Por” de los artefactos:

Desplegado Por

Este script simplemente intenta encontrar recursivamente todos los usuarios que han desplegado artefactos. Ten en cuenta que podría tardar un tiempo en completarse si hay muchos repositorios (>1000).

./artifactory_list_users.py http://127.0.0.1:8081/artifactory
There are 23 repositories to process
Found user admin
Found user test
Found user user
Found user test_deploy

Permisos

Aquí están los permisos básicos y su utilidad:

  • Manage: ?
  • Delete/Overwrite: interesante para pentesting
  • Deploy/Cache: interesante para pentesting
  • Annotate: necesario para CVE-2020-7931
  • Read: generalmente un permiso por defecto

Vulnerabilidades conocidas

Aquí hay una lista curada de vulnerabilidades públicas de alto impacto:

CVE-2016-10036: Carga de Archivos Arbitrarios & RCE (<4.8.6)

Detalles aquí.

Esta es un poco antigua y es poco probable que encuentres una versión de Artifactory tan desactualizada. Sin embargo, es bastante efectiva, ya que es una simple travesía de directorio que permite la ejecución de código arbitrario a nivel de Tomcat.

CVE-2019-9733: Bypass de Autenticación (<6.8.6)

Advertencia original aquí.

En versiones anteriores de Artifactory (hasta 6.7.3), la cuenta access-admin utilizaba una contraseña predeterminada password.

Esta cuenta local normalmente no tiene permiso para acceder a la UI o API, pero hasta la versión 6.8.6 se podía engañar a Artifactory para que creyera que la solicitud se originaba localmente si el encabezado HTTP X-Forwarded-For se establecía en 127.0.0.1.

CVE-2020-7931: Inyección de Plantillas en el Servidor (Artifactory Pro)

Advertencia original aquí.

Aquí hay una herramienta que escribí para automatizar la explotación de esta vulnerabilidad.

Estos son requeridos para la explotación:

  • un usuario con permisos de deploy (crear archivos) y annotate (establecer filtrado)
  • Artifactory Pro

La vulnerabilidad es bastante simple: si un recurso desplegado se establece como filtrado, se interpreta como una Plantilla Freemarker, lo que le da al atacante una ventana de ataque SSTI. Recurso Filtrado

Aquí están las primitivas implementadas:

  • lecturas básicas del sistema de archivos
  • escrituras limitadas en el sistema de archivos

Estas deberían ser suficientes para darte ejecución de código remoto de varias maneras, desde la más fácil/discreta hasta la más difícil/ruidosa:

  • leer un secreto en el sistema de archivos que te permita pivotar (/home/user/.bash_history, /home/user/password.txt, /home/user/.ssh/id_rsa …)
  • añadir una clave SSH al usuario
  • desplegar un .war para ejecutar un servlet
  • desplegar un script de usuario Groovy de Artifactory

Historias de .war: Travesuras de Java renameTo()

Esta es una pequeña historia de cómo me golpeé la cabeza contra la pared durante horas, si no días, durante un pentest. Me encontré con un Artifactory desactualizado que sabía que era vulnerable a CVE-2020-7931. Desplegué la plantilla SSTI del aviso original y comencé a examinar el sistema de archivos. Parecía que Artifactory había sido instalado en una ubicación no estándar, lo cual no es tan inusual ya que los administradores suelen mantener particiones separadas entre los binarios de la aplicación, los datos, los registros y la configuración (¡esto es bueno!). No había claves SSH ni contraseñas en el directorio del usuario que me hubieran proporcionado un pivote fácil, así que llegó el momento de ser menos discreto y escribir en el sistema de archivos. Dejar el payload inicial (una clave pública) en el directorio de carga de Artifactory fue bien, pero simplemente no pude moverlo al directorio de claves SSH. Así que volví a mi sandbox de explotación, lo probé de nuevo y, he aquí, funcionó bien. Así que tenía que haber una configuración diferente que me impidiera completar el método renameTo(). En este punto siempre es una buena idea consultar la documentación ... que claramente indica que no puedes renombrar archivos a través de diferentes sistemas de archivos, lo cual supongo que tiene sentido dependiendo de la implementación del método, es decir, si funciona a nivel de inode. Arg.

¿Recuerdas lo que dije sobre los administradores y las particiones? Bueno, este es un caso de un administrador que sin saberlo fortaleció su configuración contra mi exploit. Así que tuve que investigar lo que es esencialmente una cárcel de Java para encontrar otro método que me permitiera escribir un archivo en el disco. Y eso no fue nada divertido, ya que no estoy familiarizado con ninguna de las cosas involucradas: Plantillas FTL, Java, Tomcat/Catalina. Rápidamente descubrí que los escapes de cárcel de Java regulares simplemente no funcionarían, ya que estaba prohibido instanciar nuevas clases. Después de horas de leer la documentación de las clases de Java y Catalina, finalmente encontré un método write() en un objeto al que podía acceder. Pero estaba limitado a la ruta base de la aplicación web... Entonces pensé en combinar la escritura a otro sistema de archivos y el renameTo() a través de este nuevo sistema de archivos accesible para poder escribir en cualquier lugar. ¿Y funcionó? Más o menos. Logré escribir fuera del directorio temporal de carga ... pero no muy lejos de él, ya que ahora estaba atascado en otro sistema de archivos que era el punto de montaje de todo lo relacionado con artifactory: configuración, aplicación y cosas. Así que todavía no tenía clave SSH para mí.

Bueno, podía escribir en la carpeta raíz de artifactory, seguramente podría hacer algo aquí, ¿no? Oye, el Tomcat predeterminado automáticamente despliega archivos WAR escritos en su ruta de aplicación, ¿no es así? Así que usé msfvenom para generar un webshell JSP empaquetado en un archivo WAR y lo probé en mi sandbox... bueno, se desplegó bien, pero no me proporcionó ejecución de comandos. Parece que el Tomcat predeterminado no maneja JSPs. Ugh. Cada vez más frustrado, busqué otra forma de ejecutar código en Tomcat, y encontré otro método de ejecución usando servlets. No pude encontrar un payload apropiado, así que a la mierda, estoy all in en este punto y hice mi propio que puedes encontrar aquí. Lo probé en la sandbox, funciona, ok. Lo puse en el objetivo, se despliega y ... nada. Resulta que había un proxy frente a artifactory que reescribía todas las URLs a /artifactory. Así que aunque mi puerta trasera estaba desplegada y funcionando, no había forma de acceder a ella... Si había alguna ejecución de código remoto que lograr en este punto, tendría que ser en el contexto de Artifactory, no de Tomcat.

A la mañana siguiente, estoy sollozando en mi escritorio mirando por última vez la documentación de Artifactory con la vana esperanza de una epifanía. Y entonces las palabras mágicas "scripts Groovy" aparecieron. Resulta que hay una forma enrevesada de ejecutar scripts Groovy, escribiéndolos en disco y luego recargándolos a través de la API. ¡Salvado al fin! Así que lancé un reverseshell Groovy a la máquina y eso fue todo. Aún desearía haber encontrado un método más limpio que hubiera escrito en cualquier lugar del sistema de archivos usando el SSTI, pero seguro que no iba a volver a desarrollar.

Afortunadamente, no todos los pentests son así :)

Post-Explotación

Lo siguiente solo es útil una vez que has logrado ejecución de código remoto o lectura de archivos arbitrarios en el servidor y podría ayudarte a pivotar a otra máquina.

Almacenamiento de contraseñas y secretos externos

Contraseñas locales

Las contraseñas locales de artifactory se almacenan en forma de MD5 salado o bcrypt, siendo el primero obsoleto.

Las contraseñas MD5 siempre están saladas con el valor spring codificado {CAFEBABEEBABEFAC}, y utilizan una simple concatenación sin rondas, es decir, hash = md5(password + salt). La base de datos dice que la sal es CAFEBABEEBABEFAC pero créeme, es {CAFEBABEEBABEFAC}, me costó mucho encontrarlo :)

Para romper estas contraseñas MD5 se requiere usar un modo dinámico para JtR:

cat artifactory.hashes
user:1f70548d73baca61aab8660733c7de81${CAFEBABEEBABEFAC}
john artifactory.hashes --format=dynamic_1
Loaded 1 password hash (dynamic_1 [md5($p.$s) (joomla) 256/256 AVX2 8x3])
password         (user)

El otro tipo de contraseña bcrypt no requiere nada especial, es solo un hash bcrypt estándar:

cat artifactory_bcrypt.hashes
admin:$2a$08$EbfHSAjPLoJnG/yHS/zmi.VizaWSipUuKAo7laKt6b8LePPTfDVeW
john artifactory_bcrypt.hashes
Loaded 1 password hash (bcrypt [Blowfish 32/64 X2])
password          (admin)

Secretos remotos

Artifactory puede necesitar almacenar secretos para identificarse ante servicios remotos. Estos secretos no están hasheados, por supuesto, se almacenan cifrados en el disco, con la clave al lado de ellos. Hay dos tipos de secretos mencionados en la documentación oficial.

Formato antiguo (<5.9): DES-EDE

TODO. Abre un issue si tienes datos cifrados de muestra.

Formato nuevo (>=5.9): cifrado AES128-CBC, almacenado como base58

Los secretos externos (como contraseñas de servidores remotos) se encuentran en los descriptores de configuración, por ejemplo, /var/opt/jfrog/artifactory/etc/artifactory.config.latest.xml y parecen:

<keyStorePassword>AM.25rLQ.AES128.vJMeKkaK6RBRQCUKJWvYEHUw6zs394X1CrRugvJsQGPanhMgQ5be8yjWDhJYC4BEz2KRE</keyStorePassword>

Donde:

  • AM siempre denota un secreto cifrado de artifactory
  • 25rLQ es el identificador del secreto que debe coincidir con el identificador de la clave
  • AES128 obviamente es el algoritmo utilizado
  • vJMeK...KRE es la codificación base58 de IV_SIZE|IV|secreto|CRC

Se pueden encontrar más secretos (tokens, copias de seguridad de configuración ...) utilizando la siguiente expresión regular:

grep -r 'AM\..*\.AES128\.' /var/opt/jfrog/artifactory/

La clave se almacena en /var/opt/jfrog/artifactory/etc/security/artifactory.key y luce así:

JS.25rLQ.AES128.7fcJFd3Y2ib3wi4EHnhbvZuxu

Donde:

  • JS denota una clave
  • 25rLQ es un identificador de clave único que lleva un registro de qué clave puede descifrar qué secretos
  • AES128 obviamente es el algoritmo utilizado
  • 7fcJFd3Y2ib3wi4EHnhbvZuxu es la codificación base58 de la clave y 2 bytes de CRC

Esta herramienta que escribí se puede usar sin conexión para descifrar secretos de Artifactory: ArtifactoryDecryptor.

Defendiendo Artifactory

Si eres del equipo azul o un administrador de Artifactory, para este momento deberías tener una idea bastante clara de qué hacer:

  • mantener Artifactory actualizado, especialmente cuando se emiten actualizaciones críticas
  • implementar una política de contraseñas sólida (sin contraseñas predeterminadas, contraseñas fuertes obligatorias, bloqueos), preferiblemente delegada a un LDAP externo para una mejor supervisión
  • restringir accesos (respetar el principio de mínimo privilegio), especialmente para el usuario anónimo
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks: