Class: Ronin::CLI::Commands::Proxy Private

Inherits:
Ronin::CLI::Command show all
Includes:
Core::CLI::Logging, HostAndPort
Defined in:
lib/ronin/cli/commands/proxy.rb

Overview

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

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

Since:

  • 2.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HostAndPort

#host_and_port, #host_and_port_from_url

Constructor Details

#initialize(protocol: :tcp, **kwargs) ⇒ Proxy

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.

Initializes the proxy command.

Parameters:

  • protocol (:tcp, :udp, :ssl, :tls) (defaults to: :tcp)

    The protocol to use.

Since:

  • 2.0.0



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# 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

Instance Attribute Details

#closeArray<Regexp> (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 client/server close rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



246
247
248
# File 'lib/ronin/cli/commands/proxy.rb', line 246

def close
  @close
end

#close_clientArray<Regexp> (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 client close rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



206
207
208
# File 'lib/ronin/cli/commands/proxy.rb', line 206

def close_client
  @close_client
end

#close_serverArray<Regexp> (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 server close rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



226
227
228
# File 'lib/ronin/cli/commands/proxy.rb', line 226

def close_server
  @close_server
end

#ignoreArray<Regexp> (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 client/server ignore rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



251
252
253
# File 'lib/ronin/cli/commands/proxy.rb', line 251

def ignore
  @ignore
end

#ignore_clientArray<Regexp> (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 client ignore rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



211
212
213
# File 'lib/ronin/cli/commands/proxy.rb', line 211

def ignore_client
  @ignore_client
end

#ignore_serverArray<Regexp> (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 server ignore rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



231
232
233
# File 'lib/ronin/cli/commands/proxy.rb', line 231

def ignore_server
  @ignore_server
end

#protocol:tcp, ... (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 proxy protocol to use.

Returns:

  • (:tcp, :udp, :ssl, :tls)

Since:

  • 2.0.0



196
197
198
# File 'lib/ronin/cli/commands/proxy.rb', line 196

def protocol
  @protocol
end

#resetArray<Regexp> (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 client/server reset rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



241
242
243
# File 'lib/ronin/cli/commands/proxy.rb', line 241

def reset
  @reset
end

#reset_clientArray<Regexp> (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 client reset rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



201
202
203
# File 'lib/ronin/cli/commands/proxy.rb', line 201

def reset_client
  @reset_client
end

#reset_serverArray<Regexp> (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 server reset rules.

Returns:

  • (Array<Regexp>)

Since:

  • 2.0.0



221
222
223
# File 'lib/ronin/cli/commands/proxy.rb', line 221

def reset_server
  @reset_server
end

#rewriteArray<(Regexp,String)> (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 client/server rewrite rules.

Returns:

  • (Array<(Regexp,String)>)

Since:

  • 2.0.0



256
257
258
# File 'lib/ronin/cli/commands/proxy.rb', line 256

def rewrite
  @rewrite
end

#rewrite_clientArray<(Regexp,String)> (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 client rewrite rules.

Returns:

  • (Array<(Regexp,String)>)

Since:

  • 2.0.0



216
217
218
# File 'lib/ronin/cli/commands/proxy.rb', line 216

def rewrite_client
  @rewrite_client
end

#rewrite_serverArray<(Regexp,String)> (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 server rewrite rules.

Returns:

  • (Array<(Regexp,String)>)

Since:

  • 2.0.0



236
237
238
# File 'lib/ronin/cli/commands/proxy.rb', line 236

def rewrite_server
  @rewrite_server
end

Instance Method Details

#address(connection) ⇒ String (protected)

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.

Returns the address for the connection.

Parameters:

  • connection ((UDPSocket,(host, port)), TCPSocket, UDPSocket)

    The connection.

Returns:

  • (String)

    The address of the connection.

Since:

  • 2.0.0



461
462
463
464
465
466
467
468
469
470
471
472
# 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) ⇒ Object (protected)

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.

Since:

  • 2.0.0



423
424
425
426
427
428
429
430
431
432
# 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

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.

Prints data from a message.

Parameters:

  • data (String)

    The data from a message.

Since:

  • 2.0.0



506
507
508
509
510
# File 'lib/ronin/cli/commands/proxy.rb', line 506

def print_data(data)
  if @hexdumper then @hexdumper.dump(data)
  else               puts data
  end
end

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.

Prints a connection header for an incoming event.

Parameters:

  • client ((UDPSocket,(host, port)), TCPSocket, UDPSocket)

    The client.

  • event (String) (defaults to: nil)

    The optional name of the event.

Since:

  • 2.0.0



483
484
485
# File 'lib/ronin/cli/commands/proxy.rb', line 483

def print_incoming(client,event=nil)
  log_info "#{address(client)} <- #{@proxy} #{event}"
end

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.

Prints a connection header for an outgoing event.

Parameters:

  • client ((UDPSocket,(host, port)), TCPSocket, UDPSocket)

    The client.

  • type (String) (defaults to: nil)

    The optional name of the event.

Since:

  • 2.0.0



496
497
498
# File 'lib/ronin/cli/commands/proxy.rb', line 496

def print_outgoing(client,type=nil)
  log_info "#{address(client)} -> #{@proxy} #{type}"
end

#proxy_classNetwork::TCP::Proxy, Network::UDP::Proxy (protected)

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.

Determines the Proxy class based on the --tcp or --udp options.

Returns:

  • (Network::TCP::Proxy, Network::UDP::Proxy)

    The proxy class.

Since:

  • 2.0.0



441
442
443
444
445
446
447
448
449
450
# 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

#run(*args) ⇒ Object

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.

Starts the proxy.

Since:

  • 2.0.0



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# 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