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
|
#ifdef _WIN32
|
||||||
|
|
||||||
//#define DEBUGTRACE
|
// #define DEBUGTRACE 1
|
||||||
|
|
||||||
#ifdef DEBUGTRACE
|
#ifdef DEBUGTRACE
|
||||||
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
||||||
|
|
|
@ -251,7 +251,8 @@ static BOOL server_negotiate_ssl(Remote *remote)
|
||||||
{
|
{
|
||||||
BOOL success = TRUE;
|
BOOL success = TRUE;
|
||||||
SOCKET fd = 0;
|
SOCKET fd = 0;
|
||||||
DWORD ret = 0;
|
DWORD ret = 0;
|
||||||
|
DWORD res = 0;
|
||||||
|
|
||||||
lock_acquire( remote->lock );
|
lock_acquire( remote->lock );
|
||||||
|
|
||||||
|
@ -274,12 +275,23 @@ static BOOL server_negotiate_ssl(Remote *remote)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (ret = SSL_connect(remote->ssl)) != 1 )
|
do {
|
||||||
{
|
if( (ret = SSL_connect(remote->ssl)) != 1 )
|
||||||
dprintf("[SERVER] connect failed %d\n", SSL_get_error(remote->ssl, ret));
|
{
|
||||||
success = FALSE;
|
res = SSL_get_error(remote->ssl, ret);
|
||||||
break;
|
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...");
|
dprintf("[SERVER] Sending a HTTP GET request to the remote side...");
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,6 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||||
#
|
#
|
||||||
def load_stdapi()
|
def load_stdapi()
|
||||||
original = console.disable_output
|
original = console.disable_output
|
||||||
|
|
||||||
console.disable_output = true
|
console.disable_output = true
|
||||||
console.run_single('use stdapi')
|
console.run_single('use stdapi')
|
||||||
console.disable_output = original
|
console.disable_output = original
|
||||||
|
@ -209,7 +208,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||||
#
|
#
|
||||||
def load_session_info()
|
def load_session_info()
|
||||||
begin
|
begin
|
||||||
::Timeout.timeout(20) do
|
::Timeout.timeout(60) do
|
||||||
username = self.sys.config.getuid
|
username = self.sys.config.getuid
|
||||||
sysinfo = self.sys.config.sysinfo
|
sysinfo = self.sys.config.sysinfo
|
||||||
self.info = "#{username} @ #{sysinfo['Computer']}"
|
self.info = "#{username} @ #{sysinfo['Computer']}"
|
||||||
|
|
|
@ -44,7 +44,7 @@ module MeterpreterOptions
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
::Timeout.timeout(10) do
|
::Timeout.timeout(30) do
|
||||||
if session.railgun and session.railgun.shell32.IsUserAnAdmin()["return"] == true
|
if session.railgun and session.railgun.shell32.IsUserAnAdmin()["return"] == true
|
||||||
session.load_priv
|
session.load_priv
|
||||||
session.info += " (ADMIN)"
|
session.info += " (ADMIN)"
|
||||||
|
|
|
@ -161,10 +161,10 @@ module ReverseTcp
|
||||||
# Start a new thread and pass the client connection
|
# Start a new thread and pass the client connection
|
||||||
# as the input and output pipe. Client's are expected
|
# as the input and output pipe. Client's are expected
|
||||||
# to implement the Stream interface.
|
# to implement the Stream interface.
|
||||||
conn_threads << Thread.new {
|
conn_threads << Thread.new(client) { |client_copy|
|
||||||
begin
|
begin
|
||||||
handle_connection(client)
|
handle_connection(client_copy)
|
||||||
rescue
|
rescue ::Exception
|
||||||
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
|
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,16 @@ class Client
|
||||||
#
|
#
|
||||||
@@ext_hash = {}
|
@@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
|
# Checks the extension hash to see if a class has already been associated
|
||||||
# with the supplied extension name.
|
# with the supplied extension name.
|
||||||
|
@ -133,6 +143,11 @@ class Client
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_ssl_context
|
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){ }
|
key = OpenSSL::PKey::RSA.new(1024){ }
|
||||||
cert = OpenSSL::X509::Certificate.new
|
cert = OpenSSL::X509::Certificate.new
|
||||||
cert.version = 2
|
cert.version = 2
|
||||||
|
@ -175,7 +190,14 @@ class Client
|
||||||
|
|
||||||
ctx.session_id_context = Rex::Text.rand_text(16)
|
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
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -197,7 +219,7 @@ class Client
|
||||||
# waiting for a response.
|
# waiting for a response.
|
||||||
#
|
#
|
||||||
def Client.default_timeout
|
def Client.default_timeout
|
||||||
return 30
|
return 300
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
Loading…
Reference in New Issue