mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 21:24:06 +00:00
193 lines
16 KiB
Markdown
193 lines
16 KiB
Markdown
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
- Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
|
|
|
- Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
|
|
- Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
|
|
- **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
|
|
- **Partagez vos astuces de piratage en soumettant des PR au [repo hacktricks](https://github.com/carlospolop/hacktricks) et au [repo hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
|
|
|
|
</details>
|
|
|
|
|
|
**Ce contenu a été pris à partir de** [**https://www.errno.fr/artifactory/Attacking\_Artifactory**](https://www.errno.fr/artifactory/Attacking\_Artifactory)
|
|
|
|
# Fondamentaux d'Artifactory <a href="#artifactory-basics" id="artifactory-basics"></a>
|
|
|
|
## Utilisateurs et mots de passe par défaut <a href="#default-users-and-passwords" id="default-users-and-passwords"></a>
|
|
|
|
Les comptes par défaut d'Artifactory sont :
|
|
|
|
| Compte | Mot de passe par défaut | Notes |
|
|
| ------------ | ---------------------------------------------- | -------------------------------------------------------------------- |
|
|
| admin | password | compte d'administration commun |
|
|
| access-admin | password (<6.8.0) ou une valeur aléatoire (>= 6.8.0) | utilisé uniquement pour les opérations d'administration locale |
|
|
| anonymous | '' | utilisateur anonyme pour récupérer des packages à distance, pas activé par défaut |
|
|
|
|
Par défaut, aucune politique de verrouillage de mot de passe n'est en place, ce qui fait d'Artifactory une cible privilégiée pour les attaques de bourrage de mots de passe et de pulvérisation de mots de passe.
|
|
|
|
## Autorisations <a href="#authorizations" id="authorizations"></a>
|
|
|
|
Idéalement, voici ce que vous devriez voir lorsque vous vous connectez à Artifactory :
|
|
|
|
![Page de connexion](https://www.errno.fr/artifactory/artif\_login.png)
|
|
|
|
D'autre part, si vous êtes accueilli avec quelque chose de plus proche de ceci :
|
|
|
|
![Page par défaut](https://www.errno.fr/artifactory/artif\_default.png)
|
|
|
|
Cela signifie que l'accès anonyme a été activé dans le panneau d'administration, ce qui est un paramètre courant utilisé pour permettre aux applications de récupérer des artefacts sans tracas, mais vous permet, en tant qu'attaquant, de voir plus que ce qui est préférable.
|
|
|
|
## Vérification des droits du compte <a href="#checking-account-rights" id="checking-account-rights"></a>
|
|
|
|
Parfois, en raison d'une mauvaise configuration, anonymous est autorisé à déployer des fichiers sur certains référentiels !
|
|
|
|
Pour vérifier sur quels référentiels l'utilisateur anonyme peut déployer, utilisez la requête suivante :
|
|
```
|
|
curl http://localhost:8081/artifactory/ui/repodata?deploy=true
|
|
{"repoList":["artifactory-build-info","example-repo-local"]}
|
|
```
|
|
Si des entrées `repoKey` sont présentes dans la requête, un utilisateur anonyme peut y déployer des fichiers, ce qui est vraiment très dangereux. Vous devez absolument être authentifié pour déployer des fichiers.
|
|
|
|
Cela peut être généralisé à d'autres comptes une fois que vous avez leur mot de passe ou leur jeton.
|
|
|
|
## Liste des utilisateurs <a href="#listing-users" id="listing-users"></a>
|
|
|
|
Pour une raison quelconque, la liste des utilisateurs est réservée aux administrateurs uniquement. J'ai trouvé une méthode alternative pour lister les utilisateurs (ceux qui déploient au moins) qui repose sur la valeur "Déployé par" des artefacts :
|
|
|
|
![Déployé par](https://www.errno.fr/artifactory/artif\_deployed\_by.png)
|
|
|
|
[Ce script](https://gist.github.com/gquere/347e8e042490be87e6e9e32e428cb47a) essaie simplement de trouver de manière récursive tous les utilisateurs qui ont déployé des artefacts. Notez que cela peut prendre un certain temps pour se terminer s'il y a beaucoup de référentiels (>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
|
|
```
|
|
## Permissions <a href="#permissions" id="permissions"></a>
|
|
|
|
Voici les autorisations de base et leur utilité :
|
|
|
|
* Gérer : ?
|
|
* Supprimer/Écraser : intéressant pour le pentest
|
|
* Déployer/Mettre en cache : intéressant pour le pentest
|
|
* Annoter : nécessaire pour CVE-2020-7931
|
|
* Lire : généralement une autorisation par défaut
|
|
|
|
# Vulnérabilités connues <a href="#known-vulnerabilities" id="known-vulnerabilities"></a>
|
|
|
|
Voici une liste sélectionnée de vulnérabilités publiques à fort impact :
|
|
|
|
## CVE-2016-10036 : Téléchargement de fichiers arbitraires et RCE (<4.8.6) <a href="#cve-2016-10036-arbitrary-file-upload--rce-486" id="cve-2016-10036-arbitrary-file-upload--rce-486"></a>
|
|
|
|
[Détails ici.](https://www.exploit-db.com/exploits/44543)
|
|
|
|
Celle-ci commence à dater et il est peu probable que vous tombiez sur une version Artifactory aussi obsolète. Néanmoins, elle est assez efficace, car il s'agit d'une simple traversée de répertoire qui permet une exécution de code arbitraire au niveau de Tomcat.
|
|
|
|
## CVE-2019-9733 : Contournement de l'authentification (<6.8.6) <a href="#cve-2019-9733-authentication-bypass-686" id="cve-2019-9733-authentication-bypass-686"></a>
|
|
|
|
[Advisory original ici.](https://www.ciphertechs.com/jfrog-artifactory-advisory/)
|
|
|
|
Sur les anciennes versions d'Artifactory (jusqu'à 6.7.3), le compte `access-admin` utilisait un mot de passe par défaut `password`.
|
|
|
|
Ce compte local est normalement interdit d'accès à l'interface utilisateur ou à l'API, mais jusqu'à la version 6.8.6, Artifactory pouvait être trompé en croyant que la demande émanait localement si l'en-tête HTTP `X-Forwarded-For` était défini sur `127.0.0.1`.
|
|
|
|
## CVE-2020-7931 : Injection de modèles côté serveur (Artifactory Pro) <a href="#cve-2020-7931-server-side-template-injection-artifactory-pro" id="cve-2020-7931-server-side-template-injection-artifactory-pro"></a>
|
|
|
|
[Advisory original ici.](https://github.com/atredispartners/advisories/blob/master/ATREDIS-2019-0006.md)
|
|
|
|
Voici un [outil que j'ai écrit](https://github.com/gquere/CVE-2020-7931) pour automatiser l'exploitation de cette vulnérabilité.
|
|
|
|
Ces éléments sont nécessaires pour l'exploitation :
|
|
|
|
* un utilisateur disposant des droits de déploiement (création de fichiers) et d'annotation (définition de filtres)
|
|
* Artifactory Pro
|
|
|
|
La vulnérabilité est assez simple : si une ressource déployée est définie comme filtrée, elle est interprétée comme un modèle Freemarker, ce qui donne à l'attaquant une fenêtre d'attaque SSTI. ![Ressource filtrée](https://www.errno.fr/artifactory/artif_filtered.png)
|
|
|
|
Voici les primitives implémentées :
|
|
|
|
* lectures de système de fichiers de base
|
|
* écritures limitées de système de fichiers
|
|
|
|
Ces primitives devraient suffire à vous donner une exécution de code à distance de plusieurs manières, de la plus facile/la plus silencieuse à la plus difficile/la plus bruyante :
|
|
|
|
* lecture d'un secret sur le système de fichiers qui vous permet de pivoter (/home/user/.bash\_history, /home/user/password.txt, /home/user/.ssh/id\_rsa ...)
|
|
* ajout d'une clé SSH à l'utilisateur
|
|
* déploiement d'un fichier .war pour exécuter un servlet
|
|
* déploiement d'un script utilisateur Groovy Artifactory
|
|
|
|
### Histoires de .war : les manigances de Java renameTo() <a href="#war-stories-java-renameto-shenanigans" id="war-stories-java-renameto-shenanigans"></a>
|
|
|
|
Voici une petite histoire de comment j'ai cogné ma tête contre le mur pendant des heures, voire des jours, lors d'un pentest. Je suis tombé sur une version obsolète d'Artifactory que je savais vulnérable à CVE-2020-7931. J'ai déployé le modèle SSTI de l'avis original et j'ai commencé à parcourir le système de fichiers. Il semblait qu'Artifactory avait été installé dans un emplacement non standard, ce qui n'est pas trop inhabituel car les administrateurs aiment garder des partitions séparées entre les binaires d'application, les données, les journaux et la configuration (ce qui est une bonne chose !). Il n'y avait pas de clés SSH ou de mots de passe dans le répertoire personnel de l'utilisateur qui m'auraient permis de pivoter facilement, donc il était temps d'être moins discret et d'écrire sur le système de fichiers. Le dépôt de la charge utile initiale (une clé publique) dans le répertoire de téléchargement d'Artifactory s'est bien passé, mais je n'ai tout simplement pas réussi à la déplacer vers le répertoire des clés SSH. Alors je suis retourné dans mon bac à sable d'exploitation, je l'ai testé à nouveau et ça a marché. Il devait donc y avoir une configuration différente qui m'empêchait de terminer la méthode `renameTo()`. À ce stade, il est toujours bon de [vérifier la documentation](https://docs.oracle.com/javase/8/docs/api/java/io/File.html#renameTo-java.io.File-) ... qui indique clairement que vous ne pouvez pas renommer des fichiers entre différents systèmes de fichiers, ce qui a du sens en fonction de la mise en œuvre de la méthode, c'est-à-dire si elle fonctionne au niveau de l'inode. Arg.
|
|
|
|
Rappelez-vous ce que j'ai dit sur les administrateurs qui aiment les partitions ? Eh bien, c'est un cas d'un administrateur qui a durci sa configuration à l'insu de son plein gré contre mon exploit ! J'ai donc dû fouiller dans ce qui est essentiellement une prison Java pour trouver une autre méthode qui me permettrait d'écrire un fichier sur le disque. Et ce n'était pas amusant du tout, car je ne suis pas familier avec aucune des choses impliquées : les modèles FTL, Java, Tomcat/Catalina. J'ai rapidement découvert que les évasions de prison Java régulières ne suffiraient pas, car l'instanciation de nouvelles classes était interdite. Après des heures de lecture de la documentation des classes Java et Catalina, j'ai enfin trouvé une méthode write() sur un objet auquel je pouvais accéder. Mais elle était limitée au chemin de base de l'application web... Alors j'ai pensé à combiner l'écriture sur un autre système de fichiers et le `renameTo()` sur ce nouveau système de fichiers accessible pour espérer pouvoir écrire n'importe où ? Et ça a marché un peu. J'ai réussi à écrire en dehors du répertoire de téléchargement temporaire... mais pas très loin de celui-ci car j'étais maintenant bloqué sur un autre système de fichiers qui était le point de montage de toutes les choses Artifactory : configuration, application et autres. Donc toujours pas de clé SSH pour moi.
|
|
|
|
D'accord, je pourrais écrire dans le dossier racine d'Artifactory, sûrement je pourrais faire quelque chose ici ? Hé, Tomcat par défaut déploie automatiquement les fichiers WAR écrits dans son chemin d'application, n'est-ce pas ? Alors j'ai utilisé msfvenom pour générer un shell web JSP empaqueté dans un fichier WAR et je l'ai testé dans mon bac à sable... eh bien, il a été déployé correctement, mais ne m'a pas donné d'exécution de commande. Il semble que Tomcat par défaut ne gère pas les JSP. Ugh. De plus en plus frustré, j'ai cherché un autre moyen d'exécuter du code dans Tomcat et j'ai trouvé une autre méthode d'exécution en utilisant des servlets. Je n'ai pas trouvé de charge utile appropriée, alors je me suis dit que je suis tout dedans à ce stade et [j'ai développé le mien que vous pouvez trouver ici](https://github.com/gquere/javaWebShell). Je l'ai testé dans le bac à sable, ça marche, ok
|
|
```
|
|
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)
|
|
```
|
|
Le deuxième type de mot de passe bcrypt ne nécessite rien de spécial, c'est juste un hachage bcrypt standard :
|
|
```
|
|
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)
|
|
```
|
|
### Secrets distants <a href="#remote-secrets" id="remote-secrets"></a>
|
|
|
|
Artifactory peut avoir besoin de stocker des secrets pour s'identifier auprès de services distants. Ces secrets ne sont évidemment pas hashés, ils sont stockés chiffrés sur le disque, avec la clé à côté d'eux. Il existe deux types de secrets mentionnés dans la [documentation officielle](https://jfrog.com/knowledge-base/what-are-the-artifactory-key-master-key-and-what-are-they-used-for/).
|
|
|
|
**Ancien format (<5.9): DES-EDE**
|
|
|
|
TODO. [Ouvrez une issue si vous avez des données chiffrées d'exemple](https://github.com/gquere/ArtifactoryDecryptor).
|
|
|
|
**Nouveau format (>=5.9): chiffrement AES128-CBC, stocké en base58**
|
|
|
|
Les secrets externes (tels que les mots de passe des serveurs distants) se trouvent dans les [descripteurs de configuration](https://www.jfrog.com/confluence/display/JFROG/Configuration+Files#ConfigurationFiles-GlobalConfigurationDescriptor), par exemple `/var/opt/jfrog/artifactory/etc/artifactory.config.latest.xml` et ressemblent à:
|
|
```
|
|
<keyStorePassword>AM.25rLQ.AES128.vJMeKkaK6RBRQCUKJWvYEHUw6zs394X1CrRugvJsQGPanhMgQ5be8yjWDhJYC4BEz2KRE</keyStorePassword>
|
|
```
|
|
Où :
|
|
|
|
* `AM` désigne toujours un secret chiffré d'Artifactory
|
|
* `25rLQ` est l'identificateur de secret qui doit correspondre à l'identificateur de clé
|
|
* `AES128` est évidemment l'algorithme utilisé
|
|
* `vJMeK...KRE` est l'encodage en base58 de `IV_SIZE|IV|secret|CRC`
|
|
|
|
D'autres secrets peuvent être trouvés (jetons, sauvegardes de configuration...) en utilisant l'expression régulière suivante :
|
|
```
|
|
grep -r 'AM\..*\.AES128\.' /var/opt/jfrog/artifactory/
|
|
```
|
|
La clé est stockée dans `/var/opt/jfrog/artifactory/etc/security/artifactory.key` et ressemble à :
|
|
```
|
|
JS.25rLQ.AES128.7fcJFd3Y2ib3wi4EHnhbvZuxu
|
|
```
|
|
Où :
|
|
|
|
* `JS` représente une clé
|
|
* `25rLQ` est un identifiant de clé unique qui permet de savoir quelle clé peut décrypter quels secrets
|
|
* `AES128` est évidemment l'algorithme utilisé
|
|
* `7fcJFd3Y2ib3wi4EHnhbvZuxu` est l'encodage base58 de la clé et de 2 octets de CRC
|
|
|
|
Cet outil que j'ai écrit peut être utilisé hors ligne pour décrypter les secrets d'Artifactory : [ArtifactoryDecryptor](https://github.com/gquere/ArtifactoryDecryptor).
|
|
|
|
# Défendre Artifactory <a href="#defending-artifactory" id="defending-artifactory"></a>
|
|
|
|
Si vous êtes l'équipe bleue ou un administrateur d'Artifactory, à ce stade, vous devriez avoir une assez bonne idée de ce qu'il faut faire :
|
|
|
|
* maintenir Artifactory à jour, surtout lorsqu'il y a des mises à jour critiques
|
|
* mettre en place une politique de mot de passe solide (pas de mots de passe par défaut, des mots de passe forts obligatoires, des verrouillages), de préférence différée à un LDAP externe pour une meilleure supervision
|
|
* restreindre les accès (respecter le principe du moindre privilège), en particulier pour l'utilisateur anonyme
|