This commit overhauls much of the meterpreter timeouts and staging processes. This fixes a bug with concurrent session handling, reduces CPU load by caching a single SSL certificate for all sessions, increases all of the critical timeouts, and generally makes mass ownage work better. We still need to limit the maximum number of concurrent on_session() threads to something sane to prevent sesssion spikes from dragging out the process even longer. The C-side meterpreter change is minimal and will only help with future compatibility if we move to non-blocking fd's for the SSL socket.

git-svn-id: file:///home/svn/framework3/trunk@10595 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2010-10-08 04:11:47 +00:00
parent e4a00b2fd1
commit 2e9138ebbc
21 changed files with 49 additions and 16 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -68,7 +68,7 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
#ifdef _WIN32
//#define DEBUGTRACE
// #define DEBUGTRACE 1
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)

View File

@ -251,7 +251,8 @@ static BOOL server_negotiate_ssl(Remote *remote)
{
BOOL success = TRUE;
SOCKET fd = 0;
DWORD ret = 0;
DWORD ret = 0;
DWORD res = 0;
lock_acquire( remote->lock );
@ -274,12 +275,23 @@ static BOOL server_negotiate_ssl(Remote *remote)
break;
}
if( (ret = SSL_connect(remote->ssl)) != 1 )
{
dprintf("[SERVER] connect failed %d\n", SSL_get_error(remote->ssl, ret));
success = FALSE;
break;
}
do {
if( (ret = SSL_connect(remote->ssl)) != 1 )
{
res = SSL_get_error(remote->ssl, ret);
dprintf("[SERVER] connect failed %d\n", res);
if (res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE) {
// Catch non-blocking socket errors and retry
continue;
}
success = FALSE;
break;
}
} while(ret != 1);
if (success == FALSE) break;
dprintf("[SERVER] Sending a HTTP GET request to the remote side...");

View File

@ -187,7 +187,6 @@ class Meterpreter < Rex::Post::Meterpreter::Client
#
def load_stdapi()
original = console.disable_output
console.disable_output = true
console.run_single('use stdapi')
console.disable_output = original
@ -209,7 +208,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
#
def load_session_info()
begin
::Timeout.timeout(20) do
::Timeout.timeout(60) do
username = self.sys.config.getuid
sysinfo = self.sys.config.sysinfo
self.info = "#{username} @ #{sysinfo['Computer']}"

View File

@ -44,7 +44,7 @@ module MeterpreterOptions
end
begin
::Timeout.timeout(10) do
::Timeout.timeout(30) do
if session.railgun and session.railgun.shell32.IsUserAnAdmin()["return"] == true
session.load_priv
session.info += " (ADMIN)"

View File

@ -161,10 +161,10 @@ module ReverseTcp
# Start a new thread and pass the client connection
# as the input and output pipe. Client's are expected
# to implement the Stream interface.
conn_threads << Thread.new {
conn_threads << Thread.new(client) { |client_copy|
begin
handle_connection(client)
rescue
handle_connection(client_copy)
rescue ::Exception
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
end
}

View File

@ -41,6 +41,16 @@ class Client
#
@@ext_hash = {}
#
# Cached SSL certificate (required to scale)
#
@@ssl_ctx = nil
#
# Mutex to synchronize class-wide operations
#
@@ssl_mutex = ::Mutex.new
#
# Checks the extension hash to see if a class has already been associated
# with the supplied extension name.
@ -133,6 +143,11 @@ class Client
end
def generate_ssl_context
@@ssl_mutex.synchronize do
if not @@ssl_ctx
wlog("Generating SSL certificate for Meterpreter sessions")
key = OpenSSL::PKey::RSA.new(1024){ }
cert = OpenSSL::X509::Certificate.new
cert.version = 2
@ -175,7 +190,14 @@ class Client
ctx.session_id_context = Rex::Text.rand_text(16)
return ctx
wlog("Generated SSL certificate for Meterpreter sessions")
@@ssl_ctx = ctx
end # End of if not @ssl_ctx
end # End of mutex.synchronize
@@ssl_ctx
end
#
@ -197,7 +219,7 @@ class Client
# waiting for a response.
#
def Client.default_timeout
return 30
return 300
end
##