Janvier 2015, lors de la conférence AppSecCali, Chris Frohoff et Gabriel Lawrence présentent leurs travaux [1] sur les possibilités d’exécution de commandes suite à la désérialisation d’objets de certaines bibliothèques chargées par la JVM (le fameux CLASSPATH)…
En novembre 2015, Stephen Breen s’empare du sujet pour lui donner un impact d’envergure : il découvre que ces bibliothèques sont chargées dans des serveurs applicatifs qui utilisent nativement la sérialisation/désérialisation (WebLogic, JBoss, etc.) et qu’il suffit alors d’envoyer une requête, pour leur faire exécuter du code…
Et depuis, le sujet ne fait pas beaucoup parler de lui… pourtant, il soulève de nombreuses problématiques :
Quand on connait les difficultés pour avoir un parc de serveurs applicatifs à jour, comment gérer les bibliothèques utilisées par les applicatifs, les développements, etc. ?
Même en corrigeant les bibliothèques identifiées, d’autres (bibliothèques tierces, internes, etc.) pourraient présenter ces failles !
Au-delà de ces premières interrogations, c’est le mécanisme même de la sérialisation/désérialisation qui est remis en cause. Dans un article de son blog [2], la Fondation Apache écrit : « The best protection against this, is to avoid using a complex serialization protocol with untrusted peer ». No comment ;-)
Rappel des faits
La sérialisation est un mécanisme qui permet de rendre
un objet persistant à des fins :
- De stockage : l’objet peut alors être rechargé depuis un fichier, une base de données, etc.
- De transmission : une application A peut directement transmettre l’objet à une application B.
En Java, tout objet implémentant la classe « Serializable »
ou « Externalizable » ou définissant les méthodes « readObject »,
« readResolve » ou « readExternal » peut être manipulé de
la sorte.
Et c’est ces méthodes, « readObject », qui sont
appelées par la JVM avant même que l’application puisse contrôler le contenu de
l’objet, source de cette problématique !
En effet, si l’application A attend un objet sérialisé
qui autorise, par cette méthode, la réalisation d’actions dangereuses, alors
ces dernières seront exécutées par la JVM et à l’insu de l’application A.
Les travaux de Chris Frohoff et Gabriel Lawrence ont
montré comment un objet de la bibliothèque « Apache Commons Collections »
(« Transformer ») pouvait être manipulé dans ce sens. Il rend
possible la transformation d’un objet en spécifiant la classe utilisée
pour l’opération. En l’occurrence, « Runtime.Exec », bien connu des
pentesters pour permettre l’exécution de commande système.
Si la bibliothèque « Apache Commons Collections »
est chargée par la JVM (autrement dit, présente dans son CLASSPATH), alors
l’application A va charger l’objet, le lire… et exécuter la commande
système !
Notons que ce type de faille a été exploitée dans
cette bibliothèque, mais qu’elle est également présente dans
d’autres (Spring, Groovy et d’autres à découvrir).
Et concrètement ?
En
reprenant cette découverte (jusqu’alors passée sous silence), Stephen Breen a
remarqué :
- Que cette bibliothèque était inclue par défaut dans de nombreux serveurs applicatifs : WebLogic, JBoss, Jenkins, etc.
- Que ces composants manipulaient nativement des objets sérialisés :
- WebLogic sur les flux T3 ;
- JBoss et Jenkins sur des flux HTTP.
Dans le
pire des cas, la manipulation des objets est réalisée avant
authentification (puisque l’authentification repose elle-même sur
l’envoi d’un objet sérialisé) : une simple requête permet l’exécution de
code sur un serveur WebLogic activant le protocole T3 (ou T3S).
De
manière globale, tous composants manipulant des objets
sérialisés et en capacité de charger une classe
vulnérable sont sujets à cette faille :
- Serveurs applicatifs évoqués ;
- Serveur d’un applet ou d’un client lourd Java communiquant par objets sérialisés ;
- Composant exposant une interface RMI (Remote Method Invocation).
Si certains de ces services n’ont pas à être exposés
de toute manière sur Internet, il n’en est clairement pas de même sur un réseau
interne ou entre serveurs de zones de confiance très différentes.
Mais que faire alors ?
C’est surement dans la remédiation à cette faille que
réside la plus grande problématique… Car pour un applicatif utilisant ces
principes, la désactivation du protocole T3 [3] (comme recommandé actuellement en solution de secours pour WebLogic) n’est
clairement pas envisageable.
La suppression ou la mise à jour des bibliothèques sujettes à ces failles ne représente pas une solution pérenne : d’autres
failles dans d’autres bibliothèques seront découvertes…
À l’heure actuelle, une solution [4] possible consiste à surcharger la méthode
« resolveClass() » de «
java.io.ObjectInputStream »
afin de créer un filtre personnalisé limitant les désérialisations à une liste
blanche. Mais cette solution demande des développements et recettes non
négligeables.
L’exploitation de cette
faille conduira peut-être à l’intégration de limitation au sein de la JVM, qui
serait le meilleur compromis… reste à attendre les mises à jour...
Sources :
[1] https://frohoff.github.io/appseccali-marshalling-pickles/
[2] https://blogs.apache.org/foundation/entry/apache_commons_statement_to_widespread
[3] http://www.oracle.com/technetwork/topics/security/alert-cve-2015-4852-2763333.html?evite=WWSU12091612MPP001
[4] http://www.ibm.com/developerworks/library/se-lookahead/
Aucun commentaire:
Publier un commentaire