class Ronin::CLI::Commands::Proxy

Starts a TCP/UDP/SSL/TLS intercept proxy server.

## Usage

ronin proxy [options]

## Options

-t, --tcp                        TCP Proxy
-S, --ssl                        SSL Proxy
-T, --tls                        TLS Proxy
-u, --udp                        UDP Proxy
-x, --[no-]hexdump               Enable hexdump output
-r, --rewrite /REGEXP/:STRING    Rewrite rules
    --rewrite-client /REGEXP/:STRING
                                 Client rewrite rules
    --rewrite-server /REGEXP/:STRING
                                 Server rewrite rules
-i, --ignore /REGEXP/            Ignore rules
    --ignore-client /REGEXP/     Client ignore rules
    --ignore-server /REGEXP/     Server ignore rules
-C, --close /REGEXP/             Close rules
    --close-client /REGEXP/      Client close rules
    --close-server /REGEXP/      Server close rules
-R, --reset /REGEXP/             Reset rules
    --reset-client /REGEXP/      Client reset rules
    --reset-server /REGEXP/      Server reset rules
-h, --help                       Print help information

## Arguments

[PROXY_HOST:]PROXY_PORT          The local host and/or port to
                                 listen on.
REMOTE_HOST:REMOTE_PORT          The remote server to proxy data to.

## Examples

ronin proxy 8080 google.com:80
ronin proxy --udp --hexdump 0.0.0.0:53 8.8.8.8:53

Attributes

close[R]

The client/server close rules.

@return [Array<Regexp>]

close_client[R]

The client close rules.

@return [Array<Regexp>]

close_server[R]

The server close rules.

@return [Array<Regexp>]

ignore[R]

The client/server ignore rules.

@return [Array<Regexp>]

ignore_client[R]

The client ignore rules.

@return [Array<Regexp>]

ignore_server[R]

The server ignore rules.

@return [Array<Regexp>]

protocol[R]

The proxy protocol to use.

@return [:tcp, :udp, :ssl, :tls]

reset[R]

The client/server reset rules.

@return [Array<Regexp>]

reset_client[R]

The client reset rules.

@return [Array<Regexp>]

reset_server[R]

The server reset rules.

@return [Array<Regexp>]

rewrite[R]

The client/server rewrite rules.

@return [Array<(Regexp,String)>]

rewrite_client[R]

The client rewrite rules.

@return [Array<(Regexp,String)>]

rewrite_server[R]

The server rewrite rules.

@return [Array<(Regexp,String)>]

Public Class Methods

new(protocol: :tcp, **kwargs) click to toggle source

Initializes the proxy command.

@param [:tcp, :udp, :ssl, :tls] protocol

The protocol to use.
Calls superclass method
# File lib/ronin/cli/commands/proxy.rb, line 264
def initialize(protocol: :tcp, **kwargs)
  super(**kwargs)

  @protocol = protocol

  # client rules
  @reset_client   = []
  @close_client   = []
  @ignore_client  = []
  @rewrite_client = []

  # server rules
  @reset_server   = []
  @close_server   = []
  @ignore_server  = []
  @rewrite_server = []

  # client/server rules
  @reset   = []
  @close   = []
  @ignore  = []
  @rewrite = []
end

Public Instance Methods

run(*args) click to toggle source

Starts the proxy.

# File lib/ronin/cli/commands/proxy.rb, line 291
def run(*args)
  local, upstream = *args

  if local.include?(':')
    proxy_host, proxy_port = host_and_port(local)
  else
    proxy_port = local.to_i
  end

  upstream_host, upstream_port = host_and_port(upstream)

  if options[:hexdump]
    @hexdumper = Hexdump::Hexdump.new
  end

  @proxy = proxy_class.new(
    port:   proxy_port,
    host:   proxy_host,
    server: [upstream_host, upstream_port]
  )

  case @protocol
  when :tcp, :ssl, :tls
    @proxy.on_client_connect do |client|
      print_outgoing client, '[connecting]'
    end

    @proxy.on_client_disconnect do |client,server|
      print_outgoing client, '[disconnecting]'
    end

    @proxy.on_server_connect do |client,server|
      print_incoming client, '[connected]'
    end

    @proxy.on_server_disconnect do |client,server|
      print_incoming client, '[disconnected]'
    end
  end

  # configure the client rules
  @reset_client.each do |pattern|
    @proxy.on_client_data do |client,server,data|
      @proxy.reset! if data =~ pattern
    end
  end

  @close_client.each do |pattern|
    @proxy.on_client_data do |client,server,data|
      @proxy.close! if data =~ pattern
    end
  end

  @ignore_client.each do |pattern|
    @proxy.on_client_data do |client,server,data|
      @proxy.ignore! if data =~ pattern
    end
  end

  @rewrite_client.each do |pattern,replace|
    @proxy.on_client_data do |client,server,data|
      data.gsub!(pattern,replace)
    end
  end

  # configure the server rules
  @reset_server.each do |pattern|
    @proxy.on_server_data do |client,server,data|
      @proxy.reset! if data =~ pattern
    end
  end

  @close_server.each do |pattern|
    @proxy.on_server_data do |client,server,data|
      @proxy.close! if data =~ pattern
    end
  end

  @ignore_server.each do |pattern|
    @proxy.on_server_data do |client,server,data|
      @proxy.ignore! if data =~ pattern
    end
  end

  @rewrite_server.each do |pattern,replace|
    @proxy.on_server_data do |client,server,data|
      data.gsub!(pattern,replace)
    end
  end

  # configure the client/server rules
  @reset.each do |pattern|
    @proxy.on_data do |client,server,data|
      @proxy.reset! if data =~ pattern
    end
  end

  @close.each do |pattern|
    @proxy.on_data do |client,server,data|
      @proxy.close! if data =~ pattern
    end
  end

  @ignore.each do |pattern|
    @proxy.on_data do |client,server,data|
      @proxy.ignore! if data =~ pattern
    end
  end

  @rewrite.each do |pattern,replace|
    @proxy.on_data do |client,server,data|
      data.gsub!(pattern,replace)
    end
  end

  # printing rules
  @proxy.on_client_data do |client,server,data|
    print_outgoing client
    print_data data
  end

  @proxy.on_server_data do |client,server,data|
    print_incoming client
    print_data data
  end

  log_info "Listening on #{proxy_host}:#{proxy_port} ..."
  @proxy.start
end

Protected Instance Methods

address(connection) click to toggle source

Returns the address for the connection.

@param [(UDPSocket,(host, port)), TCPSocket, UDPSocket] connection

The connection.

@return [String]

The address of the connection.
# File lib/ronin/cli/commands/proxy.rb, line 461
def address(connection)
  case connection
  when Array
    _socket, (host, port) = connection

    "#{host}:#{port}"
  when TCPSocket, UDPSocket
    addrinfo = connection.peeraddr

    "#{addrinfo[3]}:#{addrinfo[1]}"
  end
end
parse_rewrite_rule(string) click to toggle source
# File lib/ronin/cli/commands/proxy.rb, line 423
def parse_rewrite_rule(string)
  unless (index = string.rindex('/:'))
    raise(OptionParser::InvalidArgument,"invalid rewrite rule: #{string}")
  end

  regexp  = Regexp.new(string[1...index])
  pattern = string[(index + 2)..]

  return regexp, pattern
end
print_data(data) click to toggle source

Prints data from a message.

@param [String] data

The data from a message.
print_incoming(client,event=nil) click to toggle source

Prints a connection header for an incoming event.

@param [(UDPSocket,(host, port)), TCPSocket, UDPSocket] client

The client.

@param [String] event

The optional name of the event.
print_outgoing(client,type=nil) click to toggle source

Prints a connection header for an outgoing event.

@param [(UDPSocket,(host, port)), TCPSocket, UDPSocket] client

The client.

@param [String] type

The optional name of the event.
proxy_class() click to toggle source

Determines the Proxy class based on the ‘–tcp` or `–udp` options.

@return [Network::TCP::Proxy, Network::UDP::Proxy]

The proxy class.
# File lib/ronin/cli/commands/proxy.rb, line 441
def proxy_class
  case @protocol
  when :tcp then Support::Network::TCP::Proxy
  when :udp then Support::Network::UDP::Proxy
  when :ssl then Support::Network::SSL::Proxy
  when :tls then Support::Network::TLS::Proxy
  else
    raise(NotImplementedError,"#{@protocol.inspect} proxy value not supported")
  end
end