xettercap 1.5.7xerob

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 (98) hide show
  1. checksums.yaml +7 -0
  2. data/bin/xettercap +61 -0
  3. data/lib/bettercap/banner +2 -0
  4. data/lib/bettercap/context.rb +259 -0
  5. data/lib/bettercap/discovery/agents/arp.rb +37 -0
  6. data/lib/bettercap/discovery/agents/base.rb +73 -0
  7. data/lib/bettercap/discovery/agents/icmp.rb +44 -0
  8. data/lib/bettercap/discovery/agents/udp.rb +30 -0
  9. data/lib/bettercap/discovery/thread.rb +128 -0
  10. data/lib/bettercap/error.rb +16 -0
  11. data/lib/bettercap/firewalls/base.rb +103 -0
  12. data/lib/bettercap/firewalls/bsd.rb +74 -0
  13. data/lib/bettercap/firewalls/linux.rb +65 -0
  14. data/lib/bettercap/firewalls/redirection.rb +42 -0
  15. data/lib/bettercap/loader.rb +27 -0
  16. data/lib/bettercap/logger.rb +131 -0
  17. data/lib/bettercap/memory.rb +56 -0
  18. data/lib/bettercap/monkey/celluloid/actor.rb +23 -0
  19. data/lib/bettercap/monkey/celluloid/io/udp_socket.rb +26 -0
  20. data/lib/bettercap/monkey/em-proxy/proxy.rb +23 -0
  21. data/lib/bettercap/monkey/openssl/server.rb +35 -0
  22. data/lib/bettercap/monkey/packetfu/pcap.rb +51 -0
  23. data/lib/bettercap/monkey/packetfu/utils.rb +210 -0
  24. data/lib/bettercap/monkey/system.rb +25 -0
  25. data/lib/bettercap/network/arp_reader.rb +91 -0
  26. data/lib/bettercap/network/hw-prefixes +21326 -0
  27. data/lib/bettercap/network/network.rb +102 -0
  28. data/lib/bettercap/network/packet_queue.rb +129 -0
  29. data/lib/bettercap/network/protos/base.rb +154 -0
  30. data/lib/bettercap/network/protos/dhcp.rb +227 -0
  31. data/lib/bettercap/network/protos/mysql.rb +40 -0
  32. data/lib/bettercap/network/protos/ntlm.rb +97 -0
  33. data/lib/bettercap/network/protos/snmp.rb +49 -0
  34. data/lib/bettercap/network/protos/teamviewer.rb +119 -0
  35. data/lib/bettercap/network/servers/dnsd.rb +152 -0
  36. data/lib/bettercap/network/servers/httpd.rb +55 -0
  37. data/lib/bettercap/network/services +2182 -0
  38. data/lib/bettercap/network/target.rb +168 -0
  39. data/lib/bettercap/network/validator.rb +96 -0
  40. data/lib/bettercap/options/core_options.rb +197 -0
  41. data/lib/bettercap/options/options.rb +165 -0
  42. data/lib/bettercap/options/proxy_options.rb +314 -0
  43. data/lib/bettercap/options/server_options.rb +73 -0
  44. data/lib/bettercap/options/sniff_options.rb +90 -0
  45. data/lib/bettercap/options/spoof_options.rb +71 -0
  46. data/lib/bettercap/pluggable.rb +37 -0
  47. data/lib/bettercap/proxy/http/module.rb +105 -0
  48. data/lib/bettercap/proxy/http/modules/injectcss.rb +79 -0
  49. data/lib/bettercap/proxy/http/modules/injecthtml.rb +80 -0
  50. data/lib/bettercap/proxy/http/modules/injectjs.rb +79 -0
  51. data/lib/bettercap/proxy/http/proxy.rb +184 -0
  52. data/lib/bettercap/proxy/http/request.rb +192 -0
  53. data/lib/bettercap/proxy/http/response.rb +226 -0
  54. data/lib/bettercap/proxy/http/ssl/authority.rb +182 -0
  55. data/lib/bettercap/proxy/http/ssl/bettercap-ca.pem +49 -0
  56. data/lib/bettercap/proxy/http/ssl/server.rb +63 -0
  57. data/lib/bettercap/proxy/http/sslstrip/cookiemonitor.rb +67 -0
  58. data/lib/bettercap/proxy/http/sslstrip/lock.ico +0 -0
  59. data/lib/bettercap/proxy/http/sslstrip/strip.rb +325 -0
  60. data/lib/bettercap/proxy/http/streamer.rb +225 -0
  61. data/lib/bettercap/proxy/stream_logger.rb +181 -0
  62. data/lib/bettercap/proxy/tcp/module.rb +75 -0
  63. data/lib/bettercap/proxy/tcp/proxy.rb +123 -0
  64. data/lib/bettercap/proxy/thread_pool.rb +194 -0
  65. data/lib/bettercap/shell.rb +70 -0
  66. data/lib/bettercap/sniffer/parsers/base.rb +87 -0
  67. data/lib/bettercap/sniffer/parsers/cookie.rb +45 -0
  68. data/lib/bettercap/sniffer/parsers/creditcard.rb +62 -0
  69. data/lib/bettercap/sniffer/parsers/custom.rb +26 -0
  70. data/lib/bettercap/sniffer/parsers/dhcp.rb +45 -0
  71. data/lib/bettercap/sniffer/parsers/dict.rb +37 -0
  72. data/lib/bettercap/sniffer/parsers/ftp.rb +24 -0
  73. data/lib/bettercap/sniffer/parsers/httpauth.rb +44 -0
  74. data/lib/bettercap/sniffer/parsers/https.rb +42 -0
  75. data/lib/bettercap/sniffer/parsers/irc.rb +24 -0
  76. data/lib/bettercap/sniffer/parsers/mail.rb +24 -0
  77. data/lib/bettercap/sniffer/parsers/mpd.rb +36 -0
  78. data/lib/bettercap/sniffer/parsers/mysql.rb +27 -0
  79. data/lib/bettercap/sniffer/parsers/nntp.rb +24 -0
  80. data/lib/bettercap/sniffer/parsers/ntlmss.rb +34 -0
  81. data/lib/bettercap/sniffer/parsers/pgsql.rb +36 -0
  82. data/lib/bettercap/sniffer/parsers/post.rb +33 -0
  83. data/lib/bettercap/sniffer/parsers/redis.rb +39 -0
  84. data/lib/bettercap/sniffer/parsers/rlogin.rb +45 -0
  85. data/lib/bettercap/sniffer/parsers/snmp.rb +44 -0
  86. data/lib/bettercap/sniffer/parsers/snpp.rb +37 -0
  87. data/lib/bettercap/sniffer/parsers/teamviewer.rb +30 -0
  88. data/lib/bettercap/sniffer/parsers/url.rb +30 -0
  89. data/lib/bettercap/sniffer/parsers/whatsapp.rb +33 -0
  90. data/lib/bettercap/sniffer/sniffer.rb +142 -0
  91. data/lib/bettercap/spoofers/arp.rb +150 -0
  92. data/lib/bettercap/spoofers/base.rb +152 -0
  93. data/lib/bettercap/spoofers/icmp.rb +202 -0
  94. data/lib/bettercap/spoofers/none.rb +57 -0
  95. data/lib/bettercap/update_checker.rb +57 -0
  96. data/lib/bettercap/version.rb +18 -0
  97. data/lib/bettercap.rb +70 -0
  98. metadata +276 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bbfc85fac2603c848498feb4a8acd1ea7bba9ebecfbf22b053b374138db3a272
4
+ data.tar.gz: f45da6057ca6f78421932054270e47258643d68905d632d438e09c8874b637b7
5
+ SHA512:
6
+ metadata.gz: b24afaa692025254897bd1aaa78759847f86e5a55d2b49507bd779965fc286a6d8298b26e44569ac6ce42b6cf739134116ee4678c6c589896a67a32cb9554ce8
7
+ data.tar.gz: 3615020fca5dff0349202c8355becf5fccc507edec430a6289c890221c439aea00f6aff6fc88f3caff9d23a5ef57d8f91541b341a8cf504d1bc98ac1a354b92d
data/bin/xettercap ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ =begin
5
+
6
+ BETTERCAP
7
+
8
+ Author : Simone 'evilsocket' Margaritelli
9
+ Email : evilsocket@gmail.com
10
+ Blog : http://www.evilsocket.net/
11
+
12
+ This project is released under the GPL 3 license.
13
+
14
+ =end
15
+
16
+ require 'bettercap'
17
+ begin
18
+
19
+ # We need this in order to report unhandled exceptions.
20
+
21
+
22
+ # Create global context, parse command line arguments and perform basic
23
+ # error checking.
24
+ ctx = BetterCap::Options.parse!
25
+
26
+ ctx.start!
27
+
28
+ loop do
29
+ sleep 10
30
+ end
31
+
32
+ rescue SystemExit, Interrupt, SignalException
33
+ BetterCap::Logger.raw "\n"
34
+
35
+ rescue OptionParser::InvalidOption,
36
+ OptionParser::AmbiguousOption,
37
+ OptionParser::MissingArgument => e
38
+ BetterCap::Logger.error "'#{e.message.capitalize}', verify your command line arguments executing 'bettercap --help'."
39
+
40
+ rescue BetterCap::Error => e
41
+ BetterCap::Logger.error e.message
42
+
43
+ rescue Exception => e
44
+ puts "\n\n"
45
+ BetterCap::Logger.error "Oooops, seems like something weird occurred, please copy paste the following output " \
46
+ "and open a new issue on https://github.com/evilsocket/bettercap/issues :\n"
47
+
48
+ BetterCap::Logger.error "Platform : #{RUBY_PLATFORM}"
49
+ BetterCap::Logger.error "Ruby Version : #{RUBY_VERSION}"
50
+ BetterCap::Logger.error "BetterCap Version : #{BetterCap::VERSION}"
51
+ BetterCap::Logger.error "Command Line : #{original_argv.join(" ")}"
52
+ BetterCap::Logger.error "Exception : #{e.class}"
53
+ BetterCap::Logger.error "Message : #{e.message}"
54
+ BetterCap::Logger.error "Backtrace :\n\n #{e.backtrace.join("\n ")}\n"
55
+
56
+ ensure
57
+ # Make sure all the messages on the logger queue are printed.
58
+ BetterCap::Logger.wait!
59
+
60
+ ctx.finalize unless ctx.nil?
61
+ end
@@ -0,0 +1,2 @@
1
+
2
+
@@ -0,0 +1,259 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ module BetterCap
15
+ # This class holds global states and data, moreover it exposes high level
16
+ # methods to manipulate the program behaviour.
17
+ class Context
18
+ # Instance of BetterCap::Options class.
19
+ attr_accessor :options
20
+ # Instance of the current BetterCap::Firewalls class.
21
+ attr_accessor :firewall
22
+ # Local interface ( as an instance of BetterCap::Network::Target ).
23
+ attr_accessor :iface
24
+ # Network gateway ( as an instance of BetterCap::Network::Target ).
25
+ attr_accessor :gateway
26
+ # A list of BetterCap::Target objects which is periodically updated.
27
+ attr_accessor :targets
28
+ # Instance of BetterCap::Discovery::Thread class.
29
+ attr_accessor :discovery
30
+ # A list of BetterCap::Spoofers class instances.
31
+ attr_accessor :spoofer
32
+ # Instance of BetterCap::Network::Servers::HTTPD class.
33
+ attr_accessor :httpd
34
+ # Instance of BetterCap::Network::Servers::DNSD class.
35
+ attr_accessor :dnsd
36
+ # Set to true if the program is running, to false if a shutdown was
37
+ # scheduled by the user which pressed CTRL+C
38
+ attr_accessor :running
39
+ # Timeout for discovery operations.
40
+ attr_reader :timeout
41
+ # Instance of BetterCap::PacketQueue.
42
+ attr_reader :packets
43
+ # Instance of BetterCap::Memory.
44
+ attr_reader :memory
45
+
46
+ @@instance = nil
47
+
48
+ # Return the global instance of the program Context, if the instance
49
+ # was not yet created it will be initialized and returned.
50
+ def self.get
51
+ @@instance ||= self.new
52
+ end
53
+
54
+ # Initialize the global context object.
55
+ def initialize
56
+ begin
57
+ iface = PCAPRUB::Pcap.lookupdev
58
+ rescue Exception => e
59
+ iface = nil
60
+ Logger.exception e
61
+ end
62
+
63
+ @running = true
64
+ @timeout = 5
65
+ @options = Options.new iface
66
+ @discovery = Discovery::Thread.new self
67
+ @firewall = Firewalls::Base.get
68
+ @memory = Memory.new
69
+ @iface = nil
70
+ @original_mac = nil
71
+ @gateway = nil
72
+ @targets = []
73
+ @spoofer = nil
74
+ @httpd = nil
75
+ @dnsd = nil
76
+ @proxies = []
77
+ @redirections = []
78
+ @packets = nil
79
+ end
80
+
81
+ # Update the Context state parsing network related informations.
82
+ def update!
83
+ gw = @options.core.gateway || Network.get_gateway
84
+ raise BetterCap::Error, "Could not detect the gateway address for interface #{@options.core.iface}, "\
85
+ 'make sure you\'ve specified the correct network interface to use and to have the '\
86
+ 'correct network configuration, this could also happen if bettercap '\
87
+ 'is launched from a virtual environment.' unless Network::Validator.is_ip?(gw)
88
+
89
+ unless @options.core.use_mac.nil?
90
+ cfg = PacketFu::Utils.ifconfig @options.core.iface
91
+ raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.core.iface}', make sure this interface "\
92
+ 'is active and connected.' if cfg[:ip4_obj].nil?
93
+
94
+ @original_mac = Network::Target.normalized_mac(cfg[:eth_saddr])
95
+
96
+ Logger.info "Changing interface MAC address to #{@options.core.use_mac}"
97
+
98
+ Shell.ifconfig( "#{@options.core.iface} ether #{@options.core.use_mac}")
99
+ end
100
+
101
+ cfg = PacketFu::Utils.ifconfig @options.core.iface
102
+ raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.core.iface}', make sure this interface "\
103
+ 'is active and connected.' if cfg[:ip4_obj].nil?
104
+
105
+ @gateway = Network::Target.new gw
106
+ @targets = @options.core.targets unless @options.core.targets.nil?
107
+ @iface = Network::Target.new( cfg[:ip_saddr], cfg[:eth_saddr], cfg[:ip4_obj], cfg[:iface] )
108
+
109
+ ###Logger.info "[#{@iface.name.green}] #{@iface.to_s(false)}"
110
+
111
+ Logger.debug '----- NETWORK INFORMATIONS -----'
112
+ Logger.debug " network = #{@iface.network} ( #{@iface.network.to_range.to_s.split('..').join( ' -> ')} )"
113
+ Logger.debug " gateway = #{@gateway.ip}"
114
+ Logger.debug " local_ip = #{@iface.ip}"
115
+ Logger.debug "--------------------------------\n"
116
+
117
+ @packets = Network::PacketQueue.new( @iface.name, @options.core.packet_throttle, 4 )
118
+ # Spoofers need the context network data to be initialized.
119
+ @spoofer = @options.spoof.parse_spoofers
120
+ end
121
+
122
+ # Find a target given its +ip+ and +mac+ addresses inside the #targets
123
+ # list, if not found return nil.
124
+ def find_target ip, mac
125
+ @targets.each do |target|
126
+ if target.equals?(ip,mac)
127
+ return target
128
+ end
129
+ end
130
+ nil
131
+ end
132
+
133
+ # Start everything!
134
+ def start!
135
+ # Start targets auto discovery.
136
+ @discovery.start
137
+
138
+ # Start network spoofers if any.
139
+ @spoofer.each do |spoofer|
140
+ spoofer.start
141
+ end
142
+
143
+ # Start proxies and setup port redirection.
144
+ if @options.proxies.any?
145
+ if ( @options.proxies.proxy or @options.proxies.proxy_https ) and @options.sniff.enabled?('URL')
146
+ BetterCap::Logger.warn "WARNING: Both HTTP transparent proxy and URL parser are enabled, you're gonna see duplicated logs."
147
+ end
148
+ create_proxies!
149
+ end
150
+
151
+ enable_port_redirection!
152
+
153
+ create_servers!
154
+
155
+ # Start network sniffer.
156
+ if @options.sniff.enabled?
157
+ Sniffer.start self
158
+ elsif @options.spoof.enabled? and !@options.proxies.any?
159
+ Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this '\
160
+ 'will cause the MITM to run but no data to be collected.'
161
+ end
162
+ end
163
+
164
+ # Stop every running daemon that was started and reset system state.
165
+ def finalize
166
+ @running = false
167
+
168
+ # Logger is silent if @running == false
169
+ puts "\nStopping MITM attack ...\n"
170
+
171
+ Logger.debug 'Stopping target discovery manager ...'
172
+ @discovery.stop
173
+
174
+ Logger.debug 'Stopping spoofers ...'
175
+ @spoofer.each do |spoofer|
176
+ spoofer.stop
177
+ end
178
+
179
+ # Spoofer might be sending some last packets to restore the targets,
180
+ # the packet queue must be stopped here.
181
+ @packets.stop
182
+
183
+ Logger.debug 'Stopping proxies ...'
184
+ @proxies.each do |proxy|
185
+ proxy.stop
186
+ end
187
+
188
+ Logger.debug 'Disabling port redirections ...'
189
+ @redirections.each do |r|
190
+ @firewall.del_port_redirection( r )
191
+ end
192
+
193
+ Logger.debug 'Restoring firewall state ...'
194
+ @firewall.restore
195
+
196
+ @dnsd.stop unless @dnsd.nil?
197
+ @httpd.stop unless @httpd.nil?
198
+
199
+ Shell.ifconfig( "#{@options.core.iface} ether #{@original_mac}") unless @original_mac.nil?
200
+ end
201
+
202
+ private
203
+
204
+ # Apply needed BetterCap::Firewalls::Redirection objects.
205
+ def enable_port_redirection!
206
+ @redirections = @options.get_redirections(@iface)
207
+ @redirections.each do |r|
208
+ Logger.debug "Redirecting #{r.protocol} traffic from #{r.src_address.nil? ? '*' : r.src_address}:#{r.src_port} to #{r.dst_address}:#{r.dst_port}"
209
+ @firewall.add_port_redirection( r )
210
+ end
211
+ end
212
+
213
+ # Initialize the needed transparent proxies and the processor routined which
214
+ # is needed in order to run proxy modules.
215
+ def create_proxies!
216
+ if @options.proxies.has_proxy_module?
217
+ Proxy::HTTP::Module.register_modules
218
+ raise BetterCap::Error, "#{@options.proxies.proxy_module} is not a valid bettercap proxy module." if Proxy::HTTP::Module.modules.empty?
219
+ end
220
+
221
+ # create HTTP proxy
222
+ if @options.proxies.proxy
223
+ @proxies << Proxy::HTTP::Proxy.new( @iface.ip, @options.proxies.proxy_port, false )
224
+ end
225
+
226
+ # create HTTPS proxy
227
+ if @options.proxies.proxy_https
228
+ @proxies << Proxy::HTTP::Proxy.new( @iface.ip, @options.proxies.proxy_https_port, true )
229
+ end
230
+
231
+ # create TCP proxy
232
+ if @options.proxies.tcp_proxy
233
+ @proxies << Proxy::TCP::Proxy.new( @iface.ip, @options.proxies.tcp_proxy_port, @options.proxies.tcp_proxy_upstream_address, @options.proxies.tcp_proxy_upstream_port )
234
+ end
235
+
236
+ @proxies.each do |proxy|
237
+ proxy.start
238
+ end
239
+ end
240
+
241
+ # Initialize and start the needed servers.
242
+ def create_servers!
243
+ # Start local DNS server.
244
+ if @options.servers.dnsd
245
+ Logger.warn "Starting DNS server with spoofing disabled, bettercap will only reply to local DNS queries." unless @options.spoof.enabled?
246
+
247
+ @dnsd = Network::Servers::DNSD.new( @options.servers.dnsd_file, @iface.ip, @options.servers.dnsd_port )
248
+ @dnsd.start
249
+ end
250
+
251
+ # Start local HTTP server.
252
+ if @options.servers.httpd
253
+ @httpd = Network::Servers::HTTPD.new( @options.servers.httpd_port, @options.servers.httpd_path )
254
+ @httpd.start
255
+ end
256
+ end
257
+
258
+ end
259
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ # Parse the ARP table searching for new hosts.
15
+ module BetterCap
16
+ module Discovery
17
+ module Agents
18
+ # Class responsible of sending ARP probes to each possible IP on the network.
19
+ class Arp < Discovery::Agents::Base
20
+ private
21
+
22
+ # Build a PacketFu::ARPPacket instance for the specified +ip+ address.
23
+ def get_probe( ip )
24
+ pkt = PacketFu::ARPPacket.new
25
+
26
+ pkt.eth_saddr = pkt.arp_saddr_mac = @ctx.iface.mac
27
+ pkt.eth_daddr = 'ff:ff:ff:ff:ff:ff'
28
+ pkt.arp_daddr_mac = '00:00:00:00:00:00'
29
+ pkt.arp_saddr_ip = @ctx.iface.ip
30
+ pkt.arp_daddr_ip = ip.to_s
31
+
32
+ pkt
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ # Base class for discovery agents.
15
+ module BetterCap
16
+ module Discovery
17
+ module Agents
18
+ # Base class for BetterCap::Discovery::Agents.
19
+ class Base
20
+ # Initialize the agent using the +ctx+ BetterCap::Context instance.
21
+ # If +address+ is not nil only that ip will be probed.
22
+ def initialize( ctx, address = nil )
23
+ @ctx = ctx
24
+ @address = address
25
+
26
+ if @address.nil?
27
+ net = ip = @ctx.iface.network
28
+ # loop each ip in our subnet and push it to the queue
29
+ while net.include?ip
30
+ unless skip_address?(ip)
31
+ @ctx.packets.push( get_probe(ip) )
32
+ end
33
+ ip = ip.succ
34
+ end
35
+ else
36
+ if skip_address?(@address)
37
+ Logger.debug "Skipping #{@address} ..."
38
+ else
39
+ Logger.debug "Probing #{@address} ..."
40
+ @ctx.packets.push( get_probe(@address) )
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ # Return true if +ip+ must be skipped during discovery, otherwise false.
48
+ def skip_address?(ip)
49
+ # don't send probes to the gateway if we already have its MAC.
50
+ if ip == @ctx.gateway.ip
51
+ return !@ctx.gateway.mac.nil?
52
+ # don't send probes to our device
53
+ elsif ip == @ctx.iface.ip
54
+ return true
55
+ # don't stress endpoints we already discovered
56
+ else
57
+ target = @ctx.find_target( ip.to_s, nil )
58
+ # known target?
59
+ return false if target.nil?
60
+ # do we still need to get the mac for this target?
61
+ return ( target.mac.nil?? false : true )
62
+ end
63
+
64
+ end
65
+
66
+ # Each Discovery::Agent::Base derived class should implement this method.
67
+ def get_probe( ip )
68
+ Logger.warn "#{self.class.name}#get_probe not implemented!"
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ # Send a broadcast ping trying to filling the ARP table.
15
+ module BetterCap
16
+ module Discovery
17
+ module Agents
18
+ # Class responsible to do a ping-sweep on the network.
19
+ class Icmp
20
+ # Create a thread which will perform a ping-sweep on the network in order
21
+ # to populate the ARP cache with active targets.
22
+ def initialize( ctx, address = nil )
23
+ Firewalls::Base.get.enable_icmp_bcast(true)
24
+
25
+ # TODO: Use the real broadcast address for this network.
26
+ 3.times do
27
+ pkt = PacketFu::ICMPPacket.new
28
+
29
+ pkt.eth_saddr = ctx.iface.mac
30
+ pkt.eth_daddr = 'ff:ff:ff:ff:ff:ff'
31
+ pkt.ip_saddr = ctx.iface.ip
32
+ pkt.ip_daddr = '255.255.255.255'
33
+ pkt.icmp_type = 8
34
+ pkt.icmp_code = 0
35
+ pkt.payload = "ABCD"
36
+ pkt.recalc
37
+
38
+ ctx.packets.push(pkt)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ # Send UDP probes trying to filling the ARP table.
15
+ module BetterCap
16
+ module Discovery
17
+ module Agents
18
+ # Class responsible to send UDP probe packets to each possible IP on the network.
19
+ class Udp < Discovery::Agents::Base
20
+ private
21
+
22
+ # Build an UDP packet for the specified +ip+ address.
23
+ def get_probe( ip )
24
+ # send dummy udp packet, just to fill ARP table
25
+ [ ip.to_s, 137, "\x10\x12\x85\x00\x00" ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,128 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+ module BetterCap
14
+ module Discovery
15
+ # Class responsible to actively discover targets on the network.
16
+ class Thread
17
+ # Initialize the class using the +ctx+ BetterCap::Context instance.
18
+ def initialize( ctx )
19
+ @ctx = ctx
20
+ @running = false
21
+ @thread = nil
22
+ end
23
+
24
+ # Start the active network discovery thread.
25
+ def start
26
+ @running = true
27
+ @thread = ::Thread.new { worker }
28
+
29
+ if @ctx.options.core.discovery?
30
+ ###Logger.info "[#{'DISCOVERY'.green}] Targeting the whole subnet #{@ctx.iface.network.to_range} ..."
31
+ # give some time to the discovery thread to spawn its workers,
32
+ # this will prevent 'Too many open files' errors to delay host
33
+ # discovery.
34
+ sleep(1.5)
35
+ end
36
+ end
37
+
38
+ # Stop the active network discovery thread.
39
+ def stop
40
+ @running = false
41
+ if @thread != nil
42
+ begin
43
+ @thread.exit
44
+ rescue
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # Return true if the +list+ of targets includes +target+.
52
+ def list_include_target?( list, target )
53
+ list.each do |t|
54
+ if t.equals?(target.ip, target.mac)
55
+ return true
56
+ end
57
+ end
58
+ false
59
+ end
60
+
61
+ # Print informations about new and lost targets.
62
+ def print_differences( prev )
63
+ diff = { :new => [], :lost => [] }
64
+
65
+ @ctx.targets.each do |target|
66
+ unless list_include_target?( prev, target )
67
+ diff[:new] << target
68
+ end
69
+ end
70
+
71
+ prev.each do |target|
72
+ unless list_include_target?( @ctx.targets, target )
73
+ diff[:lost] << target
74
+ end
75
+ end
76
+
77
+ unless diff[:new].empty? and diff[:lost].empty?
78
+ if diff[:new].empty?
79
+ snew = ""
80
+ else
81
+ snew = "Acquired #{diff[:new].size} new target#{diff[:new].size > 1 ? "s" : ""}"
82
+ end
83
+
84
+ if diff[:lost].empty?
85
+ slost = ""
86
+ else
87
+ slost = "#{snew.empty?? 'L' : ', l'}ost #{diff[:lost].size} target#{diff[:lost].size > 1 ? "s" : ""}"
88
+ end
89
+
90
+ Logger.info "#{snew}#{slost} :"
91
+
92
+ msg = "\n"
93
+ diff[:new].each do |target|
94
+ msg += " [#{'NEW'.green}] #{target.to_s(false)}\n"
95
+ end
96
+ diff[:lost].each do |target|
97
+ msg += " [#{'LOST'.red}] #{target.to_s(false)}\n"
98
+ end
99
+ msg += "\n"
100
+ Logger.raw msg
101
+ end
102
+ end
103
+
104
+ # This method implements the main discovery logic, it will be executed within
105
+ # the spawned thread.
106
+ def worker
107
+ Logger.debug( 'Network discovery thread started.' ) if @ctx.options.core.discovery?
108
+
109
+ prev = []
110
+ while @running
111
+ # No targets specified.
112
+ if @ctx.options.core.targets.nil?
113
+ @ctx.targets = Network.get_alive_targets(@ctx).sort_by {
114
+ |t| t.sortable_ip
115
+ }
116
+ end
117
+
118
+ print_differences( prev ) if @ctx.options.core.discovery?
119
+
120
+ prev = @ctx.targets
121
+
122
+ @ctx.memory.optimize!
123
+ sleep(1) if @ctx.options.core.discovery?
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+ module BetterCap
14
+ # Class used to distinghuish between handled and unhandled exceptions.
15
+ class Error < StandardError; end
16
+ end