bettercap 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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