diff --git a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md index 7205c5152..fd2df1abf 100644 --- a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md +++ b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md @@ -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 ऑब्जेक्ट को कैसे सीरियलाइज और डेसिरियलाइज किया जाए:** + +**निम्नलिखित उदाहरण से है** ```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` का उपयोग करें। +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}}