
مكتبة C++ تسترجع وتزور وسائط استدعاءات نظام Windows باستخدام نقاط توقف الأجهزة ومعالجات الاستثناءات لتقويض تتبع EDR.
TamperingSyscalls هو مشروع جديد من جزأين يتكون من انتحال الوسائط (argument spoofing) واسترجاع استدعاءات النظام (syscall retrieval)، وكلاهما يسيء استخدام معالج الاستثناءات (EH) من أجل خداع حلول EDRs. يجمع هذا المشروع بين هذين المشروعين لتوفير حل بديل لاستدعاءات النظام المباشرة.
العبث باستدعاءات النظام (Tampering with syscalls).
SetUnhandledExceptionFilter( OneShotHardwareBreakpointHandler );
0f05 في سجل Dr0.
يمكننا تحديد عنوان كعبرة استدعاء النظام (syscall stub) عبر هذا البحث السريع عن البايتات في الذاكرة.BYTE stub[] = { 0x0F, 0x05 };
for( unsigned int i = 0; i < (unsigned int)25; i++ )
{
if( memcmp( (LPVOID)((DWORD_PTR)function + i), stub, 2 ) == 0 ) {
return (LPVOID)((DWORD_PTR)function + i);
}
}
if( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
if( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
{
if( ExceptionInfo->ContextRecord->Dr7 & 1 ) {
if( ExceptionInfo->ContextRecord->Rip == ExceptionInfo->ContextRecord->Dr0 ) {
ExceptionInfo->ContextRecord->Dr0 = 0;
mov r10, rcx لأن سجل RCX يتم إتلافه في التعليمات التالية.case NTMAPVIEWOFSECTION_ENUM:
ExceptionInfo->ContextRecord->R10 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->SectionHandle;
ExceptionInfo->ContextRecord->Rdx =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->ProcessHandle;
ExceptionInfo->ContextRecord->R8 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->BaseAddress;
ExceptionInfo->ContextRecord->R9 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->ZeroBits;
يمكننا أن نرى في هذا المثال أننا نقوم بإصلاح الوسائط للدالة NtMapViewOfSection.
إذا كنت ترغب في البدء في تزييف بيانات القياس عن بُعد الخاصة بحل EDR، فمن الممكن تعديل تعريفات p[FunctionName] حيث تكون معينة حاليًا إلى NULL.
لتوليد الدوال المطلوبة، استخدم gen.py. يدعم هذا الأمر أيًا مما يلي:
python gen.py NtOpenSection,NtMapViewOfSection,NtUnmapViewOfSection
سينتج ذلك 3 ملفات: TamperingSyscalls.cpp و TamperingSyscalls.h و main.cpp. يمكنك تضمين #include "TamperingSyscalls.h" في مشروعك. يمكننا استدعاء الدوال بإلحاق اسم الدالة بـ p، على سبيل المثال pNtOpenSection(...);
لا يمكننا تعيين نقطة توقف على NtSetThreadContext أو المتغيرات الخاصة بها لأنها تُستخدم لتعيين سجلات التصحيح (debug registers). توجد فترة وجيزة يتم فيها تعيين سجلات التصحيح، لكنها صغيرة جدًا ولا أعتقد أنه سيتم اكتشافنا بسبب إبقاء Dr0 مفتوحًا.
لقد نشرت تدوينة صغيرة على مدونتي تتناول هذه التقنيات.