2016-02-28 15:14:39 -05:00
# -*- coding: binary -*-
module Msf
###
#
# This mixin provides a generic interface for running a socket server of some
# sort that is designed to exploit clients. Exploits that include this mixin
# automatically take a passive stance.
#
###
module Exploit::Remote::SocketServer
def initialize ( info = { } )
super ( update_info ( info ,
'Stance' = > Msf :: Exploit :: Stance :: Passive ) )
register_options (
[
2020-05-13 16:30:00 +02:00
OptAddressLocal . new ( 'SRVHOST' , [ true , 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.' , '0.0.0.0' ] ) ,
2016-02-28 15:14:39 -05:00
OptPort . new ( 'SRVPORT' , [ true , " The local port to listen on. " , 8080 ] ) ,
] , Msf :: Exploit :: Remote :: SocketServer
)
register_advanced_options (
[
OptString . new ( 'ListenerComm' , [ false , 'The specific communication channel to use for this service' ] )
] , Msf :: Exploit :: Remote :: SocketServer
)
end
#
# This mixin overrides the exploit method so that it can initiate the
# service that corresponds with what the client has requested.
#
def exploit
start_service ( )
print_status ( " Server started. " )
# Call the exploit primer
primer
# Wait on the service to stop
self . service . wait
end
#
# Primer method to call after starting service but before handling connections
#
def primer
end
#
# Stops the service, if one was created.
#
def cleanup
super
if ( service )
stop_service ( )
print_status ( " Server stopped. " )
end
end
#
# Called when a client has data available for reading.
#
def on_client_data ( client )
end
#
# Starts the service. Override this method in consumers
#
def start_service ( * args )
end
#
# Stops the service.
#
def stop_service
if ( service )
begin
self . service . deref if self . service . kind_of? ( Rex :: Service )
2018-04-20 15:10:53 -04:00
if self . service . kind_of? ( Rex :: Socket ) || self . service . kind_of? ( Rex :: Post :: Meterpreter :: Channel )
2016-02-28 15:14:39 -05:00
self . service . close
self . service . stop
end
self . service = nil
rescue :: Exception
end
end
end
#
# Returns the local host that is being listened on.
#
def srvhost
datastore [ 'SRVHOST' ]
end
#
# Returns the local port that is being listened on.
#
def srvport
datastore [ 'SRVPORT' ]
end
#
# Re-generates the payload, substituting the current RHOST and RPORT with
# the supplied client host and port from the socket.
#
def regenerate_payload ( cli , arch = nil , platform = nil , target = nil )
ohost = datastore [ 'RHOST' ]
oport = datastore [ 'RPORT' ]
p = nil
begin
# Update the datastore with the supplied client peerhost/peerport
datastore [ 'RHOST' ] = cli . peerhost
datastore [ 'RPORT' ] = cli . peerport
if ( ( p = super ( arch , platform , target ) ) == nil )
print_error ( " Failed to generate payload " )
return nil
end
# Allow the payload to start a new handler
add_handler ( {
'RHOST' = > datastore [ 'RHOST' ] ,
'RPORT' = > datastore [ 'RPORT' ]
} )
ensure
datastore [ 'RHOST' ] = ohost
datastore [ 'RPORT' ] = oport
end
p
end
protected
#
# Determines appropriate listener comm
#
2016-02-28 16:43:55 -05:00
def _determine_server_comm ( srv_comm = datastore [ 'ListenerComm' ] . to_s )
case srv_comm
when 'local'
2016-02-28 15:14:39 -05:00
comm = :: Rex :: Socket :: Comm :: Local
2016-02-28 16:43:55 -05:00
when / \ A[0-9]+ \ Z /
comm = framework . sessions [ srv_comm . to_i ]
raise ( RuntimeError , " Socket Server Comm (Session #{ srv_comm } ) does not exist " ) unless comm
raise ( RuntimeError , " Socket Server Comm (Session #{ srv_comm } ) does not implement Rex::Socket::Comm " ) unless comm . is_a? :: Rex :: Socket :: Comm
when nil , ''
2020-03-24 18:08:34 +05:30
comm = nil
2016-02-28 15:14:39 -05:00
else
2016-02-28 16:43:55 -05:00
raise ( RuntimeError , " SocketServer Comm ' #{ srv_comm } ' is invalid " )
2020-03-24 18:08:34 +05:30
end
2016-02-28 16:43:55 -05:00
comm
2016-02-28 15:14:39 -05:00
end
2018-04-20 16:02:33 -04:00
def via_string_for_ip ( ip , comm )
comm_used = comm
comm_used || = Rex :: Socket :: SwitchBoard . best_comm ( ip )
comm_used || = Rex :: Socket :: Comm :: Local
if comm_used . respond_to? ( :type ) && comm_used . respond_to? ( :sid )
via = " via the #{ comm_used . type } on session #{ comm_used . sid } "
else
via = " "
end
via
end
2016-02-28 15:14:39 -05:00
attr_accessor :service # :nodoc:
end
end