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 +4 -4
- data/lib/bettercap/context.rb +1 -2
- data/lib/bettercap/discovery/thread.rb +13 -5
- data/lib/bettercap/memory.rb +1 -1
- data/lib/bettercap/network/network.rb +1 -1
- data/lib/bettercap/network/packet_queue.rb +3 -1
- data/lib/bettercap/network/validator.rb +9 -0
- data/lib/bettercap/options/core_options.rb +12 -16
- data/lib/bettercap/options/options.rb +1 -1
- data/lib/bettercap/options/proxy_options.rb +37 -1
- data/lib/bettercap/options/server_options.rb +6 -4
- data/lib/bettercap/options/sniff_options.rb +6 -6
- data/lib/bettercap/options/spoof_options.rb +2 -2
- data/lib/bettercap/proxy/http/module.rb +2 -2
- data/lib/bettercap/proxy/tcp/module.rb +2 -2
- data/lib/bettercap/spoofers/base.rb +1 -1
- data/lib/bettercap/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1fb03c684e4f5c63193e20fa8d8cd226f619059
|
4
|
+
data.tar.gz: 02c684a36e92f414fb1ba06095e6690309320d60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f0b04d7769d9d27a02c53bdf7af45024a417bd67fae18a3fa67b7b47af51454a8246e222df3d38657ab519af3dfa7d3e947406916ac963d6735f5514e7bc831
|
7
|
+
data.tar.gz: 9a145c4ecb97d929433b5411657d551145f3e1e4c642a42c54c5d6deba673556e53aae746647e1c82d713f0d7bb7bb049aec3648bd3ab00dcf85d5f5ae227ee5
|
data/lib/bettercap/context.rb
CHANGED
@@ -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)
|
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.' )
|
103
|
+
Logger.debug( 'Network discovery thread started.' ) if @ctx.options.core.discovery?
|
101
104
|
|
102
105
|
prev = []
|
103
106
|
while @running
|
104
|
-
|
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 )
|
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.
|
119
|
+
sleep(1) if @ctx.options.core.discovery?
|
112
120
|
end
|
113
121
|
end
|
114
122
|
end
|
data/lib/bettercap/memory.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
45
|
-
@gateway
|
46
|
-
@targets
|
47
|
-
@logfile
|
48
|
-
@log_timestamp
|
49
|
-
@silent
|
50
|
-
@debug
|
51
|
-
@ignore
|
52
|
-
@arpcache
|
53
|
-
@no_target_nbns
|
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
|
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
|
@@ -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
|
-
|
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
|
31
|
+
@httpd = false
|
32
32
|
@httpd_port = 8081
|
33
33
|
@httpd_path = './'
|
34
|
-
@dnsd
|
35
|
-
@dnsd_port
|
36
|
-
@dnsd_file
|
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
|
35
|
-
@output
|
36
|
-
@filter
|
37
|
-
@src
|
38
|
-
@parsers
|
34
|
+
@enabled = false
|
35
|
+
@output = nil
|
36
|
+
@filter = nil
|
37
|
+
@src = nil
|
38
|
+
@parsers = ['*']
|
39
39
|
@custom_parser = nil
|
40
|
-
@local
|
40
|
+
@local = false
|
41
41
|
end
|
42
42
|
|
43
43
|
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|
|
data/lib/bettercap/version.rb
CHANGED
@@ -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.
|
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.
|
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-
|
11
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|