Translated ['src/pentesting-web/deserialization/basic-java-deserializati

This commit is contained in:
Translator 2025-07-28 18:12:46 +00:00
parent fd254b35a2
commit b65e3e44d7

View File

@ -1,15 +1,27 @@
# Basic Java Deserialization with ObjectInputStream readObject
{{#include ../../banners/hacktricks-training.md}}
इस POST में `java.io.Serializable` का उपयोग करते हुए एक उदाहरण समझाया जाएगा
इस POST में एक उदाहरण समझाया जाएगा जिसमें `java.io.Serializable` **और यह क्यों खतरनाक हो सकता है यदि इनकमिंग स्ट्रीम हमलावर द्वारा नियंत्रित है, `readObject()` को ओवरराइड करना**
# Serializable
## Serializable
Java `Serializable` इंटरफेस (`java.io.Serializable` एक मार्कर इंटरफेस है जिसे आपकी कक्षाओं को लागू करना चाहिए यदि उन्हें **serializable** और **deserializable** होना है। Java ऑब्जेक्ट सीरियलाइजेशन (लेखन) [ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html) के साथ किया जाता है और डेसिरियलाइजेशन (पढ़ना) [ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html) के साथ किया जाता है।
Java `Serializable` इंटरफेस (`java.io.Serializable`) एक मार्कर इंटरफेस है जिसे आपकी कक्षाओं को लागू करना चाहिए यदि उन्हें **सीरियलाइज** और **डेसिरियलाइज** किया जाना है। Java ऑब्जेक्ट सीरियलाइजेशन (लेखन) [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) के साथ किया जाता है और डेसिरियलाइजेशन (पढ़ना) [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html) के साथ किया जाता है।
आइए एक **क्लास Person** का उदाहरण देखें जो **serializable** है। यह क्लास **readObject** फ़ंक्शन को **ओवरराइट** करती है, इसलिए जब इस **क्लास** का **कोई ऑब्जेक्ट** **deserialized** होता है, तो यह **फंक्शन** **एक्ज़ीक्यूट** होगा।\
उदाहरण में, क्लास Person का **readObject फंक्शन** उसके पालतू जानवर के `eat()` फ़ंक्शन को कॉल करता है और कुत्ते का `eat()` फ़ंक्शन (किसी कारण से) एक **calc.exe** को कॉल करता है। **हम देखेंगे कि इस कैलकुलेटर को चलाने के लिए एक Person ऑब्जेक्ट को कैसे सीरियलाइज और डेसिरियलाइज किया जाए:**
### Reminder: Which methods are implicitly invoked during deserialization?
**निम्नलिखित उदाहरण [https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649) से है।**
1. `readObject()` कक्षा-विशिष्ट पढ़ने की लॉजिक (यदि लागू किया गया और *निजी* है)।
2. `readResolve()` डेसिरियलाइज्ड ऑब्जेक्ट को दूसरे के साथ बदल सकता है।
3. `validateObject()` `ObjectInputValidation` कॉलबैक के माध्यम से।
4. `readExternal()` कक्षाओं के लिए जो `Externalizable` को लागू करती हैं।
5. कंस्ट्रक्टर्स **नहीं** चलाए जाते हैं इसलिए गैजेट चेन पूरी तरह से पिछले कॉलबैक पर निर्भर करती है।
उस चेन में कोई भी विधि जो हमलावर द्वारा नियंत्रित डेटा (कमांड निष्पादन, JNDI लुकअप, रिफ्लेक्शन, आदि) को कॉल करती है, डेसिरियलाइजेशन रूटीन को RCE गैजेट में बदल देती है।
आइए एक उदाहरण देखें जिसमें एक **कक्षा Person** है जो **सीरियलाइजेबल** है। यह कक्षा **readObject** फ़ंक्शन को ओवरराइट करती है, इसलिए जब इस **कक्षा** का **कोई ऑब्जेक्ट** **डेसिरियलाइज** किया जाता है, तो यह **फंक्शन** **निष्पादित** होगा।\
उदाहरण में, कक्षा Person का **readObject** फ़ंक्शन उसके पालतू जानवर के फ़ंक्शन `eat()` को कॉल करता है और कुत्ते का फ़ंक्शन `eat()` (किसी कारण से) एक **calc.exe** को कॉल करता है। **हम देखेंगे कि इस कैलकुलेटर को निष्पादित करने के लिए एक Person ऑब्जेक्ट को कैसे सीरियलाइज और डेसिरियलाइज किया जाए:**
**निम्नलिखित उदाहरण <https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649> से है**
```java
import java.io.Serializable;
import java.io.*;
@ -80,8 +92,63 @@ payloadTest("test.ser");
}
}
```
## निष्कर्ष
### निष्कर्ष (क्लासिक परिदृश्य)
जैसा कि आप इस बहुत बुनियादी उदाहरण में देख सकते हैं, यहाँ "कमजोरी" इस कारण से प्रकट होती है क्योंकि **readObject** फ़ंक्शन **अन्य कमजोर फ़ंक्शनों को कॉल कर रहा है**
जैसा कि आप इस बहुत बुनियादी उदाहरण में देख सकते हैं, यहाँ "कमजोरी" इस कारण से प्रकट होती है क्योंकि **readObject()** विधि **अन्य हमलावर-नियंत्रित कोड को कॉल कर रही है**। वास्तविक दुनिया की गैजेट श्रृंखलाओं में, बाहरी पुस्तकालयों (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, आदि) में शामिल हजारों कक्षाओं का दुरुपयोग किया जा सकता है - हमलावर को कोड निष्पादन प्राप्त करने के लिए केवल *एक* पहुंच योग्य गैजेट की आवश्यकता होती है।
---
## 2023-2025: Java deserialization हमलों में क्या नया है?
* 2023 CVE-2023-34040: Spring-Kafka deserialization में error-record headers जब `checkDeserExWhen*` फ्लैग सक्षम होते हैं, तो हमलावर द्वारा प्रकाशित विषयों से मनमाने गैजेट निर्माण की अनुमति दी। 3.0.10 / 2.9.11 में ठीक किया गया। ¹
* 2023 CVE-2023-36480: Aerospike Java क्लाइंट का trusted-server अनुमान टूट गया दुर्भावनापूर्ण सर्वर उत्तरों में ऐसे serialized payloads शामिल थे जिन्हें क्लाइंट द्वारा deserialized किया गया → RCE। ²
* 2023 CVE-2023-25581: `pac4j-core` उपयोगकर्ता प्रोफ़ाइल विशेषता पार्सिंग ने `{#sb64}`-पूर्ववर्ती Base64 blobs को स्वीकार किया और `RestrictedObjectInputStream` के बावजूद उन्हें deserialized किया। 4.0.0 या उससे ऊपर अपग्रेड करें।
* 2023 CVE-2023-4528: JSCAPE MFT प्रबंधक सेवा (पोर्ट 10880) ने XML-encoded Java वस्तुओं को स्वीकार किया जिससे RCE के रूप में root/SYSTEM के रूप में पहुंच मिली।
* 2024 ysoserial-plus(mod) में कई नए गैजेट श्रृंखलाएँ जोड़ी गईं जिनमें Hibernate5, TomcatEmbed, और SnakeYAML 2.x कक्षाएँ शामिल हैं जो कुछ पुराने फ़िल्टरों को बायपास करती हैं।
## आधुनिक उपाय जो आपको लागू करने चाहिए
1. **JEP 290 / Serialization Filtering (Java 9+)**
*कक्षाओं की एक अनुमति-सूची या अस्वीकृति-सूची जोड़ें:*
```bash
# केवल आपके DTOs और java.base को स्वीकार करें, अन्य सभी को अस्वीकृत करें
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"
```
प्रोग्रामेटिक उदाहरण:
```java
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
ObjectInputFilter.Config.setSerialFilter(filter);
```
2. **JEP 415 (Java 17+) संदर्भ-विशिष्ट फ़िल्टर फैक्ट्रियाँ** विभिन्न निष्पादन संदर्भ (जैसे, प्रति RMI कॉल, प्रति संदेश कतार उपभोक्ता) के लिए विभिन्न फ़िल्टर लागू करने के लिए `BinaryOperator<ObjectInputFilter>` का उपयोग करें।
3. **कच्चे `ObjectInputStream` को नेटवर्क पर उजागर न करें** कोड निष्पादन अर्थशास्त्र के बिना JSON/Binary एन्कोडिंग को प्राथमिकता दें (डिफ़ॉल्ट टाइपिंग को अक्षम करने के बाद जैक्सन, Protobuf, Avro, आदि)।
4. **Defense-in-Depth सीमाएँ** अधिकतम एरे लंबाई, गहराई, संदर्भ सेट करें:
```bash
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
```
5. **निरंतर गैजेट स्कैनिंग** यदि कोई खतरनाक गैजेट पहुंच योग्य हो जाता है तो निर्माण विफल करने के लिए अपने CI में `gadget-inspector` या `serialpwn-cli` जैसे उपकरण चलाएँ।
## अपडेटेड टूलिंग चीट-शीट (2024)
* `ysoserial-plus.jar` > 130 गैजेट श्रृंखलाओं के साथ सामुदायिक फोर्क:
```bash
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
```
* `marshalsec` JNDI गैजेट निर्माण के लिए अभी भी संदर्भ।
* `gadget-probe` नेटवर्क सेवाओं के खिलाफ तेज़ ब्लैक-बॉक्स गैजेट खोज।
* `SerialSniffer` JVMTI एजेंट जो `ObjectInputStream` द्वारा पढ़ी गई प्रत्येक कक्षा को प्रिंट करता है (फ़िल्टर बनाने के लिए उपयोगी)।
* **पता लगाने की टिप** फ़िल्टर निर्णयों और अस्वीकृत कक्षाओं को लॉग करने के लिए `-Djdk.serialDebug=true` (JDK 22+) सक्षम करें।
## सुरक्षित `readObject()` कार्यान्वयन के लिए त्वरित चेकलिस्ट
1. विधि को `private` बनाएं और `@Serial` एनोटेशन जोड़ें (स्थिर विश्लेषण में मदद करता है)।
2. कभी भी उपयोगकर्ता-प्रदत्त विधियों को कॉल न करें या विधि में I/O न करें केवल फ़ील्ड पढ़ें।
3. यदि मान्यता की आवश्यकता है, तो इसे deserialization के **बाद** करें, `readObject()` के बाहर।
4. `Externalizable` को लागू करने को प्राथमिकता दें और डिफ़ॉल्ट serialization के बजाय स्पष्ट फ़ील्ड पढ़ें।
5. आंतरिक सेवाओं के लिए भी एक मजबूत `ObjectInputFilter` पंजीकृत करें (समझौता-प्रतिरोधी डिज़ाइन)।
## संदर्भ
1. Spring Security Advisory CVE-2023-34040 Java Deserialization in Spring-Kafka (अगस्त 2023)
2. GitHub Security Lab GHSL-2023-044: Unsafe Deserialization in Aerospike Java Client (जुलाई 2023)
{{#include ../../banners/hacktricks-training.md}}