Désérialisation Non Sécurisée : Comprendre les "Gadget Chains" Java et PHP
La désérialisation non sécurisée reste l'une des vulnérabilités logicielles les plus complexes et dévastatrices répertoriées dans le Top 10 de l'OWASP. Elle trompe l'environnement d'exécution du serveur en convertissant des flux d'octets malveillants en exécution de code. Cela entraîne régulièrement une exécution de code à distance (RCE) non authentifiée.
Dans cet article approfondi de Cayvora Security, nous explorerons les concepts sous-jacents, comment les attaquants construisent des "Gadget Chains" en Java et PHP, et les stratégies d'atténuation.
Qu'est-ce que la Sérialisation ?
La sérialisation convertit un objet en mémoire en un flux d'octets. La désérialisation est le processus inverse. La vulnérabilité survient lorsqu'une application reçoit un objet sérialisé d'une source non fiable et le désérialise sans vérifier sa validité.
Le Mécanisme : Méthodes Magiques
Lorsqu'un objet est désérialisé, les langages invoquent automatiquement des "méthodes magiques" (__wakeup(), __destruct() en PHP, readObject() en Java). Si un attaquant manipule les données sérialisées, il peut contrôler les attributs de l'objet instancié pour dicter le comportement de la méthode magique.
Exploitation de la Désérialisation PHP
Examinons un extrait PHP vulnérable :
class Logger {
public $logFile;
public $logData;
public function __destruct() {
file_put_contents($this->logFile, $this->logData);
}
}
$user_data = unserialize($_COOKIE['pref']);
L'attaquant crée une chaîne sérialisée malveillante :
O:6:"Logger":2:{s:7:"logFile";s:12:"shell.php";s:7:"logData";s:27:"<?php system($_GET['cmd']); ?>";}
Lorsque ce cookie est injecté :
1. unserialize() lit la chaîne et instancie un objet Logger.
2. Le ramasse-miettes de PHP détruit l'objet, déclenchant __destruct().
3. Un webshell est déposé sur le serveur.
Les Gadget Chains (POP)
Les attaquants relient plusieurs classes légitimes entre elles. La méthode __destruct() d'une classe A appelle une méthode d'une classe B, qui exécute accidentellement une fonction RCE. Des outils comme PHPGGC génèrent ces charges utiles.
Exploitation de la Désérialisation Java
Java gère la sérialisation via java.io.ObjectInputStream. Par défaut, il permet la désérialisation de toute classe implémentant Serializable.
Si l'application utilise une bibliothèque vulnérable (comme commons-collections), l'attaquant peut utiliser l'outil ysoserial pour générer un flux binaire exécutant Runtime.getRuntime().exec().
Prévention et Conception Sécurisée
1. Éviter les Formats Natifs
Évitez unserialize() en PHP ou ObjectInputStream en Java avec des données non fiables. Utilisez des formats sûrs comme JSON ou XML.
2. Implémenter des Contrôles d'Intégrité
Signez cryptographiquement l'objet sérialisé à l'aide de HMAC. Si la signature est invalide, rejetez la requête.
3. Utiliser des Listes Blanches (Java)
En Java, surchargez resolveClass() dans ObjectInputStream pour restreindre strictement les classes pouvant être désérialisées :
public class SecureObjectInputStream extends ObjectInputStream {
// Liste blanche stricte
}
Conclusion
En remplaçant la sérialisation native par un JSON/XML strictement typé ou en appliquant des listes blanches d'objets, les ingénieurs de sécurité ferment définitivement la porte à l'exploitation par gadget chain.
Auditez vos API
Les failles de désérialisation contournent les scanners automatisés. Contactez Cayvora Security pour une revue de code experte.
📱 Discutez avec un expert en sécurité