bettercap 1.1.9 → 1.1.10

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +2 -2
  3. data/TODO.md +5 -2
  4. data/bin/bettercap +19 -11
  5. data/lib/bettercap.rb +5 -1
  6. data/lib/bettercap/base/ifirewall.rb +2 -0
  7. data/lib/bettercap/base/ispoofer.rb +2 -0
  8. data/lib/bettercap/context.rb +5 -2
  9. data/lib/bettercap/discovery/{arp.rb → agents/arp.rb} +15 -14
  10. data/lib/bettercap/discovery/{base.rb → agents/base.rb} +4 -4
  11. data/lib/bettercap/discovery/{icmp.rb → agents/icmp.rb} +2 -3
  12. data/lib/bettercap/discovery/{udp.rb → agents/udp.rb} +2 -2
  13. data/lib/bettercap/{discovery.rb → discovery/discovery.rb} +8 -1
  14. data/lib/bettercap/factories/firewall_factory.rb +2 -0
  15. data/lib/bettercap/factories/parser_factory.rb +11 -5
  16. data/lib/bettercap/factories/spoofer_factory.rb +3 -1
  17. data/lib/bettercap/firewalls/linux.rb +2 -0
  18. data/lib/bettercap/firewalls/osx.rb +2 -0
  19. data/lib/bettercap/firewalls/redirection.rb +2 -1
  20. data/lib/bettercap/httpd/server.rb +2 -3
  21. data/lib/bettercap/logger.rb +27 -10
  22. data/lib/bettercap/monkey/packetfu/utils.rb +5 -5
  23. data/lib/bettercap/network.rb +26 -16
  24. data/lib/bettercap/options.rb +27 -6
  25. data/lib/bettercap/proxy/certstore.rb +4 -3
  26. data/lib/bettercap/proxy/module.rb +2 -2
  27. data/lib/bettercap/proxy/proxy.rb +5 -5
  28. data/lib/bettercap/proxy/request.rb +2 -2
  29. data/lib/bettercap/proxy/response.rb +2 -0
  30. data/lib/bettercap/proxy/stream_logger.rb +15 -3
  31. data/lib/bettercap/proxy/streamer.rb +3 -1
  32. data/lib/bettercap/proxy/thread_pool.rb +4 -2
  33. data/lib/bettercap/shell.rb +2 -0
  34. data/lib/bettercap/sniffer/parsers/base.rb +3 -12
  35. data/lib/bettercap/sniffer/parsers/custom.rb +21 -0
  36. data/lib/bettercap/sniffer/parsers/ftp.rb +2 -0
  37. data/lib/bettercap/sniffer/parsers/httpauth.rb +4 -5
  38. data/lib/bettercap/sniffer/parsers/https.rb +3 -4
  39. data/lib/bettercap/sniffer/parsers/irc.rb +2 -0
  40. data/lib/bettercap/sniffer/parsers/mail.rb +2 -0
  41. data/lib/bettercap/sniffer/parsers/ntlmss.rb +3 -3
  42. data/lib/bettercap/sniffer/parsers/post.rb +7 -7
  43. data/lib/bettercap/sniffer/parsers/url.rb +11 -11
  44. data/lib/bettercap/sniffer/sniffer.rb +8 -2
  45. data/lib/bettercap/spoofers/arp.rb +15 -5
  46. data/lib/bettercap/spoofers/none.rb +2 -0
  47. data/lib/bettercap/target.rb +29 -10
  48. data/lib/bettercap/update_checker.rb +2 -0
  49. data/lib/bettercap/version.rb +1 -1
  50. metadata +8 -40
  51. data/Rakefile +0 -7
  52. data/test/factories/firewall_factory_test.rb +0 -54
  53. data/test/factories/parser_factory_test.rb +0 -36
  54. data/test/factories/spoofer_factory_test.rb +0 -15
  55. data/test/firewalls/linux_firewall_test.rb +0 -72
  56. data/test/firewalls/osx_firewall_test.rb +0 -72
  57. data/test/helpers/mock_shell.rb +0 -17
  58. data/test/logger_test.rb +0 -12
  59. data/test/network_test.rb +0 -14
  60. data/test/pcap/ftp.pcap +0 -0
  61. data/test/pcap/http.pcap +0 -0
  62. data/test/pcap/packets.pcap +0 -0
  63. data/test/proxy/response_test.rb +0 -56
  64. data/test/shell_test.rb +0 -15
  65. data/test/sniffer/parsers/base_parser_test.rb +0 -20
  66. data/test/sniffer/parsers/ftp_parser_test.rb +0 -27
  67. data/test/sniffer/parsers/url_parser_test.rb +0 -25
  68. data/test/target_test.rb +0 -24
  69. data/test/test_helper.rb +0 -47
@@ -9,6 +9,7 @@ Blog : http://www.evilsocket.net/
9
9
  This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
+ module BetterCap
12
13
  class Redirection
13
14
  attr_reader :interface, :protocol, :src_port, :dst_address, :dst_port
14
15
 
@@ -20,4 +21,4 @@ class Redirection
20
21
  @dst_port = dst_port
21
22
  end
22
23
  end
23
-
24
+ end
@@ -13,8 +13,8 @@ require 'webrick'
13
13
 
14
14
  require 'bettercap/logger'
15
15
 
16
+ module BetterCap
16
17
  module HTTPD
17
-
18
18
  class Server
19
19
  def initialize( port = 8081, path = './' )
20
20
  @port = port
@@ -41,6 +41,5 @@ class Server
41
41
  @thread.join
42
42
  end
43
43
  end
44
-
45
44
  end
46
-
45
+ end
@@ -9,13 +9,21 @@ Blog : http://www.evilsocket.net/
9
9
  This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
+ module BetterCap
12
13
  module Logger
13
14
  class << self
14
- def init( debug, logfile )
15
+ @@queue = Queue.new
16
+ @@debug = false
17
+ @@silent = false
18
+ @@logfile = nil
19
+ @@thread = nil
20
+
21
+ def init( debug, logfile, silent )
15
22
  @@debug = debug
16
23
  @@logfile = logfile
17
- @@queue = Queue.new
18
24
  @@thread = Thread.new { worker }
25
+ @@silent = silent
26
+ @@ctx = Context.get
19
27
  end
20
28
 
21
29
  def error(message)
@@ -23,7 +31,7 @@ module Logger
23
31
  end
24
32
 
25
33
  def info(message)
26
- @@queue.push formatted_message(message, 'I')
34
+ @@queue.push( formatted_message(message, 'I') ) unless @@silent
27
35
  end
28
36
 
29
37
  def warn(message)
@@ -31,13 +39,19 @@ module Logger
31
39
  end
32
40
 
33
41
  def debug(message)
34
- if @@debug
42
+ if @@debug and not @@silent
35
43
  @@queue.push formatted_message(message, 'D').light_black
36
44
  end
37
45
  end
38
46
 
39
47
  def raw(message)
40
- @@queue.push message
48
+ @@queue.push( message )
49
+ end
50
+
51
+ def wait!
52
+ while not @@queue.empty?
53
+ sleep 0.3
54
+ end
41
55
  end
42
56
 
43
57
  private
@@ -45,11 +59,13 @@ module Logger
45
59
  def worker
46
60
  loop do
47
61
  message = @@queue.pop
48
- puts message
49
- unless @@logfile.nil?
50
- f = File.open( @@logfile, 'a+t' )
51
- f.puts( message.gsub( /\e\[(\d+)(;\d+)*m/, '') + "\n")
52
- f.close
62
+ if @@ctx.running
63
+ puts message
64
+ unless @@logfile.nil?
65
+ f = File.open( @@logfile, 'a+t' )
66
+ f.puts( message.gsub( /\e\[(\d+)(;\d+)*m/, '') + "\n")
67
+ f.close
68
+ end
53
69
  end
54
70
  end
55
71
  end
@@ -59,3 +75,4 @@ module Logger
59
75
  end
60
76
  end
61
77
  end
78
+ end
@@ -23,9 +23,9 @@ module PacketFu
23
23
  ret = {}
24
24
  iface = iface.to_s.scan(/[0-9A-Za-z]/).join
25
25
 
26
- Logger.debug "ifconfig #{iface}"
27
-
28
- ifconfig_data = Shell.ifconfig(iface)
26
+ BetterCap::Logger.debug "ifconfig #{iface}"
27
+
28
+ ifconfig_data = BetterCap::Shell.ifconfig(iface)
29
29
  if ifconfig_data =~ /#{iface}/i
30
30
  ifconfig_data = ifconfig_data.split(/[\s]*\n[\s]*/)
31
31
  else
@@ -45,7 +45,7 @@ module PacketFu
45
45
  private
46
46
 
47
47
  def self.linux_ifconfig(iface='eth0',ifconfig_data)
48
- Logger.debug "Linux ifconfig #{iface}:\n#{ifconfig_data}"
48
+ BetterCap::Logger.debug "Linux ifconfig #{iface}:\n#{ifconfig_data}"
49
49
 
50
50
  ret = {}
51
51
  real_iface = ifconfig_data.first
@@ -81,7 +81,7 @@ module PacketFu
81
81
  end
82
82
 
83
83
  def self.darwin_ifconfig(iface='eth0',ifconfig_data)
84
- Logger.debug "OSX ifconfig #{iface}:\n#{ifconfig_data}"
84
+ BetterCap::Logger.debug "OSX ifconfig #{iface}:\n#{ifconfig_data}"
85
85
 
86
86
  ret = {}
87
87
  real_iface = ifconfig_data.first
@@ -11,15 +11,7 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
  require 'thread'
13
13
 
14
- require 'bettercap/error'
15
- require 'bettercap/logger'
16
- require 'bettercap/shell'
17
- require 'bettercap/target'
18
- require 'bettercap/factories/firewall_factory'
19
- require 'bettercap/discovery/icmp'
20
- require 'bettercap/discovery/udp'
21
- require 'bettercap/discovery/arp'
22
-
14
+ module BetterCap
23
15
  class Network
24
16
  class << self
25
17
  def is_ip?(ip)
@@ -29,6 +21,10 @@ class Network
29
21
  false
30
22
  end
31
23
 
24
+ def is_mac?(mac)
25
+ ( /^[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}$/i =~ mac.to_s )
26
+ end
27
+
32
28
  def get_gateway
33
29
  nstat = Shell.execute('netstat -nr')
34
30
 
@@ -62,13 +58,7 @@ class Network
62
58
 
63
59
  def get_alive_targets( ctx, timeout = 5 )
64
60
  if ctx.options.should_discover_hosts?
65
- icmp = IcmpAgent.new timeout
66
- udp = UdpAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
67
- arp = ArpAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
68
-
69
- icmp.wait
70
- arp.wait
71
- udp.wait
61
+ start_agents( ctx, timeout )
72
62
  else
73
63
  Logger.debug 'Using current ARP cache.'
74
64
  end
@@ -76,6 +66,15 @@ class Network
76
66
  ArpAgent.parse ctx
77
67
  end
78
68
 
69
+ def get_ip_address( ctx, mac, timeout = 5 )
70
+ ip = ArpAgent.find_mac( mac )
71
+ if ip.nil?
72
+ start_agents( ctx, timeout )
73
+ ip = ArpAgent.find_mac( mac )
74
+ end
75
+ ip
76
+ end
77
+
79
78
  =begin
80
79
  Apparently on Mac OSX the gem pcaprub ( or libpcap itself ) has
81
80
  a bug, so we can't use 'PacketFu::Utils::arp' since the funtion
@@ -132,6 +131,16 @@ class Network
132
131
 
133
132
  private
134
133
 
134
+ def start_agents( ctx, timeout )
135
+ icmp = IcmpAgent.new timeout
136
+ udp = UdpAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
137
+ arp = ArpAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
138
+
139
+ icmp.wait
140
+ arp.wait
141
+ udp.wait
142
+ end
143
+
135
144
  def get_mac_from_capture( cap, ip_address )
136
145
  cap.stream.each do |p|
137
146
  arp_response = PacketFu::Packet.parse(p)
@@ -141,3 +150,4 @@ class Network
141
150
  end
142
151
  end
143
152
  end
153
+ end
@@ -9,7 +9,7 @@ Blog : http://www.evilsocket.net/
9
9
  This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
-
12
+ module BetterCap
13
13
  class Options
14
14
  attr_accessor :gateway,
15
15
  :iface,
@@ -17,6 +17,7 @@ class Options
17
17
  :half_duplex,
18
18
  :target,
19
19
  :logfile,
20
+ :silent,
20
21
  :debug,
21
22
  :arpcache,
22
23
  :ignore,
@@ -25,6 +26,7 @@ class Options
25
26
  :sniffer_filter,
26
27
  :sniffer_src,
27
28
  :parsers,
29
+ :custom_parser,
28
30
  :local,
29
31
  :proxy,
30
32
  :proxy_https,
@@ -39,7 +41,8 @@ class Options
39
41
  :httpd,
40
42
  :httpd_port,
41
43
  :httpd_path,
42
- :check_updates
44
+ :check_updates,
45
+ :no_target_nbns
43
46
 
44
47
  def initialize( iface )
45
48
  @gateway = nil
@@ -48,8 +51,10 @@ class Options
48
51
  @half_duplex = false
49
52
  @target = nil
50
53
  @logfile = nil
54
+ @silent = false
51
55
  @debug = false
52
56
  @arpcache = false
57
+ @no_target_nbns = false
53
58
 
54
59
  @ignore = nil
55
60
 
@@ -58,6 +63,7 @@ class Options
58
63
  @sniffer_filter = nil
59
64
  @sniffer_src = nil
60
65
  @parsers = ['*']
66
+ @custom_parser = nil
61
67
  @local = false
62
68
 
63
69
  @proxy = false
@@ -144,6 +150,16 @@ class Options
144
150
  ctx.options.parsers = ParserFactory.from_cmdline(v)
145
151
  end
146
152
 
153
+ 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|
154
+ ctx.options.sniffer = true
155
+ ctx.options.parsers = ['CUSTOM']
156
+ ctx.options.custom_parser = Regexp.new(v)
157
+ end
158
+
159
+ opts.on( '--silent', 'Suppress every message which is not an error or a warning, default to false.' ) do
160
+ ctx.options.silent = true
161
+ end
162
+
147
163
  opts.on( '--no-discovery', 'Do not actively search for hosts, just use the current ARP cache, default to false.' ) do
148
164
  ctx.options.arpcache = true
149
165
  end
@@ -152,6 +168,10 @@ class Options
152
168
  ctx.options.spoofer = 'NONE'
153
169
  end
154
170
 
171
+ opts.on( '--no-target-nbns', 'Disable target NBNS hostname resolution.' ) do
172
+ ctx.options.no_target_nbns = true
173
+ end
174
+
155
175
  opts.on( '--half-duplex', 'Enable half-duplex MITM, this will make bettercap work in those cases when the router is not vulnerable.' ) do
156
176
  ctx.options.half_duplex = true
157
177
  end
@@ -228,7 +248,7 @@ class Options
228
248
  end
229
249
  end.parse!
230
250
 
231
- Logger.init( ctx.options.debug, ctx.options.logfile )
251
+ Logger.init( ctx.options.debug, ctx.options.logfile, ctx.options.silent )
232
252
 
233
253
  Logger.warn "You are running an unstable/beta version of this software, please" \
234
254
  " update to a stable one if available." if BetterCap::VERSION =~ /[\d\.+]b/
@@ -309,13 +329,13 @@ class Options
309
329
 
310
330
  def to_targets
311
331
  targets = @target.split(",")
312
- valid_targets = targets.select { |target| Network.is_ip?(target) }
332
+ valid_targets = targets.select { |target| Network.is_ip?(target) or Network.is_mac?(target) }
313
333
 
314
- raise BetterCap::Error, "Invalid target" if valid_targets.empty?
334
+ raise BetterCap::Error, "Invalid target specified." if valid_targets.empty?
315
335
 
316
336
  invalid_targets = targets - valid_targets
317
337
  invalid_targets.each do |target|
318
- Logger.warn "Invalid target #{target}"
338
+ Logger.warn "Invalid target specified: #{target}"
319
339
  end
320
340
 
321
341
  valid_targets.map { |target| Target.new(target) }
@@ -368,3 +388,4 @@ class Options
368
388
  redirections
369
389
  end
370
390
  end
391
+ end
@@ -12,13 +12,14 @@ This project is released under the GPL 3 license.
12
12
  require 'bettercap/logger'
13
13
  require 'openssl'
14
14
 
15
+ module BetterCap
15
16
  module Proxy
16
17
  class CertStore
17
18
  @@selfsigned = {}
18
19
  @@frompems = {}
19
20
 
20
21
  def self.from_file( filename )
21
- if !@@frompems.has_key? filename
22
+ unless @@frompems.has_key? filename
22
23
  Logger.info "Loading self signed HTTPS certificate from '#{filename}' ..."
23
24
 
24
25
  pem = File.read filename
@@ -30,7 +31,7 @@ module Proxy
30
31
  end
31
32
 
32
33
  def self.get_selfsigned( subject = '/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com' )
33
- if !@@selfsigned.has_key? subject
34
+ unless @@selfsigned.has_key? subject
34
35
  Logger.info "Generating self signed HTTPS certificate for subject '#{subject}' ..."
35
36
 
36
37
  key = OpenSSL::PKey::RSA.new(2048)
@@ -63,5 +64,5 @@ module Proxy
63
64
  @@selfsigned[subject]
64
65
  end
65
66
  end
66
-
67
+ end
67
68
  end
@@ -11,8 +11,8 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
  require 'bettercap/logger'
13
13
 
14
+ module BetterCap
14
15
  module Proxy
15
-
16
16
  class Module
17
17
  @@modules = []
18
18
 
@@ -35,5 +35,5 @@ class Module
35
35
  end
36
36
  end
37
37
  end
38
-
38
+ end
39
39
  end
@@ -16,6 +16,7 @@ require 'uri'
16
16
  require 'bettercap/logger'
17
17
  require 'bettercap/network'
18
18
 
19
+ module BetterCap
19
20
  module Proxy
20
21
 
21
22
  class Proxy
@@ -93,8 +94,7 @@ class Proxy
93
94
  begin
94
95
  @pool << @server.accept
95
96
  rescue Exception => e
96
- Logger.warn("Error while accepting #{@type} connection: #{e.inspect}") \
97
- unless !@running
97
+ Logger.warn("Error while accepting #{@type} connection: #{e.inspect}") if @running
98
98
  end
99
99
  end
100
100
 
@@ -122,7 +122,7 @@ class Proxy
122
122
  end
123
123
 
124
124
  def get_client_details( client )
125
- if !@is_https
125
+ unless @is_https
126
126
  client_port, client_ip = Socket.unpack_sockaddr_in(client.getpeername)
127
127
  else
128
128
  _, client_port, _, client_ip = client.peeraddr
@@ -179,7 +179,7 @@ class Proxy
179
179
  response = Response.from_socket server
180
180
 
181
181
  if response.textual?
182
- StreamLogger.log( @is_https, client_ip, request, response )
182
+ StreamLogger.log_http( @is_https, client_ip, request, response )
183
183
 
184
184
  Logger.debug 'Detected textual response'
185
185
 
@@ -207,5 +207,5 @@ class Proxy
207
207
  end
208
208
  end
209
209
 
210
-
210
+ end
211
211
  end
@@ -10,8 +10,8 @@ This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
12
 
13
+ module BetterCap
13
14
  module Proxy
14
-
15
15
  class Request
16
16
  attr_reader :lines, :verb, :url, :host, :port, :content_length
17
17
 
@@ -94,5 +94,5 @@ class Request
94
94
  @lines.join("\n") + "\n"
95
95
  end
96
96
  end
97
-
97
+ end
98
98
  end
@@ -10,6 +10,7 @@ This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
12
 
13
+ module BetterCap
13
14
  module Proxy
14
15
 
15
16
  class Response
@@ -103,3 +104,4 @@ class Response
103
104
  end
104
105
 
105
106
  end
107
+ end