hacktricks/network-services-pentesting/pentesting-web/artifactory-hacking-guide.md
2023-06-03 13:10:46 +00:00

16 KiB

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Ce contenu a été pris à partir de https://www.errno.fr/artifactory/Attacking_Artifactory

Fondamentaux d'Artifactory

Utilisateurs et mots de passe par défaut

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

Idéalement, voici ce que vous devriez voir lorsque vous vous connectez à Artifactory :

Page de connexion

D'autre part, si vous êtes accueilli avec quelque chose de plus proche de ceci :

Page par défaut

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

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

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

Ce script 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

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

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)

Détails ici.

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)

Advisory original ici.

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)

Advisory original ici.

Voici un outil que j'ai écrit 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

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()

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 ... 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. 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

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.

Ancien format (<5.9): DES-EDE

TODO. Ouvrez une issue si vous avez des données chiffrées d'exemple.

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, 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.

Défendre Artifactory

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