Put a bandaid over getsockname

Depending on how a socket was created, #getsockname will return either a
struct sockaddr as a String (the default ruby Socket behavior) or an
Array (the extend'd Rex::Socket::Tcp behavior). Avoid the ambiguity when
generating SSL certificates for meterpreter handlers by always picking a
random hostname.

This is by no means a proper fix for the underlying problem of
Socket#getsockname having ambiguous behavior before and after being
extended with Rex::Socket::Tcp. It does, however, solve the immediate
problem of not being able to create tunneled meterpreter sessions over
http(s) sessions.

[SeeRM #7350]
This commit is contained in:
James Lee 2012-10-29 22:45:46 -05:00
parent 5c0fb2789f
commit d0650dfb25
3 changed files with 13 additions and 4 deletions

View File

@ -127,7 +127,7 @@ module BindTcp
rescue Rex::ConnectionRefused rescue Rex::ConnectionRefused
# Connection refused is a-okay # Connection refused is a-okay
rescue ::Exception rescue ::Exception
wlog("Exception caught in bind handler: #{$!}") wlog("Exception caught in bind handler: #{$!.class} #{$!}")
end end
break if client break if client
@ -138,7 +138,6 @@ module BindTcp
# Valid client connection? # Valid client connection?
if (client) if (client)
# Increment the has connection counter # Increment the has connection counter
self.pending_connections += 1 self.pending_connections += 1

View File

@ -149,6 +149,9 @@ protected
closed = true closed = true
wlog("monitor_rsock: closed remote socket due to nil read") wlog("monitor_rsock: closed remote socket due to nil read")
end end
rescue EOFError => e
closed = true
dlog("monitor_rsock: EOF in rsock")
rescue ::Exception => e rescue ::Exception => e
closed = true closed = true
wlog("monitor_rsock: exception during read: #{e.class} #{e}") wlog("monitor_rsock: exception during read: #{e.class} #{e}")

View File

@ -154,7 +154,7 @@ class Client
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
# Use non-blocking OpenSSL operations on Windows # Use non-blocking OpenSSL operations on Windows
if not ( ssl.respond_to?(:accept_nonblock) and Rex::Compat.is_windows ) if !( ssl.respond_to?(:accept_nonblock) and Rex::Compat.is_windows )
ssl.accept ssl.accept
else else
begin begin
@ -211,12 +211,19 @@ class Client
cert.version = 2 cert.version = 2
cert.serial = rand(0xFFFFFFFF) cert.serial = rand(0xFFFFFFFF)
# Depending on how the socket was created, getsockname will
# return either a struct sockaddr as a String (the default ruby
# Socket behavior) or an Array (the extend'd Rex::Socket::Tcp
# behavior). Avoid the ambiguity by always picking a random
# hostname. See #7350.
subject_cn = Rex::Text.rand_hostname
subject = OpenSSL::X509::Name.new([ subject = OpenSSL::X509::Name.new([
["C","US"], ["C","US"],
['ST', Rex::Text.rand_state()], ['ST', Rex::Text.rand_state()],
["L", Rex::Text.rand_text_alpha(rand(20) + 10)], ["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
["O", Rex::Text.rand_text_alpha(rand(20) + 10)], ["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
["CN", self.sock.getsockname[1] || Rex::Text.rand_hostname], ["CN", subject_cn],
]) ])
issuer = OpenSSL::X509::Name.new([ issuer = OpenSSL::X509::Name.new([
["C","US"], ["C","US"],