bettercap 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9a2d2ef953dadd1f83f919602e1ce9ea7412196
4
- data.tar.gz: 3f72b7be236e36d547ea39d8542946202c2299d1
3
+ metadata.gz: d1fb03c684e4f5c63193e20fa8d8cd226f619059
4
+ data.tar.gz: 02c684a36e92f414fb1ba06095e6690309320d60
5
5
  SHA512:
6
- metadata.gz: ab73ae16afddedccdc90f7a4e5c1a370ff6e020514562dfaa06b46123b838cfee1166751bec560c63143d3c24cf9e5c3bf25c7120aedf1abde3d31b2ea39503b
7
- data.tar.gz: 43286b7a2efabda473a34c333d5cbe37c1fb83706aba9a8beced40c314c84b7799062084cb2ce5eafdd9b183aa1973a664bf96aba1b5adb661d298807eb52255
6
+ metadata.gz: 9f0b04d7769d9d27a02c53bdf7af45024a417bd67fae18a3fa67b7b47af51454a8246e222df3d38657ab519af3dfa7d3e947406916ac963d6735f5514e7bc831
7
+ data.tar.gz: 9a145c4ecb97d929433b5411657d551145f3e1e4c642a42c54c5d6deba673556e53aae746647e1c82d713f0d7bb7bb049aec3648bd3ab00dcf85d5f5ae227ee5
@@ -121,12 +121,11 @@ class Context
121
121
  # Start everything!
122
122
  def start!
123
123
  # Start targets auto discovery.
124
- BetterCap::Logger.info( "Targeting the whole subnet #{@ifconfig[:ip4_obj].to_range} ..." ) unless @options.spoof.enabled? or @options.core.arpcache
125
124
  @discovery.start
126
125
  # give some time to the discovery thread to spawn its workers,
127
126
  # this will prevent 'Too many open files' errors to delay host
128
127
  # discovery.
129
- sleep(1.5) unless @options.core.arpcache
128
+ sleep(1.5) if @options.core.discovery?
130
129
 
131
130
  # Start network spoofers if any.
132
131
  @spoofer.each do |spoofer|
@@ -23,6 +23,10 @@ class Thread
23
23
 
24
24
  # Start the active network discovery thread.
25
25
  def start
26
+ if @ctx.options.core.discovery?
27
+ Logger.info "[#{'DISCOVERY'.green}] Targeting the whole subnet #{@ctx.ifconfig[:ip4_obj].to_range} ..."
28
+ end
29
+
26
30
  @running = true
27
31
  @thread = ::Thread.new { worker }
28
32
  end
@@ -31,7 +35,6 @@ class Thread
31
35
  def stop
32
36
  @running = false
33
37
  if @thread != nil
34
- Logger.info( 'Stopping network discovery thread ...' ) unless @ctx.options.core.arpcache
35
38
  begin
36
39
  @thread.exit
37
40
  rescue
@@ -97,18 +100,23 @@ class Thread
97
100
  # This method implements the main discovery logic, it will be executed within
98
101
  # the spawned thread.
99
102
  def worker
100
- Logger.debug( 'Network discovery thread started.' ) unless @ctx.options.core.arpcache
103
+ Logger.debug( 'Network discovery thread started.' ) if @ctx.options.core.discovery?
101
104
 
102
105
  prev = []
103
106
  while @running
104
- @ctx.targets = Network.get_alive_targets(@ctx).sort_by { |t| t.sortable_ip }
107
+ # No targets specified.
108
+ if @ctx.options.core.targets.nil?
109
+ @ctx.targets = Network.get_alive_targets(@ctx).sort_by {
110
+ |t| t.sortable_ip
111
+ }
112
+ end
105
113
 
106
- print_differences( prev ) unless @ctx.options.core.arpcache
114
+ print_differences( prev ) if @ctx.options.core.discovery?
107
115
 
108
116
  prev = @ctx.targets
109
117
 
110
118
  @ctx.memory.optimize!
111
- sleep(1) if @ctx.options.core.arpcache
119
+ sleep(1) if @ctx.options.core.discovery?
112
120
  end
113
121
  end
114
122
  end
@@ -46,7 +46,7 @@ class Memory
46
46
  freed_d = new_freed
47
47
  end
48
48
 
49
- Logger.debug "GC: allocd objects: #{allocs_d} freed objects: #{freed_d}"
49
+ # Logger.debug "GC: allocd objects: #{allocs_d} freed objects: #{freed_d}"
50
50
 
51
51
  @total_allocs = new_allocs
52
52
  @total_freed = new_freed
@@ -54,7 +54,7 @@ class << self
54
54
  # Return a list of BetterCap::Target objects found on the network, given a
55
55
  # BetterCap::Context ( +ctx+ ) and a +timeout+ in seconds for the operation.
56
56
  def get_alive_targets( ctx )
57
- if ctx.options.core.should_discover_hosts?
57
+ if ctx.options.core.discovery?
58
58
  start_agents( ctx )
59
59
  else
60
60
  Logger.debug 'Using current ARP cache.'
@@ -100,7 +100,9 @@ class PacketQueue
100
100
  sleep(@throttle) if @throttle != 0.0
101
101
 
102
102
  rescue Exception => e
103
- Logger.debug "#{self.class.name} ( #{packet.class.name} ) : #{e.message}"
103
+ if !e.message.include?('Host is down') and !e.message.include?('Permission denied') and !e.message.include?('No route to host')
104
+ Logger.debug "#{self.class.name} ( #{packet.class.name} ) : #{e.message}"
105
+ end
104
106
 
105
107
  # If we've got an error message such as:
106
108
  # (cannot open BPF device) /dev/bpf0: Too many open files
@@ -27,6 +27,15 @@ class Validator
27
27
  false
28
28
  end
29
29
 
30
+ # Return true if +port+ is a valid port, otherwise false.
31
+ def self.is_valid_port?(port)
32
+ port ||= ""
33
+ return false if port.strip.empty?
34
+ return false unless port =~ /^[0-9]+$/
35
+ port = port.to_i
36
+ return ( port > 0 and port <= 65535 )
37
+ end
38
+
30
39
  # Extract valid IP addresses from +data+ and yields each one of them.
31
40
  def self.each_ip(data)
32
41
  data.scan(/(#{IP_ADDRESS_REGEX})/).each do |m|
@@ -41,18 +41,18 @@ class CoreOptions
41
41
  attr_accessor :check_updates
42
42
 
43
43
  def initialize( iface )
44
- @iface = iface
45
- @gateway = nil
46
- @targets = nil
47
- @logfile = nil
48
- @log_timestamp = false
49
- @silent = false
50
- @debug = false
51
- @ignore = nil
52
- @arpcache = false
53
- @no_target_nbns = false
44
+ @iface = iface
45
+ @gateway = nil
46
+ @targets = nil
47
+ @logfile = nil
48
+ @log_timestamp = false
49
+ @silent = false
50
+ @debug = false
51
+ @ignore = nil
52
+ @arpcache = false
53
+ @no_target_nbns = false
54
54
  @packet_throttle = 0.0
55
- @check_updates = false
55
+ @check_updates = false
56
56
  end
57
57
 
58
58
  def parse!( ctx, opts )
@@ -127,6 +127,7 @@ class CoreOptions
127
127
  raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' if @iface.nil?
128
128
  end
129
129
 
130
+ # Return true if active host discovery is enabled, otherwise false.
130
131
  def discovery?
131
132
  ( @targets.nil? and !@arpcache )
132
133
  end
@@ -179,11 +180,6 @@ class CoreOptions
179
180
  def ignore_ip?(ip)
180
181
  !@ignore.nil? and @ignore.include?(ip)
181
182
  end
182
-
183
- # Return true if active host discovery is enabled, otherwise false.
184
- def should_discover_hosts?
185
- !@arpcache
186
- end
187
183
  end
188
184
 
189
185
  end
@@ -78,7 +78,7 @@ class Options
78
78
  end
79
79
 
80
80
  def need_gateway?
81
- ( @core.should_discover_hosts? or @spoof.enabled? )
81
+ ( @core.discovery? or @spoof.enabled? )
82
82
  end
83
83
 
84
84
  # Helper method to create a Firewalls::Redirection object.
@@ -98,17 +98,35 @@ class ProxyOptions
98
98
  end
99
99
 
100
100
  opts.on( '--tcp-proxy-port PORT', "Set local TCP proxy port, default to #{@tcp_proxy_port.to_s.yellow} ." ) do |v|
101
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
101
102
  @tcp_proxy = true
102
103
  @tcp_proxy_port = v.to_i
103
104
  end
104
105
 
106
+ opts.on( '--tcp-proxy-upstream ADDRESS:PORT', 'Set TCP proxy upstream server address and port.' ) do |v|
107
+ if v =~ /^(.+):(\d+)$/
108
+ address = $1
109
+ port = $2
110
+ else
111
+ raise BetterCap::Error, "Invalid address and port specified, the correct syntax is ADDRESS:PORT ( i.e. 192.168.1.2:22 )."
112
+ end
113
+
114
+ address, port = validate_address address, port
115
+
116
+ @tcp_proxy = true
117
+ @tcp_proxy_upstream_address = address
118
+ @tcp_proxy_upstream_port = port.to_i
119
+ end
120
+
105
121
  opts.on( '--tcp-proxy-upstream-address ADDRESS', 'Set TCP proxy upstream server address.' ) do |v|
106
- raise BetterCap::Error, 'Invalid TCP proxy upstream server address specified.' unless Network::Validator.is_ip?(v)
122
+ v, _ = validate_address v
123
+
107
124
  @tcp_proxy = true
108
125
  @tcp_proxy_upstream_address = v
109
126
  end
110
127
 
111
128
  opts.on( '--tcp-proxy-upstream-port PORT', 'Set TCP proxy upstream server port.' ) do |v|
129
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
112
130
  @tcp_proxy = true
113
131
  @tcp_proxy_upstream_port = v.to_i
114
132
  end
@@ -121,6 +139,7 @@ class ProxyOptions
121
139
  end
122
140
 
123
141
  opts.on( '--proxy-port PORT', "Set HTTP proxy port, default to #{@proxy_port.to_s.yellow}." ) do |v|
142
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
124
143
  @proxy = true
125
144
  @proxy_port = v.to_i
126
145
  end
@@ -146,6 +165,7 @@ class ProxyOptions
146
165
  end
147
166
 
148
167
  opts.on( '--proxy-https-port PORT', "Set HTTPS proxy port, default to #{@proxy_https_port.to_s.yellow}." ) do |v|
168
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
149
169
  @proxy_https = true
150
170
  @proxy_https_port = v.to_i
151
171
  end
@@ -168,6 +188,7 @@ class ProxyOptions
168
188
  end
169
189
 
170
190
  opts.on( '--custom-proxy-port PORT', "Specify a port for the custom HTTP upstream proxy, default to #{@custom_proxy_port.to_s.yellow}." ) do |v|
191
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
171
192
  @custom_proxy_port = v.to_i
172
193
  end
173
194
 
@@ -176,6 +197,7 @@ class ProxyOptions
176
197
  end
177
198
 
178
199
  opts.on( '--custom-https-proxy-port PORT', "Specify a port for the custom HTTPS upstream proxy, default to #{@custom_https_proxy_port.to_s.yellow}." ) do |v|
200
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
179
201
  @custom_https_proxy_port = v.to_i
180
202
  end
181
203
 
@@ -253,6 +275,20 @@ class ProxyOptions
253
275
  def any?
254
276
  @proxy or @proxy_https or @tcp_proxy or @custom_proxy
255
277
  end
278
+
279
+ def validate_address( address, port = nil )
280
+ unless Network::Validator.is_ip?(address)
281
+ begin
282
+ address = IPSocket.getaddress address
283
+ rescue SocketError
284
+ raise BetterCap::Error, "Could not resolve '#{address}' to a valid ip address."
285
+ end
286
+ end
287
+
288
+ raise BetterCap::Error, "Invalid port '#{port}' specified." unless port.nil? or Network::Validator.is_valid_port?(port)
289
+
290
+ [ address, port ]
291
+ end
256
292
  end
257
293
 
258
294
  end
@@ -28,12 +28,12 @@ class ServerOptions
28
28
  attr_accessor :dnsd_file
29
29
 
30
30
  def initialize
31
- @httpd = false
31
+ @httpd = false
32
32
  @httpd_port = 8081
33
33
  @httpd_path = './'
34
- @dnsd = false
35
- @dnsd_port = 5300
36
- @dnsd_file = nil
34
+ @dnsd = false
35
+ @dnsd_port = 5300
36
+ @dnsd_file = nil
37
37
  end
38
38
 
39
39
  def parse!( ctx, opts )
@@ -46,6 +46,7 @@ class ServerOptions
46
46
  end
47
47
 
48
48
  opts.on( '--httpd-port PORT', "Set HTTP server port, default to #{@httpd_port.to_s.yellow}." ) do |v|
49
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
49
50
  @httpd = true
50
51
  @httpd_port = v.to_i
51
52
  end
@@ -61,6 +62,7 @@ class ServerOptions
61
62
  end
62
63
 
63
64
  opts.on( '--dns-port PORT', "Set DNS server port, default to #{@dnsd_port.to_s.yellow}." ) do |v|
65
+ raise BetterCap::Error, "Invalid port '#{v}' specified." unless Network::Validator.is_valid_port?(v)
64
66
  @dnsd_port = v.to_i
65
67
  end
66
68
 
@@ -31,13 +31,13 @@ class SniffOptions
31
31
  attr_accessor :local
32
32
 
33
33
  def initialize
34
- @enabled = false
35
- @output = nil
36
- @filter = nil
37
- @src = nil
38
- @parsers = ['*']
34
+ @enabled = false
35
+ @output = nil
36
+ @filter = nil
37
+ @src = nil
38
+ @parsers = ['*']
39
39
  @custom_parser = nil
40
- @local = false
40
+ @local = false
41
41
  end
42
42
 
43
43
  def parse!( ctx, opts )
@@ -23,9 +23,9 @@ class SpoofOptions
23
23
  attr_accessor :kill
24
24
 
25
25
  def initialize
26
- @spoofer = 'ARP'
26
+ @spoofer = 'ARP'
27
27
  @half_duplex = false
28
- @kill = false
28
+ @kill = false
29
29
  end
30
30
 
31
31
  def parse!( ctx, opts )
@@ -51,8 +51,8 @@ class Module
51
51
  require ctx.options.proxies.proxy_module
52
52
 
53
53
  self.register_options(opts)
54
- rescue LoadError
55
- raise BetterCap::Error, "Invalid proxy module name '#{name}' ."
54
+ rescue LoadError => e
55
+ raise BetterCap::Error, "Invalid proxy module name '#{name}': #{e.message}"
56
56
  end
57
57
  end
58
58
 
@@ -51,8 +51,8 @@ class Module
51
51
  def load( file )
52
52
  begin
53
53
  require file
54
- rescue LoadError
55
- raise BetterCap::Error, "Invalid TCP proxy module specified."
54
+ rescue LoadError => e
55
+ raise BetterCap::Error, "Invalid TCP proxy module specified: #{e.message}"
56
56
  end
57
57
 
58
58
  @@loaded.each do |name,mod|
@@ -92,7 +92,7 @@ private
92
92
  break
93
93
  end
94
94
 
95
- Logger.debug "Spoofing #{@ctx.targets.size} targets ..."
95
+ Logger.debug "Spoofing #{@ctx.targets.size} targets ..." unless @ctx.targets.empty?
96
96
 
97
97
  update_targets!
98
98
 
@@ -12,7 +12,7 @@ This project is released under the GPL 3 license.
12
12
  =end
13
13
  module BetterCap
14
14
  # Current version of bettercap.
15
- VERSION = '1.5.0'
15
+ VERSION = '1.5.1'
16
16
  # Program banner.
17
17
  BANNER = File.read( File.dirname(__FILE__) + '/banner' ).gsub( '#VERSION#', "v#{VERSION}")
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bettercap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simone Margaritelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-16 00:00:00.000000000 Z
11
+ date: 2016-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize