
استدعاءات نظام غير مباشرة نظيفة مع التلاعب باستدعاءات النظام.
SyscallRevenant هو أسلوب جديد لتنفيذ استدعاءات نظام غير مباشرة نظيفة.
يقوم المكوّن الرئيسي بحل أرقام خدمة النظام (SSNs) وعناوين تعليمة syscall ديناميكيًا.
ويتم ذلك عبر تفعيل علامة المصيدة (trap flag) أثناء التنفيذ.
أما المكوّن الثانوي فهو التلاعب عبر استبدال المعاملات قبل syscall.
صُمم هذا المزيج لتجاوز خطافات فضاء المستخدم أثناء استدعاء النظام اللاحق مع استبدال المعاملات المعروضة في البداية.
إخلاء المسؤولية: الغرض من هذا هو لأغراض تعليمية واختبارية فقط. لا تستخدم هذا على أجهزة لا تملك إذنًا باستخدامها. لا تستخدم هذا للاستغلال والتواصل مع أجهزة لا تملك تصريحًا باستخدامها.
الاستدعاءات غير المباشرة للنظام هي أسلوب لتنفيذ تعليمات syscall في فضاء مستخدم موثوق.
إذا وجد المستخدم تعليمة syscall، فقد يقفز إليها بشكل غير مباشر.
يمكن لحدث مُفعَّل أثناء جلسة تتبع أن يكشف عنوان العودة مباشرة بعد التعليمة.
وهذا لا يأخذ في الحسبان خطافات فضاء المستخدم الخاصة بـ كشف وإجابة نقاط النهاية (EDR).
قد يقوم نظام EDR بإدراج خطافات في ntdll.dll، مما يُبطل عملية البحث عن SSNs وتعليمات syscall.
الدخول إلى خطاف سيفيد الخيط المالك، ولن يرفع درجة الخباثة.
إن ملاحظة الدخول إلى دالة وملاحظة العملية الناتجة أمران مختلفان.
يبحث RevenantSyscalls في تلك الفجوة.
توضح الأقسام التالية المكوّنين الرئيسيين للمشروع.
يحل المكوّن الأول عناوين الدوال من ntdll.dll المحمّلة بواسطة العملية.
وقد يُنفَّذ بعد ذلك مسح بالمصيدة إذا كانت معلومات استدعاء النظام مطلوبة.
ويقوم المكوّن الثاني بقفزة غير مباشرة إلى معلومات الدالة المحفوظة.
يمكن استرداد كتلة بيئة العملية (PEB) عبر القراءة من سجل المقطع.
LoaderData هو حقل في PEB يحتوي على البيانات المحمّلة مع كل عملية.
يحتوي LoaderData على معلومات حول الوحدات المحمّلة إلى جانب كل عملية.
توجد أسماء الوحدات وعناوين قواعدها في إدخالات الوحدات.
تصف معلومات تصدير مكتبة مرتبطة ديناميكيًا (DLL) الرموز التي تصدّرها. تدعم بيانات التصدير الوصفية تحديد موقع الرموز المصدّرة. ينطبق فهرس الدالة على الأسماء والأرقام الترتيبية للأسماء فقط. تجزئة اسم الدالة هي الأفضل في البيئات محدودة الذاكرة.
معالج الاستثناءات الموجّهة هو آلية لمعالجة الاستثناءات تلتقط الاستثناءات من أي مكان داخل العملية.
يؤدي تفعيل علامة المصيدة إلى استثناء EXCEPTION_SINGLE_STEP عند التعليمة التالية التي تُنفَّذ.
يمكن لمعالج استثناءات موجّه مخصص فحص RIP والتحقق من وجود syscall.
وبإعادة تعيين علامة المصيدة بشكل متكرر، سيُكتشف عنوان syscall ويُحفظ SSN.
البحث عن استدعاء النظام
|
تنفيذ استدعاء النظام
|
لكل استدعاء نظام البحث الأولي عن معلومات استدعاء النظام؛ ستُدخل الخطافات لاسترداد معلومات استدعاء النظام. وبالمتابعة، ستُجرى قفزة غير مباشرة إلى استدعاء النظام. سيكون هناك RIP مزيف مرتبط (من الإدخال الأصلي). ومع إعادة الدخول، تكون المعاملات الأولية قد تعرّضت للتلاعب.
من منظور تتبع الأحداث لنظام Windows (ETW)، فإن الأحداث التي قد تُصدر هي: SysEnter وSysExit وStackWalk لكليهما.
إذا بنى نظام EDR أحداثًا مشابهة أو مماثلة، فستبدو هذه متطابقة تقريبًا.
ستكمن الاختلافات الوحيدة في طوابع زمنية مختلفة جذريًا لـ عداد أداء الاستعلام (QPC).
src/AsmRevenant.asm REAL_RTN: DQ 0
FAKE_RTN: DQ 0
; If a syscall information lookup is in progress, the
; initial entry return address needs to be preserved.
MOV RAX, QWORD PTR [RSP]
MOV QWORD PTR [FAKE_RTN], RAX
; Once the re-entry is made, the real return is saved,
; and the current is spoofed with initial return.
MOV RAX, QWORD PTR [RSP]
MOV QWORD PTR [REAL_RTN], RAX
MOV RAX, QWORD PTR [FAKE_RTN]
MOV QWORD PTR [RSP], RAX
src/Revenant.cLONG VectoredExceptionHandler(EXCEPTION_POINTERS *BreakPoint) {
...
// If a syscall information lookup is being made, the
// syscall instruction address is saved, the SSN is
// saved, and the return is rerouted.
if (LookupInProgress && *(USHORT*)BreakPoint->Address == 0x050F) {
SyscallInstruction = BreakPoint->Address;
SyscallSSN = BreakPoint->Context->Rax;
BreakPoint->Context->Rip = SyscallExit;
}
// When re-entered, if the previous instruction was
// a syscall, reset return address, and exit.
if (!LookupInProgress && *(USHORT*)(BreakPoint->Address - 2) == 0x050F) {
*(VOID**)BreakPoint->Context->Rsp = REAL_RTN;
BreakPoint->Context->Rip = SyscallExit;
}
...
}