Description
Watchdog Antivirus v1.6.415 is vulnerable to a Denial of Service vulnerability by triggering the 0x80002014 IOCTL code of the wsdk-driver.sys driver.
Vulnerability
The 0x80002014 IOCTL code of the wsdk-driver.sys driver allows to perform a Denial of Service, leading to a BSOD of the affected computer caused by a NULL pointer dereference.
The disassembled vulnerable function is sub_140008D5C:
__int64 __fastcall sub_140008D5C(HANDLE ProcessId)
{
__int64 v1;
const char *ProcessImageFileName;
NTSTATUS v3;
int v4;
int v5;
PEPROCESS Process;
Process = 0i64;
v1 = (unsigned int)ProcessId;
ProcessImageFileName = 0i64;
v3 = PsLookupProcessByProcessId((HANDLE)(unsigned int)ProcessId, &Process);
if ( v3 < 0 )
{
if ( off_140005250 != &off_140005250 )
{
_mm_lfence();
LOBYTE(v4) = 3;
sub_140001084((int)off_140005248->DeviceExtension, v4, v5, 0x14, (__int64)&unk_140003960, v3);
}
}
else
{
ProcessImageFileName = (const char *)PsGetProcessImageFileName(Process);
ObfDereferenceObject(Process);
}
if ( stricmp(ProcessImageFileName, "WAV.exe") )
return 0xC0000001i64;
qword_140005298 = v1;
return 0i64
__int64 __fastcall sub_140008D5C(HANDLE ProcessId)
{
__int64 v1;
const char *ProcessImageFileName;
NTSTATUS v3;
int v4;
int v5;
PEPROCESS Process;
Process = 0i64;
v1 = (unsigned int)ProcessId;
ProcessImageFileName = 0i64;
v3 = PsLookupProcessByProcessId((HANDLE)(unsigned int)ProcessId, &Process);
if ( v3 < 0 )
{
if ( off_140005250 != &off_140005250 )
{
_mm_lfence();
LOBYTE(v4) = 3;
sub_140001084((int)off_140005248->DeviceExtension, v4, v5, 0x14, (__int64)&unk_140003960, v3);
}
}
else
{
ProcessImageFileName = (const char *)PsGetProcessImageFileName(Process);
ObfDereferenceObject(Process);
}
if ( stricmp(ProcessImageFileName, "WAV.exe") )
return 0xC0000001i64;
qword_140005298 = v1;
return 0i64
__int64 __fastcall sub_140008D5C(HANDLE ProcessId)
{
__int64 v1;
const char *ProcessImageFileName;
NTSTATUS v3;
int v4;
int v5;
PEPROCESS Process;
Process = 0i64;
v1 = (unsigned int)ProcessId;
ProcessImageFileName = 0i64;
v3 = PsLookupProcessByProcessId((HANDLE)(unsigned int)ProcessId, &Process);
if ( v3 < 0 )
{
if ( off_140005250 != &off_140005250 )
{
_mm_lfence();
LOBYTE(v4) = 3;
sub_140001084((int)off_140005248->DeviceExtension, v4, v5, 0x14, (__int64)&unk_140003960, v3);
}
}
else
{
ProcessImageFileName = (const char *)PsGetProcessImageFileName(Process);
ObfDereferenceObject(Process);
}
if ( stricmp(ProcessImageFileName, "WAV.exe") )
return 0xC0000001i64;
qword_140005298 = v1;
return 0i64
__int64 __fastcall sub_140008D5C(HANDLE ProcessId)
{
__int64 v1;
const char *ProcessImageFileName;
NTSTATUS v3;
int v4;
int v5;
PEPROCESS Process;
Process = 0i64;
v1 = (unsigned int)ProcessId;
ProcessImageFileName = 0i64;
v3 = PsLookupProcessByProcessId((HANDLE)(unsigned int)ProcessId, &Process);
if ( v3 < 0 )
{
if ( off_140005250 != &off_140005250 )
{
_mm_lfence();
LOBYTE(v4) = 3;
sub_140001084((int)off_140005248->DeviceExtension, v4, v5, 0x14, (__int64)&unk_140003960, v3);
}
}
else
{
ProcessImageFileName = (const char *)PsGetProcessImageFileName(Process);
ObfDereferenceObject(Process);
}
if ( stricmp(ProcessImageFileName, "WAV.exe") )
return 0xC0000001i64;
qword_140005298 = v1;
return 0i64
The sub_140008D5C function tries to find the process instance of the WAV.exe executable. It receives a parameter called ProcessId at [1], tries to find the image filename with PsGetProcessImageFileName at [2] and compares if the file name matches with WAV.exe using stricmp() at [3]. However, the parameter ProcessId can be controlled by the attacker, making the result of PsGetProcessImageFileName to be NULL, performing an invalid comparison with stricmp(), resulting in a NULL pointer dereference:
CONTEXT: ffffca0f2802ed20 -- (.cxr 0xffffca0f2802ed20)
rax=0000000000000000 rbx=0000000041414141 rcx=0000000000000000
rdx=fffff80172caac80 rsi=0000000080002014 rdi=0000000000000000
rip=fffff80177dcc6b2 rsp=ffffca0f2802f728 rbp=ffffcf0c89df45c0
r8=0000000000000000 r9=ffffcf0c8efe40a8 r10=fffff80172caac80
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=ffffcf0c8e61d8f0
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050286
nt!_ascii_stricmp+0x6:
fffff801`77dcc6b2 450fb603 movzx r8d,byte ptr [r11] ds:002b:00000000`00000000=??
Resetting default scope
PROCESS_NAME: IOCTLBruteForce.exe
STACK_TEXT:
ffffca0f`2802f728 fffff801`77dcc709 : ffffca0f`28020014 ffffca0f`2802f788 00000000`00000004 00000000`00000000 : nt!_ascii_stricmp+0x6
ffffca0f`2802f730 fffff801`72ca8de7 : 00000000`41414141 00000000`80002014 00000000`41414141 00000000`00000000 : nt!stricmp+0x9
ffffca0f`2802f760 fffff801`72ca806e : ffffcf0c`89df45c0 00000000`00000000 00000000`000000c8 fffff801`780d4b41 : wsdkd+0x8de7
ffffca0f`2802f7a0 fffff801`77cd1f35 : ffffcf0c`89df45c0 00000000`00000004 00000000`00000002 00000000`00000001 : wsdkd+0x806e
CONTEXT: ffffca0f2802ed20 -- (.cxr 0xffffca0f2802ed20)
rax=0000000000000000 rbx=0000000041414141 rcx=0000000000000000
rdx=fffff80172caac80 rsi=0000000080002014 rdi=0000000000000000
rip=fffff80177dcc6b2 rsp=ffffca0f2802f728 rbp=ffffcf0c89df45c0
r8=0000000000000000 r9=ffffcf0c8efe40a8 r10=fffff80172caac80
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=ffffcf0c8e61d8f0
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050286
nt!_ascii_stricmp+0x6:
fffff801`77dcc6b2 450fb603 movzx r8d,byte ptr [r11] ds:002b:00000000`00000000=??
Resetting default scope
PROCESS_NAME: IOCTLBruteForce.exe
STACK_TEXT:
ffffca0f`2802f728 fffff801`77dcc709 : ffffca0f`28020014 ffffca0f`2802f788 00000000`00000004 00000000`00000000 : nt!_ascii_stricmp+0x6
ffffca0f`2802f730 fffff801`72ca8de7 : 00000000`41414141 00000000`80002014 00000000`41414141 00000000`00000000 : nt!stricmp+0x9
ffffca0f`2802f760 fffff801`72ca806e : ffffcf0c`89df45c0 00000000`00000000 00000000`000000c8 fffff801`780d4b41 : wsdkd+0x8de7
ffffca0f`2802f7a0 fffff801`77cd1f35 : ffffcf0c`89df45c0 00000000`00000004 00000000`00000002 00000000`00000001 : wsdkd+0x806e
CONTEXT: ffffca0f2802ed20 -- (.cxr 0xffffca0f2802ed20)
rax=0000000000000000 rbx=0000000041414141 rcx=0000000000000000
rdx=fffff80172caac80 rsi=0000000080002014 rdi=0000000000000000
rip=fffff80177dcc6b2 rsp=ffffca0f2802f728 rbp=ffffcf0c89df45c0
r8=0000000000000000 r9=ffffcf0c8efe40a8 r10=fffff80172caac80
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=ffffcf0c8e61d8f0
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050286
nt!_ascii_stricmp+0x6:
fffff801`77dcc6b2 450fb603 movzx r8d,byte ptr [r11] ds:002b:00000000`00000000=??
Resetting default scope
PROCESS_NAME: IOCTLBruteForce.exe
STACK_TEXT:
ffffca0f`2802f728 fffff801`77dcc709 : ffffca0f`28020014 ffffca0f`2802f788 00000000`00000004 00000000`00000000 : nt!_ascii_stricmp+0x6
ffffca0f`2802f730 fffff801`72ca8de7 : 00000000`41414141 00000000`80002014 00000000`41414141 00000000`00000000 : nt!stricmp+0x9
ffffca0f`2802f760 fffff801`72ca806e : ffffcf0c`89df45c0 00000000`00000000 00000000`000000c8 fffff801`780d4b41 : wsdkd+0x8de7
ffffca0f`2802f7a0 fffff801`77cd1f35 : ffffcf0c`89df45c0 00000000`00000004 00000000`00000002 00000000`00000001 : wsdkd+0x806e
CONTEXT: ffffca0f2802ed20 -- (.cxr 0xffffca0f2802ed20)
rax=0000000000000000 rbx=0000000041414141 rcx=0000000000000000
rdx=fffff80172caac80 rsi=0000000080002014 rdi=0000000000000000
rip=fffff80177dcc6b2 rsp=ffffca0f2802f728 rbp=ffffcf0c89df45c0
r8=0000000000000000 r9=ffffcf0c8efe40a8 r10=fffff80172caac80
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=ffffcf0c8e61d8f0
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050286
nt!_ascii_stricmp+0x6:
fffff801`77dcc6b2 450fb603 movzx r8d,byte ptr [r11] ds:002b:00000000`00000000=??
Resetting default scope
PROCESS_NAME: IOCTLBruteForce.exe
STACK_TEXT:
ffffca0f`2802f728 fffff801`77dcc709 : ffffca0f`28020014 ffffca0f`2802f788 00000000`00000004 00000000`00000000 : nt!_ascii_stricmp+0x6
ffffca0f`2802f730 fffff801`72ca8de7 : 00000000`41414141 00000000`80002014 00000000`41414141 00000000`00000000 : nt!stricmp+0x9
ffffca0f`2802f760 fffff801`72ca806e : ffffcf0c`89df45c0 00000000`00000000 00000000`000000c8 fffff801`780d4b41 : wsdkd+0x8de7
ffffca0f`2802f7a0 fffff801`77cd1f35 : ffffcf0c`89df45c0 00000000`00000004 00000000`00000002 00000000`00000001 : wsdkd+0x806e
Our security policy
We have reserved the ID CVE-2024-1241 to refer to this issue from now on.
Disclosure policy
System Information
Version: Watchdog Antivirus v1.6.415
Operating System: Windows
Mitigation
There is currently no patch available for this vulnerability.
References
Credits
The vulnerability was discovered by Andres Roldan from Fluid Attacks' Offensive Team.