Class: Ronin::Listener::HTTP::Server

Inherits:
Async::HTTP::Server
  • Object
show all
Defined in:
lib/ronin/listener/http/server.rb

Overview

A simple HTTP server that receives exfiltrated HTTP requests.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host: '0.0.0.0', port: 80, vhost: nil, root: '/') {|request| ... } ⇒ Server

Initializes the HTTP listener server.

Parameters:

  • host (String) (defaults to: '0.0.0.0')

    The interface to listen on.

  • port (Integer) (defaults to: 80)

    The local port to listen on.

  • vhost (String, Regexp) (defaults to: nil)

    The virtual host (vhost) to filter requests with.

  • root (String) (defaults to: '/')

    The root directory to filter requests with. Defaults to /.

Yields:

  • (request)

    The given block will be passed each received HTTP request.

Yield Parameters:

  • request (Request)

    The received HTTP request object.

Raises:

  • (ArgumentError)

    No callback block was given.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ronin/listener/http/server.rb', line 88

def initialize(host:  '0.0.0.0',
               port:  80,
               vhost: nil,
               root:  '/',
               &callback)
  unless callback
    raise(ArgumentError,"#{self.class}#initialize requires a callback block")
  end

  @host = host
  @port = port

  # filtering options
  @vhost = vhost
  @root  = if root.end_with?('/') then root
           else                        "#{root}/"
           end

  @callback = callback

  endpoint = Async::HTTP::Endpoint.parse("http://#{host}:#{port}")

  super(method(:process),endpoint)
end

Instance Attribute Details

#callbackProc (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The callback which will be passed all received queries.

Returns:

  • (Proc)


62
63
64
# File 'lib/ronin/listener/http/server.rb', line 62

def callback
  @callback
end

#hostString (readonly)

The host the server will listen on.

Returns:

  • (String)


40
41
42
# File 'lib/ronin/listener/http/server.rb', line 40

def host
  @host
end

#portInteger (readonly)

The port the server will listen on.

Returns:

  • (Integer)


45
46
47
# File 'lib/ronin/listener/http/server.rb', line 45

def port
  @port
end

#rootString (readonly)

The root directory to filter requests with.

Returns:

  • (String)


55
56
57
# File 'lib/ronin/listener/http/server.rb', line 55

def root
  @root
end

#vhostString, ... (readonly)

The virtual host (vhost) to filter requests with.

Returns:

  • (String, Regexp, nil)


50
51
52
# File 'lib/ronin/listener/http/server.rb', line 50

def vhost
  @vhost
end

Instance Method Details

#process(request) ⇒ Protocol::HTTP::Response

Processes a received request.

Parameters:

  • request (Async::HTTP::Protocol::HTTP1::Request, Async::HTTP::Protocol::HTTP2::Request)

Returns:

  • (Protocol::HTTP::Response)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/ronin/listener/http/server.rb', line 130

def process(request)
  if (@vhost.nil? || @vhost === request.authority)
    reference = Protocol::HTTP::Reference.parse(request.path)
    path      = reference.path

    if path == @root || path.start_with?(@root)
      @callback.call(
        Request.new(
          remote_addr: request.remote_address,
          method:      request.method,
          path:        path,
          query:       reference.query,
          version:     request.version,
          headers:     request.headers,
          body:        request.body
        )
      )
    end
  end

  return Protocol::HTTP::Response[404, {}, ["Not Found"]]
end

#run(*args) ⇒ Object

Runs the HTTP server.



116
117
118
119
120
# File 'lib/ronin/listener/http/server.rb', line 116

def run(*args)
  Async::Reactor.run do |task|
    super(*args)
  end
end