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-b9f4589650daunstable
parent
e4a00b2fd1
commit
2e9138ebbc
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.
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.
Binary file not shown.
|
@ -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__)
|
||||
|
|
|
@ -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...");
|
||||
|
||||
|
|
|
@ -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']}"
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
##
|
||||
|
|
Loading…
Reference in New Issue