Class: BetterCap::Options

Inherits:
Object
  • Object
show all
Defined in:
lib/bettercap/options.rb

Overview

Parse command line arguments, set options and initialize Context accordingly.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(iface) ⇒ Options

Create a BetterCap::Options class instance using the specified network interface.


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
# File 'lib/bettercap/options.rb', line 94

def initialize( iface )
  @gateway = nil
  @iface = iface
  @spoofer = 'ARP'
  @half_duplex = false
  @target = nil
  @logfile = nil
  @silent = false
  @debug = false
  @arpcache = false
  @no_target_nbns = false
  @kill = false
  @packet_throttle = 0.0
  @http_ports = [ 80 ]
  @https_ports = [ 443 ]
  @ignore = nil

  @sniffer = false
  @sniffer_pcap = nil
  @sniffer_filter = nil
  @sniffer_src = nil
  @parsers = ['*']
  @custom_parser = nil
  @local = false

  @proxy = false
  @proxy_https = false
  @proxy_port = 8080
  @proxy_https_port = 8083
  @proxy_pem_file = nil
  @proxy_module = nil

  @custom_proxy = nil
  @custom_proxy_port = 8080

  @custom_https_proxy = nil
  @custom_https_proxy_port = 8083

  @httpd = false
  @httpd_port = 8081
  @httpd_path = './'

  @check_updates = false
end

Instance Attribute Details

#arpcacheObject

If true will disable active network discovery, the program will just use the current ARP cache.


35
36
37
# File 'lib/bettercap/options.rb', line 35

def arpcache
  @arpcache
end

#check_updatesObject

If true, bettercap will check for updates then exit.


84
85
86
# File 'lib/bettercap/options.rb', line 84

def check_updates
  @check_updates
end

#custom_https_proxyObject

Custom HTTPS transparent proxy address.


74
75
76
# File 'lib/bettercap/options.rb', line 74

def custom_https_proxy
  @custom_https_proxy
end

#custom_https_proxy_portObject

Custom HTTPS transparent proxy port.


76
77
78
# File 'lib/bettercap/options.rb', line 76

def custom_https_proxy_port
  @custom_https_proxy_port
end

#custom_parserObject

Regular expression to use with the BetterCap::Parsers::Custom parser.


50
51
52
# File 'lib/bettercap/options.rb', line 50

def custom_parser
  @custom_parser
end

#custom_proxyObject

Custom HTTP transparent proxy address.


70
71
72
# File 'lib/bettercap/options.rb', line 70

def custom_proxy
  @custom_proxy
end

#custom_proxy_portObject

Custom HTTP transparent proxy port.


72
73
74
# File 'lib/bettercap/options.rb', line 72

def custom_proxy_port
  @custom_proxy_port
end

#debugObject

If true will enable debug messages.


32
33
34
# File 'lib/bettercap/options.rb', line 32

def debug
  @debug
end

#gatewayObject

Gateway IP address.


18
19
20
# File 'lib/bettercap/options.rb', line 18

def gateway
  @gateway
end

#half_duplexObject

If true half duplex mode is enabled.


24
25
26
# File 'lib/bettercap/options.rb', line 24

def half_duplex
  @half_duplex
end

#http_portsObject

List of HTTP ports, [ 80 ] by default.


60
61
62
# File 'lib/bettercap/options.rb', line 60

def http_ports
  @http_ports
end

#httpdObject

If true, BetterCap::HTTPD::Server will be enabled.


78
79
80
# File 'lib/bettercap/options.rb', line 78

def httpd
  @httpd
end

#httpd_pathObject

Web root of the BetterCap::HTTPD::Server.


82
83
84
# File 'lib/bettercap/options.rb', line 82

def httpd_path
  @httpd_path
end

#httpd_portObject

The port to bind BetterCap::HTTPD::Server to.


80
81
82
# File 'lib/bettercap/options.rb', line 80

def httpd_port
  @httpd_port
end

#https_portsObject

List of HTTPS ports, [ 443 ] by default.


64
65
66
# File 'lib/bettercap/options.rb', line 64

def https_ports
  @https_ports
end

#ifaceObject

Network interface.


20
21
22
# File 'lib/bettercap/options.rb', line 20

def iface
  @iface
end

#ignoreObject

Comma separated list of ip addresses to ignore.


37
38
39
# File 'lib/bettercap/options.rb', line 37

def ignore
  @ignore
end

#killObject

If true, bettercap won't forward packets for any target, causing connections to be killed.


89
90
91
# File 'lib/bettercap/options.rb', line 89

def kill
  @kill
end

#localObject

If true, bettercap will sniff packets from the local interface as well.


52
53
54
# File 'lib/bettercap/options.rb', line 52

def local
  @local
end

#logfileObject

Log file name.


28
29
30
# File 'lib/bettercap/options.rb', line 28

def logfile
  @logfile
end

#no_target_nbnsObject

If true, targets NBNS hostname resolution won't be performed.


86
87
88
# File 'lib/bettercap/options.rb', line 86

def no_target_nbns
  @no_target_nbns
end

#packet_throttleObject

If different than 0, this time will be used as a delay while sending packets.


91
92
93
# File 'lib/bettercap/options.rb', line 91

def packet_throttle
  @packet_throttle
end

#parsersObject

Comma separated list of BetterCap::Parsers to enable.


48
49
50
# File 'lib/bettercap/options.rb', line 48

def parsers
  @parsers
end

#proxyObject

If true, HTTP transparent proxy will be enabled.


54
55
56
# File 'lib/bettercap/options.rb', line 54

def proxy
  @proxy
end

#proxy_httpsObject

If true, HTTPS transparent proxy will be enabled.


56
57
58
# File 'lib/bettercap/options.rb', line 56

def proxy_https
  @proxy_https
end

#proxy_https_portObject

HTTPS proxy port.


62
63
64
# File 'lib/bettercap/options.rb', line 62

def proxy_https_port
  @proxy_https_port
end

#proxy_moduleObject

File name of the transparent proxy module to load.


68
69
70
# File 'lib/bettercap/options.rb', line 68

def proxy_module
  @proxy_module
end

#proxy_pem_fileObject

File name of the PEM certificate to use for the HTTPS proxy.


66
67
68
# File 'lib/bettercap/options.rb', line 66

def proxy_pem_file
  @proxy_pem_file
end

#proxy_portObject

HTTP proxy port.


58
59
60
# File 'lib/bettercap/options.rb', line 58

def proxy_port
  @proxy_port
end

#silentObject

If true will suppress every log message which is not an error or a warning.


30
31
32
# File 'lib/bettercap/options.rb', line 30

def silent
  @silent
end

#snifferObject

If true the BetterCap::Sniffer will be enabled.


39
40
41
# File 'lib/bettercap/options.rb', line 39

def sniffer
  @sniffer
end

#sniffer_filterObject

BPF filter to apply to sniffed packets.


43
44
45
# File 'lib/bettercap/options.rb', line 43

def sniffer_filter
  @sniffer_filter
end

#sniffer_pcapObject

PCAP file name to save captured packets to.


41
42
43
# File 'lib/bettercap/options.rb', line 41

def sniffer_pcap
  @sniffer_pcap
end

#sniffer_srcObject

Input PCAP file, if specified the BetterCap::Sniffer will read packets from it instead of the network.


46
47
48
# File 'lib/bettercap/options.rb', line 46

def sniffer_src
  @sniffer_src
end

#spooferObject

Name of the spoofer to use.


22
23
24
# File 'lib/bettercap/options.rb', line 22

def spoofer
  @spoofer
end

#targetObject

Comma separated list of targets.


26
27
28
# File 'lib/bettercap/options.rb', line 26

def target
  @target
end

Class Method Details

.parse!Object

Initialize the BetterCap::Context, parse command line arguments and update program state accordingly. Will rise a BetterCap::Error if errors occurred.

Raises:


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
175
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
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
# File 'lib/bettercap/options.rb', line 142

def self.parse!
  ctx = Context.get

  OptionParser.new do |opts|
    opts.version = BetterCap::VERSION
    opts.banner = "Usage: bettercap [options]"
    opts.separator ""
    opts.separator "Specific options:"
    opts.separator ""

    opts.on( '-G', '--gateway ADDRESS', 'Manually specify the gateway address, if not specified the current gateway will be retrieved and used. ' ) do |v|
      ctx.options.gateway = v
    end

    opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options.iface.to_s ) do |v|
      ctx.options.iface = v
    end

    opts.on( '-S', '--spoofer NAME', 'Spoofer module to use, available: ' + Factories::Spoofer.available.join(', ') + ' - default: ' + ctx.options.spoofer ) do |v|
      ctx.options.spoofer = v
    end

    opts.on( '-T', '--target ADDRESS1,ADDRESS2', 'Target IP addresses, if not specified the whole subnet will be targeted.' ) do |v|
      ctx.options.target = v
    end

    opts.on( '--ignore ADDRESS1,ADDRESS2', 'Ignore these addresses if found while searching for targets.' ) do |v|
      ctx.options.ignore = v
    end

    opts.on( '-O', '--log LOG_FILE', 'Log all messages into a file, if not specified the log messages will be only print into the shell.' ) do |v|
      ctx.options.logfile = v
    end

    opts.on( '-D', '--debug', 'Enable debug logging.' ) do
      ctx.options.debug = true
    end

    opts.on( '-L', '--local', 'Parse packets coming from/to the address of this computer ( NOTE: Will set -X to true ), default to false.' ) do
      ctx.options.local = true
      ctx.options.sniffer = true
    end

    opts.on( '-X', '--sniffer', 'Enable sniffer.' ) do
      ctx.options.sniffer = true
    end

    opts.on( '--sniffer-source FILE', 'Load packets from the specified PCAP file instead of the interface ( will enable sniffer ).' ) do |v|
      ctx.options.sniffer = true
      ctx.options.sniffer_src = File.expand_path v
    end

    opts.on( '--sniffer-pcap FILE', 'Save all packets to the specified PCAP file ( will enable sniffer ).' ) do |v|
      ctx.options.sniffer = true
      ctx.options.sniffer_pcap = File.expand_path v
    end

    opts.on( '--sniffer-filter EXPRESSION', 'Configure the sniffer to use this BPF filter ( will enable sniffer ).' ) do |v|
      ctx.options.sniffer = true
      ctx.options.sniffer_filter = v
    end

    opts.on( '-P', '--parsers PARSERS', 'Comma separated list of packet parsers to enable, "*" for all ( NOTE: Will set -X to true ), available: ' + Factories::Parser.available.join(', ') + ' - default: *' ) do |v|
      ctx.options.sniffer = true
      ctx.options.parsers = Factories::Parser.from_cmdline(v)
    end

    opts.on( '--custom-parser EXPRESSION', 'Use a custom regular expression in order to capture and show sniffed data ( NOTE: Will set -X to true ).' ) do |v|
      ctx.options.sniffer       = true
      ctx.options.parsers       = ['CUSTOM']
      ctx.options.custom_parser = Regexp.new(v)
    end

    opts.on( '--silent', 'Suppress every message which is not an error or a warning, default to false.' ) do
      ctx.options.silent = true
    end

    opts.on( '--no-discovery', 'Do not actively search for hosts, just use the current ARP cache, default to false.' ) do
      ctx.options.arpcache = true
    end

    opts.on( '--no-spoofing', 'Disable spoofing, alias for --spoofer NONE.' ) do
      ctx.options.spoofer = 'NONE'
    end

    opts.on( '--no-target-nbns', 'Disable target NBNS hostname resolution.' ) do
      ctx.options.no_target_nbns = true
    end

    opts.on( '--half-duplex', 'Enable half-duplex MITM, this will make bettercap work in those cases when the router is not vulnerable.' ) do
      ctx.options.half_duplex = true
    end

    opts.on( '--proxy', 'Enable HTTP proxy and redirects all HTTP requests to it, default to false.' ) do
      ctx.options.proxy = true
    end

    opts.on( '--proxy-https', 'Enable HTTPS proxy and redirects all HTTPS requests to it, default to false.' ) do
      ctx.options.proxy = true
      ctx.options.proxy_https = true
    end

    opts.on( '--proxy-port PORT', 'Set HTTP proxy port, default to ' + ctx.options.proxy_port.to_s + ' .' ) do |v|
      ctx.options.proxy = true
      ctx.options.proxy_port = v.to_i
    end

    opts.on( '--http-ports PORT1,PORT2', 'Comma separated list of HTTP ports to redirect to the proxy, default to ' + ctx.options.http_ports.join(', ') + ' .' ) do |v|
      ctx.options.http_ports = v
    end

    opts.on( '--https-ports PORT1,PORT2', 'Comma separated list of HTTPS ports to redirect to the proxy, default to ' + ctx.options.https_ports.join(', ') + ' .' ) do |v|
      ctx.options.https_ports = v
    end

    opts.on( '--proxy-https-port PORT', 'Set HTTPS proxy port, default to ' + ctx.options.proxy_https_port.to_s + ' .' ) do |v|
      ctx.options.proxy = true
      ctx.options.proxy_https = true
      ctx.options.proxy_https_port = v.to_i
    end

    opts.on( '--proxy-pem FILE', 'Use a custom PEM certificate file for the HTTPS proxy.' ) do |v|
      ctx.options.proxy = true
      ctx.options.proxy_https = true
      ctx.options.proxy_pem_file = File.expand_path v
    end

    opts.on( '--proxy-module MODULE', 'Ruby proxy module to load, either a custom file or one of the following: ' + Proxy::Module.available.join(', ') + ' .' ) do |v|
      Proxy::Module.load(ctx, opts, v)
    end

    opts.on( '--custom-proxy ADDRESS', 'Use a custom HTTP upstream proxy instead of the builtin one.' ) do |v|
      ctx.options.custom_proxy = v
    end

    opts.on( '--custom-proxy-port PORT', 'Specify a port for the custom HTTP upstream proxy, default to ' + ctx.options.custom_proxy_port.to_s + ' .' ) do |v|
      ctx.options.custom_proxy_port = v.to_i
    end

    opts.on( '--custom-https-proxy ADDRESS', 'Use a custom HTTPS upstream proxy instead of the builtin one.' ) do |v|
      ctx.options.custom_https_proxy = v
    end

    opts.on( '--custom-https-proxy-port PORT', 'Specify a port for the custom HTTPS upstream proxy, default to ' + ctx.options.custom_https_proxy_port.to_s + ' .' ) do |v|
      ctx.options.custom_https_proxy_port = v.to_i
    end

    opts.on( '--httpd', 'Enable HTTP server, default to false.' ) do
      ctx.options.httpd = true
    end

    opts.on( '--httpd-port PORT', 'Set HTTP server port, default to ' + ctx.options.httpd_port.to_s +  '.' ) do |v|
      ctx.options.httpd = true
      ctx.options.httpd_port = v.to_i
    end

    opts.on( '--httpd-path PATH', 'Set HTTP server path, default to ' + ctx.options.httpd_path +  '.' ) do |v|
      ctx.options.httpd = true
      ctx.options.httpd_path = v
    end

    opts.on( '--kill', 'Instead of forwarding packets, this switch will make targets connections to be killed.' ) do
      ctx.options.kill = true
    end

    opts.on( '--packet-throttle NUMBER', 'Number of seconds ( can be a decimal number ) to wait between each packet to be sent.' ) do |v|
      ctx.options.packet_throttle = v.to_f
      raise BetterCap::Error, "Invalid packet throttle value specified." if ctx.options.packet_throttle <= 0.0
    end

    opts.on( '--check-updates', 'Will check if any update is available and then exit.' ) do
      ctx.options.check_updates = true
    end

    opts.on('-h', '--help', 'Display the available options.') do
      puts opts
      puts "\nFor examples & docs please visit " + "http://bettercap.org/docs/".bold
      exit
    end
  end.parse!

  Logger.init( ctx.options.debug, ctx.options.logfile, ctx.options.silent )

  Logger.warn "You are running an unstable/beta version of this software, please" \
              " update to a stable one if available." if BetterCap::VERSION =~ /[\d\.+]b/

  if ctx.options.check_updates
    UpdateChecker.check
    exit
  end

  raise BetterCap::Error, 'This software must run as root.' unless Process.uid == 0
  raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' if ctx.options.iface.nil?

  unless ctx.options.gateway.nil?
    raise BetterCap::Error, "The specified gateway '#{ctx.options.gateway}' is not a valid IPv4 address." unless Network.is_ip?(ctx.options.gateway)
    ctx.gateway = ctx.options.gateway
    Logger.debug("Targetting manually specified gateway #{ctx.gateway}")
  end

  unless ctx.options.target.nil?
    ctx.targets = ctx.options.to_targets
  end

  # Load firewall instance, network interface informations and detect the
  # gateway address.
  ctx.update!

  # Spoofers need the context network data to be initialized.
  ctx.spoofer = ctx.options.to_spoofers

  ctx
end

Instance Method Details

#has_http_sniffer_enabled?Boolean

Return true if the BetterCap::Parsers::URL is enabled, otherwise false.

Returns:

  • (Boolean)

372
373
374
# File 'lib/bettercap/options.rb', line 372

def has_http_sniffer_enabled?
  @sniffer and ( @parsers.include?'*' or @parsers.include?'URL' )
end

#has_proxy_module?Boolean

Return true if a proxy module was specified, otherwise false.

Returns:

  • (Boolean)

362
363
364
# File 'lib/bettercap/options.rb', line 362

def has_proxy_module?
  !@proxy_module.nil?
end

#has_spoofer?Boolean

Return true if a spoofer module was specified, otherwise false.

Returns:

  • (Boolean)

367
368
369
# File 'lib/bettercap/options.rb', line 367

def has_spoofer?
  @spoofer != 'NONE' and @spoofer != 'none'
end

#ignore_ip?(ip) ⇒ Boolean

Return true if the ip address needs to be ignored, otherwise false.

Returns:

  • (Boolean)

377
378
379
# File 'lib/bettercap/options.rb', line 377

def ignore_ip?(ip)
  !@ignore.nil? and @ignore.include?(ip)
end

#should_discover_hosts?Boolean

Return true if active host discovery is enabled, otherwise false.

Returns:

  • (Boolean)

357
358
359
# File 'lib/bettercap/options.rb', line 357

def should_discover_hosts?
  !@arpcache
end

#to_ports(value) ⇒ Object

Parse a comma separated list of ports and return an array containing only valid ports, raise BetterCap::Error if that array is empty.

Raises:


415
416
417
418
419
420
421
422
423
424
425
# File 'lib/bettercap/options.rb', line 415

def to_ports(value)
  ports = []
  value.split(",").each do |v|
    v = v.strip.to_i
    if v > 0 and v <= 65535
      ports << v
    end
  end
  raise BetterCap::Error, 'Invalid ports specified.' if ports.empty?
  ports
end

#to_redirections(ifconfig) ⇒ Object

Create a list of BetterCap::Firewalls::Redirection objects which are needed given the specified command line arguments.


468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/bettercap/options.rb', line 468

def to_redirections ifconfig
  redirections = []

  if @proxy
    @http_ports.each do |port|
      redirections << Firewalls::Redirection.new( @iface,
                                       'TCP',
                                       port,
                                       ifconfig[:ip_saddr],
                                       @proxy_port )
    end
  end

  if @proxy_https
    @https_ports.each do |port|
      redirections << Firewalls::Redirection.new( @iface,
                                       'TCP',
                                       port,
                                       ifconfig[:ip_saddr],
                                       @proxy_https_port )
    end
  end

  if @custom_proxy
    @http_ports.each do |port|
      redirections << Firewalls::Redirection.new( @iface,
                                       'TCP',
                                       port,
                                       @custom_proxy,
                                       @custom_proxy_port )
    end
  end

  if @custom_https_proxy
    @https_ports.each do |port|
      redirections << Firewalls::Redirection.new( @iface,
                                       'TCP',
                                       port,
                                       @custom_https_proxy,
                                       @custom_https_proxy_port )
    end
  end

  redirections
end

#to_spoofersObject

Parse spoofers and return a list of BetterCap::Spoofers objects. Raise a BetterCap::Error if an invalid spoofer name was specified.


457
458
459
460
461
462
463
464
# File 'lib/bettercap/options.rb', line 457

def to_spoofers
  spoofers = []
  spoofer_modules_names = @spoofer.split(",")
  spoofer_modules_names.each do |module_name|
    spoofers << Factories::Spoofer.get_by_name( module_name )
  end
  spoofers
end

#to_targetsObject

Split specified targets and parse them ( either as IP or MAC ), will raise a BetterCap::Error if one or more invalid addresses are specified.

Raises:


441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/bettercap/options.rb', line 441

def to_targets
  targets = @target.split(",")
  valid_targets = targets.select { |target| Network.is_ip?(target) or Network.is_mac?(target) }

  raise BetterCap::Error, "Invalid target specified." if valid_targets.empty?

  invalid_targets = targets - valid_targets
  invalid_targets.each do |target|
    Logger.warn "Invalid target specified: #{target}"
  end

  valid_targets.map { |target| Network::Target.new(target) }
end