
EDRSandblast-GodFault
بواسطة Gabriel Landau في Elastic Security. تعديل من EDRSandblast - انظر README الأصلي أدناه.
يدمج GodFault في EDR Sandblast، محققًا نفس النتيجة دون استخدام أي برامج تشغيل ضعيفة.
C:\Users\user\Desktop\Offsets>EDRSandblast.exe --kernelmode cmd
| | __ | __ \ / | | | | | | | |
| | | | | | |) | ( __ _ _ __ | | | | | __ _ | |
| | | | | | _ / _ \ / | '_ \ / _ | ' | |/ ` / __| __|
| || || | | \ \ ) | (| | | | | (| | |) | | (| _ | |
||_____/|| _|/ _,|| ||_,|_./||_,|__/__|
D3FC0N 30 Edition | Thomas DIOT (@_Qazeer) & Maxime MEIGNAN (@th3m4ks)
[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)
[===== KERNEL MODE =====]
[+] Setting up prerequisites for the kernel read/write primitives... [+] Loading kernel related offsets from the CSV file [*] System's ntoskrnl.exe file version is: ntoskrnl_22621-1702.exe [+] Offsets are available for this version of ntoskrnl.exe (ntoskrnl_22621-1702.exe)! [+] Checking if any EDR kernel notify rountines are set for image loading, process and thread creations... [+] [NotifyRountines] Enumerating process creation callbacks [+] Running command: GodFault.exe -t 2684 [?] Server does not appear to be running. Attempting to install it... [+] CSRSS PID is 748 [+] Testing initial ability to acquire PROCESS_ALL_ACCESS to System: Failure [+] Ready. Spawning WinTcb. [+] SpawnPPL: Waiting for child process to finish. [+] Thread 2684 (KTHREAD FFFF910961E4C080) has been blessed by GodFault [+] [NotifyRountines] fffff8034df25500 [cng.sys + 0x5500] [+] [NotifyRountines] fffff8034e9efdc0 [WdFilter.sys + 0x4fdc0] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff803487bc460 [ksecdd.sys + 0x1c460] [+] [NotifyRountines] fffff8034eff3fd0 [tcpip.sys + 0x13fd0] [+] [NotifyRountines] fffff8034f5ed980 [iorate.sys + 0xd980] [+] [NotifyRountines] fffff8034dea8890 [CI.dll + 0x88890] [+] [NotifyRountines] fffff803525079f0 [dxgkrnl.sys + 0x179f0] [+] [NotifyRountines] fffff80352be0a70 [vm3dmp.sys + 0x10a70] [+] [NotifyRountines] fffff8036ebccd00 [peauth.sys + 0x3cd00] [+] [NotifyRountines] fffff8036eda1550 [wtd.sys + 0x1550] [+] [NotifyRountines] Found a total of 1 EDR / security products driver(s) [+] [NotifyRountines] Enumerating thread creation callbacks [+] [NotifyRountines] fffff8034e9f15c0 [WdFilter.sys + 0x515c0] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff8034e9f1350 [WdFilter.sys + 0x51350] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff8036eb71010 [mmcss.sys + 0x1010] [+] [NotifyRountines] Found a total of 2 EDR / security products driver(s) [+] [NotifyRountines] Enumerating image loading callbacks [+] [NotifyRountines] fffff8034e9f0820 [WdFilter.sys + 0x50820] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff80352ab5710 [ahcache.sys + 0x25710] [+] [NotifyRountines] Found a total of 1 EDR / security products driver(s)
[+] Checking if EDR callbacks are registered on processes and threads handle creation/duplication... [+] [ObjectCallblacks] Enumerating Process object callbacks : [+] [ObjectCallblacks] Callback at FFFF800C5E2F2940 for handle creations & duplications: [+] [ObjectCallblacks] Status: Enabled [+] [ObjectCallblacks] Preoperation at 0xfffff8034e9eda30 [WdFilter.sys + 0x4da30] [+] [ObjectCallblacks] Callback belongs to an EDR and is enabled! [+] [ObjectCallblacks] Enumerating Thread object callbacks : [+] [ObjectCallblacks] Object callbacks are present !
[+] [ETWTI] Checking the ETW Threat Intelligence Provider state... [+] [ETWTI] ETW Threat Intelligence Provider is ENABLED!
[+] Process is NOT "safe" to launch our payload, removing monitoring and starting another process...
[+] [ETWTI] Disabling the ETW Threat Intel provider by patching ProviderEnableInfo at 0xffff91095ce8c430 with 0x00. [+] [ETWTI] The ETW Threat Intel provider was successfully disabled!
[+] Removing kernel callbacks registered by EDR for process creation, thread creation and image loading... [+] [NotifyRountines] Removing process creation callbacks [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c2a8 | callback struct: 0xffff91095dbf3a5f | callback function: 0xfffff8034e9efdc0] [+] [NotifyRountines] Removing thread creation callbacks [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c4a0 | callback struct: 0xffff91095dbf3b1f | callback function: 0xfffff8034e9f15c0] [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c4a8 | callback struct: 0xffff91095dbf3b4f | callback function: 0xfffff8034e9f1350] [+] [NotifyRountines] Removing image loading callbacks [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c6a0 | callback struct: 0xffff91095dbf3e4f | callback function: 0xfffff8034e9f0820]
[+] Disabling kernel callbacks registered by EDR for process and thread opening or handle duplication... [+] [ObjectCallblacks] Disabling WdFilter.sys callback...
[+] All EDR drivers were successfully removed from Kernel callbacks!
[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)
[===== KERNEL MODE =====]
[+] Setting up prerequisites for the kernel read/write primitives... [+] Loading kernel related offsets from the CSV file [*] System's ntoskrnl.exe file version is: ntoskrnl_22621-1702.exe [+] Offsets are available for this version of ntoskrnl.exe (ntoskrnl_22621-1702.exe)! [+] Checking if any EDR kernel notify rountines are set for image loading, process and thread creations... [+] [NotifyRountines] Enumerating process creation callbacks [+] Running command: GodFault.exe -t 8344 [+] Thread 8344 (KTHREAD FFFF91096169F080) has been blessed by GodFault [+] Initial blessing successful [+] [NotifyRountines] fffff8034df25500 [cng.sys + 0x5500] [+] [NotifyRountines] fffff803487bc460 [ksecdd.sys + 0x1c460] [+] [NotifyRountines] fffff8034eff3fd0 [tcpip.sys + 0x13fd0] [+] [NotifyRountines] fffff8034f5ed980 [iorate.sys + 0xd980] [+] [NotifyRountines] fffff8034dea8890 [CI.dll + 0x88890] [+] [NotifyRountines] fffff803525079f0 [dxgkrnl.sys + 0x179f0] [+] [NotifyRountines] fffff80352be0a70 [vm3dmp.sys + 0x10a70] [+] [NotifyRountines] fffff8036ebccd00 [peauth.sys + 0x3cd00] [+] [NotifyRountines] fffff8036eda1550 [wtd.sys + 0x1550] [+] [NotifyRountines] No EDR driver(s) found! [+] [NotifyRountines] Enumerating thread creation callbacks [+] [NotifyRountines] fffff8036eb71010 [mmcss.sys + 0x1010] [+] [NotifyRountines] No EDR driver(s) found! [+] [NotifyRountines] Enumerating image loading callbacks [+] [NotifyRountines] fffff80352ab5710 [ahcache.sys + 0x25710] [+] [NotifyRountines] No EDR driver(s) found!
[+] Checking if EDR callbacks are registered on processes and threads handle creation/duplication... [+] [ObjectCallblacks] Enumerating Process object callbacks : [+] [ObjectCallblacks] Callback at FFFF800C5E2F2940 for handle creations & duplications: [+] [ObjectCallblacks] Status: Disabled [+] [ObjectCallblacks] Preoperation at 0xfffff8034e9eda30 [WdFilter.sys + 0x4da30] [+] [ObjectCallblacks] Callback belongs to an EDR but is disabled. [+] [ObjectCallblacks] Enumerating Thread object callbacks : [+] [ObjectCallblacks] Object callbacks are not found !
[+] [ETWTI] Checking the ETW Threat Intelligence Provider state... [+] [ETWTI] ETW Threat Intelligence Provider is DISABLED!
[+] Process is "safe" to launch our payload
[+] Kernel callbacks have normally been removed, starting cmd.exe WARNING: EDR kernel callbacks will be restored after exiting the cmd prompt (by typing exit) WARNING: While unlikely, the longer the callbacks are removed, the higher the chance of being detected / causing a BSoD upon restore is!
Microsoft Windows [Version 10.0.22621.1702] (c) Microsoft Corporation. All rights reserved.
C:\Users\user\Desktop\Offsets>
# EDRSandBlast
`EDRSandBlast` هي أداة مكتوبة بلغة `C` تستغل برنامج تشغيل موقع ضعيف لتجاوز اكتشافات EDR (استدعاءات إشعارات الروتين، استدعاءات الكائنات وموفر `ETW TI`) وحماية `LSASS`. كما تم تنفيذ تقنيات متعددة لإزالة التعليق من مساحة المستخدم لتجنب المراقبة في مساحة المستخدم.
اعتبارًا من الإصدار، تم استخدام مجموعة من تقنيات مساحة المستخدم (`--usermode`) ومساحة kernel (`--kernelmode`) لتفريغ ذاكرة `LSASS` تحت مراقبة EDR، دون التعرض للحظر أو إنشاء أحداث متعلقة بـ "OS Credential Dumping" في وحدة تحكم المنتج (السحابية). تم إجراء الاختبارات على 3 منتجات EDR مختلفة وكانت ناجحة في كل حالة.
## الوصف
### تجاوز EDR من خلال إزالة إشعارات روتين Kernel
تستخدم منتجات EDR استدعاءات "Notify Routines" الخاصة بـ Kernel في Windows ليتم إعلامها من قبل kernel بنشاط النظام، مثل إنشاء العمليات والسلاسل وتحميل الصور (`exe` / `DLL`).
يتم تعريف هذه الاستدعاءات من مساحة kernel، عادة من برنامج التشغيل الذي ينفذ الاستدعاءات، باستخدام عدد من واجهات برمجة التطبيقات الموثقة (`nt!PsSetCreateProcessNotifyRoutine`, `nt!PsSetCreateThreadNotifyRoutine`, إلخ). تضيف واجهات برمجة التطبيقات هذه روتينات استدعاء يقدمها برنامج التشغيل إلى مصفوفات غير موثقة من الروتينات في مساحة kernel:
- `PspCreateProcessNotifyRoutine` لإنشاء العمليات
- `PspCreateThreadNotifyRoutine` لإنشاء السلاسل
- `PspLoadImageNotifyRoutine` لتحميل الصور
يقوم `EDRSandBlast` بتعداد الروتينات المعرفة في تلك المصفوفات وإزالة أي روتين استدعاء مرتبط بقائمة محددة مسبقًا من برامج تشغيل EDR (أكثر من 1000 برنامج تشغيل لمنتجات أمنية مدعومة، انظر [قسم كشف برامج تشغيل EDR](#edr-drivers-and-processes-detection). يتم التعداد والإزالة من خلال استغلال أولية قراءة / كتابة ذاكرة kernel تعسفية مقدمة من استغلال برنامج تشغيل ضعيف (انظر [قسم برامج التشغيل الضعيفة](#vulnerable-drivers-detection)).
يتم استرداد إزاحات المصفوفات المذكورة باستخدام تقنيات متعددة، يرجى الرجوع إلى [قسم الإزاحات](#ntoskrnl-and-wdigest-offsets).
### تجاوز EDR من خلال إزالة استدعاءات الكائنات
غالبًا ما تسجل منتجات EDR (وحتى EPP) "استدعاءات الكائنات" من خلال استخدام واجهة برمجة تطبيقات kernel `nt!ObRegisterCallbacks`. تسمح هذه الاستدعاءات للمنتج الأمني بأن يتم إعلامه عند كل إنشاء مقبض على أنواع كائنات محددة (استدعاءات الكائنات المتعلقة بالعمليات والسلاسل وسطح المكتب مدعومة الآن بواسطة Windows). قد يحدث إنشاء مقبض عند فتح كائن (استدعاء `OpenProcess`، `OpenThread`، إلخ) وكذلك عند تكرار المقابض (استدعاء `DuplicateHandle`، إلخ).
من خلال إعلام kernel لكل من هذه العمليات، قد يقوم المنتج الأمني بتحليل شرعية إنشاء المقبض (*على سبيل المثال، عملية غير معروفة تحاول فتح LSASS*)، وحتى حظره إذا تم اكتشاف تهديد.
في كل تسجيل استدعاء باستخدام `ObRegisterCallbacks`، يتم إضافة عنصر جديد إلى القائمة المرتبطة المزدوجة `CallbackList` الموجودة في كائن `_OBJECT_TYPE` الذي يصف نوع الكائن المتأثر بالاستدعاء (إما عملية أو سلسلة أو سطح مكتب). لسوء الحظ، يتم وصف هذه العناصر ببنية غير موثقة ولا منشورة في ملفات الرموز بواسطة Microsoft. ومع ذلك، فإن دراستها من إصدارات `ntoskrnl.exe` المختلفة تشير إلى أن البنية لم تتغير بين (على الأقل) إصدارات Windows 10 builds 10240 و 22000 (من 2015 إلى 2022).
البنية المذكورة، التي تمثل تسجيل استدعاء كائن، هي التالية:```C
typedef struct OB_CALLBACK_ENTRY_t {
LIST_ENTRY CallbackList; // linked element tied to _OBJECT_TYPE.CallbackList
OB_OPERATION Operations; // bitfield : 1 for Creations, 2 for Duplications
BOOL Enabled; // self-explanatory
OB_CALLBACK* Entry; // points to the structure in which it is included
POBJECT_TYPE ObjectType; // points to the object type affected by the callback
POB_PRE_OPERATION_CALLBACK PreOperation; // callback function called before each handle operation
POB_POST_OPERATION_CALLBACK PostOperation; // callback function called after each handle operation
KSPIN_LOCK Lock; // lock object used for synchronization
} OB_CALLBACK_ENTRY;
هيكل OB_CALLBACK المذكور أعلاه غير موثق أيضًا، ويتم تعريفه على النحو التالي:```C
typedef struct OB_CALLBACK_t {
USHORT Version; // usually 0x100
USHORT OperationRegistrationCount; // number of registered callbacks
PVOID RegistrationContext; // arbitrary data passed at registration time
UNICODE_STRING AltitudeString; // used to determine callbacks order
struct OB_CALLBACK_ENTRY_t EntryItems[1]; // array of OperationRegistrationCount items
WCHAR AltitudeBuffer[1]; // is AltitudeString.MaximumLength bytes long, and pointed by AltitudeString.Buffer
} OB_CALLBACK;
من أجل تعطيل استدعاءات الكائنات المسجلة بواسطة EDR، تم تنفيذ ثلاث تقنيات في `EDRSandblast`؛ لكن تقنية واحدة فقط مفعلة حاليًا.
#### استخدام حقل `Enabled` في `OB_CALLBACK_ENTRY`
هذه هي التقنية الافتراضية المفعلة في `EDRSandblast`. لاكتشاف وتعطيل استدعاءات الكائنات المرتبطة بـ EDR، يتم تصفح قائمة `CallbackList` الموجودة في كائنات `_OBJECT_TYPE` المرتبطة بنوعي *العملية* و*الخيط*. يتم الإشارة إلى كائني `_OBJECT_TYPE` بواسطة رموز عامة عالمية في النواة، `PsProcessType` و`PsThreadType`.
يُفترض أن كل عنصر في القائمة يتوافق مع بنية `OB_CALLBACK_ENTRY` الموصوفة أعلاه (افتراض يبدو صحيحًا على الأقل في جميع إصدارات Windows 10 وقت كتابة هذا الشرح). يتم تحديد الدوال المعرفة في حقلي `PreOperation` و`PostOperation` للتحقق مما إذا كانت تنتمي إلى برنامج تشغيل EDR، وإذا كان الأمر كذلك، يتم تعطيل الاستدعاءات ببساطة عن طريق تبديل علامة `Enabled`.
على الرغم من أن هذه التقنية آمنة إلى حد كبير، إلا أن لها عيب الاعتماد على بنية غير موثقة؛ لتقليل مخاطر التلاعب غير الآمن بهذه البنية، يتم إجراء فحوصات أساسية للتحقق من أن بعض الحقول لها القيم المتوقعة:
* `Enabled` إما `TRUE` أو `FALSE` (*لا تضحك، `BOOL` هو `int`، لذا يمكن أن يكون أي شيء غير `1` أو `0`*);
* `Operations` إما `OB_OPERATION_HANDLE_CREATE` أو `OB_OPERATION_HANDLE_DUPLICATE` أو كليهما;
* `ObjectType` يشير إلى `PsProcessType` أو `PsThreadType`.
#### فصل قائمة `CallbackList` للخيوط والعمليات
استراتيجية أخرى لا تعتمد على بنية غير موثقة (وبالتالي فهي أكثر متانة من الناحية النظرية تجاه تغييرات نواة NT) هي فصل قائمة `CallbackList` بأكملها لكل من العمليات والخيوط. كائن `_OBJECT_TYPE` هو كما يلي:```C
struct _OBJECT_TYPE {
LIST_ENTRY TypeList;
UNICODE_STRING Name;
[...]
_OBJECT_TYPE_INITIALIZER TypeInfo;
[...]
LIST_ENTRY CallbackList;
}
جعل مؤشري Flink وBlink من CallbackList LIST_ENTRY يشيران إلى LIST_ENTRY نفسه يؤدي عمليًا إلى جعل القائمة فارغة. نظرًا لأن بنية _OBJECT_TYPE منشورة في رموز kernel، فإن التقنية لا تعتمد على إزاحات/بنى ثابتة. ومع ذلك، فإن لها بعض العيوب.
الأول هو عدم القدرة على تعطيل الاستدعاءات من EDR فقط؛ بل إن التقنية تؤثر على جميع استدعاءات الكائنات التي قد تكون سُجِّلت بواسطة برامج "شرعية". ومع ذلك، تجدر الإشارة إلى أن استدعاءات الكائنات لا تُستخدم بواسطة أي مكون مثبت مسبقًا على Windows 10 (في وقت كتابة هذا التقرير)، لذا فإن تعطيلها لا ينبغي أن يؤثر على استقرار الجهاز (بل وأكثر من ذلك إذا كان التعطيل مؤقتًا فقط).
العيب الثاني هو أن عمليات مقابض العمليات أو الخيوط متكررة جدًا (شبه مستمرة) في الأداء الطبيعي لنظام التشغيل. وبالتالي، إذا كانت بدائية الكتابة في kernel المستخدمة لا يمكنها إجراء كتابة QWORD "ذرية"، فهناك احتمال كبير أن يتم الوصول إلى مؤشر _OBJECT_TYPE.CallbackList.Flink بواسطة kernel في منتصف عملية الكتابة فوقه. على سبيل المثال، يمكن للسائق الضعيف MSI RTCore64.sys إجراء كتابة DWORD واحدة فقط في المرة الواحدة، لذا ستكون هناك حاجة إلى 2 IOCTLs متميزة لكتابة المؤشر، وبينهما هناك احتمال كبير أن يستخدمه kernel (مما يؤدي إلى تعطل). من ناحية أخرى، يمكن للسائق الضعيف DELL DBUtil_2_3.sys إجراء كتابات بأحجام عشوائية في IOCTL واحدة، لذا فإن استخدام هذه الطريقة معه لا يخاطر بالتسبب في تعطل.
آخر تقنية وجدناها هي تعطيل دعم استدعاءات الكائنات تمامًا للخيوط والعمليات. داخل بنية _OBJECT_TYPE المقابلة لأنواع العمليات والخيوط يوجد حقل TypeInfo، يتبع بنية _OBJECT_TYPE_INITIALIZER الموثقة. يحتوي الأخير على حقل بتات ObjectTypeFlags، حيث يحدد علم SupportsObjectCallbacks ما إذا كان نوع الكائن الموصوف (عملية، خيط، سطح مكتب، رمز، ملف، إلخ) يدعم تسجيل استدعاءات الكائنات أم لا. كما ذكر سابقًا، فقط أنواع كائنات العملية والخيط وسطح المكتب تدعم هذه الاستدعاءات على تثبيت Windows في وقت كتابة هذا التقرير.
نظرًا لأن بت SupportsObjectCallbacks يتم التحقق منه بواسطة ObpCreateHandle أو ObDuplicateObject قبل حتى قراءة CallbackList (وقبل تنفيذ الاستدعاءات بالطبع)، فإن قلب البت في وقت تشغيل kernel يؤدي فعليًا إلى تعطيل تنفيذ جميع استدعاءات الكائنات.
العيب الرئيسي لهذه الطريقة هو ببساطة أن KPP ("PatchGuard") يراقب سلامة بعض (كل؟) بنى _OBJECT_TYPE، ويطلق 0x109 Bug Check مع المعامل 4 يساوي 0x8، مما يعني أن بنية نوع الكائن قد تم تغييرها.
ومع ذلك، فإن إجراء التعطيل / إعادة التمكين (والإجراء "الضار" بينهما) بسرعة كافية يجب أن يكون كافيًا "للتغلب" على PatchGuard (إلا إذا كنت غير محظوظ وتم إجراء فحص دوري في الوقت الخطأ).
يقوم موفر ETW Microsoft-Windows-Threat-Intelligence بتسجيل بيانات حول استخدامات بعض واجهات برمجة تطبيقات Windows المستخدمة بشكل ضار. يتضمن ذلك واجهة برمجة التطبيقات nt!MiReadWriteVirtualMemory، التي يتم استدعاؤها بواسطة nt!NtReadVirtualMemory (التي تُستخدم لتفريغ ذاكرة LSASS) وتراقبها وظيفة nt!EtwTiLogReadWriteVm.
يمكن لمنتجات EDR استهلاك السجلات التي ينتجها موفر ETW TI من خلال خدمات أو عمليات تعمل كـ SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT أو PS_PROTECTED_ANTIMALWARE_LIGHT على التوالي، ومرتبطة بسائق Early Launch Anti Malware (ELAM).
كما نشر slaeryan في منشور مدونة CNO Development Labs، يمكن تعطيل موفر ETW TI بالكامل عن طريق تصحيح، في ذاكرة kernel، السمة ProviderEnableInfo الخاصة به إلى 0x0. راجع منشور المدونة الرائع المذكور أعلاه لمزيد من المعلومات حول التقنية.
على غرار إزالة استدعاءات Kernel، يتم حساب الإزاحات اللازمة لـ ntoskrnl.exe (nt!EtwThreatIntProvRegHandleOffset، و GuidEntry الخاص بـ _ETW_REG_ENTRY، و ProviderEnableInfo الخاص بـ _ETW_GUID_ENTRY) في ملف NtoskrnlOffsets.csv لعدد من إصدارات Windows Kernel.
من أجل مراقبة الإجراءات التي تقوم بها العمليات بسهولة، غالبًا ما تنشر منتجات EDR آلية تسمى الربط في وضع المستخدم. أولاً، تسجل منتجات EDR استدعاء kernel (عادةً استدعاءات تحميل الصورة أو إنشاء العملية، انظر أعلاه) الذي يسمح لها بتلقي الإشعارات عند بدء كل عملية.
عندما يتم تحميل عملية بواسطة Windows، وقبل أن تبدأ فعليًا، يكون EDR قادرًا على حقن بعض DLL المخصصة في مساحة عنوان العملية، والتي تحتوي على منطق المراقبة الخاص به. أثناء التحميل، تقوم هذه DLL بحقن "خطافات" في بداية كل وظيفة يجب مراقبتها بواسطة EDR. في وقت التشغيل، عندما يتم استدعاء الوظائف المراقبة بواسطة العملية تحت المراقبة، تقوم هذه الخطافات بإعادة توجيه تدفق التحكم إلى بعض كود الإشراف الموجود في DLL الخاصة بـ EDR، مما يسمح له بفحص الوسائط وقيم الإرجاع لهذه الاستدعاءات.
في معظم الأوقات، تكون الوظائف المراقبة هي استدعاءات النظام (مثل NtReadVirtualMemory، NtOpenProcess، إلخ)، والتي توجد تطبيقاتها في ntdll.dll. اعتراض الاستدعاءات لوظائف Nt* يسمح للمنتجات بأن تكون قريبة قدر الإمكان من الحدود بين وضع المستخدم ووضع kernel (مع البقاء في وضع المستخدم)، ولكن قد يتم أيضًا مراقبة وظائف من بعض DLLs ذات المستوى الأعلى.
أدناه أمثلة على نفس الوظيفة، قبل وبعد ربطها بواسطة منتج EDR:```assembly NtProtectVirtualMemory proc near mov r10, rcx mov eax, 50h test byte ptr ds:7FFE0308h, 1 jnz short loc_18009D1E5 syscall retn loc_18009D1E5: int 2Eh retn NtProtectVirtualMemory endp
**الميزات الرئيسية:**
- يدمج أدوات التحليل الثابت (Bandit، Semgrep، Brakeman، إلخ) لتحديد الثغرات ونقاط الضعف الأمنية في الشيفرة المصدرية.
- يُحلل صور الحاويات باستخدام أدوات الفحص (Trivy، Grype، Syft) لاكتشاف ثغرات أنظمة التشغيل والاعتماديات البرمجية.
- يُجري تحليلًا ديناميكيًا باستخدام OWASP ZAP لكشف العيوب الأمنية النشطة.
- يُقيّم أمان البنية التحتية ككود (IaC) باستخدام KICS، ويكشف عن التهيئات الخاطئة في Terraform و CloudFormation، إلخ.
- يُولّد تقارير مفصلة عن الثغرات تتضمن بيانات وصفية وتصنيفًا وإرشادات للمعالجة.```assembly
NtProtectVirtualMemory proc near
jmp sub_7FFC74490298 ; --> "hook", jump to EDR analysis function
int 3 ; overwritten instructions
int 3 ; overwritten instructions
int 3 ; overwritten instructions
test byte_7FFE0308, 1 ; <-- execution resumes here after analysis
jnz short loc_7FFCB44AD1E5
syscall
retn
loc_7FFCB44AD1E5:
int 2Eh
retn
NtProtectVirtualMemory endp
خطافات المستخدم (Userland hooks) لها "نقطة ضعف" تتمثل في وجودها في ذاكرة المستخدم، مما يعني أنها قابلة للملاحظة والتعديل المباشر من قبل العملية قيد المراقبة. للكشف تلقائيًا عن الخطافات في مساحة عنوان العملية، الفكرة الرئيسية هي مقارنة الاختلافات بين ملف DLL الأصلي على القرص والمكتبة الموجودة في الذاكرة، والتي يحتمل أن تكون قد تم تغييرها بواسطة EDR. لإجراء هذه المقارنة، يتم اتباع الخطوات التالية بواسطة EDRSandblast:
InLoadOrderModuleList الموجود
في PEB (لتجنب استدعاء أي API قد يكون مراقبًا ومريبًا)ملاحظة: يمكن تعميم العملية للعثور على الاختلافات في أي مكان في المقاطع غير القابلة للكتابة
وليس فقط في بداية وظائف التصدير، على سبيل المثال إذا بدأت منتجات EDR في تطبيق الخطافات
في منتصف الدالة :) وبالتالي لا يتم استخدامها من قبل الأداة، ولكن تم تنفيذها
في findDiffsInNonWritableSections.
لتجاوز المراقبة التي تقوم بها هذه الخطافات، هناك تقنيات متعددة ممكنة، ولكل منها مزايا وعيوب.
الطريقة الأكثر بديهية لتجاوز المراقبة القائمة على الخطاف هي إزالة الخطافات. نظرًا لأن الخطافات موجودة في ذاكرة يمكن للعملية نفسها الوصول إليها، لإزالة خطاف، يمكن للعملية ببساطة:
هذا الأسلوب بسيط إلى حد ما، ويمكن استخدامه لإزالة كل خطاف تم اكتشافه دفعة واحدة. عند تنفيذه بواسطة أداة هجومية في بدايتها، يسمح هذا لبقية الكود بأن يكون غير مدرك تمامًا لآلية الخطاف وأن يعمل بشكل طبيعي دون مراقبة.
ومع ذلك، له عيبان رئيسيان. من المحتمل أن EDR يراقب استخدام
NtProtectVirtualMemory، لذا فإن استخدامه لتغيير أذونات الصفحة التي تم تثبيت
الخطافات عليها (على الأقل من الناحية النظرية) فكرة سيئة. أيضًا، إذا تم تنفيذ سلسلة رسائل
(thread) بواسطة EDR وتقوم بشكل دوري بالتحقق من سلامة الخطافات، فقد يؤدي ذلك أيضًا إلى
إثارة بعض الاكتشافات.
للحصول على تفاصيل التنفيذ، راجع مسار الكود الخاص بوظيفة unhook() عندما يكون unhook_method هو
UNHOOK_WITH_NTPROTECTVIRTUALMEMORY.
ملاحظة مهمة: للتبسيط، تم تنفيذ هذه التقنية في EDRSandblast كأساس
لتقنية لعرض تقنيات التجاوز الأخرى؛ كل منها يوضح
كيفية الحصول على نسخة غير مراقبة من NtProtectVirtualMemory، ولكنه يؤدي نفس
العملية بعد ذلك (إزالة خطاف معين).
لتجاوز خطاف معين، من الممكن ببساطة "القفز فوقه" وتنفيذ بقية الدالة كما هي. أولاً، يجب استرداد البايتات الأصلية للدالة المراقبة، التي تم الكتابة فوقها بواسطة EDR لتثبيت الخطاف، من ملف DLL. في مثال الكود السابق، ستكون هذه هي البايتات المقابلة للتعليمات التالية:```assembly mov r10, rcx mov eax, 50h
تحديد هذه البايتات مهمة بسيطة حيث يمكننا إجراء *diff* نظيف لكل من نسختي الذاكرة والقرص من المكتبة، كما هو موصوف سابقًا. بعد ذلك، نقوم بتجميع تعليمة قفزة مصممة لإعادة توجيه تدفق التحكم إلى الكود الذي يلي مباشرةً الـ hook، على العنوان `NtProtectVirtualMemory + sizeof(overwritten_instructions)````assembly
jmp NtProtectVirtualMemory+8
أخيرًا، نقوم بتجميع هذه الأوبكود وتخزينها في ذاكرة قابلة للتنفيذ (تم إنشاؤها حديثًا) ونحتفظ بمؤشر لها. يُطلق على هذا الكائن اسم "trampoline" ويمكن استخدامه بعد ذلك كمؤشر دالة، مكافئ تمامًا لدالة NtProtectVirtualMemory الأصلية.
الفائدة الرئيسية لهذه التقنية، كما هو الحال مع جميع التقنيات أدناه، هي أن الخطاف لا يتم مسحه أبدًا، لذا فإن أي فحص سلامة يتم إجراؤه على الخطافات بواسطة EDR يجب أن ينجح. ومع ذلك، فإنه يتطلب تخصيص ذاكرة قابلة للكتابة ثم قابلة للتنفيذ، وهو أمر نموذجي لتخصيص الشيل كود، مما يجذب تدقيق EDR.
للحصول على تفاصيل التنفيذ، راجع مسار الكود الخاص بوظيفة unhook() عندما تكون unhook_method هي UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE. يرجى تذكر أن التقنية معروضة فقط في تنفيذنا، وفي النهاية تُستخدم لإزالة الخطافات من الذاكرة، مثل كل تقنية أدناه.
لكي يعمل خطاف منتج EDR، يجب عليه حفظ الأوبكود التي أزالها في مكان ما في الذاكرة. والأسوأ من ذلك (أو "الأفضل" من وجهة نظر المهاجم)، لاستخدام التعليمات الأصلية بشكل فعال، من المحتمل أن يكون EDR قد خصص لنفسه trampoline في مكان ما لتنفيذ الدالة الأصلية بعد اعتراض الاستدعاء.
يمكن البحث عن هذا الترامبولين واستخدامه كبديل للدالة المُخططة، دون الحاجة إلى تخصيص ذاكرة قابلة للتنفيذ، أو استدعاء أي API باستثناء VirtualQuery، والتي من المرجح ألا تتم مراقبتها باعتبارها دالة غير ضارة.
للعثور على الترامبولين في الذاكرة، نتصفح مساحة العنوان بأكملها باستخدام VirtualQuery بحثًا عن ذاكرة ملتزمة وقابلة للتنفيذ. لكل منطقة من الذاكرة من هذا القبيل، نفحصها للبحث عن تعليمة قفز تستهدف العنوان الذي يلي التعليمات المستبدلة (NtProtectVirtualMemory+8 في مثالنا السابق). يمكن استخدام الترامبولين بعد ذلك لاستدعاء الدالة المُخططة دون تشغيل الخطاف.
تعمل هذه التقنية بشكل جيد بشكل مفاجئ حيث تستعيد جميع الترامبولينات تقريبًا على EDR المختبر. للحصول على تفاصيل التنفيذ، راجع مسار الكود الخاص بوظيفة unhook() عندما تكون unhook_method هي UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE.
طريقة أخرى بسيطة للوصول إلى نسخة غير مراقبة من دالة NtProtectVirtualMemory هي تحميل نسخة مكررة من مكتبة ntdll.dll في مساحة عنوان العملية. نظرًا لأنه يمكن تحميل مكتبتين DLL متطابقتين في نفس العملية، بشرط أن يكون لهما أسماء مختلفة، يمكننا ببساطة نسخ ملف ntdll.dll الشرعي إلى موقع آخر، وتحميله باستخدام LoadLibrary (أو إعادة تنفيذ عملية التحميل)، والوصول إلى الدالة باستخدام GetProcAddress على سبيل المثال.
هذه التقنية بسيطة جدًا في الفهم والتنفيذ، ولديها فرصة جيدة للنجاح، نظرًا لأن معظم منتجات EDR لا تعيد تثبيت الخطافات على مكتبات DLL المحملة حديثًا بمجرد تشغيل العملية. ومع ذلك، فإن العيب الرئيسي هو أن نسخ الثنائيات الموقعة من Microsoft تحت اسم مختلف غالبًا ما يعتبر مشبوهًا من قبل منتجات EDR نفسها.
ومع ذلك، تم تنفيذ هذه التقنية في EDRSandblast. للحصول على تفاصيل التنفيذ، راجع مسار الكود الخاص بوظيفة unhook() عندما تكون unhook_method هي UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY.
لاستخدام الوظائف ذات الصلة باستدعاءات النظام، يمكن لأحد البرامج إعادة تنفيذ استدعاءات النظام (في لغة التجميع) لاستدعاء ميزات نظام التشغيل المقابلة دون لمس الكود في ntdll.dll، والذي قد يتم مراقبته من قبل EDR. هذا يتجاوز تمامًا أي خطاف على مستوى المستخدم يتم إجراؤه على وظائف استدعاء النظام في ntdll.dll.
ومع ذلك، هذا له بعض العيوب. أولاً، هذا يعني القدرة على معرفة قائمة أرقام استدعاءات النظام للوظائف التي يحتاجها البرنامج، والتي تتغير لكل إصدار من Windows. يتم التخفيف من ذلك من خلال تنفيذ العديد من الاستدلالات التي من المعروف أنها تعمل في جميع الإصدارات السابقة من Windows NT (فرز صادرات Zw* الخاصة بـ ntdll، والبحث عن تعليمة mov rax, #syscall_number في دالة ntdll المرتبطة، وما إلى ذلك)، والتحقق من أنها جميعها تُرجع نفس النتيجة (راجع Syscalls.c لمزيد من التفاصيل).
أيضًا، الوظائف التي ليست تقنيًا استدعاءات نظام (مثل LoadLibraryX/LdrLoadDLL) يمكن مراقبتها أيضًا، ولا يمكن إعادة تنفيذها ببساطة باستخدام استدعاء نظام.
تقنية استدعاءات النظام المباشرة منفذة في EDRSandblast. كما ذكرنا سابقًا، تُستخدم فقط لتنفيذ NtProtectVirtualMemory بأمان، وإزالة جميع الخطافات المكتشفة.
للحصول على تفاصيل التنفيذ، راجع مسار الكود الخاص بوظيفة unhook() عندما تكون unhook_method هي UNHOOK_WITH_DIRECT_SYSCALL.
كما ذكرنا سابقًا، كل إجراء يحتاج إلى قراءة أو كتابة في ذاكرة kernel يعتمد على برنامج تشغيل ضعيف لتوفير هذه البدائية. في EDRSanblast، يمكن إضافة الدعم لبرنامج تشغيل جديد يوفر بدائية القراءة/الكتابة "بسهولة"، حيث يلزم تنفيذ ثلاث وظائف فقط:
ReadMemoryPrimitive_DRIVERNAME(SIZE_T Size, DWORD64 Address, PVOID Buffer)، تنسخ Size بايت من عنوان kernel Address إلى المخزن المؤقت للمستخدم Buffer؛WriteMemoryPrimitive_DRIVERNAME(SIZE_T Size, DWORD64 Address, PVOID Buffer)، تنسخ Size بايت من المخزن المؤقت للمستخدم Buffer إلى عنوان kernel Address؛CloseDriverHandle_DRIVERNAME() التي تضمن إغلاق جميع المقابض لبرنامج التشغيل (مطلوبة قبل عملية الإلغاء التي تكون مستقلة عن برنامج التشغيل، في الوقت الحالي).على سبيل المثال، يتم حاليًا دعم برنامجي تشغيل بواسطة EDRSandblast، RTCore64.sys (SHA256: 01AA278B07B58DC46C84BD0B1B5C8E9EE4E62EA0BF7A695862444AF32E87F1FD) و DBUtils_2_3.sys (SHA256: 0296e2ce999e67c76352613a718e11516fe1b0efc3ffdb8918fc999dd76a73a5). الكود التالي في KernelMemoryPrimitives.h يجب تحديثه إذا كان برنامج التشغيل الضعيف المستخدم بحاجة إلى التغيير، أو إذا تم تنفيذ برنامج تشغيل جديد.```C
#define RTCore 0
#define DBUtil 1
// Select the driver to use with the following #define
#define VULN_DRIVER RTCore
#if VULN_DRIVER == RTCore #define DEFAULT_DRIVER_FILE TEXT("RTCore64.sys") #define CloseDriverHandle CloseDriverHandle_RTCore #define ReadMemoryPrimitive ReadMemoryPrimitive_RTCore #define WriteMemoryPrimitive WriteMemoryPrimitive_RTCore #elif VULN_DRIVER == DBUtil #define DEFAULT_DRIVER_FILE TEXT("DBUtil_2_3.sys") #define CloseDriverHandle CloseDriverHandle_DBUtil #define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil #define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil #endif
### اكتشاف برامج تشغيل وعمليات EDR
تُستخدم حاليًا تقنيات متعددة لتحديد ما إذا كان برنامج تشغيل أو عملية معينة تنتمي
إلى منتج EDR أم لا.
أولاً، يمكن استخدام اسم برنامج التشغيل ببساطة لهذا الغرض. في الواقع، تخصص Microsoft
أرقامًا محددة تُسمى "الارتفاعات" (Altitudes) لجميع برامج التشغيل التي تحتاج إلى إدراج استدعاءات راجعة
في النواة. يتيح ذلك ترتيبًا حتميًا في تنفيذ الاستدعاءات الراجعة، بشكل مستقل عن
ترتيب التسجيل، ولكن يعتمد فقط على استخدام برنامج التشغيل. يمكن العثور على قائمة (بائعي) برامج التشغيل
التي حجزت *ارتفاعات* محددة
[على MSDN](https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/allocated-altitudes).
ونتيجة لذلك، تقدم Microsoft قائمة شاملة تقريبًا لأسماء برامج تشغيل الأمان المرتبطة بمنتجات
الأمان، بشكل أساسي في قوائم "FSFilter Anti-Virus" و"FSFilter Activity
Monitor". تم تضمين قوائم أسماء برامج التشغيل هذه في EDRSandblast، بالإضافة إلى
مساهمات إضافية.
علاوة على ذلك، غالبًا ما تكون ملفات EDR التنفيذية وDLL موقعة رقميًا باستخدام
شهادة توقيع البائع. وبالتالي، فإن التحقق من الموقّع لملف تنفيذي أو DLL مرتبط
بعملية قد يسمح بتحديد منتجات EDR بسرعة.
أيضًا، يجب أن تكون برامج التشغيل موقعة مباشرة من قبل Microsoft للسماح بتحميلها في
مساحة النواة. بينما لا يكون بائع برنامج التشغيل هو الموقّع المباشر على برنامج التشغيل نفسه،
يبدو أن اسم البائع لا يزال مضمنًا داخل سمة من التوقيع؛
ومع ذلك، لم يتم بعد التحقيق في تقنية الكشف هذه وتنفيذها.
أخيرًا، عند مواجهة EDR غير معروف لـ EDRSandblast، فإن أفضل نهج هو تشغيل
الأداة في وضع "التدقيق" (audit)، والتحقق من قائمة برامج التشغيل التي سجلت استدعاءات راجعة للنواة؛
ثم يمكن إضافة اسم برنامج التشغيل إلى القائمة، وإعادة تجميع الأداة وتشغيلها مرة أخرى.
### تجاوز RunAsPPL
آلية `حماية سلطة الأمان المحلية (LSA Protection)`، التي تم تقديمها لأول مرة
في Windows 8.1 وWindows Server 2012 R2، تستخدم تقنية `العملية الخفيفة المحمية (Protected Process
Light - PPL)` لتقييد الوصول إلى عملية `LSASS`. ينظم حماية `PPL` ويقيد العمليات، مثل حقن الذاكرة أو
تفريغ ذاكرة العمليات المحمية، حتى من عملية تمتلك صلاحية `SeDebugPrivilege`. تحت نموذج حماية العملية،
فقط العمليات التي تعمل بمستويات حماية أعلى يمكنها تنفيذ عمليات على العمليات المحمية.
هيكل `_EPROCESS`، الذي تستخدمه نواة Windows لتمثيل عملية
في ذاكرة النواة، يتضمن حقل `_PS_PROTECTION` الذي يحدد مستوى الحماية
لعملية من خلال سمات `Type` (`_PS_PROTECTED_TYPE`) و`Signer` (`_PS_PROTECTED_SIGNER`).
من خلال الكتابة في ذاكرة النواة، تستطيع عملية EDRSandblast ترقية مستوى الحماية الخاص بها
إلى `PsProtectedSignerWinTcb-Light`. يكفي هذا المستوى لتفريغ
ذاكرة عملية `LSASS`، لأنه "يسيطر" على `PsProtectedSignerLsa-Light`،
مستوى الحماية لعملية `LSASS` التي تعمل بآلية `RunAsPPL`.
تنفذ `EDRSandBlast` الحماية الذاتية على النحو التالي:
- فتح مقبض (handle) للعملية الحالية
- تسريب جميع مقابض النظام باستخدام `NtQuerySystemInformation` للعثور على المقبض المفتوح
على العملية الحالية، وعنوان هيكل `EPROCESS` الخاص بالعملية الحالية في ذاكرة النواة.
- استخدام ثغرة القراءة / الكتابة العشوائية لبرنامج تشغيل `Micro-Star MSI
Afterburner` للكتابة فوق حقل `_PS_PROTECTION` الخاص بالعملية
الحالية في ذاكرة النواة. يتم حساب إزاحات حقل `_PS_PROTECTION`
بالنسبة لهيكل `EPROCESS` (المحددة بواسطة إصدار `ntoskrnl` المستخدم)
في ملف `NtoskrnlOffsets.csv`.
### تجاوز Credential Guard
`Microsoft Credential Guard` هي تقنية عزل قائمة على المحاكاة الافتراضية،
تم تقديمها في `Windows 10 (إصدار Enterprise)` من Microsoft مما يمنع
الوصول المباشر إلى بيانات الاعتماد المخزنة في عملية `LSASS`.
عند تنشيط `Credentials Guard`، يتم إنشاء عملية `LSAIso` (*LSA معزولة*) في
`الوضع الآمن الافتراضي (Virtual Secure Mode)`، وهي ميزة تستخدم امتدادات
المحاكاة الافتراضية لوحدة المعالجة المركزية لتوفير أمان إضافي للبيانات في الذاكرة. الوصول إلى
عملية `LSAIso` مقيد حتى للوصول بسياق الأمان `NT AUTHORITY\SYSTEM`. عند معالجة تجزئة (hash)، تقوم عملية `LSA`
بإجراء استدعاء `RPC` إلى عملية `LSAIso`، وتنتظر
نتيجة `LSAIso` للمتابعة. وبالتالي، لن تحتوي عملية `LSASS` على أي
أسرار وستخزن بدلاً من ذلك `بيانات LSA المعزولة (LSA Isolated Data)`.
كما ورد في الأبحاث الأصلية التي أجراها `N4kedTurtle`: "يمكن تمكين `Wdigest`
على نظام مع Credential Guard عن طريق تصحيح قيم
`g_fParameter_useLogonCredential` و`g_IsCredGuardEnabled` في الذاكرة".
سيؤدي تنشيط `Wdigest` إلى تخزين بيانات الاعتماد بنص واضح في
ذاكرة `LSASS` لأي تسجيلات دخول تفاعلية جديدة (دون الحاجة إلى إعادة تشغيل
النظام). راجع
[منشور المدونة البحثي الأصلي](https://teamhydra.blog/2020/08/25/bypassing-credential-guard/)
لمزيد من التفاصيل حول هذه التقنية.
تجعل `EDRSandBlast` ببساطة PoC الأصلي أكثر ملاءمة من حيث الأمان العملياتي (opsec) وتوفر
دعمًا لعدد من إصدارات `wdigest.dll` (من خلال الإزاحات المحسوبة
لـ `g_fParameter_useLogonCredential` و`g_IsCredGuardEnabled`).
### استرجاع الإزاحات
من أجل تنفيذ عمليات تجاوز مراقبة النواة بشكل موثوق، يحتاج EDRSandblast
إلى معرفة بالضبط أين يقرأ ويكتب ذاكرة النواة. يتم ذلك باستخدام إزاحات
المتغيرات العالمية داخل الصورة المستهدفة (ntoskrnl.exe, wdigest.dll)، بالإضافة إلى إزاحة
حقول محددة في الهياكل التي تنشر تعريفاتها Microsoft في ملفات الرموز.
هذه الإزاحات خاصة بكل بناء للصور المستهدفة، ويجب جمعها
مرة واحدة على الأقل لإصدار منصة معينة.
تبرير استخدام الإزاحات "المشفرة بشكل ثابت" (hardcoded) بدلاً من عمليات البحث عن الأنماط (pattern searches) لتحديد موقع الهياكل
والمتغيرات المستخدمة بواسطة EDRSandblast هو حقيقة أن واجهات برمجة التطبيقات غير الموثقة
المسؤولة عن إضافة / إزالة استدعاءات النواة قابلة للتغيير وأن أي محاولة
لقراءة أو كتابة ذاكرة النواة في عنوان خاطئ قد يؤدي (وغالبًا ما يؤدي) إلى
`فحص خطأ (Bug Check)` (`شاشة الموت الزرقاء`). تعطل الجهاز غير مقبول في سيناريوهات
الاختراق الأحمر (red-teaming) واختبار الاختراق العادي، لأن الجهاز الذي يتعطل
يمكن رؤيته بسهولة من قبل المدافعين، وسيفقد أي بيانات اعتماد كانت لا تزال في الذاكرة
في لحظة الهجوم.
لاسترجاع الإزاحات لكل إصدار محدد من Windows، تم تنفيذ طريقتين.
#### استرجاع الإزاحة يدويًا
يمكن استخراج إزاحات `ntoskrnl.exe` و`wdigest.dll` المطلوبة باستخدام
البرنامج النصي Python المقدم `ExtractOffsets.py`، الذي يعتمد على `radare2`
و `r2pipe` لتنزيل وتحليل الرموز من ملفات PDB، واستخراج الإزاحات اللازمة
منها. يتم بعد ذلك تخزين الإزاحات في ملفات CSV لاستخدامها لاحقًا من قبل EDRSandblast.
لدعم مجموعة واسعة من إصدارات Windows بشكل جاهز، تتم الإشارة إلى العديد من إصدارات
ملفات `ntoskrnl.exe` و`wdigest.dll` بواسطة
[Winbindex](https://winbindex.m417z.com/) ، ويمكن تنزيلها تلقائيًا
(واستخراج إزاحاتها) بواسطة `ExtractOffsets.py`. يتيح ذلك استخراج الإزاحات
من جميع الملفات تقريبًا التي تم نشرها على الإطلاق في حزم تحديثات Windows (حتى الآن 450+
نسخة من `ntoskrnl.exe` و 30+ نسخة من `wdigest.dll` متاحة ومحسوبة مسبقًا).
#### استرجاع الإزاحة تلقائيًا وتحديثها
تم تنفيذ خيار إضافي في `EDRSandBlast` للسماح للبرنامج
بتنزيل ملفات `.pdb` اللازمة بنفسه من خادم رموز Microsoft (Microsoft Symbol Server)، واستخراج
الإزاحات المطلوبة، وحتى تحديث ملفات `.csv` المقابلة إذا كانت موجودة.
استخدام الخيار `--internet` يجعل تنفيذ الأداة أبسط بكثير، مع تقديم
مخاطر أمان عملياتي (OpSec) إضافية، حيث يتم تنزيل ملف `.pdb` وإسقاطه على القرص أثناء
العملية. هذا مطلوب بواسطة وظائف `dbghelp.dll` المستخدمة لتحليل قاعدة بيانات
الرموز؛ ومع ذلك، قد يتم تنفيذ تحليل PDB كامل في الذاكرة في المستقبل
لإلغاء هذا المطلب وتقليل بصمة الأداة.
## الاستخدام
يمكن الحصول على برنامج التشغيل الضعيف `RTCore64.sys` من:```
http://download-eu2.guru3d.com/afterburner/%5BGuru3D.com%5D-MSIAfterburnerSetup462Beta2.zip
Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard> [--usermode [--unhook-method ]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll ]* [-o | --dump-output <DUMP_FILE>]
### الخيارات```
-h | --help Show this help message and exit.
-v | --verbose Enable a more verbose output.
Actions mode:
audit Display the user-land hooks and / or Kernel callbacks without taking actions.
dump Dump the LSASS process, by default as 'lsass' in the current directory or at the
specified file using -o | --output <DUMP_FILE>.
cmd Open a cmd.exe prompt.
credguard Patch the LSASS process' memory to enable Wdigest cleartext passwords caching even if
Credential Guard is enabled on the host. No kernel-land actions required.
--usermode Perform user-land operations (DLL unhooking).
--kernelmode Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).
--unhook-method <N>
Choose the userland un-hooking technique, from the following:
1 (Default) Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all
present userland hooks.
2 Constructs a 'unhooked' (i.e. unmonitored) version of NtProtectVirtualMemory, by
allocating an executable trampoline jumping over the hook, and remove all present
userland hooks.
3 Searches for an existing trampoline allocated by the EDR itself, to get an 'unhooked'
(i.e. unmonitored) version of NtProtectVirtualMemory, and remove all present userland
hooks.
4 Loads an additional version of ntdll library into memory, and use the (hopefully
unmonitored) version of NtProtectVirtualMemory present in this library to remove all
present userland hooks.
5 Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory,
and uses it to remove all detected hooks
Other options:
--dont-unload-driver Keep the vulnerable driver installed on the host
Default to automatically unsinstall the driver.
--dont-restore-callbacks Do not restore the EDR drivers' Kernel Callbacks that were removed.
Default to restore the callbacks.
--driver <RTCore64.sys> Path to the vulnerable driver file.
Default to 'RTCore64.sys' in the current directory.
--service <SERVICE_NAME> Name of the vulnerable service to intall / start.
--nt-offsets <NtoskrnlOffsets.csv> Path to the CSV file containing the required ntoskrnl.exe's offsets.
Default to 'NtoskrnlOffsets.csv' in the current directory.
--wdigest-offsets <WdigestOffsets.csv> Path to the CSV file containing the required wdigest.dll's offsets
(only for the 'credguard' mode).
Default to 'WdigestOffsets.csv' in the current directory.
--add-dll <dll name or path> Loads arbitrary libraries into the process' address space, before starting
anything. This can be useful to audit userland hooking for DLL that are not
loaded by default by this program. Use this option multiple times to load
multiple DLLs all at once.
Example of interesting DLLs to look at: user32.dll, ole32.dll, crypt32.dll,
samcli.dll, winhttp.dll, urlmon.dll, secur32.dll, shell32.dll...
-o | --output <DUMP_FILE> Output path to the dump file that will be generated by the 'dump' mode.
Default to 'lsass' in the current directory.
-i | --internet Enables automatic symbols download from Microsoft Symbol Server
If a corresponding *Offsets.csv file exists, appends the downloaded offsets to the file for later use
OpSec warning: downloads and drops on disk a PDB file for ntoskrnl.exe and/or wdigest.dll
EDRSandBlast (x64 فقط) تم بناؤه على Visual Studio 2019 (Windows SDK
الإصدار: 10.0.19041.0 ومجموعة الأدوات الأساسية: Visual Studio 2019 (v142)).
لاحظ أن ExtractOffsets.py تم اختباره فقط على Windows.```
pip.exe install -m .\requirements.txt
ExtractOffsets.py [-h] -i INPUT [-o OUTPUT] [-d] mode
positional arguments: mode ntoskrnl or wdigest. Mode to download and extract offsets for either ntoskrnl or wdigest
optional arguments: -h, --help show this help message and exit -i INPUT, --input INPUT Single file or directory containing ntoskrnl.exe / wdigest.dll to extract offsets from. If in download mode, the PE downloaded from MS symbols servers will be placed in this folder. -o OUTPUT, --output OUTPUT CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be downloaded / analyzed. Defaults to NtoskrnlOffsets.csv / WdigestOffsets.csv in the current folder. -d, --download Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.
## الكشف
من وجهة نظر المدافع (بائع EDR، Microsoft، محللو SOC الذين ينظرون إلى بيانات EDR عن بعد، ...)، يمكن استخدام مؤشرات متعددة لاكتشاف أو منع هذا النوع من التقنيات.
### قائمة السماح للسائقين
نظرًا لأن كل إجراء يقوم به الأداة في ذاكرة وضع النواة يعتمد على سائق ضعيف لقراءة/كتابة محتوى عشوائي، يجب فحص أحداث تحميل السائقين بدقة بواسطة منتج EDR (أو محللي SOC)، وإصدار تنبيه عند أي تحميل سائق غير شائع، أو حتى حظر السائقين الضعفاء المعروفين. هذا الأسلوب الأخير موصى به حتى [من قبل Microsoft نفسها](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-driver-block-rules): أي جهاز Windows مزوّد بـ HVCI (*حماية سلامة الشيفرة المحمية بواسطة برنامج المراقبة الافتراضي*) يحتوي على قائمة حظر للسائقين، وسيصبح هذا السلوك تدريجيًا افتراضيًا على Windows (وهو بالفعل كذلك على Windows 11).
### فحوصات سلامة ذاكرة النواة
نظرًا لأن المهاجم قد يستخدم سائقًا ضعيفًا غير معروف لتنفيذ نفس الإجراءات في الذاكرة، يمكن لسائق EDR التحقق دوريًا من أن عمليات الاسترجاع الخاصة بالنواة لا تزال مسجلة، إما عن طريق فحص ذاكرة النواة مباشرة (كما تفعل هذه الأداة)، أو ببساطة عن طريق تشغيل أحداث (إنشاء عملية، إنشاء خيط، تحميل صورة، إلخ) والتحقق من أن دوال الاسترجاع تتم استدعاؤها بالفعل بواسطة النواة التنفيذية.
كملاحظة جانبية، يمكن حماية هذا النوع من بنية البيانات عبر آلية [حماية بيانات النواة (KDP)](https://www.microsoft.com/security/blog/2020/07/08/introducing-kernel-data-protection-a-new-platform-security-technology-for-preventing-data-corruption/)، التي تعتمد على الأمان القائم على الظاهرية، لجعل مصفوفة استرجاعات النواة غير قابلة للكتابة دون استدعاء واجهات برمجة التطبيقات الصحيحة.
يمكن تطبيق نفس المنطق على متغيرات ETW الحساسة مثل `ProviderEnableInfo`، التي تسيء الأداة استخدامها لتعطيل توليد أحداث استخبارات التهديدات الخاصة بـ ETW.
### الكشف في وضع المستخدم
المؤشر الأول على أن عملية تحاول بنشاط تجنب اختراق وضع المستخدم هو عمليات الوصول إلى الملفات لكل DLL يقابل الوحدات المحملة؛ في التنفيذ العادي، نادرًا ما تحتاج عملية وضع المستخدم إلى قراءة ملفات DLL خارج استدعاء `LoadLibrary`، خاصة `ntdll.dll`.
من أجل حماية اختراق API من الالتفاف، يمكن لمنتجات EDR التحقق دوريًا من عدم تغيير الخطافات في الذاكرة، داخل كل عملية مراقبة.
أخيرًا، لاكتشاف تجاوز الاختراق (إساءة استخدام الترامبولين، استخدام استدعاءات النظام المباشرة، إلخ) الذي لا يتضمن إزالة الخطافات، يمكن لمنتجات EDR الاعتماد على استرجاعات النواة المرتبطة باستدعاءات النظام المسيء استخدامها (مثل `PsCreateProcessNotifyRoutine` لاستدعاء النظام `NtCreateProcess`، `ObRegisterCallbacks` لاستدعاء النظام `NtOpenProcess`، إلخ)، وإجراء تحليل لمكدس الاستدعاءات في وضع المستخدم لتحديد ما إذا كان استدعاء النظام تم تشغيله من مسار طبيعي (`kernel32.dll` -> `ntdll.dll` -> استدعاء النظام) أم مسار غير طبيعي (مثل `program.exe` -> استدعاء نظام مباشر).
## شكر وتقدير
- تعيين استرجاعات النواة وإزالتها:
https://github.com/br-sn/CheekyBlinder
- أوليات القراءة/الكتابة لذاكرة النواة من خلال السائق الضعيف
`Micro-Star MSI Afterburner`:
https://github.com/Barakat/CVE-2019-16098/
- تعطيل مزود استخبارات التهديدات لـ ETW:
https://public.cnotools.studio/bring-your-own-vulnerable-kernel-driver-byovkd/exploits/data-only-attack-neutralizing-etwti-provider
- تثبيت/إزالة السائق: https://github.com/gentilkiwi/mimikatz
- قائمة أولية بأسماء سائقين EDR:
https://github.com/SadProcessor/SomeStuff/blob/master/Invoke-EDRCheck.ps1
- تجاوز Credential Guard عن طريق إعادة تمكين `Wdigest` من خلال تصحيح ذاكرة `LSASS`:
https://teamhydra.blog/2020/08/25/bypassing-credential-guard/
## المؤلفون
[Thomas DIOT (Qazeer)](https://github.com/Qazeer/)
[Maxime MEIGNAN (themaks)](https://github.com/themaks)
## الترخيص
رخصة CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/