Fix for #291, Meterpreter over PassiveX now working again :)

git-svn-id: file:///home/svn/framework3/trunk@8653 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
Stephen Fewer 2010-02-26 05:13:58 +00:00
parent e1c5334d56
commit 300cede801
2 changed files with 80 additions and 35 deletions

View File

@ -23,37 +23,67 @@ module PassiveX
class PxSessionChannel
include Rex::IO::StreamAbstraction
def initialize(sid)
@sid = sid
@remote_queue = ''
initialize_abstraction
# Start a thread that monitors the local side of the pipe and writes
# data from it to the remote side.
@monitor_thread = Thread.new {
module PxSocketInterface
def type?
'tcp'
end
def shutdown(how)
return false if not remote
begin
begin
if ((rsock.has_read_data?(1)) and
(buf = rsock.get_once))
write_remote(buf)
else
flush_output
end
end while true
return (remote.shutdown(how) == 0)
rescue ::Exception
end
}
end
def peerinfo
if (pi = getpeername)
return pi[1] + ':' + pi[2].to_s
end
end
def localinfo
if (pi = getlocalname)
return pi[1] + ':' + pi[2].to_s
end
end
def getlocalname
getsockname
end
def getsockname
return [2,'',''] if not remote
remote.getsockname
end
def getpeername
return [2,'',''] if not remote
remote.getpeername
end
attr_accessor :remote
end
def initialize(sid)
@remote = nil
@sid = sid
@remote_queue = ''
initialize_abstraction
# sf: we don't include Rex::Socket::Tcp as it messes with closing passivex sessions.
lsock.extend( PxSocketInterface )
lsock.remote = nil
end
#
# Closes the stream abstraction and kills the monitor thread.
#
def close
@monitor_thread.kill if (@monitor_thread)
@monitor_thread = nil
cleanup_abstraction
end
@ -62,17 +92,17 @@ module PassiveX
# data to the client side.
#
def remote=(cli)
# If we already have a remote, then close it now that we have a new
# one.
# If we already have a remote, then close it now that we have a new one.
if (@remote)
begin
@remote.server.close_client(@remote)
rescue ::Exception
rescue
end
end
@remote = cli
@remote = cli
lsock.remote = @remote
flush_output
end
@ -80,7 +110,7 @@ module PassiveX
# Writes data to the local side of the abstraction that comes in from
# the remote.
#
def write_local(buf)
def write_local(buf)
dlog("PassiveX:#{self} Writing #{buf.length} to local side", 'core', LEV_3)
rsock.put(buf)
@ -89,28 +119,43 @@ module PassiveX
#
# Writes data to the remote HTTP client via an indirect queue.
#
def write_remote(buf)
def write_remote(buf)
dlog("PassiveX:#{self} Queuing #{buf.length} to remote side", 'core', LEV_3)
@remote_queue += buf
flush_output
end
#
# The write function for Rex::IO::StreamAbstraction.monitor_rsock
#
def write(buf)
write_remote(buf)
return buf.length
end
#
# The close_write function for Rex::IO::StreamAbstraction.monitor_rsock
#
def close_write
end
#
# Flushes the output queue if there is an associated output HTTP client.
#
def flush_output
return if (@remote_queue == nil or @remote_queue.length == 0)
resp = Rex::Proto::Http::Response.new
resp.body = @remote_queue
# sf: we must specify a content type
resp['Content-Type'] = 'application/octet-stream'
begin
if (@remote)
dlog("PassiveX:#{self} Flushing remote output queue at #{resp.body.length} bytes", 'core', LEV_3)
@remote.keepalive = false
# sf: this naughty keepalive was killing the meterpreter over passivex payload, dont re-enable!
#@remote.keepalive = false
@remote.send_response(resp)
@remote = nil
@remote_queue = ''
@ -391,6 +436,7 @@ if (marker == false) {
if (s = find_session_channel(sid))
Thread.new {
begin
s.remote = cli
handle_connection(s.lsock)
rescue ::Exception
elog("Exception raised during PX handle connection: #{$!}", 'core', LEV_1)
@ -403,10 +449,9 @@ if (marker == false) {
print_status("Sending stage to sid #{sid} (#{resp.body.length} bytes)")
when "/tunnel_in"
s.write_local(req.body) if (s = find_session_channel(sid))
when "/tunnel_out"
when "/tunnel_out"
cli.keepalive = true
resp = nil
s.remote = cli if (s = find_session_channel(sid))
else
resp.code = 404

View File

@ -27,7 +27,7 @@ module Payload::Windows::ReflectiveDllInject
'Arch' => ARCH_X86,
'PayloadCompat' =>
{
'Convention' => 'sockedi -passivex',
'Convention' => 'sockedi',
},
'Stage' =>
{