class Metasploit::Aggregator::Http::Responder

a Responder acts a a gateway to convert data from a port to into a Request object used in the aggregator. It also reverses this process as a gateway for sending Request object back as responses to the original Request.

Attributes

log_messages[RW]
queue[RW]
time[RW]
uri[R]

Public Class Methods

get_data(connection, guaranteed_length) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 111
def self.get_data(connection, guaranteed_length)
  checked_first = has_length = guaranteed_length
  content_length = 0
  request_lines = []

  while (input = connection.gets)
    request_lines << input
    # break for body read
    break if (input.inspect.gsub /^"|"$/, '').eql? '\r\n'

    if !checked_first && !has_length
      has_length = input.include?('POST')
      checked_first = true
    end

    if has_length && input.include?('Content-Length')
      content_length = input[(input.index(':') + 1)..input.length].to_i
    end

  end
  body = ''
  if has_length
    while body.length < content_length
      body += connection.read(content_length - body.length)
    end
  end
  Metasploit::Aggregator::Http::Request.new request_lines, body, connection
end
new(uri) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 18
def initialize(uri)
  @uri = uri
  @queue = Queue.new
  @thread = Thread.new { process_requests }
  @time = Time.now
  @router = Router.instance
  @session_service = SessionDetailService.instance
  @pending_request = nil
end

Public Instance Methods

close_connection(connection) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 144
def close_connection(connection)
  connection.close
end
get_connection(host, port) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 140
def get_connection(host, port)
  TCPSocket.new host, port
end
process_requests() click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 28
def process_requests

  while true do
    begin
      request_task = @queue.pop
      connection = request_task.socket
      request_task.headers

      send, recv = @router.get_forward(@uri)
      if send.nil?
        # when no forward found park the connection for now
        # in the future this may get smarter and return a 404 or something
        send_parked_response(connection)
        next
      end

      # response from get_forward will be a queue to push messages onto and a response queue to retrieve result from
      @session_service.add_request(request_task, @uri)
      send << request_task
      @pending_request = connection

      log 'queued to console'

      # now get the response once available and send back using this connection
      begin
        request_obj = recv.pop
        @session_service.add_request(request_obj, @uri)
        tlv_response = @session_service.eval_tlv_enc(request_obj)
        unless tlv_response.nil?
          # build a new request with a the new tlv
          suppression = Metasploit::Aggregator::Http::Request.forge_request(@uri, tlv_response.to_r, connection)
          send << suppression
          log "Suppressing cryptTLV on session #{@uri}"
          send << request_task
          request_obj = recv.pop
          @session_service.add_request(suppression, @uri)
        end
        @pending_request = nil
        request_obj.headers.each do |line|
          connection.write line
        end
        unless request_obj.body.nil?
          connection.write request_obj.body
        end
        connection.flush
        @session_service.add_request(request_obj, @uri)
        log 'message delivered from console'
      rescue Exception
        log "error processing console response for #{@uri}"
      end
      close_connection(connection)
    rescue Exception => e
      log "an error occurred processing request from #{@uri}"
    end
  end

end
send_response(request_obj, connection) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 100
def send_response(request_obj, connection)
  @pending_request = nil
  request_obj.headers.each do |line|
    connection.write line
  end
  unless request_obj.body.nil?
    connection.write request_obj.body
  end
  connection.flush
end
stop_processing() click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 86
def stop_processing
  @thread.exit
  if @pending_request
    send_parked_response(@pending_request)
    close_connection(@pending_request)
  end
end

Private Instance Methods

log(message) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 148
def log(message)
  Logger.log message if @log_messages
end
send_parked_response(connection) click to toggle source
# File lib/metasploit/aggregator/http/responder.rb, line 94
def send_parked_response(connection)
  address = connection.peeraddr[3]
  log "sending parked response to #{address}"
  send_response(Metasploit::Aggregator::Http::Request.parked, connection)
end