
FortiOS 8.0.0 फ़र्मवेयर इमेज को डिक्रिप्ट और एक्स्ट्रैक्ट करें।
FortiOS 8.0.0 फर्मवेयर इमेज को डिक्रिप्ट और एक्सट्रैक्ट करें।
यह स्क्रिप्ट Bishop Fox के Forticrack को विस्तारित करती है ताकि 8.0.0 फर्मवेयर इमेज का समर्थन किया जा सके। साथ ही, FortiGate 7.4.7 फर्मवेयर एन्क्रिप्शन पर RandoriSec का लेख FortiOS 8.0.0 के एन्क्रिप्शन को रिवर्स करने में वास्तव में सहायक था, क्योंकि यह 7.4.7 वाले का एक नया संस्करण प्रतीत होता है।
यह FGT और FFW दोनों इमेज के लिए काम करता है।
यह FGT और FFW v8.0.0.F-build0167 दोनों पर परीक्षण किया गया था। अन्य बिल्ड में RSA सार्वजनिक कुंजी और XOR कुंजी के सटीक कर्नेल सेगमेंट और वर्चुअल एड्रेस खोजने के लिए कर्नेल को फिर से रिवर्स करने की आवश्यकता हो सकती है।
यह स्क्रिप्ट नामकरण के आधार पर स्वचालित रूप से पता लगाने का प्रयास करती है कि .out फ़ाइल FGT से है या FFW से। इसे यदि आवश्यक हो तो एक वैकल्पिक तर्क के रूप में भी निर्दिष्ट किया जा सकता है।
$ python3 forticrack_v8.py
[x] Usage: python3 forticrack_v8.py <.out file> [FGT|FFW]
डेमो:

परिणामी निर्देशिका:

FortiOS डिक्रिप्शन पर पहले से ही कई लेख और स्क्रिप्ट मौजूद हैं (जैसे पहले उल्लिखित)। हालाँकि, उनमें से कोई भी FortiOS 8.0.0 पर लागू नहीं होता, क्योंकि Fortinet ने अपने एन्क्रिप्शन को एक बार फिर संशोधित किया है।
Fortinet https://support.fortinet.com/ > Login > Support > VM Images पर FortiFirewall और FortiGate दोनों के लिए अपग्रेड इमेज डाउनलोड करने की अनुमति देता है। ये इमेज .out फ़ाइलें होती हैं, जिन्हें यह स्क्रिप्ट इनपुट के रूप में अपेक्षा करती है। निष्पादित होने पर, यह 4 प्रमुख ऑपरेशन करती है:
.out फ़ाइल डिक्रिप्ट करें (Bishop Fox का काम).out अपग्रेड फ़ाइल एक कस्टम XOR-आधारित ब्लॉक सिफर से एन्क्रिप्ट होती है। Bishop Fox ने इसे रिवर्स इंजीनियर किया और forticrack के साथ एक शानदार लेख प्रकाशित किया। स्क्रिप्ट का यह हिस्सा व्यावहारिक रूप से Bishop Fox के मूल forticrack के समान कोड का उपयोग करता है, जो संबंधित 32-बाइट कुंजी निकालता है और .out फ़ाइल को डिक्रिप्ट करता है। यदि आप इसके बारे में और जानना चाहते हैं, तो मैं सुझाव देता हूँ कि आप वह लेख पढ़ें।
डिक्रिप्ट की गई फ़ाइल एक मानक Fortinet फर्मवेयर इमेज है। स्क्रिप्ट इसे binwalk का उपयोग करके निकालती है, जिससे निम्नलिखित फ़ाइल सिस्टम प्राप्त होता है:
ext-root
├── boot
│ ├── cert.der
│ └── grub
│ ├── BOOTX64.EFI
│ ├── grub.cfg
│ └── grubx64.efi
├── boot.msg
├── datafs.tar.gz
├── datafs.tar.gz.bak
├── datafs.tar.gz.chk
├── datafs.tar.gz.chk.bak
├── extlinux.conf
├── filechecksum
├── flatkc
├── flatkc.chk
├── flatkc.sig
├── hash_bin.sha256
├── ldlinux.c32
├── ldlinux.sys
├── rootfs.gz
└── rootfs.gz.chk
जहाँ:
boot/ : बूटलोडर फ़ाइलों वाली निर्देशिकाdatafs.tar.gz : डेटा फ़ाइल सिस्टमflatkc : Linux कर्नेल bzImagerootfs.gz : एन्क्रिप्टेड फ़ाइल सिस्टमवल्नरेबिलिटी शोधकर्ताओं के लिए सभी दिलचस्प फ़ाइलें, जैसे /sbin/init, rootfs.gz के अंदर एन्क्रिप्टेड होती हैं।
rootfs.gz को डिक्रिप्ट करें (नया हिस्सा)यह वह हिस्सा है जो संस्करण 8.0.0 के लिए नया है। इसे समझने के लिए, Claude Code का बड़े पैमाने पर उपयोग संबंधित डिक्रिप्शन लॉजिक को रिवर्स करने और कर्नेल इमेज के अंदर हार्डकोडेड वर्चुअल एड्रेस प्राप्त करने के लिए किया गया, जिसमें FortiGate 7.4.7 पर RandoriSec का लेख को संदर्भ के रूप में लिया गया। मेरे अनुभव से, AI-सहायता प्राप्त रिवर्सिंग क्रिप्टोग्राफी का विश्लेषण करते समय वास्तव में बहुत प्रभावी होती है, जो उस समय एक क्लासिक कठिन कार्य था जब मैन्युअल रिवर्सिंग ही एकमात्र विकल्प था।
rootfs.gz फ़ाइल FORT-RC4 नामक एक कस्टम स्ट्रीम सिफर से एन्क्रिप्ट होती है। इसे डिक्रिप्ट करने की कुंजी फ़ाइल के अंत में जोड़े गए PKCS#1 RSA हस्ताक्षर के अंदर एम्बेडेड होती है। इस हस्ताक्षर को डिक्रिप्ट करने के लिए संबंधित RSA सार्वजनिक कुंजी का उपयोग करना आवश्यक है, जिसे कर्नेल इमेज से प्राप्त किया जा सकता है।
चूँकि flatkc एक bzImage है, कर्नेल ELF को अंदर स्थित gzip पेलोड को ढूँढकर और उसे डीकंप्रेस करके आसानी से निकाला जा सकता है। ELF के अंदर, वर्चुअल एड्रेस 0xffffffff8179a1a0 पर, RSA सार्वजनिक कुंजी को दर्शाने वाला 270 बाइट्स का XOR-एन्कोडेड DER डेटा होता है। इसे डिकोड करने के लिए 32-बाइट XOR कुंजी 0xffffffff8179a2c0 पर स्थित होती है। डिकोडिंग बस decoded[i] = encoded[i] ^ xor_key[i & 0x1f] है, और परिणाम एक मानक PKCS#1 RSAPublicKey DER संरचना (RSA-2048 सार्वजनिक कुंजी) के रूप में पार्स होता है।
RSA सार्वजनिक कुंजी प्राप्त होने पर, हस्ताक्षर ब्लॉक (rootfs.gz के अंतिम 256 बाइट्स) को m = sig^e mod n की गणना करके डिक्रिप्ट किया जाता है। 256-बाइट परिणाम निम्नलिखित लेआउट के साथ एक PKCS#1 v1.5 Type 1 पैडेड संदेश है:
m[0x00] = 0x00
m[0x01] = 0x01
m[0x02..0x9E] = 0xFF (157 padding bytes)
m[0x9F] = 0x00
m[0xA0..0xBF] = SHA256(rootfs.gz[:-256])
m[0xC0..0xDF] = (unused)
m[0xE0..0xFF] = RC4 key (32 bytes)
SHA-256 हैश को एक सत्यापन जाँच के रूप में rootfs.gz के बॉडी के साथ मिलान किया जाता है, और अंत में मौजूद 32-बाइट RC4 कुंजी वास्तव में फ़ाइल को डिक्रिप्ट करने के लिए उपयोग की जाती है।
FORT-RC4 के संबंध में, इसे पूरी तरह से Claude द्वारा vibe-reversed किया गया था। यह इस प्रकार काम करता है:
FORT-RC4 में एक मानक KSA है लेकिन संशोधित PRGA है: एकल S-box लुकअप से प्रति राउंड एक कीस्ट्रीम बाइट उत्पन्न करने के बजाय, यह
iऔरjके बिट-मिक्स्ड संस्करणों का उपयोग करके दो अतिरिक्त लुकअप करता है, एक मिक्स इंडेक्स में0xAAXOR करता है, और अंतिम बाइट उत्पन्न करने के लिए दो S-box मानों को जोड़ता है। FGT और FFW के बीच भी एक अंतर है: FGT में, PRGA शुरू होने से पहले KSA के बादiऔरjदोनों को 0 पर रीसेट किया जाता है, जबकि FFW मेंjKSA से आगे बढ़ता है। यह FGT कर्नेल में सिफर फ़ंक्शन के अंदर ऑफ़सेट+0x83पर बाइट अनुक्रम31 c0 31 d2(xor eax,eax; xor edx,edx) के रूप में दिखाई देता है, जो FFW में अनुपस्थित है। यही कारण है कि स्क्रिप्ट को वैरिएंट जानने की आवश्यकता होती है।
जैसा कि उल्लेख किया गया है, 7.4.7 पर RandoriSec का लेख एक उपयोगी संदर्भ था, लेकिन एन्क्रिप्शन तंत्र इतना बदल गया कि उनका दृष्टिकोण सीधे 8.0.0 पर लागू नहीं हुआ, इसलिए ये मुख्य अंतर हैं:
.init.data कर्नेल सेक्शन से प्राप्त सीड का उपयोग करके ChaCha20 के साथ अस्पष्ट (obfuscated) किया जाता है। 8.0.0 में, वह सेक्शन पूरी तरह शून्य होता है, इसलिए इसके बजाय एक साधारण XOR योजना का उपयोग किया जाता है।rootfs AES-CTR से एन्क्रिप्ट होता है। 8.0.0 में, यह FORT-RC4 (एक कस्टम एन्क्रिप्शन एल्गोरिदम) है।rsa_parse_pub_key के क्रॉस-रेफरेंस का अनुसरण करके खोजा जा सकता है। 8.0.0 कर्नेल स्ट्रिप्ड है, इसलिए वर्चुअल एड्रेस को डिक्रिप्शन रूटीन को सीधे रिवर्स करके खोजना पड़ा।RSA key blob के वर्चुअल एड्रेस संस्करणों के बीच करीब हैं (0x3000 से स्थानांतरित), जिसने रिवर्सिंग के दौरान भी मदद की।
डिक्रिप्ट किया गया आउटपुट एक वास्तविक gzip फ़ाइल है। इसे डीकंप्रेस करने पर एक CPIO आर्काइव प्राप्त होता है, जो मानक Linux initrd प्रारूप है और इसे cpio -idmv के साथ आसानी से निकाला जा सकता है।