Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
EDRSandblast-GodFault — EDRSandblast-GodFault | Kitploit
도구/GitHubGitHub/gabriellandau/edrsandblast-godfault
Defensive ToolsPrivilege EscalationMemory ForensicsExploitationPost-ExploitationRed TeamingPayload DevelopmentArchived
GitHubgabriellandau/edrsandblast-godfault

EDRSandblast-GodFault

EDRSandblast-GodFault

저장소 보기
273502년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

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!

================================================== Starting a new unmonitored process...

[!] 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>

root@kitploit:~
# EDRSandBlast

`EDRSandBlast`는 취약한 서명된 드라이버를 무기화하여 EDR 탐지(Notify Routine 콜백, Object Callbacks 및 `ETW TI` 공급자)와 `LSASS` 보호를 우회하는 `C`로 작성된 도구입니다. 또한 여러 사용자 모드 언후킹 기술이 구현되어 사용자 모드 모니터링을 회피합니다.

릴리스 시점 기준으로, 사용자 모드(`--usermode`) 및 커널 모드(`--kernelmode`) 기술의 조합을 사용하여 EDR 감시 하에 `LSASS` 메모리를 덤프했으며, 제품(클라우드) 콘솔에서 차단되거나 "OS Credential Dumping" 관련 이벤트를 생성하지 않았습니다. 테스트는 3개의 다른 EDR 제품에서 수행되었으며 각각 성공했습니다.

## 설명

### 커널 Notify Routines 제거를 통한 EDR 우회

EDR 제품은 Windows에서 커널 "Notify Routines" 콜백을 사용하여 프로세스 및 스레드 생성, 이미지(`exe` / `DLL`) 로딩과 같은 시스템 활동을 커널로부터 알림 받습니다.

이러한 커널 콜백은 일반적으로 콜백을 구현하는 드라이버가 문서화된 API(`nt!PsSetCreateProcessNotifyRoutine`, `nt!PsSetCreateThreadNotifyRoutine` 등)를 사용하여 커널 영역에서 정의됩니다. 이러한 API는 커널 공간에 있는 문서화되지 않은 루틴 배열에 드라이버가 제공하는 콜백 루틴을 추가합니다:
  - 프로세스 생성을 위한 `PspCreateProcessNotifyRoutine`
  - 스레드 생성을 위한 `PspCreateThreadNotifyRoutine`
  - 이미지 로딩을 위한 `PspLoadImageNotifyRoutine`

`EDRSandBlast`는 해당 배열에 정의된 루틴을 열거하고, 사전 정의된 EDR 드라이버 목록(1000개 이상의 보안 제품 드라이버 지원, [EDR 드라이버 탐지 섹션](#edr-drivers-and-processes-detection) 참조)과 연결된 모든 콜백 루틴을 제거합니다. 열거 및 제거는 취약한 드라이버의 악용을 통해 제공되는 임의의 커널 메모리 읽기/쓰기 프리미티브를 사용하여 가능해집니다([취약한 드라이버 섹션](#vulnerable-drivers-detection) 참조).

앞서 언급된 배열의 오프셋은 여러 기술을 사용하여 복구되며, [오프셋 섹션](#ntoskrnl-and-wdigest-offsets)을 참조하십시오.

### Object Callbacks 제거를 통한 EDR 우회
EDR(및 EPP) 제품은 종종 `nt!ObRegisterCallbacks` 커널 API를 사용하여 "Object callbacks"를 등록합니다. 이러한 콜백을 통해 보안 제품은 특정 객체 유형(프로세스, 스레드 및 데스크톱 관련 객체 콜백은 이제 Windows에서 지원됨)에 대한 각 핸들 생성 시 알림을 받을 수 있습니다. 핸들 생성은 객체 열기(`OpenProcess`, `OpenThread` 등의 호출) 및 핸들 복제(`DuplicateHandle` 등의 호출) 시 발생할 수 있습니다.

이러한 각 작업에서 커널이 알림을 받음으로써 보안 제품은 핸들 생성의 적법성을 분석하고(예: 알 수 없는 프로세스가 LSASS를 열려고 시도), 위협이 감지되면 차단할 수도 있습니다.

`ObRegisterCallbacks`를 사용한 각 콜백 등록 시, 콜백의 영향을 받는 객체 유형(프로세스, 스레드 또는 데스크톱)을 설명하는 `_OBJECT_TYPE` 객체에 있는 `CallbackList` 이중 연결 리스트에 새 항목이 추가됩니다. 불행히도 이러한 항목은 Microsoft에서 문서화하거나 기호 파일에 게시하지 않은 구조체로 설명됩니다. 그러나 다양한 `ntoskrnl.exe` 버전에서 이를 연구한 결과, 이 구조체는 (최소한) Windows 10 빌드 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;

root@kitploit:~
EDR에 등록된 객체 콜백을 비활성화하기 위해 `EDRSandblast`에는 세 가지 기법이 구현되어 있습니다. 그러나 현재는 하나만 활성화되어 있습니다.

#### `OB_CALLBACK_ENTRY`의 `Enabled` 필드 사용
이는 `EDRSandblast`의 기본 활성화 기법입니다. EDR 관련 객체 콜백을 탐지하고 비활성화하기 위해 *Process* 및 *Thread* 유형에 연결된 `_OBJECT_TYPE` 객체에 위치한 `CallbackList` 목록을 탐색합니다. 두 `_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;
}

CallbackList의 LIST_ENTRY에 대한 Flink 및 Blink 포인터가 LIST_ENTRY 자체를 가리키도록 만들면 리스트가 효과적으로 비워집니다. _OBJECT_TYPE 구조체가 커널 심볼에 공개되어 있으므로 이 기술은 하드코딩된 오프셋이나 구조체에 의존하지 않습니다. 하지만 몇 가지 단점이 있습니다.

첫 번째 단점은 EDR의 콜백만 비활성화할 수 없다는 것입니다. 실제로 이 기술은 "합법적인" 소프트웨어에 의해 등록되었을 수 있는 모든 객체 콜백에 영향을 미칩니다. 그럼에도 불구하고 Windows 10 (현재 작성 시점 기준)에서 객체 콜백은 사전 설치된 구성 요소에서 사용되지 않으므로 비활성화해도 시스템 안정성에 영향을 미치지 않아야 합니다 (비활성화가 일시적인 경우 더욱 그렇습니다).

두 번째 단점은 프로세스 또는 스레드 핸들 작업이 OS의 정상적인 기능에서 매우 빈번하다는 것입니다. 따라서 사용되는 커널 쓰기 프리미티브가 QWORD 쓰기를 "원자적으로" 수행할 수 없는 경우, _OBJECT_TYPE.CallbackList.Flink 포인터가 덮어쓰기 도중 커널에 의해 접근될 가능성이 높습니다. 예를 들어, MSI 취약 드라이버 RTCore64.sys는 한 번에 DWORD 쓰기만 수행할 수 있으므로 포인터를 덮어쓰려면 2개의 별도 IOCTL이 필요하며, 그 사이에 커널이 이를 사용할 확률이 높습니다 (충돌 발생). 반면에 취약한 DELL 드라이버 DBUtil_2_3.sys는 하나의 IOCTL에서 임의 크기의 쓰기를 수행할 수 있으므로 이 방법을 사용해도 충돌 위험이 없습니다.

객체 콜백 완전 비활성화

마지막으로 찾은 한 가지 기술은 스레드와 프로세스에 대한 객체 콜백 지원을 완전히 비활성화하는 것입니다. 프로세스와 스레드 유형에 해당하는 _OBJECT_TYPE 구조체 내부에는 문서화된 _OBJECT_TYPE_INITIALIZER 구조체를 따르는 TypeInfo 필드가 있습니다. 후자에는 ObjectTypeFlags 비트 필드가 포함되어 있으며, 그 SupportsObjectCallbacks 플래그는 설명된 객체 유형(Process, Thread, Desktop, Token, File 등)이 객체 콜백 등록을 지원하는지 여부를 결정합니다. 앞서 언급했듯이 현재 Windows 설치에서는 Process, Thread 및 Desktop 객체 유형만 이러한 콜백을 지원합니다.

SupportsObjectCallbacks 비트는 ObpCreateHandle 또는 ObDuplicateObject가 CallbackList를 읽기 전에 (그리고 당연히 콜백을 실행하기 전에) 검사하므로, 커널 런타임에 이 비트를 플립하면 모든 객체 콜백 실행이 효과적으로 비활성화됩니다.

이 방법의 주요 단점은 KPP("PatchGuard")가 일부 (전부?) _OBJECT_TYPE 구조체의 무결성을 모니터링하고, 매개변수 4가 0x8인 0x109 Bug Check를 트리거한다는 것입니다. 이는 객체 유형 구조체가 변경되었음을 의미합니다.

그러나 비활성화/재활성화(그리고 그 사이의 "악의적인" 작업)를 충분히 빠르게 수행하면 PatchGuard를 "앞서갈" 수 있어야 합니다 (운이 나빠서 주기적인 검사가 잘못된 시점에 수행되지 않는 한).

ETW Microsoft-Windows-Threat-Intelligence 공급자 비활성화를 통한 EDR 우회

ETW Microsoft-Windows-Threat-Intelligence 공급자는 일반적으로 악의적으로 사용되는 일부 Windows API 사용에 대한 데이터를 기록합니다. 여기에는 nt!MiReadWriteVirtualMemory API가 포함되며, 이는 nt!NtReadVirtualMemory에 의해 호출되고 (LSASS 메모리 덤프에 사용됨) nt!EtwTiLogReadWriteVm 함수에 의해 모니터링됩니다.

EDR 제품은 각각 SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT 또는 PS_PROTECTED_ANTIMALWARE_LIGHT로 실행되고 ELAM (Early Launch Anti Malware) 드라이버와 연결된 서비스 또는 프로세스를 통해 ETW TI 공급자가 생성한 로그를 소비할 수 있습니다.

slaeryan의 CNO Development Labs 블로그 게시물에 게시된 바와 같이, ETW TI 공급자는 커널 메모리에서 해당 ProviderEnableInfo 속성을 0x0으로 패치하여 완전히 비활성화할 수 있습니다. 자세한 내용은 위의 훌륭한 블로그 게시물을 참조하십시오.

커널 콜백 제거와 유사하게, 필요한 ntoskrnl.exe 오프셋(nt!EtwThreatIntProvRegHandleOffset, _ETW_REG_ENTRY의 GuidEntry, _ETW_GUID_ENTRY의 ProviderEnableInfo)은 다양한 Windows 커널 버전에 대해 NtoskrnlOffsets.csv 파일에서 계산됩니다.

사용자랜드 후킹 우회를 통한 EDR 우회

사용자랜드 후킹 작동 방식

프로세스가 수행하는 작업을 쉽게 모니터링하기 위해 EDR 제품은 종종 사용자랜드 후킹이라는 메커니즘을 배포합니다. 먼저 EDR 제품은 커널 콜백(일반적으로 이미지 로딩 또는 프로세스 생성 콜백, 위 참조)을 등록하여 각 프로세스 시작 시 알림을 받습니다.

Windows에서 프로세스가 로드되고 실제로 시작되기 전에 EDR은 모니터링 로직이 포함된 일부 사용자 정의 DLL을 프로세스 주소 공간에 주입할 수 있습니다. 로딩 중에 이 DLL은 EDR이 모니터링할 모든 함수의 시작 부분에 "후크"를 주입합니다. 런타임 시, 감시 중인 프로세스가 모니터링되는 함수를 호출하면 이러한 후크는 제어 흐름을 EDR의 DLL에 있는 일부 감독 코드로 리디렉션하여 이러한 호출의 인수와 반환 값을 검사할 수 있도록 합니다.

대부분의 경우 모니터링되는 함수는 ntdll.dll에 구현이 있는 시스템 호출(예: NtReadVirtualMemory, NtOpenProcess 등)입니다. Nt* 함수 호출을 가로채면 제품이 사용자랜드/커널랜드 경계에 최대한 가깝게 위치할 수 있지만 (사용자랜드에 남아 있음) 일부 상위 수준 DLL의 함수도 모니터링될 수 있습니다.

다음은 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

root@kitploit:~
(No input provided.)```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			

Hooks detection

Userland hooks는 사용자 영역 메모리에 위치한다는 "약점"을 가지고 있습니다. 즉, 검사 대상 프로세스가 직접 관찰하고 수정할 수 있다는 뜻입니다. 프로세스 주소 공간에서 후크를 자동으로 감지하기 위한 주요 아이디어는 디스크 상의 원본 DLL과 EDR에 의해 잠재적으로 변경된 메모리 상의 라이브러리 간의 차이를 비교하는 것입니다. 이 비교를 수행하기 위해 EDRSandblast는 다음 단계를 따릅니다:

  • 로드된 모든 DLL 목록은 PEB에 있는 InLoadOrderModuleList를 통해 열거됩니다 (모니터링되거나 의심스러울 수 있는 API 호출을 피하기 위해).
  • 로드된 각 DLL에 대해 디스크 상의 내용을 읽고 헤더를 구문 분석합니다. 메모리 상의 해당 라이브러리도 구문 분석하여 섹션, 내보내기 등을 식별합니다.
  • DLL의 재배치를 구문 분석하고 해당 로드된 라이브러리의 기본 주소를 고려하여 적용합니다. 이를 통해 메모리 내 라이브러리와 디스크에서 가져온 DLL의 내용이 (재배치가 적용된 섹션에서) 정확히 동일해져 비교가 신뢰할 수 있게 됩니다.
  • 내보낸 함수를 열거하고 "메모리 내" 버전과 "디스크 상" 버전의 첫 번째 바이트를 비교합니다. 차이가 발견되면 DLL이 로드된 후에 변경이 이루어졌음을 나타내며, 이는 거의 확실히 EDR 후크입니다.

참고: 이 프로세스는 내보낸 함수의 시작 부분뿐만 아니라 쓰기 불가능한 섹션의 모든 위치에서 차이를 찾도록 일반화할 수 있습니다. 예를 들어 EDR 제품이 함수 중간에 후크를 적용하기 시작하는 경우에도 가능합니다 :) 따라서 도구에서 사용되지는 않지만, findDiffsInNonWritableSections에 구현되어 있습니다.

이러한 후크가 수행하는 모니터링을 우회하기 위해 여러 가지 기술이 가능하며, 각각 장단점이 있습니다.

후크 우회: ... 언후킹 사용

후크 기반 모니터링을 우회하는 가장 직관적인 방법은 후크를 제거하는 것입니다. 후크는 프로세스 자체가 접근할 수 있는 메모리에 존재하므로, 후크를 제거하기 위해 프로세스는 간단히 다음을 수행할 수 있습니다:

  • 후크가 있는 페이지의 권한 변경 (RX -> RWX 또는 RW)
  • 디스크 DLL 내용을 통해 알려진 원래 바이트 쓰기
  • 권한을 다시 RX로 변경

이 접근 방식은 비교적 간단하며, 감지된 모든 후크를 한 번에 제거하는 데 사용할 수 있습니다. 공격 도구가 시작될 때 수행되면, 나머지 코드는 후킹 메커니즘을 완전히 인지하지 못하고 모니터링 없이 정상적으로 실행될 수 있습니다.

그러나 두 가지 주요 단점이 있습니다. EDR이 NtProtectVirtualMemory의 사용을 모니터링할 가능성이 높으므로, 이를 사용하여 후크가 설치된 페이지의 권한을 변경하는 것은 (개념적으로라도) 나쁜 생각입니다. 또한, EDR이 스레드를 실행하여 주기적으로 후크의 무결성을 확인하는 경우, 이 또한 탐지를 유발할 수 있습니다.

구현 세부 사항은 unhook_method가 UNHOOK_WITH_NTPROTECTVIRTUALMEMORY일 때의 unhook() 함수 코드 경로를 확인하십시오.

중요 참고: 단순화를 위해 이 기술은 EDRSandblast에서 다른 우회 기술을 시연하기 위한 기본 기술로 구현되었습니다; 각 기술은 모니터링되지 않는 버전의 NtProtectVirtualMemory를 얻는 방법을 보여주지만, 이후에는 동일한 작업 (특정 후크 언후킹)을 수행합니다.

사용자 정의 트램펄린을 사용한 후크 우회

특정 후크를 우회하려면 간단히 "점프"하여 함수의 나머지 부분을 그대로 실행할 수 있습니다. 먼저, EDR이 후크를 설치하기 위해 덮어쓴 모니터링 대상 함수의 원래 바이트를 DLL 파일에서 복구해야 합니다. 이전 코드 예제에서 이는 다음 명령어에 해당하는 바이트입니다:```assembly mov r10, rcx mov eax, 50h

root@kitploit:~
이 바이트들을 식별하는 것은 앞서 설명한 대로 라이브러리의 메모리 버전과 디스크 버전을 깔끔하게 *diff*할 수 있기 때문에 간단한 작업입니다. 그런 다음, 훅 직후에 오는 코드, 즉 `NtProtectVirtualMemory + sizeof(overwritten_instructions)` 주소로 제어 흐름을 리디렉션하도록 구성된 점프 명령어를 조립합니다.```assembly
jmp NtProtectVirtualMemory+8

마지막으로, 이 opcode들을 연결하여 (새로) 실행 가능한 메모리에 저장하고 그에 대한 포인터를 유지합니다. 이 객체를 "트램펄린"이라고 하며, 원래의 NtProtectVirtualMemory 함수와 완전히 동등한 함수 포인터로 사용할 수 있습니다.

이 기술의 주요 장점은 이후의 모든 기술들과 마찬가지로, 후크가 절대 지워지지 않아 EDR이 후크에 대해 수행하는 무결성 검사를 통과해야 한다는 점입니다. 하지만, 쓰기 가능한 메모리를 할당한 후 실행 가능한 메모리로 전환해야 하므로, 이는 일반적인 셸코드 할당 방식이어서 EDR의 감시를 받을 수 있습니다.

구현 세부 사항은 unhook() 함수의 코드 경로에서 unhook_method가 UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE인 경우를 확인하십시오. 이 기술은 우리 구현에서만 시연되며, 결국 이후의 모든 기술과 마찬가지로 메모리에서 후크를 제거하는 데 사용된다는 점을 기억하십시오.

자체 EDR 트램펄린을 사용한 후크 우회

EDR 제품은 후크가 작동하려면 제거한 opcode를 메모리 어딘가에 저장해야 합니다. 최악의 경우 (또는 공격자 관점에서 "더 나은"), 원래 명령어를 효과적으로 사용하기 위해 EDR은 호출을 가로챈 후 원래 함수를 실행하기 위해 어딘가에 트램펄린을 자체적으로 할당했을 가능성이 높습니다.

이 트램펄린을 검색하여 후크된 함수의 대체로 사용할 수 있으며, 실행 가능한 메모리를 할당하거나 무해한 함수로 모니터링되지 않을 가능성이 높은 VirtualQuery를 제외한 API를 호출할 필요가 없습니다.

메모리에서 트램펄린을 찾기 위해 VirtualQuery를 사용하여 전체 주소 공간을 탐색하며 커밋되고 실행 가능한 메모리를 찾습니다. 이러한 각 메모리 영역에 대해, 덮어쓰여진 명령어 다음의 주소(이전 예제의 NtProtectVirtualMemory+8)를 대상으로 하는 점프 명령어를 찾기 위해 스캔합니다. 그러면 트램펄린을 사용하여 후크를 트리거하지 않고 후크된 함수를 호출할 수 있습니다.

이 기술은 테스트된 EDR에서 거의 모든 트램펄린을 복구할 수 있어 놀라울 정도로 잘 작동합니다. 구현 세부 사항은 unhook() 함수의 코드 경로에서 unhook_method가 UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE인 경우를 확인하십시오.

중복 DLL을 사용한 후크 우회

모니터링되지 않는 NtProtectVirtualMemory 함수 버전에 접근하는 또 다른 간단한 방법은 ntdll.dll 라이브러리의 중복 버전을 프로세스 주소 공간에 로드하는 것입니다. 이름이 다른 경우 동일한 DLL 두 개를 동일한 프로세스에 로드할 수 있으므로, 합법적인 ntdll.dll 파일을 다른 위치에 복사하고 LoadLibrary를 사용하여 로드하거나 로드 과정을 재구현한 다음, 예를 들어 GetProcAddress를 사용하여 함수에 접근할 수 있습니다.

이 기술은 이해하고 구현하기 매우 간단하며 성공 가능성이 상당히 높습니다. 대부분의 EDR 제품은 프로세스가 실행 중일 때 새로 로드된 DLL에 후크를 다시 설치하지 않기 때문입니다. 그러나 주요 단점은 Microsoft 서명된 바이너리를 다른 이름으로 복사하는 것 자체가 EDR 제품에 의해 의심스러운 것으로 간주되는 경우가 많다는 점입니다.

그럼에도 불구하고 이 기술은 EDRSandblast에 구현되어 있습니다. 구현 세부 사항은 unhook() 함수의 코드 경로에서 unhook_method가 UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY인 경우를 확인하십시오.

직접 시스템 콜을 사용한 후크 우회

시스템 콜 관련 함수를 사용하기 위해, 프로그램은 EDR에 의해 모니터링될 수 있는 ntdll.dll의 코드를 실제로 건드리지 않고 해당 OS 기능을 호출하기 위해 (어셈블리로) 시스템 콜을 재구현할 수 있습니다. 이는 ntdll.dll의 시스템 콜 함수에 대해 수행된 모든 사용자 영역 후킹을 완전히 우회합니다.

하지만 여기에는 몇 가지 단점이 있습니다. 첫째, 프로그램이 필요로 하는 함수의 시스템 콜 번호 목록을 알고 있어야 한다는 점입니다. 이 번호는 Windows 버전마다 변경됩니다. 그러나 이는 과거 Windows NT 버전 모두에서 작동하는 것으로 알려진 여러 휴리스틱을 구현하고(예: ntdll의 Zw* 내보내기 정렬, 관련 ntdll 함수에서 mov rax, #syscall_number 명령어 검색 등) 이들이 모두 동일한 결과를 반환하는지 확인함으로써 완화됩니다(자세한 내용은 Syscalls.c 참조).

또한, 기술적으로 시스템 콜이 아닌 함수들(예: LoadLibraryX/LdrLoadDLL)도 모니터링될 수 있으며, 시스템 콜을 사용하여 간단히 재구현할 수 없습니다.

직접 시스템 콜 기술은 EDRSandblast에 구현되어 있습니다. 앞서 언급했듯이, 이는 NtProtectVirtualMemory를 안전하게 실행하고 감지된 모든 후크를 제거하는 데만 사용됩니다.

구현 세부 사항은 unhook() 함수의 코드 경로에서 unhook_method가 UNHOOK_WITH_DIRECT_SYSCALL인 경우를 확인하십시오.

취약한 드라이버 악용

앞서 언급했듯이, 커널 메모리 읽기 또는 쓰기가 필요한 모든 작업은 이 프리미티브를 제공하는 취약한 드라이버에 의존합니다. EDRSandblast에서는 읽기/쓰기 프리미티브를 제공하는 새 드라이버에 대한 지원을 "쉽게" 추가할 수 있으며, 세 가지 함수만 구현하면 됩니다:

  • ReadMemoryPrimitive_DRIVERNAME(SIZE_T Size, DWORD64 Address, PVOID Buffer) 함수: 커널 주소 Address에서 Size 바이트를 사용자 영역 버퍼 Buffer로 복사합니다.
  • WriteMemoryPrimitive_DRIVERNAME(SIZE_T Size, DWORD64 Address, PVOID Buffer) 함수: 사용자 영역 버퍼 Buffer에서 Size 바이트를 커널 주소 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

root@kitploit:~
### EDR 드라이버 및 프로세스 탐지

특정 드라이버나 프로세스가 EDR 제품에 속하는지 확인하기 위해 여러 기술이 현재 사용되고 있습니다.

첫째, 드라이버 이름 자체를 그 목적으로 간단히 사용할 수 있습니다. 실제로 Microsoft는 커널에 콜백을 삽입해야 하는 모든 드라이버에 대해 "Altitude"라고 하는 특정 번호를 할당합니다. 이를 통해 등록 순서와 무관하게 콜백 실행 순서가 결정적으로 정해지며, 오직 드라이버 사용에 기반합니다. 특정 *altitude* 를 예약한 드라이버(공급업체) 목록은 [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가 직접 서명해야 합니다. 드라이버의 공급업체가 드라이버 자체의 직접적인 서명자는 아니지만, 공급업체 이름이 여전히 서명의 속성 내에 포함된 것으로 보입니다. 그러나 이 탐지 기술은 아직 조사 및 구현이 필요합니다.

마지막으로 EDRSandblast에 알려지지 않은 EDR에 직면했을 때 가장 좋은 방법은 "audit" 모드에서 도구를 실행하고 커널 콜백을 등록한 드라이버 목록을 확인하는 것입니다. 그런 다음 드라이버 이름을 목록에 추가하고 도구를 다시 컴파일하여 다시 실행할 수 있습니다.

### RunAsPPL 우회

Windows 8.1 및 Windows Server 2012 R2에서 처음 도입된 `LSA(로컬 보안 기관) 보호` 메커니즘은 `PPL(Protected Process Light)` 기술을 활용하여 `LSASS` 프로세스에 대한 액세스를 제한합니다. `PPL` 보호는 보호된 프로세스에 대한 메모리 주입이나 메모리 덤프와 같은 작업을 규제 및 제한하며, `SeDebugPrivilege` 권한을 가진 프로세스에서도 마찬가지입니다. 프로세스 보호 모델에서는 더 높은 보호 수준으로 실행되는 프로세스만 보호된 프로세스에서 작업을 수행할 수 있습니다.

Windows 커널이 커널 메모리에서 프로세스를 나타내는 데 사용하는 `_EPROCESS` 구조에는 `Type` (`_PS_PROTECTED_TYPE`) 및 `Signer` (`_PS_PROTECTED_SIGNER`) 속성을 통해 프로세스의 보호 수준을 정의하는 `_PS_PROTECTION` 필드가 포함됩니다.

커널 메모리에 쓰기를 통해 EDRSandblast 프로세스는 자체 보호 수준을 `PsProtectedSignerWinTcb-Light`로 업그레이드할 수 있습니다. 이 수준은 `RunAsPPL` 메커니즘으로 실행되는 `LSASS` 프로세스의 보호 수준인 `PsProtectedSignerLsa-Light`를 "지배"하므로 `LSASS` 프로세스 메모리를 덤프하기에 충분합니다.

`EDRSandBlast`는 다음과 같이 자체 보호를 구현합니다:
  - 현재 프로세스에 대한 핸들을 엽니다.
  - `NtQuerySystemInformation`을 사용하여 모든 시스템 핸들을 유출하여 현재 프로세스에 열린 핸들과 커널 메모리에 있는 현재 프로세스의 `EPROCESS` 구조 주소를 찾습니다.
  - `Micro-Star MSI Afterburner` 드라이버의 임의 읽기/쓰기 취약점을 사용하여 커널 메모리에 있는 현재 프로세스의 `_PS_PROTECTION` 필드를 덮어씁니다. `_PS_PROTECTION` 필드의 `EPROCESS` 구조에 대한 오프셋(사용 중인 `ntoskrnl` 버전에 따라 정의됨)은 `NtoskrnlOffsets.csv` 파일에서 계산됩니다.

### Credential Guard 우회

Microsoft `Credential Guard`는 Microsoft `Windows 10(Enterprise 에디션)`에서 도입된 가상화 기반 격리 기술로, `LSASS` 프로세스에 저장된 자격 증명에 대한 직접 액세스를 방지합니다.

`Credential Guard`가 활성화되면 `LSAIso`(*LSA 격리*) 프로세스가 `가상 보안 모드`에서 생성됩니다. 이 기능은 CPU의 가상화 확장을 활용하여 메모리 내 데이터의 보안을 강화합니다. `LSAIso` 프로세스에 대한 액세스는 `NT AUTHORITY\SYSTEM` 보안 컨텍스트에서도 제한됩니다. 해시를 처리할 때 `LSA` 프로세스는 `LSAIso` 프로세스에 `RPC` 호출을 수행하고 계속 진행하기 위해 `LSAIso` 결과를 기다립니다. 따라서 `LSASS` 프로세스에는 비밀이 포함되지 않으며 대신 `LSA 격리 데이터`가 저장됩니다.

`N4kedTurtle`이 수행한 원래 연구에서 언급했듯이: "`Credential Guard`가 활성화된 시스템에서 메모리의 `g_fParameter_useLogonCredential` 및 `g_IsCredGuardEnabled` 값을 패치하여 `Wdigest`를 활성화할 수 있습니다." `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가 기호 파일에 게시한 구조 정의의 특정 필드 오프셋을 사용하여 수행됩니다. 이러한 오프셋은 각 대상 이미지 빌드에 고유하며 특정 플랫폼 버전에 대해 적어도 한 번 수집되어야 합니다.

EDRSandblast가 사용하는 구조와 변수를 찾기 위해 패턴 검색 대신 "하드코딩된" 오프셋을 사용하기로 한 선택은 커널 콜백 추가/제거를 담당하는 문서화되지 않은 API가 변경될 수 있고 잘못된 주소에서 커널 메모리를 읽거나 쓰려는 모든 시도가 `버그 검사`(`블루 스크린`)로 이어질 수 있기 때문에 정당화됩니다. 시스템 충돌은 레드팀 및 일반 침투 테스트 시나리오 모두에서 허용되지 않습니다. 충돌하는 시스템은 방어자에게 매우 가시적이며 공격 당시 메모리에 있던 모든 자격 증명을 잃게 됩니다.

특정 Windows 버전의 오프셋을 검색하기 위해 두 가지 접근 방식이 구현됩니다.

#### 수동 오프셋 검색

필요한 `ntoskrnl.exe` 및 `wdigest.dll` 오프셋은 제공된 `ExtractOffsets.py` Python 스크립트를 사용하여 추출할 수 있습니다. 이 스크립트는 `radare2` 및 `r2pipe`를 사용하여 PDB 파일에서 기호를 다운로드 및 구문 분석하고 필요한 오프셋을 추출합니다. 오프셋은 나중에 EDRSandblast에서 사용할 수 있도록 CSV 파일에 저장됩니다.

다양한 Windows 빌드를 즉시 지원하기 위해 `ntoskrnl.exe` 및 `wdigest.dll` 바이너리의 여러 버전이 [Winbindex](https://winbindex.m417z.com/)에서 참조되며, `ExtractOffsets.py`에서 자동으로 다운로드(및 해당 오프셋 추출)할 수 있습니다. 이를 통해 Windows 업데이트 패키지에 게시된 거의 모든 파일에서 오프셋을 추출할 수 있습니다(현재 450개 이상의 `ntoskrnl.exe` 및 30개 이상의 `wdigest.dll` 버전을 사용할 수 있으며 미리 계산되어 있습니다).

#### 자동 오프셋 검색 및 업데이트

`EDRSandBlast`에 추가 옵션이 구현되어 프로그램이 Microsoft Symbol Server에서 필요한 `.pdb` 파일을 직접 다운로드하고 필요한 오프셋을 추출하며, 해당 `.csv` 파일이 있는 경우 업데이트할 수도 있습니다.

`--internet` 옵션을 사용하면 도구 실행이 훨씬 간단해지지만, 프로세스 중에 `.pdb` 파일이 다운로드되어 디스크에 드롭되므로 추가적인 OpSec 위험이 발생합니다. 이는 기호 데이터베이스를 구문 분석하는 데 사용되는 `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>]

root@kitploit:~
### 옵션```
-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 및 Plateform Toolset: Visual Studio 2019 (v142))에서 빌드되었습니다.

ExtractOffsets.py 사용법

참고: ExtractOffsets.py는 Windows에서만 테스트되었습니다.```

Installation of Python dependencies

pip.exe install -m .\requirements.txt

Script usage

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.

root@kitploit:~
## 탐지
방어자(EDR 공급업체, Microsoft, EDR 원격 측정을 분석하는 SOC 분석가 등)의 관점에서 이와 같은 기술을 탐지하거나 방지하는 데 여러 지표를 사용할 수 있습니다.

### 드라이버 허용 목록
이 도구가 커널 모드 메모리에서 수행하는 모든 작업은 취약한 드라이버에 의존하여 임의 콘텐츠를 읽거나 쓰기 때문에, 드라이버 로딩 이벤트는 EDR 제품(또는 SOC 분석가)에 의해 면밀히 조사되어야 하며, 비정상적인 드라이버 로딩이 발생하면 경고를 발생시키거나 알려진 취약한 드라이버를 차단해야 합니다. 이 후자의 접근 방식은 [Microsoft 자체에서도 권장](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-driver-block-rules)합니다. HVCI(*Hypervisor-protected code integrity*)가 활성화된 모든 Windows 장치에는 드라이버 차단 목록이 포함되어 있으며, 이는 점차 Windows의 기본 동작이 될 것입니다(Windows 11에서는 이미 기본입니다).

### 커널 메모리 무결성 검사
공격자가 알려지지 않은 취약한 드라이버를 사용하여 메모리에서 동일한 동작을 수행할 수 있으므로, EDR 드라이버는 이 도구처럼 커널 메모리를 직접 검사하거나 이벤트(프로세스 생성, 스레드 생성, 이미지 로딩 등)를 트리거한 후 콜백 함수가 실행 커널에 의해 실제로 호출되는지 확인하는 방식으로, 자신의 커널 콜백이 여전히 등록되어 있는지 주기적으로 확인할 수 있습니다.

참고로, 이러한 유형의 데이터 구조는 최근 [Kernel Data Protection (KDP)](https://www.microsoft.com/security/blog/2020/07/08/introducing-kernel-data-protection-a-new-platform-security-technology-for-preventing-data-corruption/) 메커니즘을 통해 보호될 수 있습니다. 이 메커니즘은 Virtual Based Security에 의존하여 올바른 API를 호출하지 않고는 커널 콜백 배열을 쓰기 불가능하게 만듭니다.

동일한 논리가 민감한 ETW 변수(예: 이 도구가 ETW 위협 인텔리전스 이벤트 생성을 비활성화하는 데 악용하는 `ProviderEnableInfo`)에도 적용될 수 있습니다.

### 사용자 모드 탐지
프로세스가 사용자 레벨 후킹을 적극적으로 회피하려고 한다는 첫 번째 지표는 로드된 모듈에 해당하는 각 DLL에 대한 파일 액세스입니다. 정상적인 실행에서 사용자 모드 프로세스는 `LoadLibrary` 호출 외부에서 DLL 파일을 읽을 필요가 거의 없으며, 특히 `ntdll.dll`의 경우 더욱 그렇습니다.

API 후킹이 우회되는 것을 방지하기 위해 EDR 제품은 모니터링되는 각 프로세스 내에서 메모리의 후크가 변경되지 않았는지 주기적으로 확인할 수 있습니다.

마지막으로, 후크 제거를 수반하지 않는 후킹 우회(트램펄린 악용, 직접 시스템 콜 사용 등)를 탐지하기 위해 EDR 제품은 악용된 시스템 콜과 관련된 커널 콜백(예: `NtCreateProcess` 시스템 콜의 `PsCreateProcessNotifyRoutine`, `NtOpenProcess` 시스템 콜의 `ObRegisterCallbacks` 등)을 활용하고 사용자 모드 콜 스택 분석을 수행하여 시스템 콜이 정상 경로(`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

- `LSASS` 메모리 패치를 통해 `Wdigest`를 다시 활성화하여 Credential Guard 우회:
  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/
도구 다운로드