bettercap 1.1.0

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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +225 -0
  3. data/README.md +96 -0
  4. data/bettercap.gemspec +28 -0
  5. data/bin/bettercap +184 -0
  6. data/example_proxy_module.rb +21 -0
  7. data/lib/bettercap/base/ifirewall.rb +28 -0
  8. data/lib/bettercap/base/ispoofer.rb +24 -0
  9. data/lib/bettercap/context.rb +124 -0
  10. data/lib/bettercap/discovery/arp.rb +37 -0
  11. data/lib/bettercap/discovery/icmp.rb +37 -0
  12. data/lib/bettercap/discovery/syn.rb +88 -0
  13. data/lib/bettercap/discovery/udp.rb +74 -0
  14. data/lib/bettercap/error.rb +16 -0
  15. data/lib/bettercap/factories/firewall_factory.rb +32 -0
  16. data/lib/bettercap/factories/parser_factory.rb +53 -0
  17. data/lib/bettercap/factories/spoofer_factory.rb +36 -0
  18. data/lib/bettercap/firewalls/linux.rb +55 -0
  19. data/lib/bettercap/firewalls/osx.rb +70 -0
  20. data/lib/bettercap/hw-prefixes +19651 -0
  21. data/lib/bettercap/logger.rb +53 -0
  22. data/lib/bettercap/monkey/packetfu/utils.rb +96 -0
  23. data/lib/bettercap/network.rb +131 -0
  24. data/lib/bettercap/proxy/module.rb +39 -0
  25. data/lib/bettercap/proxy/proxy.rb +262 -0
  26. data/lib/bettercap/proxy/request.rb +77 -0
  27. data/lib/bettercap/proxy/response.rb +76 -0
  28. data/lib/bettercap/shell.rb +31 -0
  29. data/lib/bettercap/sniffer/parsers/base.rb +31 -0
  30. data/lib/bettercap/sniffer/parsers/ftp.rb +19 -0
  31. data/lib/bettercap/sniffer/parsers/httpauth.rb +45 -0
  32. data/lib/bettercap/sniffer/parsers/https.rb +36 -0
  33. data/lib/bettercap/sniffer/parsers/irc.rb +19 -0
  34. data/lib/bettercap/sniffer/parsers/mail.rb +19 -0
  35. data/lib/bettercap/sniffer/parsers/ntlmss.rb +38 -0
  36. data/lib/bettercap/sniffer/parsers/post.rb +24 -0
  37. data/lib/bettercap/sniffer/parsers/url.rb +28 -0
  38. data/lib/bettercap/sniffer/sniffer.rb +39 -0
  39. data/lib/bettercap/spoofers/arp.rb +130 -0
  40. data/lib/bettercap/spoofers/none.rb +23 -0
  41. data/lib/bettercap/target.rb +52 -0
  42. data/lib/bettercap/version.rb +14 -0
  43. metadata +129 -0
@@ -0,0 +1,21 @@
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
+ class HackTitle < Proxy::Module
13
+ def on_request( request, response )
14
+ # is it a html page?
15
+ if response.content_type == 'text/html'
16
+ Logger.info "Hacking http://#{request.host}#{request.url} title tag"
17
+ # make sure to use sub! or gsub! to update the instance
18
+ response.body.sub!( '<title>', '<title> !!! HACKED !!! ' )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,28 @@
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
+ class IFirewall
13
+ def enable_forwarding(enabled)
14
+ raise 'IFirewall: Unimplemented method!'
15
+ end
16
+
17
+ def forwarding_enabled?()
18
+ raise 'IFirewall: Unimplemented method!'
19
+ end
20
+
21
+ def add_port_redirection( iface, proto, from, addr, to )
22
+ raise 'IFirewall: Unimplemented method!'
23
+ end
24
+
25
+ def del_port_redirection( iface, proto, from, addr, to )
26
+ raise 'IFirewall: Unimplemented method!'
27
+ end
28
+ end
@@ -0,0 +1,24 @@
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
+ class ISpoofer
13
+ def initialize
14
+ raise 'ISpoofer: Unimplemented method!'
15
+ end
16
+
17
+ def start
18
+ raise 'ISpoofer: Unimplemented method!'
19
+ end
20
+
21
+ def stop
22
+ raise 'ISpoofer: Unimplemented method!'
23
+ end
24
+ end
@@ -0,0 +1,124 @@
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
+
13
+ # this class holds global states & data
14
+ require 'bettercap/error'
15
+
16
+ class Context
17
+ attr_accessor :options, :iface, :ifconfig, :network, :firewall, :gateway,
18
+ :targets, :spoofer, :proxy
19
+
20
+ @@instance = nil
21
+
22
+ def self.get
23
+ if @@instance.nil?
24
+ @@instance = self.new
25
+ end
26
+ @@instance
27
+ end
28
+
29
+ def initialize
30
+ @options = {
31
+ :iface => Pcap.lookupdev,
32
+ :spoofer => 'ARP',
33
+ :target => nil,
34
+ :logfile => nil,
35
+ :sniffer => false,
36
+ :parsers => ['*'],
37
+ :local => false,
38
+ :debug => false,
39
+ :arpcache => false,
40
+ :proxy => false,
41
+ :proxy_port => 8080,
42
+ :proxy_module => nil
43
+ }
44
+
45
+ @iface = nil
46
+ @ifconfig = nil
47
+ @network = nil
48
+ @firewall = FirewallFactory.get_firewall
49
+ @gateway = nil
50
+ @targets = []
51
+ @proxy = nil
52
+ @spoofer = nil
53
+
54
+ @discovery_running = false
55
+ @discovery_thread = nil
56
+ end
57
+
58
+ def update_network
59
+ @iface = PacketFu::Utils.whoami? :iface => @options[:iface]
60
+ @ifconfig = PacketFu::Utils.ifconfig @options[:iface]
61
+ @network = @ifconfig[:ip4_obj]
62
+ @gateway = Network.get_gateway
63
+
64
+ raise BetterCap::Error, "Could not determine IPv4 address of '#{@options[:iface]}' interface." unless !@network.nil?
65
+
66
+ Logger.debug "network=#{@network} gateway=#{@gateway} local_ip=#{@iface[:ip_saddr]}"
67
+ Logger.debug "IFCONFIG: #{@ifconfig.inspect}"
68
+ Logger.debug "IFACE: #{@iface.inspect}"
69
+ end
70
+
71
+ def start_discovery_thread
72
+ @discovery_running = true
73
+ @discovery_thread = Thread.new {
74
+ Logger.info 'Network discovery thread started.'
75
+
76
+ while @discovery_running
77
+ empty_list = false
78
+
79
+ if @targets.size == 0 and !@options[:arpcache]
80
+ empty_list = true
81
+ Logger.info 'Searching for alive targets ...'
82
+ end
83
+
84
+ @targets = Network.get_alive_targets self
85
+
86
+ if empty_list and !@options[:arpcache]
87
+ Logger.info "Collected #{@targets.size} total targets."
88
+ @targets.each do |target|
89
+ Logger.info " #{target}"
90
+ end
91
+ end
92
+ end
93
+ }
94
+ end
95
+
96
+ def stop_discovery_thread
97
+ @discovery_running = false
98
+ if @discovery_thread != nil
99
+ Logger.info 'Stopping network discovery thread ...'
100
+
101
+ begin
102
+ @discovery_thread.join
103
+ rescue
104
+ end
105
+ end
106
+ end
107
+
108
+ def finalize
109
+ stop_discovery_thread
110
+
111
+ if !@spoofer.nil?
112
+ @spoofer.stop
113
+ end
114
+
115
+ if !@proxy.nil?
116
+ @proxy.stop
117
+ @firewall.del_port_redirection( @options[:iface], 'TCP', 80, @iface[:ip_saddr], @options[:proxy_port] )
118
+ end
119
+
120
+ if !@firewall.nil?
121
+ @firewall.enable_forwarding(false)
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,37 @@
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
+ require 'bettercap/logger'
13
+ require 'bettercap/shell'
14
+ require 'bettercap/target'
15
+
16
+ # Parse the ARP table searching for new hosts.
17
+ class ArpAgent
18
+ def self.parse( ctx )
19
+ arp = Shell.arp
20
+ targets = []
21
+
22
+ Logger.debug "ARP:\n#{arp}"
23
+
24
+ arp.split("\n").each do |line|
25
+ m = /[^\s]+\s+\(([0-9\.]+)\)\s+at\s+([a-f0-9:]+).+#{ctx.ifconfig[:iface]}.*/i.match(line)
26
+ if !m.nil?
27
+ if m[1] != ctx.gateway and m[1] != ctx.iface[:ip_saddr] and m[2] != 'ff:ff:ff:ff:ff:ff'
28
+ target = Target.new( m[1], m[2] )
29
+ targets << target
30
+ Logger.debug "FOUND #{target}"
31
+ end
32
+ end
33
+ end
34
+
35
+ targets
36
+ end
37
+ end
@@ -0,0 +1,37 @@
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
+ require 'bettercap/logger'
13
+ require 'bettercap/shell'
14
+ require 'bettercap/factories/firewall_factory'
15
+
16
+ # Send a broadcast ping trying to filling the ARP table.
17
+ class IcmpAgent
18
+ def initialize( timeout = 5 )
19
+ @thread = Thread.new do
20
+ FirewallFactory.get_firewall.enable_icmp_bcast(true)
21
+
22
+ if RUBY_PLATFORM =~ /darwin/
23
+ ping = Shell.execute("ping -i #{timeout} -c 2 255.255.255.255")
24
+ elsif RUBY_PLATFORM =~ /linux/
25
+ ping = Shell.execute("ping -i #{timeout} -c 2 -b 255.255.255.255")
26
+ end
27
+ end
28
+ end
29
+
30
+ def wait
31
+ begin
32
+ @thread.join
33
+ rescue Exception => e
34
+ Logger.debug "IcmpAgent.wait: #{e.message}"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,88 @@
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
+ require 'bettercap/logger'
13
+
14
+ # Send SYN probes trying to filling the ARP table.
15
+ class SynAgent
16
+ def initialize( ifconfig, gw_ip, local_ip )
17
+ @local_ip = local_ip
18
+ @ifconfig = ifconfig
19
+ @queue = Queue.new
20
+
21
+ net = ip = @ifconfig[:ip4_obj]
22
+
23
+ # loop each ip in our subnet and push it to the queue
24
+ while net.include?ip
25
+ # rescanning the gateway could cause an issue when the
26
+ # gateway itself has multiple interfaces ( LAN, WAN ... )
27
+ if ip != gw_ip and ip != local_ip
28
+ @queue.push ip
29
+ end
30
+
31
+ ip = ip.succ
32
+ end
33
+
34
+ # spawn the workers! ( tnx to https://blog.engineyard.com/2014/ruby-thread-pool )
35
+ @workers = (0...4).map do
36
+ Thread.new do
37
+ begin
38
+ while ip = @queue.pop(true)
39
+ Logger.debug "SYN Probing #{ip} ..."
40
+
41
+ pkt = get_packet ip.to_s
42
+
43
+ pkt.to_w( @ifconfig[:iface] )
44
+ end
45
+ rescue Exception => e
46
+ Logger.debug "#{ip} -> #{e.message}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def wait
53
+ begin
54
+ @workers.map(&:join)
55
+ rescue Exception => e
56
+ Logger.debug "SynAgent.wait: #{e.message}"
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def get_packet( destination )
63
+ pkt = PacketFu::TCPPacket.new
64
+ pkt.ip_v = 4
65
+ pkt.ip_hl = 5
66
+ pkt.ip_tos = 0
67
+ pkt.ip_len = 20
68
+ pkt.ip_frag = 0
69
+ pkt.ip_ttl = 115
70
+ pkt.ip_proto = 6 # TCP
71
+ pkt.ip_saddr = @local_ip
72
+ pkt.ip_daddr = destination
73
+ pkt.payload = "\xC\x0\xF\xF\xE\xE"
74
+ pkt.tcp_flags.ack = 0
75
+ pkt.tcp_flags.fin = 0
76
+ pkt.tcp_flags.psh = 0
77
+ pkt.tcp_flags.rst = 0
78
+ pkt.tcp_flags.syn = 1
79
+ pkt.tcp_flags.urg = 0
80
+ pkt.tcp_ecn = 0
81
+ pkt.tcp_win = 8192
82
+ pkt.tcp_hlen = 5
83
+ pkt.tcp_dst = rand(1024..65535)
84
+ pkt.recalc
85
+ pkt
86
+ end
87
+ end
88
+
@@ -0,0 +1,74 @@
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
+ require 'bettercap/logger'
13
+
14
+ # Send UDP probes trying to filling the ARP table.
15
+ class UdpAgent
16
+ def initialize( ifconfig, gw_ip, local_ip )
17
+ @ifconfig = ifconfig
18
+ @port = 137
19
+ @message =
20
+ "\x82\x28\x00\x00\x00" +
21
+ "\x01\x00\x00\x00\x00" +
22
+ "\x00\x00\x20\x43\x4B" +
23
+ "\x41\x41\x41\x41\x41" +
24
+ "\x41\x41\x41\x41\x41" +
25
+ "\x41\x41\x41\x41\x41" +
26
+ "\x41\x41\x41\x41\x41" +
27
+ "\x41\x41\x41\x41\x41" +
28
+ "\x41\x41\x41\x41\x41" +
29
+ "\x00\x00\x21\x00\x01"
30
+
31
+ @queue = Queue.new
32
+
33
+ net = ip = @ifconfig[:ip4_obj]
34
+
35
+ # loop each ip in our subnet and push it to the queue
36
+ while net.include?ip
37
+ # rescanning the gateway could cause an issue when the
38
+ # gateway itself has multiple interfaces ( LAN, WAN ... )
39
+ if ip != gw_ip and ip != local_ip
40
+ @queue.push ip
41
+ end
42
+
43
+ ip = ip.succ
44
+ end
45
+
46
+ # spawn the workers! ( tnx to https://blog.engineyard.com/2014/ruby-thread-pool )
47
+ @workers = (0...4).map do
48
+ Thread.new do
49
+ begin
50
+ while ip = @queue.pop(true)
51
+ Logger.debug "Probing #{ip} ..."
52
+
53
+ # send netbios udp packet, just to fill ARP table
54
+ sd = UDPSocket.new
55
+ sd.send( @message, 0, ip.to_s, @port )
56
+ sd = nil
57
+ # TODO: Parse response for hostname?
58
+ end
59
+ rescue Exception => e
60
+ Logger.debug "#{ip} -> #{e.message}"
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def wait
67
+ begin
68
+ @workers.map(&:join)
69
+ rescue Exception => e
70
+ Logger.debug "UdpAgent.wait: #{e.message}"
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,16 @@
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
+
13
+ # class used to distinghuish between handled and unhandled exceptions
14
+ module BetterCap
15
+ class Error < StandardError; end
16
+ end