كيف يتحول PROCESS_DUP_HANDLE إلى PROCESS_ALL_ACCESS

هناك ملاحظة مثيرة للاهتمام في مقالة MSDN الخاصة بأمن العمليات وحقوق الوصول :


... إذا كانت العملية A تحتوي على مقبض للمعالجة B من خلال وصول PROCESS_DUP_HANDLE ، فبإمكانها تكرار المقبض الزائف للعملية B. يؤدي هذا إلى إنشاء مؤشر له أقصى درجات الوصول إلى العملية B.

إذا قمت بترجمة هذا بحرية إلى اللغة الروسية ، فيقول هنا أن وجود واصف لعملية مع حق الوصول PROCESS_DUP_HANDLE ، يمكننا ، باستخدام وظيفة DuplicateHandle (...) ، الحصول على واصف مع أقصى أقنعة الوصول المسموح بها لهذه العملية.



مظاهرة


شفرة المصدر التي تستغل هذه الميزة بسيطة للغاية:


#include <Windows.h> int wmain(int argc, PWSTR argv[]) { HANDLE ProcessAllAccessHandle; HANDLE ProcessDuplicateHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, _wtoi(argv[1])); if (ProcessDuplicateHandle) { if (DuplicateHandle(ProcessDuplicateHandle, GetCurrentProcess(), GetCurrentProcess(), &ProcessAllAccessHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { CloseHandle(ProcessAllAccessHandle); } CloseHandle(ProcessDuplicateHandle); } return 0; } 

نتيجة للتجميع والربط ، نحصل على أداة مساعدة للاختبار تأخذ معرف العملية الهدف (PID) كوسيطة. ثم تفتح الأداة المساعدة العملية المحددة مع PROCESS_DUP_HANDLE اليمين. وبالتالي ، فإننا نحاكي الشرط الضروري لتوفر واصف لعملية مع PROCESS_DUP_HANDLE الصحيح (= = 0x40).


كتوضيح ، سأقوم بتتبع الأداة المساعدة المجمعة في WinDbg:


 0:000> lsa @$ip 0,3 > 13: if (ProcessDuplicateHandle) 14: { 15: if (DuplicateHandle(ProcessDuplicateHandle, 0:000> !handle @@C++(ProcessDuplicateHandle) 3 Handle 80 Type Process Attributes 0 GrantedAccess 0x40: None DupHandle HandleCount 9 PointerCount 260518 

وبعد ذلك نفض الغبار من المعصم عن طريق الاتصال بـ DuplicateHandle (...) ، نحصل على الواصف الثاني لنفس العملية ، ولكن مع أذونات أوسع:


 0:000> lsa @$ip 0,3 > 23: CloseHandle(ProcessAllAccessHandle); 24: } 25: CloseHandle(ProcessDuplicateHandle); 0:000> !handle @@C++(ProcessAllAccessHandle) 3 Handle 84 Type Process Attributes 0 GrantedAccess 0x1fffff: Delete,ReadControl,WriteDac,WriteOwner,Synch Terminate,CreateThread,,VMOp,VMRead,VMWrite,DupHandle,CreateProcess,SetQuota,SetInfo,QueryInfo,SetPort HandleCount 10 PointerCount 292877 

النقطة الأساسية هي قيمة GrantedAccess ، والتي هي للواصف الجديد 0x1fffff ، والتي تتوافق مع PROCESS_ALL_ACCESS . لسوء الحظ ، لا يعرض WinDbg PID العملية الهدف. ولكن للتأكد من استلام الواصف للعملية المطلوبة ، يمكنك إلقاء نظرة على الواصفات بواسطة Process Explorer (بعد تحديد معرف المنتج المحدد في وسائط سطر الأوامر في المصحح):


 0:000> dx argv[1] argv[1] : 0x1b7c2e2412c : "21652" [Type: wchar_t *] 


في لقطة الشاشة ، تفتح الأداة المساعدة واصفات لتشغيل notepad.exe.


لماذا يحدث هذا؟


أولاً ، لأنه عند تكرار واصف ، إذا لم يتم توسيع قناع الوصول للكائن (وتم تحديد علامة التشغيل DUPLICATE_SAME_ACCESS بشكل خاص) ، لا يوجد أي تحقق من أن العملية (التي سيتم فيها إنشاء واصف مكرر) يمكنها الوصول إلى هذا الكائن. يتم التحقق فقط من أن واصفات العملية التي تم تمريرها إلى وظيفة DuplicateHandle (...) لها قناع الوصول المسموح به PROCESS_DUP_HANDLE . وبعد ذلك ، يحدث نسخ الواصف بين العمليات دون التحقق من حقوق الوصول (أكرر: إذا كان للواصف الجديد قناع الحقوق المسموح به وليس أكبر من واصف النسخ الأصلي).


ثم تجدر الإشارة إلى أن استدعاء GetCurrentProcess () تُرجع ثابتًا ، وهو نفس واصف الزائفة (المؤشر الزائف) المذكور في بداية هذا المنشور. هناك نوعان من واصفات الزائفة الموثقة مع قيم ثابتة مفقودة فعليًا من جدول واصف العملية. لكن تتم معالجة هذه الواصفات بواسطة جميع وظائف kernel (جنبًا إلى جنب مع الواصفات المعتادة من جدول واصف العملية):


ماكروقيمةوصف
ZwCurrentProcess / NtCurrentProcess(مقبض) -1واصف العملية
ZwCurrentThread / NtCurrentThread(مقبض) -2واصف الموضوع

هذه هي قيمة NtCurrentProcess (== -1) التي تُرجع استدعاء GetCurrentProcess () .


يعني هذا الواصف الزائف في إطار عملية محددة وجود كائن في هذه العملية مع الحقوق PROCESS_ALL_ACCESS (في الواقع ، هناك فروق دقيقة ، لكن المقالة لا تتعلق بها). اتضح مثل هذا الرابط لنفسه ، ولكن من خلال واصف:


وهذا هو ، سيتم تفسير دعوتنا إلى DuplicateHandle (ProcessDuplicateHandle ، GetCurrentProcess () ، ...) على النحو التالي: من العملية (الهدف) المفتوحة ، قم بتكرار المقبض مع القيمة -1. وبالنسبة للعملية المستهدفة (العملية التي لدينا بها الواصف المخزن في ProcessDuplicateHandle المتغير) ، فإن القيمة -1 سوف تشير إلى نفس عملية الهدف مع حقوق PROCESS_ALL_ACCESS . لذلك ، نتيجة لذلك ، نحصل على واصف للعملية المستهدفة بأقصى حقوق.


بدلا من خاتمة


أكرر الفكرة المكتوبة في البداية: إذا تلقى شخص ما واصفًا للعملية مع PROCESS_DUP_HANDLE اليمين ، فسيتمكن بموجب نموذج أمان Windows من الحصول على واصف آخر لنفس العملية ، ولكن مع PROCESS_ALL_ACCESS حقوق (ويفعل ما يشاء مع العملية ).


شكرا لجميع الذين قرأوا المنشور حتى النهاية. أدعو الجميع إلى إجراء الاستطلاع لمعرفة كيف يمكن أن تكون هذه المنشورات مفيدة / مفيدة للجمهور.

Source: https://habr.com/ru/post/ar448472/


All Articles