Module: Msf::Handler::BindTcp
- Includes:
- Msf::Handler
- Defined in:
- lib/msf/core/handler/bind_tcp.rb
Overview
This module implements the Bind TCP handler. This means that it will attempt to connect to a remote host on a given port for a period of time (typically the duration of an exploit) to see if a the payload has started listening. This can tend to be rather verbose in terms of traffic and in general it is preferable to use reverse payloads.
Constant Summary
Constants included from Msf::Handler
Instance Attribute Summary collapse
-
#conn_threads ⇒ Object
protected
:nodoc:.
-
#listener_pairs ⇒ Object
protected
:nodoc:.
-
#listener_threads ⇒ Object
protected
:nodoc:.
Attributes included from Msf::Handler
#exploit_config, #parent_payload, #pending_connections, #session_waiter_event, #sessions
Class Method Summary collapse
-
.general_handler_type ⇒ Object
Returns the connection oriented general handler type, in this case bind.
-
.handler_type ⇒ Object
Returns the handler specific string representation, in this case ‘bind_tcp’.
Instance Method Summary collapse
-
#add_handler(opts = {}) ⇒ Object
Starts a new connecting thread.
-
#cleanup_handler ⇒ Object
Kills off the connection threads if there are any hanging around.
-
#human_name ⇒ String
A string suitable for displaying to the user.
-
#initialize(info = {}) ⇒ Object
Initializes a bind handler and adds the options common to all bind payloads, such as local port.
-
#start_handler ⇒ Object
Starts monitoring for an outbound connection to become established.
-
#stop_handler ⇒ Object
Nothing to speak of.
- #wrap_aes_socket(sock) ⇒ Object
Methods included from Msf::Handler
#create_session, #handle_connection, #handler, #handler_name, #interrupt_wait_for_session, #register_session, #setup_handler, #wait_for_session, #wfs_delay
Instance Attribute Details
#conn_threads ⇒ Object (protected)
:nodoc:
237 238 239 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 237 def conn_threads @conn_threads end |
#listener_pairs ⇒ Object (protected)
:nodoc:
239 240 241 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 239 def listener_pairs @listener_pairs end |
#listener_threads ⇒ Object (protected)
:nodoc:
238 239 240 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 238 def listener_threads @listener_threads end |
Class Method Details
.general_handler_type ⇒ Object
Returns the connection oriented general handler type, in this case bind.
29 30 31 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 29 def self.general_handler_type "bind" end |
.handler_type ⇒ Object
Returns the handler specific string representation, in this case ‘bind_tcp’.
22 23 24 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 22 def self.handler_type return "bind_tcp" end |
Instance Method Details
#add_handler(opts = {}) ⇒ Object
Starts a new connecting thread
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 72 def add_handler(opts={}) # Merge the updated datastore values opts.each_pair do |k,v| datastore[k] = v end # Start a new handler start_handler end |
#cleanup_handler ⇒ Object
Kills off the connection threads if there are any hanging around.
61 62 63 64 65 66 67 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 61 def cleanup_handler # Kill any remaining handle_connection threads that might # be hanging around conn_threads.each { |thr| thr.kill } end |
#human_name ⇒ String
A string suitable for displaying to the user
36 37 38 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 36 def human_name "bind TCP" end |
#initialize(info = {}) ⇒ Object
Initializes a bind handler and adds the options common to all bind payloads, such as local port.
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 44 def initialize(info = {}) super ( [ Opt::LPORT(4444), OptAddress.new('RHOST', [false, 'The target address', '']), ], Msf::Handler::BindTcp) self.conn_threads = [] self.listener_threads = [] self.listener_pairs = {} end |
#start_handler ⇒ Object
Starts monitoring for an outbound connection to become established.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 86 def start_handler # Maximum number of seconds to run the handler ctimeout = 150 if (exploit_config and exploit_config['active_timeout']) ctimeout = exploit_config['active_timeout'].to_i end # Take a copy of the datastore options rhost = datastore['RHOST'] lport = datastore['LPORT'] # Ignore this if one of the required options is missing return if not rhost return if not lport # Only try the same host/port combination once phash = rhost + ':' + lport.to_s return if self.listener_pairs[phash] self.listener_pairs[phash] = true # Start a new handling thread self.listener_threads << framework.threads.spawn("BindTcpHandlerListener-#{lport}", false) { client = nil print_status("Started #{human_name} handler against #{rhost}:#{lport}") if (rhost == nil) raise ArgumentError, "RHOST is not defined; bind stager cannot function.", caller end stime = Time.now.to_i while (stime + ctimeout > Time.now.to_i) begin client = Rex::Socket::Tcp.create( 'PeerHost' => rhost, 'PeerPort' => lport.to_i, 'Proxies' => datastore['Proxies'], 'Context' => { 'Msf' => framework, 'MsfPayload' => self, 'MsfExploit' => assoc_exploit }) rescue Rex::ConnectionError => e vprint_error(e.) rescue wlog("Exception caught in bind handler: #{$!.class} #{$!}") end break if client # Wait a second before trying again Rex::ThreadSafe.sleep(0.5) end # Valid client connection? if (client) # Increment the has connection counter self.pending_connections += 1 # Timeout and datastore options need to be passed through to the client opts = { :datastore => datastore, :expiration => datastore['SessionExpirationTimeout'].to_i, :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, :retry_total => datastore['SessionRetryTotal'].to_i, :retry_wait => datastore['SessionRetryWait'].to_i } # Start a new thread and pass the client connection # as the input and output pipe. Client's are expected # to implement the Stream interface. conn_threads << framework.threads.spawn("BindTcpHandlerSession", false, client) { |client_copy| begin handle_connection(wrap_aes_socket(client_copy), opts) rescue => e elog('Exception raised from BindTcp.handle_connection', error: e) end } else wlog("No connection received before the handler completed") end } end |
#stop_handler ⇒ Object
Nothing to speak of.
226 227 228 229 230 231 232 233 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 226 def stop_handler # Stop the listener threads self.listener_threads.each do |t| t.kill end self.listener_threads = [] self.listener_pairs = {} end |
#wrap_aes_socket(sock) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/msf/core/handler/bind_tcp.rb', line 176 def wrap_aes_socket(sock) if datastore["PAYLOAD"] !~ /java\// or (datastore["AESPassword"] || "") == "" return sock end socks = Rex::Socket::tcp_socket_pair() socks[0].extend(Rex::Socket::Tcp) socks[1].extend(Rex::Socket::Tcp) m = OpenSSL::Digest.new('md5') m.reset key = m.digest(datastore["AESPassword"] || "") Rex::ThreadFactory.spawn('AESEncryption', false) { c1 = OpenSSL::Cipher.new('aes-128-cfb8') c1.encrypt c1.key=key sock.put([0].pack('N')) sock.put(c1.iv=c1.random_iv) buf1 = socks[0].read(4096) while buf1 and buf1 != "" sock.put(c1.update(buf1)) buf1 = socks[0].read(4096) end sock.close() } Rex::ThreadFactory.spawn('AESEncryption', false) { c2 = OpenSSL::Cipher.new('aes-128-cfb8') c2.decrypt c2.key=key iv="" while iv.length < 16 iv << sock.read(16-iv.length) end c2.iv = iv buf2 = sock.read(4096) while buf2 and buf2 != "" socks[0].put(c2.update(buf2)) buf2 = sock.read(4096) end socks[0].close() } return socks[1] end |