bettercap 1.1.10 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/TODO.md +8 -7
  3. data/bin/bettercap +8 -2
  4. data/lib/bettercap.rb +5 -4
  5. data/lib/bettercap/context.rb +54 -8
  6. data/lib/bettercap/discovery/agents/arp.rb +17 -4
  7. data/lib/bettercap/discovery/agents/base.rb +16 -52
  8. data/lib/bettercap/discovery/agents/icmp.rb +25 -17
  9. data/lib/bettercap/discovery/agents/udp.rb +9 -20
  10. data/lib/bettercap/discovery/{discovery.rb → thread.rb} +10 -9
  11. data/lib/bettercap/error.rb +1 -2
  12. data/lib/bettercap/factories/{firewall_factory.rb → firewall.rb} +11 -7
  13. data/lib/bettercap/factories/{parser_factory.rb → parser.rb} +13 -3
  14. data/lib/bettercap/factories/{spoofer_factory.rb → spoofer.rb} +10 -3
  15. data/lib/bettercap/firewalls/base.rb +76 -0
  16. data/lib/bettercap/firewalls/linux.rb +26 -16
  17. data/lib/bettercap/firewalls/osx.rb +22 -13
  18. data/lib/bettercap/firewalls/redirection.rb +15 -1
  19. data/lib/bettercap/httpd/server.rb +5 -0
  20. data/lib/bettercap/logger.rb +29 -8
  21. data/lib/bettercap/network.rb +105 -105
  22. data/lib/bettercap/options.rb +99 -41
  23. data/lib/bettercap/packet_queue.rb +92 -0
  24. data/lib/bettercap/proxy/certstore.rb +49 -43
  25. data/lib/bettercap/proxy/module.rb +4 -2
  26. data/lib/bettercap/proxy/proxy.rb +7 -2
  27. data/lib/bettercap/proxy/request.rb +28 -16
  28. data/lib/bettercap/proxy/response.rb +23 -2
  29. data/lib/bettercap/proxy/stream_logger.rb +6 -0
  30. data/lib/bettercap/proxy/streamer.rb +13 -5
  31. data/lib/bettercap/proxy/thread_pool.rb +6 -14
  32. data/lib/bettercap/shell.rb +5 -3
  33. data/lib/bettercap/sniffer/parsers/base.rb +7 -1
  34. data/lib/bettercap/sniffer/parsers/custom.rb +6 -1
  35. data/lib/bettercap/sniffer/parsers/ftp.rb +8 -5
  36. data/lib/bettercap/sniffer/parsers/httpauth.rb +4 -1
  37. data/lib/bettercap/sniffer/parsers/https.rb +4 -1
  38. data/lib/bettercap/sniffer/parsers/irc.rb +8 -5
  39. data/lib/bettercap/sniffer/parsers/mail.rb +8 -5
  40. data/lib/bettercap/sniffer/parsers/ntlmss.rb +21 -18
  41. data/lib/bettercap/sniffer/parsers/post.rb +4 -1
  42. data/lib/bettercap/sniffer/parsers/url.rb +4 -1
  43. data/lib/bettercap/sniffer/sniffer.rb +7 -3
  44. data/lib/bettercap/spoofers/arp.rb +69 -94
  45. data/lib/bettercap/spoofers/base.rb +132 -0
  46. data/lib/bettercap/spoofers/icmp.rb +200 -0
  47. data/lib/bettercap/spoofers/none.rb +8 -2
  48. data/lib/bettercap/target.rb +117 -90
  49. data/lib/bettercap/update_checker.rb +6 -0
  50. data/lib/bettercap/version.rb +3 -1
  51. metadata +24 -8
  52. data/lib/bettercap/base/ifirewall.rb +0 -46
  53. data/lib/bettercap/base/ispoofer.rb +0 -32
@@ -10,18 +10,23 @@ This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
12
  module BetterCap
13
- class Discovery
13
+ module Discovery
14
+ # Class responsible to actively discover targets on the network.
15
+ class Thread
16
+ # Initialize the class using the +ctx+ BetterCap::Context instance.
14
17
  def initialize( ctx )
15
18
  @ctx = ctx
16
19
  @running = false
17
20
  @thread = nil
18
21
  end
19
22
 
23
+ # Start the active network discovery thread.
20
24
  def start
21
25
  @running = true
22
- @thread = Thread.new { worker }
26
+ @thread = ::Thread.new { worker }
23
27
  end
24
28
 
29
+ # Stop the active network discovery thread.
25
30
  def stop
26
31
  @running = false
27
32
  if @thread != nil
@@ -39,15 +44,10 @@ class Discovery
39
44
  Logger.debug( 'Network discovery thread started.' ) unless @ctx.options.arpcache
40
45
 
41
46
  while @running
42
- empty_list = @ctx.targets.empty?
43
-
44
- if @ctx.options.should_discover_hosts?
45
- Logger.info 'Searching for targets ...' if empty_list
46
- end
47
-
47
+ was_empty = @ctx.targets.empty?
48
48
  @ctx.targets = Network.get_alive_targets(@ctx).sort_by { |t| t.sortable_ip }
49
49
 
50
- if empty_list and not @ctx.targets.empty?
50
+ if was_empty and not @ctx.targets.empty?
51
51
  Logger.info "Collected #{@ctx.targets.size} total targets."
52
52
 
53
53
  msg = "\n"
@@ -62,3 +62,4 @@ class Discovery
62
62
  end
63
63
  end
64
64
  end
65
+ end
@@ -9,8 +9,7 @@ Blog : http://www.evilsocket.net/
9
9
  This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
-
13
- # class used to distinghuish between handled and unhandled exceptions
14
12
  module BetterCap
13
+ # Class used to distinghuish between handled and unhandled exceptions.
15
14
  class Error < StandardError; end
16
15
  end
@@ -14,25 +14,29 @@ require 'bettercap/firewalls/osx'
14
14
  require 'bettercap/firewalls/linux'
15
15
 
16
16
  module BetterCap
17
- class FirewallFactory
17
+ module Factories
18
+ # Factory class responsible of creating the correct object for the current
19
+ # operating system of the user.
20
+ class Firewall
18
21
  @@instance = nil
19
-
20
- def self.get_firewall
22
+ # Save and return an instance of the appropriate BetterCap::Firewalls object.
23
+ def self.get
21
24
  return @@instance unless @@instance.nil?
22
25
 
23
26
  if RUBY_PLATFORM =~ /darwin/
24
- @@instance = OSXFirewall.new
27
+ @@instance = Firewalls::OSX.new
25
28
  elsif RUBY_PLATFORM =~ /linux/
26
- @@instance = LinuxFirewall.new
29
+ @@instance = Firewalls::Linux.new
27
30
  else
28
31
  raise BetterCap::Error, 'Unsupported operating system'
29
32
  end
30
33
 
31
34
  @@instance
32
35
  end
33
-
34
- def FirewallFactory.clear_firewall
36
+ # Clear the instance of the BetterCap::Firewalls object.
37
+ def self.clear
35
38
  @@instance = nil
36
39
  end
37
40
  end
38
41
  end
42
+ end
@@ -14,10 +14,14 @@ require 'bettercap/error'
14
14
  require 'bettercap/logger'
15
15
 
16
16
  module BetterCap
17
- class ParserFactory
17
+ module Factories
18
+ # Factory class responsible for listing, parsing and creating BetterCap::Parsers
19
+ # object instances.
20
+ class Parser
18
21
  @@path = File.dirname(__FILE__) + '/../sniffer/parsers/'
19
22
 
20
23
  class << self
24
+ # Return a list of available parsers.
21
25
  def available
22
26
  avail = []
23
27
  Dir.foreach( @@path ) do |file|
@@ -28,6 +32,8 @@ class ParserFactory
28
32
  avail
29
33
  end
30
34
 
35
+ # Parse the +v+ command line argument and return a list of parser names.
36
+ # Will raise BetterCap::Error if one or more parser names are not valid.
31
37
  def from_cmdline(v)
32
38
  raise BetterCap::Error, "No parser names provided" if v.nil?
33
39
 
@@ -39,6 +45,7 @@ class ParserFactory
39
45
  list
40
46
  end
41
47
 
48
+ # Return a list of BetterCap::Parsers instances by their +parsers+ names.
42
49
  def load_by_names(parsers)
43
50
  loaded = []
44
51
  Dir.foreach( @@path ) do |file|
@@ -48,16 +55,19 @@ class ParserFactory
48
55
 
49
56
  require_relative "#{@@path}#{file}"
50
57
 
51
- loaded << Kernel.const_get("BetterCap::#{cname.capitalize}Parser").new
58
+ loaded << Kernel.const_get("BetterCap::Parsers::#{cname.capitalize}").new
52
59
  end
53
60
  end
54
61
  loaded
55
62
  end
56
63
 
64
+ # Load and return an instance of the BetterCap::Parsers::Custom parser
65
+ # given the +expression+ Regex object.
57
66
  def load_custom(expression)
58
67
  require_relative "#{@@path}custom.rb"
59
- [ BetterCap::CustomParser.new(expression) ]
68
+ [ BetterCap::Parsers::Custom.new(expression) ]
60
69
  end
61
70
  end
62
71
  end
63
72
  end
73
+ end
@@ -12,18 +12,24 @@ This project is released under the GPL 3 license.
12
12
  require 'bettercap/error'
13
13
 
14
14
  module BetterCap
15
- class SpooferFactory
15
+ module Factories
16
+ # Factory class responsible for listing, parsing and creating BetterCap::Spoofers
17
+ # object instances.
18
+ class Spoofer
16
19
  class << self
20
+ # Return a list of available spoofers.
17
21
  def available
18
22
  avail = []
19
23
  Dir.foreach( File.dirname(__FILE__) + '/../spoofers/') do |file|
20
- if file =~ /.rb/
24
+ if file =~ /.rb/ and file != 'base.rb'
21
25
  avail << file.gsub('.rb','').upcase
22
26
  end
23
27
  end
24
28
  avail
25
29
  end
26
30
 
31
+ # Create an instance of a BetterCap::Spoofers object given its +name+.
32
+ # Will raise a BetterCap::Error if +name+ is not valid.
27
33
  def get_by_name(name)
28
34
  raise BetterCap::Error, "Invalid spoofer name '#{name}'!" unless available? name
29
35
 
@@ -31,7 +37,7 @@ class SpooferFactory
31
37
 
32
38
  require_relative "../spoofers/#{name}"
33
39
 
34
- Kernel.const_get("BetterCap::#{name.capitalize}Spoofer").new
40
+ Kernel.const_get("BetterCap::Spoofers::#{name.capitalize}").new
35
41
  end
36
42
 
37
43
  private
@@ -42,3 +48,4 @@ class SpooferFactory
42
48
  end
43
49
  end
44
50
  end
51
+ end
@@ -0,0 +1,76 @@
1
+ =begin
2
+
3
+ BETTERCAP
4
+
5
+ Author : Simone 'evilsocket' Margaritelli
6
+ Email : evilsocket@gmail.com
7
+ Blog : http://www.evilsocket.net/
8
+
9
+ This project is released under the GPL 3 license.
10
+
11
+ =end
12
+ module BetterCap
13
+ module Firewalls
14
+ # Base class for BetterCap::Firewalls objects.
15
+ class Base
16
+ # Initialize the firewall object.
17
+ # Raise NotImplementedError
18
+ def initialize
19
+ @frwd_initial_state = forwarding_enabled?
20
+ end
21
+
22
+ # If +enabled+ is true will enable packet forwarding, otherwise it will
23
+ # disable it.
24
+ # Raise NotImplementedError
25
+ def enable_forwarding(enabled)
26
+ not_implemented_method!
27
+ end
28
+
29
+ # If +enabled+ is true will enable icmp_echo_ignore_broadcasts, otherwise it will
30
+ # disable it.
31
+ # Raise NotImplementedError
32
+ def enable_icmp_bcast(enabled)
33
+ not_implemented_method!
34
+ end
35
+
36
+ # If +enabled+ is true will enable send_redirects, otherwise it will
37
+ # disable it.
38
+ # Raise NotImplementedError
39
+ def enable_send_redirects(enabled)
40
+ not_implemented_method!
41
+ end
42
+
43
+ # Return true if packet forwarding is currently enabled, otherwise false.
44
+ # Raise NotImplementedError
45
+ def forwarding_enabled?
46
+ not_implemented_method!
47
+ end
48
+
49
+ # Apply the +r+ BetterCap::Firewalls::Redirection port redirection object.
50
+ # Raise NotImplementedError
51
+ def add_port_redirection( r )
52
+ not_implemented_method!
53
+ end
54
+
55
+ # Remove the +r+ BetterCap::Firewalls::Redirection port redirection object.
56
+ # Raise NotImplementedError
57
+ def del_port_redirection( r )
58
+ not_implemented_method!
59
+ end
60
+
61
+ # Restore the system's original packet forwarding state.
62
+ # Raise NotImplementedError
63
+ def restore
64
+ if forwarding_enabled? != @frwd_initial_state
65
+ enable_forwarding @frwd_initial_state
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def not_implemented_method!
72
+ raise NotImplementedError, 'Firewalls::Base: Unimplemented method!'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -9,43 +9,53 @@ Blog : http://www.evilsocket.net/
9
9
  This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
- require 'bettercap/base/ifirewall'
12
+ require 'bettercap/firewalls/base'
13
13
  require 'bettercap/shell'
14
14
 
15
15
  module BetterCap
16
- class LinuxFirewall < IFirewall
16
+ module Firewalls
17
+ # Linux firewall class.
18
+ class Linux < Base
19
+ # If +enabled+ is true will enable packet forwarding, otherwise it will
20
+ # disable it.
17
21
  def enable_forwarding(enabled)
18
- shell.execute("echo #{enabled ? 1 : 0} > /proc/sys/net/ipv4/ip_forward")
22
+ Shell.execute("echo #{enabled ? 1 : 0} > /proc/sys/net/ipv4/ip_forward")
19
23
  end
20
24
 
25
+ # Return true if packet forwarding is currently enabled, otherwise false.
21
26
  def forwarding_enabled?
22
- shell.execute('cat /proc/sys/net/ipv4/ip_forward').strip == '1'
27
+ Shell.execute('cat /proc/sys/net/ipv4/ip_forward').strip == '1'
23
28
  end
24
29
 
30
+ # If +enabled+ is true will enable packet icmp_echo_ignore_broadcasts, otherwise it will
31
+ # disable it.
25
32
  def enable_icmp_bcast(enabled)
26
- shell.execute("echo #{enabled ? 0 : 1} > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts")
33
+ Shell.execute("echo #{enabled ? 0 : 1} > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts")
27
34
  end
28
35
 
36
+ # If +enabled+ is true will enable send_redirects, otherwise it will
37
+ # disable it.
38
+ def enable_send_redirects(enabled)
39
+ Shell.execute("echo #{enabled ? 0 : 1} > /proc/sys/net/ipv4/conf/all/send_redirects")
40
+ end
41
+
42
+ # Apply the +r+ BetterCap::Firewalls::Redirection port redirection object.
29
43
  def add_port_redirection( r )
30
44
  # post route
31
- shell.execute('iptables -t nat -I POSTROUTING -s 0/0 -j MASQUERADE')
45
+ Shell.execute('iptables -t nat -I POSTROUTING -s 0/0 -j MASQUERADE')
32
46
  # accept all
33
- shell.execute('iptables -P FORWARD ACCEPT')
47
+ Shell.execute('iptables -P FORWARD ACCEPT')
34
48
  # add redirection
35
- shell.execute("iptables -t nat -A PREROUTING -i #{r.interface} -p #{r.protocol} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
49
+ Shell.execute("iptables -t nat -A PREROUTING -i #{r.interface} -p #{r.protocol} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
36
50
  end
37
51
 
52
+ # Remove the +r+ BetterCap::Firewalls::Redirection port redirection object.
38
53
  def del_port_redirection( r )
39
54
  # remove post route
40
- shell.execute('iptables -t nat -D POSTROUTING -s 0/0 -j MASQUERADE')
55
+ Shell.execute('iptables -t nat -D POSTROUTING -s 0/0 -j MASQUERADE')
41
56
  # remove redirection
42
- shell.execute("iptables -t nat -D PREROUTING -i #{r.interface} -p #{r.protocol} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
43
- end
44
-
45
- private
46
-
47
- def shell
48
- Shell
57
+ Shell.execute("iptables -t nat -D PREROUTING -i #{r.interface} -p #{r.protocol} --dport #{r.src_port} -j DNAT --to #{r.dst_address}:#{r.dst_port}")
49
58
  end
50
59
  end
51
60
  end
61
+ end
@@ -9,29 +9,42 @@ Blog : http://www.evilsocket.net/
9
9
  This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
- require 'bettercap/base/ifirewall'
12
+ require 'bettercap/firewalls/base'
13
13
  require 'bettercap/shell'
14
14
 
15
15
  module BetterCap
16
- class OSXFirewall < IFirewall
16
+ module Firewalls
17
+ # OSX Firewall class.
18
+ class OSX < Base
19
+ # If +enabled+ is true will enable packet forwarding, otherwise it will
20
+ # disable it.
17
21
  def enable_forwarding(enabled)
18
- shell.execute("sysctl -w net.inet.ip.forwarding=#{enabled ? 1 : 0}")
22
+ Shell.execute("sysctl -w net.inet.ip.forwarding=#{enabled ? 1 : 0}")
19
23
  end
20
24
 
25
+ # If +enabled+ is true will enable packet icmp_echo_ignore_broadcasts, otherwise it will
26
+ # disable it.
21
27
  def enable_icmp_bcast(enabled)
22
- shell.execute("sysctl -w net.inet.icmp.bmcastecho=#{enabled ? 1 : 0}")
28
+ Shell.execute("sysctl -w net.inet.icmp.bmcastecho=#{enabled ? 1 : 0}")
23
29
  end
24
30
 
31
+ # Return true if packet forwarding is currently enabled, otherwise false.
25
32
  def forwarding_enabled?
26
- shell.execute('sysctl net.inet.ip.forwarding').strip.split(' ')[1] == '1'
33
+ Shell.execute('sysctl net.inet.ip.forwarding').strip.split(' ')[1] == '1'
27
34
  end
28
35
 
36
+ # This method is ignored on OSX.
37
+ def enable_send_redirects(enabled); end
38
+
39
+ # If +enabled+ is true, the PF firewall will be enabled, otherwise it will
40
+ # be disabled.
29
41
  def enable(enabled)
30
42
  begin
31
- shell.execute("pfctl -#{enabled ? 'e' : 'd'} >/dev/null 2>&1")
43
+ Shell.execute("pfctl -#{enabled ? 'e' : 'd'} >/dev/null 2>&1")
32
44
  rescue; end
33
45
  end
34
46
 
47
+ # Apply the +r+ BetterCap::Firewalls::Redirection port redirection object.
35
48
  def add_port_redirection( r )
36
49
  # create the pf config file
37
50
  config_file = "/tmp/bettercap_pf_#{Process.pid}.conf"
@@ -41,11 +54,12 @@ class OSXFirewall < IFirewall
41
54
  end
42
55
 
43
56
  # load the rule
44
- shell.execute("pfctl -f #{config_file} >/dev/null 2>&1")
57
+ Shell.execute("pfctl -f #{config_file} >/dev/null 2>&1")
45
58
  # enable pf
46
59
  enable true
47
60
  end
48
61
 
62
+ # Remove the +r+ BetterCap::Firewalls::Redirection port redirection object.
49
63
  def del_port_redirection( r )
50
64
  # FIXME: This should search for multiple rules inside the
51
65
  # file and remove only this one.
@@ -60,11 +74,6 @@ class OSXFirewall < IFirewall
60
74
  end
61
75
 
62
76
  end
63
-
64
- private
65
-
66
- def shell
67
- Shell
68
- end
77
+ end
69
78
  end
70
79
  end
@@ -10,9 +10,22 @@ This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
12
  module BetterCap
13
+ module Firewalls
14
+ # This class represents a firewall port redirection rule.
13
15
  class Redirection
14
- attr_reader :interface, :protocol, :src_port, :dst_address, :dst_port
16
+ # Network interface name.
17
+ attr_reader :interface
18
+ # Protocol name.
19
+ attr_reader :protocol
20
+ # Source port.
21
+ attr_reader :src_port
22
+ # Destination address.
23
+ attr_reader :dst_address
24
+ # Destionation port.
25
+ attr_reader :dst_port
15
26
 
27
+ # Create the redirection rule for the specified +interface+ and +protocol+.
28
+ # Redirect *:+src_port+ to +dst_address+:+dst_port+
16
29
  def initialize( interface, protocol, src_port, dst_address, dst_port )
17
30
  @interface = interface
18
31
  @protocol = protocol
@@ -22,3 +35,4 @@ class Redirection
22
35
  end
23
36
  end
24
37
  end
38
+ end
@@ -15,7 +15,10 @@ require 'bettercap/logger'
15
15
 
16
16
  module BetterCap
17
17
  module HTTPD
18
+ # Simple HTTP server class used to serve static assets when needed.
18
19
  class Server
20
+ # Initialize the HTTP server with the specified tcp +port+ using
21
+ # +path+ as the document root.
19
22
  def initialize( port = 8081, path = './' )
20
23
  @port = port
21
24
  @path = path
@@ -27,6 +30,7 @@ class Server
27
30
  )
28
31
  end
29
32
 
33
+ # Start the server.
30
34
  def start
31
35
  Logger.info "Starting HTTPD on port #{@port} and path #{@path} ..."
32
36
  @thread = Thread.new {
@@ -34,6 +38,7 @@ class Server
34
38
  }
35
39
  end
36
40
 
41
+ # Stop the server.
37
42
  def stop
38
43
  Logger.info 'Stopping HTTPD ...'
39
44