bettercap 1.4.6 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bettercap +1 -1
  3. data/lib/bettercap.rb +1 -0
  4. data/lib/bettercap/context.rb +63 -70
  5. data/lib/bettercap/discovery/agents/base.rb +2 -2
  6. data/lib/bettercap/discovery/thread.rb +5 -4
  7. data/lib/bettercap/firewalls/base.rb +2 -4
  8. data/lib/bettercap/firewalls/{osx.rb → bsd.rb} +3 -3
  9. data/lib/bettercap/firewalls/linux.rb +2 -2
  10. data/lib/bettercap/firewalls/redirection.rb +5 -2
  11. data/lib/bettercap/logger.rb +6 -11
  12. data/lib/bettercap/memory.rb +56 -0
  13. data/lib/bettercap/monkey/em-proxy/proxy.rb +23 -0
  14. data/lib/bettercap/monkey/packetfu/pcap.rb +51 -0
  15. data/lib/bettercap/network/arp_reader.rb +2 -2
  16. data/lib/bettercap/network/network.rb +2 -2
  17. data/lib/bettercap/network/packet_queue.rb +2 -2
  18. data/lib/bettercap/network/protos/base.rb +8 -5
  19. data/lib/bettercap/network/protos/dhcp.rb +5 -124
  20. data/lib/bettercap/network/target.rb +7 -2
  21. data/lib/bettercap/options/core_options.rb +189 -0
  22. data/lib/bettercap/options/options.rb +167 -0
  23. data/lib/bettercap/options/proxy_options.rb +258 -0
  24. data/lib/bettercap/options/server_options.rb +71 -0
  25. data/lib/bettercap/options/sniff_options.rb +90 -0
  26. data/lib/bettercap/options/spoof_options.rb +71 -0
  27. data/lib/bettercap/proxy/{module.rb → http/module.rb} +8 -4
  28. data/lib/bettercap/proxy/{modules → http/modules}/injectcss.rb +2 -2
  29. data/lib/bettercap/proxy/{modules → http/modules}/injecthtml.rb +2 -2
  30. data/lib/bettercap/proxy/{modules → http/modules}/injectjs.rb +2 -2
  31. data/lib/bettercap/proxy/{proxy.rb → http/proxy.rb} +5 -2
  32. data/lib/bettercap/proxy/{request.rb → http/request.rb} +4 -0
  33. data/lib/bettercap/proxy/{response.rb → http/response.rb} +3 -0
  34. data/lib/bettercap/proxy/{ssl → http/ssl}/authority.rb +3 -1
  35. data/lib/bettercap/proxy/{ssl → http/ssl}/bettercap-ca.pem +0 -0
  36. data/lib/bettercap/proxy/{ssl → http/ssl}/server.rb +3 -1
  37. data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/cookiemonitor.rb +2 -0
  38. data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/lock.ico +0 -0
  39. data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/strip.rb +4 -2
  40. data/lib/bettercap/proxy/{streamer.rb → http/streamer.rb} +7 -4
  41. data/lib/bettercap/proxy/stream_logger.rb +25 -9
  42. data/lib/bettercap/proxy/tcp/module.rb +75 -0
  43. data/lib/bettercap/proxy/tcp/proxy.rb +123 -0
  44. data/lib/bettercap/proxy/thread_pool.rb +1 -1
  45. data/lib/bettercap/sniffer/parsers/post.rb +1 -1
  46. data/lib/bettercap/sniffer/parsers/url.rb +1 -1
  47. data/lib/bettercap/sniffer/sniffer.rb +23 -17
  48. data/lib/bettercap/spoofers/arp.rb +21 -9
  49. data/lib/bettercap/spoofers/base.rb +12 -16
  50. data/lib/bettercap/spoofers/icmp.rb +4 -5
  51. data/lib/bettercap/spoofers/none.rb +0 -1
  52. data/lib/bettercap/version.rb +1 -1
  53. metadata +48 -19
  54. data/lib/bettercap/firewalls/openbsd.rb +0 -77
  55. data/lib/bettercap/options.rb +0 -600
@@ -20,7 +20,6 @@ class None < Base
20
20
  Logger.debug 'Spoofing disabled.'
21
21
 
22
22
  @ctx = Context.get
23
- @gateway = nil
24
23
  @thread = nil
25
24
  @running = false
26
25
 
@@ -12,7 +12,7 @@ This project is released under the GPL 3 license.
12
12
  =end
13
13
  module BetterCap
14
14
  # Current version of bettercap.
15
- VERSION = '1.4.6'
15
+ VERSION = '1.5.0'
16
16
  # Program banner.
17
17
  BANNER = File.read( File.dirname(__FILE__) + '/banner' ).gsub( '#VERSION#', "v#{VERSION}")
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bettercap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.6
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simone Margaritelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-09 00:00:00.000000000 Z
11
+ date: 2016-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -130,6 +130,26 @@ dependencies:
130
130
  - - ">="
131
131
  - !ruby/object:Gem::Version
132
132
  version: 1.0.3
133
+ - !ruby/object:Gem::Dependency
134
+ name: em-proxy
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.1'
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 0.1.8
143
+ type: :runtime
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '0.1'
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 0.1.8
133
153
  description: BetterCap is the state of the art, modular, portable and easily extensible
134
154
  MITM framework featuring ARP, DNS and ICMP spoofing, sslstripping, credentials harvesting
135
155
  and more.
@@ -152,14 +172,16 @@ files:
152
172
  - lib/bettercap/discovery/thread.rb
153
173
  - lib/bettercap/error.rb
154
174
  - lib/bettercap/firewalls/base.rb
175
+ - lib/bettercap/firewalls/bsd.rb
155
176
  - lib/bettercap/firewalls/linux.rb
156
- - lib/bettercap/firewalls/openbsd.rb
157
- - lib/bettercap/firewalls/osx.rb
158
177
  - lib/bettercap/firewalls/redirection.rb
159
178
  - lib/bettercap/loader.rb
160
179
  - lib/bettercap/logger.rb
180
+ - lib/bettercap/memory.rb
161
181
  - lib/bettercap/monkey/celluloid/io/udp_socket.rb
182
+ - lib/bettercap/monkey/em-proxy/proxy.rb
162
183
  - lib/bettercap/monkey/openssl/server.rb
184
+ - lib/bettercap/monkey/packetfu/pcap.rb
163
185
  - lib/bettercap/monkey/packetfu/utils.rb
164
186
  - lib/bettercap/monkey/system.rb
165
187
  - lib/bettercap/network/arp_reader.rb
@@ -176,22 +198,29 @@ files:
176
198
  - lib/bettercap/network/services
177
199
  - lib/bettercap/network/target.rb
178
200
  - lib/bettercap/network/validator.rb
179
- - lib/bettercap/options.rb
180
- - lib/bettercap/proxy/module.rb
181
- - lib/bettercap/proxy/modules/injectcss.rb
182
- - lib/bettercap/proxy/modules/injecthtml.rb
183
- - lib/bettercap/proxy/modules/injectjs.rb
184
- - lib/bettercap/proxy/proxy.rb
185
- - lib/bettercap/proxy/request.rb
186
- - lib/bettercap/proxy/response.rb
187
- - lib/bettercap/proxy/ssl/authority.rb
188
- - lib/bettercap/proxy/ssl/bettercap-ca.pem
189
- - lib/bettercap/proxy/ssl/server.rb
190
- - lib/bettercap/proxy/sslstrip/cookiemonitor.rb
191
- - lib/bettercap/proxy/sslstrip/lock.ico
192
- - lib/bettercap/proxy/sslstrip/strip.rb
201
+ - lib/bettercap/options/core_options.rb
202
+ - lib/bettercap/options/options.rb
203
+ - lib/bettercap/options/proxy_options.rb
204
+ - lib/bettercap/options/server_options.rb
205
+ - lib/bettercap/options/sniff_options.rb
206
+ - lib/bettercap/options/spoof_options.rb
207
+ - lib/bettercap/proxy/http/module.rb
208
+ - lib/bettercap/proxy/http/modules/injectcss.rb
209
+ - lib/bettercap/proxy/http/modules/injecthtml.rb
210
+ - lib/bettercap/proxy/http/modules/injectjs.rb
211
+ - lib/bettercap/proxy/http/proxy.rb
212
+ - lib/bettercap/proxy/http/request.rb
213
+ - lib/bettercap/proxy/http/response.rb
214
+ - lib/bettercap/proxy/http/ssl/authority.rb
215
+ - lib/bettercap/proxy/http/ssl/bettercap-ca.pem
216
+ - lib/bettercap/proxy/http/ssl/server.rb
217
+ - lib/bettercap/proxy/http/sslstrip/cookiemonitor.rb
218
+ - lib/bettercap/proxy/http/sslstrip/lock.ico
219
+ - lib/bettercap/proxy/http/sslstrip/strip.rb
220
+ - lib/bettercap/proxy/http/streamer.rb
193
221
  - lib/bettercap/proxy/stream_logger.rb
194
- - lib/bettercap/proxy/streamer.rb
222
+ - lib/bettercap/proxy/tcp/module.rb
223
+ - lib/bettercap/proxy/tcp/proxy.rb
195
224
  - lib/bettercap/proxy/thread_pool.rb
196
225
  - lib/bettercap/shell.rb
197
226
  - lib/bettercap/sniffer/parsers/base.rb
@@ -1,77 +0,0 @@
1
- # encoding: UTF-8
2
- =begin
3
-
4
- BETTERCAP
5
-
6
- Author : Angelos D. Keromytis
7
- Email : angelos@cs.columbia.edu
8
-
9
- This project is released under the GPL 3 license.
10
-
11
- =end
12
-
13
- module BetterCap
14
- module Firewalls
15
- # OpenBSD Firewall class; for now, it's a direct copy of the OSX firewall
16
- class OpenBSD < Base
17
- # If +enabled+ is true will enable packet forwarding, otherwise it will
18
- # disable it.
19
- def enable_forwarding(enabled)
20
- Shell.execute("sysctl -w net.inet.ip.forwarding=#{enabled ? 1 : 0}")
21
- end
22
-
23
- # If +enabled+ is true will enable packet icmp_echo_ignore_broadcasts, otherwise it will
24
- # disable it.
25
- def enable_icmp_bcast(enabled)
26
- Shell.execute("sysctl -w net.inet.icmp.bmcastecho=#{enabled ? 1 : 0}")
27
- end
28
-
29
- # Return true if packet forwarding is currently enabled, otherwise false.
30
- def forwarding_enabled?
31
- Shell.execute('sysctl net.inet.ip.forwarding').strip.split(' ')[1] == '1'
32
- end
33
-
34
- # This method is ignored on OpenBSD.
35
- def enable_send_redirects(enabled); end
36
-
37
- # If +enabled+ is true, the PF firewall will be enabled, otherwise it will
38
- # be disabled.
39
- def enable(enabled)
40
- begin
41
- Shell.execute("pfctl -#{enabled ? 'e' : 'd'} >/dev/null 2>&1")
42
- rescue; end
43
- end
44
-
45
- # Apply the +r+ BetterCap::Firewalls::Redirection port redirection object.
46
- def add_port_redirection( r )
47
- # create the pf config file
48
- config_file = "/tmp/bettercap_pf_#{Process.pid}.conf"
49
-
50
- File.open( config_file, 'a+t' ) do |f|
51
- f.write "rdr pass on #{r.interface} proto #{r.protocol} from any to any port #{r.src_port} -> #{r.dst_address} port #{r.dst_port}\n"
52
- end
53
-
54
- # load the rule
55
- Shell.execute("pfctl -f #{config_file} >/dev/null 2>&1")
56
- # enable pf
57
- enable true
58
- end
59
-
60
- # Remove the +r+ BetterCap::Firewalls::Redirection port redirection object.
61
- def del_port_redirection( r )
62
- # FIXME: This should search for multiple rules inside the
63
- # file and remove only this one.
64
-
65
- # disable pf
66
- enable false
67
-
68
- begin
69
- # remove the pf config file
70
- File.delete( "/tmp/bettercap_pf_#{Process.pid}.conf" )
71
- rescue
72
- end
73
-
74
- end
75
- end
76
- end
77
- end
@@ -1,600 +0,0 @@
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
- # Parse command line arguments, set options and initialize +Context+
16
- # accordingly.
17
- class Options
18
- # Gateway IP address.
19
- attr_accessor :gateway
20
- # Network interface.
21
- attr_accessor :iface
22
- # Name of the spoofer to use.
23
- attr_accessor :spoofer
24
- # If true half duplex mode is enabled.
25
- attr_accessor :half_duplex
26
- # Comma separated list of targets.
27
- attr_accessor :target
28
- # Log file name.
29
- attr_accessor :logfile
30
- # If true the Logger will prepend timestamps to each line.
31
- attr_accessor :log_timestamp
32
- # If true will suppress every log message which is not an error or a warning.
33
- attr_accessor :silent
34
- # If true will enable debug messages.
35
- attr_accessor :debug
36
- # If true will disable active network discovery, the program will just use
37
- # the current ARP cache.
38
- attr_accessor :arpcache
39
- # Comma separated list of ip addresses to ignore.
40
- attr_accessor :ignore
41
- # If true the BetterCap::Sniffer will be enabled.
42
- attr_accessor :sniffer
43
- # PCAP file name to save captured packets to.
44
- attr_accessor :sniffer_pcap
45
- # BPF filter to apply to sniffed packets.
46
- attr_accessor :sniffer_filter
47
- # Input PCAP file, if specified the BetterCap::Sniffer will read packets
48
- # from it instead of the network.
49
- attr_accessor :sniffer_src
50
- # Comma separated list of BetterCap::Parsers to enable.
51
- attr_accessor :parsers
52
- # Regular expression to use with the BetterCap::Parsers::Custom parser.
53
- attr_accessor :custom_parser
54
- # If true, bettercap will sniff packets from the local interface as well.
55
- attr_accessor :local
56
- # If true, HTTP transparent proxy will be enabled.
57
- attr_accessor :proxy
58
- # If true, HTTPS transparent proxy will be enabled.
59
- attr_accessor :proxy_https
60
- # HTTP proxy port.
61
- attr_accessor :proxy_port
62
- # List of HTTP ports, [ 80 ] by default.
63
- attr_accessor :http_ports
64
- # HTTPS proxy port.
65
- attr_accessor :proxy_https_port
66
- # List of HTTPS ports, [ 443 ] by default.
67
- attr_accessor :https_ports
68
- # File name of the PEM certificate to use for the HTTPS proxy.
69
- attr_accessor :proxy_pem_file
70
- # File name of the transparent proxy module to load.
71
- attr_accessor :proxy_module
72
- # If true, sslstrip is enabled.
73
- attr_accessor :sslstrip
74
- # Custom HTTP transparent proxy address.
75
- attr_accessor :custom_proxy
76
- # Custom HTTP transparent proxy port.
77
- attr_accessor :custom_proxy_port
78
- # Custom HTTPS transparent proxy address.
79
- attr_accessor :custom_https_proxy
80
- # Custom HTTPS transparent proxy port.
81
- attr_accessor :custom_https_proxy_port
82
- # Custom list of redirections.
83
- attr_accessor :custom_redirections
84
- # If true, BetterCap::Network::Servers::HTTPD will be enabled.
85
- attr_accessor :httpd
86
- # The port to bind HTTP server to.
87
- attr_accessor :httpd_port
88
- # Web root of the HTTP server.
89
- attr_accessor :httpd_path
90
- # If true, BetterCap::Network::Servers::DNSD will be enabled.
91
- attr_accessor :dnsd
92
- # The port to bind DNS server to.
93
- attr_accessor :dnsd_port
94
- # The host resolution file to use with the DNS server.
95
- attr_accessor :dnsd_file
96
- # If true, bettercap will check for updates then exit.
97
- attr_accessor :check_updates
98
- # If true, targets NBNS hostname resolution won't be performed.
99
- attr_accessor :no_target_nbns
100
- # If true, bettercap won't forward packets for any target, causing
101
- # connections to be killed.
102
- attr_accessor :kill
103
- # If different than 0, this time will be used as a delay while sending packets.
104
- attr_accessor :packet_throttle
105
-
106
- # Create a BetterCap::Options class instance using the specified network interface.
107
- def initialize( iface )
108
- @gateway = nil
109
- @iface = iface
110
- @spoofer = 'ARP'
111
- @half_duplex = false
112
- @target = nil
113
- @logfile = nil
114
- @log_timestamp = false
115
- @silent = false
116
- @debug = false
117
- @arpcache = false
118
- @no_target_nbns = false
119
- @kill = false
120
- @packet_throttle = 0.0
121
- @http_ports = [ 80 ]
122
- @https_ports = [ 443 ]
123
- @ignore = nil
124
-
125
- @dnsd = false
126
- @dnsd_port = 5300
127
- @dnsd_file = nil
128
-
129
- @sniffer = false
130
- @sniffer_pcap = nil
131
- @sniffer_filter = nil
132
- @sniffer_src = nil
133
- @parsers = ['*']
134
- @custom_parser = nil
135
- @local = false
136
-
137
- @proxy = false
138
- @proxy_https = false
139
- @proxy_port = 8080
140
- @proxy_https_port = 8083
141
- @proxy_pem_file = nil
142
- @proxy_module = nil
143
-
144
- @custom_proxy = nil
145
- @custom_proxy_port = 8080
146
-
147
- @custom_https_proxy = nil
148
- @custom_https_proxy_port = 8083
149
-
150
- @custom_redirections = []
151
-
152
- @sslstrip = true
153
-
154
- @httpd = false
155
- @httpd_port = 8081
156
- @httpd_path = './'
157
-
158
- @check_updates = false
159
- end
160
-
161
- # Initialize the BetterCap::Context, parse command line arguments and update program
162
- # state accordingly.
163
- # Will rise a BetterCap::Error if errors occurred.
164
- def self.parse!
165
- ctx = Context.get
166
-
167
- OptionParser.new do |opts|
168
- opts.version = BetterCap::VERSION
169
- opts.banner = "Usage: bettercap [options]"
170
- opts.separator ""
171
- opts.separator "Specific options:"
172
- opts.separator ""
173
-
174
- opts.on( '-G', '--gateway ADDRESS', 'Manually specify the gateway address, if not specified the current gateway will be retrieved and used. ' ) do |v|
175
- ctx.options.gateway = v
176
- end
177
-
178
- opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options.iface.to_s.yellow ) do |v|
179
- ctx.options.iface = v
180
- end
181
-
182
- opts.on( '-S', '--spoofer NAME', "Spoofer module to use, available: #{Spoofers::Base.available.map{|x| x.yellow }.join(', ')} - default: #{ctx.options.spoofer.yellow}." ) do |v|
183
- ctx.options.spoofer = v
184
- end
185
-
186
- opts.on( '-T', '--target ADDRESS1,ADDRESS2', 'Target IP addresses, if not specified the whole subnet will be targeted.' ) do |v|
187
- ctx.options.target = v
188
- end
189
-
190
- opts.on( '--ignore ADDRESS1,ADDRESS2', 'Ignore these addresses if found while searching for targets.' ) do |v|
191
- ctx.options.parse_ignore!(v)
192
- end
193
-
194
- opts.on( '-O', '--log LOG_FILE', 'Log all messages into a file, if not specified the log messages will be only print into the shell.' ) do |v|
195
- ctx.options.logfile = v
196
- end
197
-
198
- opts.on( '--log-timestamp', 'Enable logging with timestamps for each line, disabled by default.' ) do
199
- ctx.options.log_timestamp = true
200
- end
201
-
202
- opts.on( '-D', '--debug', 'Enable debug logging.' ) do
203
- ctx.options.debug = true
204
- end
205
-
206
- opts.on( '-L', '--local', "Parse packets coming from/to the address of this computer ( NOTE: Will set -X to true ), default to #{'false'.yellow}." ) do
207
- ctx.options.local = true
208
- ctx.options.sniffer = true
209
- end
210
-
211
- opts.on( '-X', '--sniffer', 'Enable sniffer.' ) do
212
- ctx.options.sniffer = true
213
- end
214
-
215
- opts.on( '--sniffer-source FILE', 'Load packets from the specified PCAP file instead of the interface ( will enable sniffer ).' ) do |v|
216
- ctx.options.sniffer = true
217
- ctx.options.sniffer_src = File.expand_path v
218
- end
219
-
220
- opts.on( '--sniffer-pcap FILE', 'Save all packets to the specified PCAP file ( will enable sniffer ).' ) do |v|
221
- ctx.options.sniffer = true
222
- ctx.options.sniffer_pcap = File.expand_path v
223
- end
224
-
225
- opts.on( '--sniffer-filter EXPRESSION', 'Configure the sniffer to use this BPF filter ( will enable sniffer ).' ) do |v|
226
- ctx.options.sniffer = true
227
- ctx.options.sniffer_filter = v
228
- end
229
-
230
- opts.on( '-P', '--parsers PARSERS', "Comma separated list of packet parsers to enable, '*' for all ( NOTE: Will set -X to true ), available: #{Parsers::Base.available.map { |x| x.yellow }.join(', ')} - default: #{'*'.yellow}" ) do |v|
231
- ctx.options.sniffer = true
232
- ctx.options.parsers = Parsers::Base.from_cmdline(v)
233
- end
234
-
235
- 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|
236
- ctx.options.sniffer = true
237
- ctx.options.parsers = ['CUSTOM']
238
- ctx.options.custom_parser = Regexp.new(v)
239
- end
240
-
241
- opts.on( '--silent', "Suppress every message which is not an error or a warning, default to #{'false'.yellow}." ) do
242
- ctx.options.silent = true
243
- end
244
-
245
- opts.on( '--no-discovery', "Do not actively search for hosts, just use the current ARP cache, default to #{'false'.yellow}." ) do
246
- ctx.options.arpcache = true
247
- end
248
-
249
- opts.on( '--no-spoofing', "Disable spoofing, alias for #{'--spoofer NONE'.yellow}." ) do
250
- ctx.options.spoofer = 'NONE'
251
- end
252
-
253
- opts.on( '--no-target-nbns', 'Disable target NBNS hostname resolution.' ) do
254
- ctx.options.no_target_nbns = true
255
- end
256
-
257
- opts.on( '--half-duplex', 'Enable half-duplex MITM, this will make bettercap work in those cases when the router is not vulnerable.' ) do
258
- ctx.options.half_duplex = true
259
- end
260
-
261
- opts.on( '--proxy', "Enable HTTP proxy and redirects all HTTP requests to it, default to #{'false'.yellow}." ) do
262
- ctx.options.proxy = true
263
- end
264
-
265
- opts.on( '--proxy-https', "Enable HTTPS proxy and redirects all HTTPS requests to it, default to #{'false'.yellow}." ) do
266
- ctx.options.proxy_https = true
267
- end
268
-
269
- opts.on( '--proxy-port PORT', "Set HTTP proxy port, default to #{ctx.options.proxy_port.to_s.yellow}." ) do |v|
270
- ctx.options.proxy = true
271
- ctx.options.proxy_port = v.to_i
272
- end
273
-
274
- opts.on( '--http-ports PORT1,PORT2', "Comma separated list of HTTP ports to redirect to the proxy, default to #{ctx.options.http_ports.map{|x| x.to_s.yellow }.join(', ')}." ) do |v|
275
- ctx.options.http_ports = ctx.options.parse_ports( v )
276
- end
277
-
278
- opts.on( '--https-ports PORT1,PORT2', "Comma separated list of HTTPS ports to redirect to the proxy, default to #{ctx.options.https_ports.map{|x| x.to_s.yellow }.join(', ')}." ) do |v|
279
- ctx.options.https_ports = ctx.options.parse_ports( v )
280
- end
281
-
282
- opts.on( '--proxy-https-port PORT', "Set HTTPS proxy port, default to #{ctx.options.proxy_https_port.to_s.yellow}." ) do |v|
283
- ctx.options.proxy_https = true
284
- ctx.options.proxy_https_port = v.to_i
285
- end
286
-
287
- opts.on( '--proxy-pem FILE', "Use a custom PEM CA certificate file for the HTTPS proxy, default to #{Proxy::SSL::Authority::DEFAULT.yellow} ." ) do |v|
288
- ctx.options.proxy_https = true
289
- ctx.options.proxy_pem_file = File.expand_path v
290
- end
291
-
292
- opts.on( '--proxy-module MODULE', "Ruby proxy module to load, either a custom file or one of the following: #{Proxy::Module.available.map{|x| x.yellow}.join(', ')}." ) do |v|
293
- Proxy::Module.load(ctx, opts, v)
294
- end
295
-
296
- opts.on( '--custom-proxy ADDRESS', 'Use a custom HTTP upstream proxy instead of the builtin one.' ) do |v|
297
- ctx.options.parse_custom_proxy!(v)
298
- end
299
-
300
- opts.on( '--custom-proxy-port PORT', "Specify a port for the custom HTTP upstream proxy, default to #{ctx.options.custom_proxy_port.to_s.yellow}." ) do |v|
301
- ctx.options.custom_proxy_port = v.to_i
302
- end
303
-
304
- opts.on( '--no-sslstrip', 'Disable SSLStrip.' ) do
305
- ctx.options.sslstrip = false
306
- end
307
-
308
- opts.on( '--custom-https-proxy ADDRESS', 'Use a custom HTTPS upstream proxy instead of the builtin one.' ) do |v|
309
- ctx.options.parse_custom_proxy!( v, true )
310
- end
311
-
312
- opts.on( '--custom-https-proxy-port PORT', "Specify a port for the custom HTTPS upstream proxy, default to #{ctx.options.custom_https_proxy_port.to_s.yellow}." ) do |v|
313
- ctx.options.custom_https_proxy_port = v.to_i
314
- end
315
-
316
- opts.on( '--custom-redirection RULE', "Apply a custom port redirection, the format of the rule is #{'PROTOCOL ORIGINAL_PORT NEW_PORT'.yellow}. For instance #{'TCP 21 2100'.yellow} will redirect all TCP traffic going to port 21, to port 2100." ) do |v|
317
- ctx.options.parse_redirection!( v )
318
- end
319
-
320
- opts.on( '--httpd', "Enable HTTP server, default to #{'false'.yellow}." ) do
321
- ctx.options.httpd = true
322
- end
323
-
324
- opts.on( '--httpd-port PORT', "Set HTTP server port, default to #{ctx.options.httpd_port.to_s.yellow}." ) do |v|
325
- ctx.options.httpd = true
326
- ctx.options.httpd_port = v.to_i
327
- end
328
-
329
- opts.on( '--dns FILE', 'Enable DNS server and use this file as a hosts resolution table.' ) do |v|
330
- ctx.options.dnsd = true
331
- ctx.options.dnsd_file = File.expand_path v
332
- end
333
-
334
- opts.on( '--dns-port PORT', "Set DNS server port, default to #{ctx.options.dnsd_port.to_s.yellow}." ) do |v|
335
- ctx.options.dnsd_port = v.to_i
336
- end
337
-
338
- opts.on( '--httpd-path PATH', "Set HTTP server path, default to #{ctx.options.httpd_path.yellow} ." ) do |v|
339
- ctx.options.httpd = true
340
- ctx.options.httpd_path = v
341
- end
342
-
343
- opts.on( '--kill', 'Instead of forwarding packets, this switch will make targets connections to be killed.' ) do
344
- ctx.options.kill = true
345
- end
346
-
347
- opts.on( '--packet-throttle NUMBER', 'Number of seconds ( can be a decimal number ) to wait between each packet to be sent.' ) do |v|
348
- ctx.options.packet_throttle = v.to_f
349
- raise BetterCap::Error, "Invalid packet throttle value specified." if ctx.options.packet_throttle <= 0.0
350
- end
351
-
352
- opts.on( '--check-updates', 'Will check if any update is available and then exit.' ) do
353
- ctx.options.check_updates = true
354
- end
355
-
356
- opts.on('-h', '--help', 'Display the available options.') do
357
- puts opts
358
- puts "\nFor examples & docs please visit " + "http://bettercap.org/docs/".bold
359
- exit
360
- end
361
- end.parse!
362
-
363
- Logger.init( ctx.options.debug, ctx.options.logfile, ctx.options.silent, ctx.options.log_timestamp )
364
-
365
- if ctx.options.check_updates
366
- UpdateChecker.check
367
- exit
368
- end
369
-
370
- raise BetterCap::Error, 'This software must run as root.' unless Process.uid == 0
371
- raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' if ctx.options.iface.nil?
372
-
373
- ctx.options.starting_message
374
-
375
- if ctx.options.sslstrip and ctx.options.dnsd
376
- raise BetterCap::Error, "SSL Stripping and builtin DNS server are mutually exclusive features, " \
377
- "either use the --no-sslstrip option or remove the --dns option."
378
- end
379
-
380
- if ctx.options.has_proxy_module? and ( !ctx.options.proxy and !ctx.options.proxy_https )
381
- raise BetterCap::Error, "A proxy module was specified but none of the HTTP or HTTPS proxies are " \
382
- "enabled, specify --proxy or --proxy-https options."
383
- end
384
-
385
- unless ctx.options.gateway.nil?
386
- raise BetterCap::Error, "The specified gateway '#{ctx.options.gateway}' is not a valid IPv4 address." unless Network::Validator.is_ip?(ctx.options.gateway)
387
- ctx.gateway = ctx.options.gateway
388
- Logger.debug("Targetting manually specified gateway #{ctx.gateway}")
389
- end
390
-
391
- unless ctx.options.target.nil?
392
- ctx.targets = ctx.options.parse_targets
393
- end
394
-
395
- # Load firewall instance, network interface informations and detect the
396
- # gateway address.
397
- ctx.update!
398
-
399
- # Spoofers need the context network data to be initialized.
400
- ctx.spoofer = ctx.options.parse_spoofers
401
-
402
- ctx
403
- end
404
-
405
- # Return true if active host discovery is enabled, otherwise false.
406
- def should_discover_hosts?
407
- !@arpcache
408
- end
409
-
410
- # Return true if a proxy module was specified, otherwise false.
411
- def has_proxy_module?
412
- !@proxy_module.nil?
413
- end
414
-
415
- # Return true if a spoofer module was specified, otherwise false.
416
- def has_spoofer?
417
- @spoofer != 'NONE' and @spoofer != 'none'
418
- end
419
-
420
- # Return true if the BetterCap::Parsers::URL is enabled, otherwise false.
421
- def has_http_sniffer_enabled?
422
- @sniffer and ( @parsers.include?'*' or @parsers.include?'URL' )
423
- end
424
-
425
- # Return true if the +ip+ address needs to be ignored, otherwise false.
426
- def ignore_ip?(ip)
427
- !@ignore.nil? and @ignore.include?(ip)
428
- end
429
-
430
- # Parsing Routines
431
-
432
- # Setter for the #ignore attribute, will raise a BetterCap::Error if one
433
- # or more invalid IP addresses are specified.
434
- def parse_ignore!(value)
435
- @ignore = value.split(",")
436
- valid = @ignore.select { |target| Network::Validator.is_ip?(target) }
437
-
438
- raise BetterCap::Error, "Invalid ignore addresses specified." if valid.empty?
439
-
440
- invalid = @ignore - valid
441
- invalid.each do |target|
442
- Logger.warn "Not a valid address: #{target}"
443
- end
444
-
445
- @ignore = valid
446
-
447
- Logger.warn "Ignoring #{valid.join(", ")} ."
448
- end
449
-
450
- # Setter for the #custom_proxy or #custom_https_proxy attribute, will raise a
451
- # BetterCap::Error if +value+ is not a valid IP address.
452
- def parse_custom_proxy!(value, https=false)
453
- raise BetterCap::Error, 'Invalid custom HTTP upstream proxy address specified.' unless Network::Validator.is_ip?(value)
454
- if https
455
- @custom_https_proxy = value
456
- else
457
- @custom_proxy = value
458
- end
459
- end
460
-
461
- # Parse a custom redirection rule.
462
- def parse_redirection!(rule)
463
- if rule =~ /^((TCP)|(UDP))\s+(\d+)\s+(\d+)$/i
464
- @custom_redirections << {
465
- :proto => $1.upcase,
466
- :from => $4.to_i,
467
- :to => $5.to_i
468
- }
469
- else
470
- raise BetterCap::Error, 'Invalid custom redirection rule specified.'
471
- end
472
- end
473
-
474
- # Parse a comma separated list of ports and return an array containing only
475
- # valid ports, raise BetterCap::Error if that array is empty.
476
- def parse_ports(value)
477
- ports = []
478
- value.split(",").each do |v|
479
- v = v.strip.to_i
480
- if v > 0 and v <= 65535
481
- ports << v
482
- end
483
- end
484
- raise BetterCap::Error, 'Invalid ports specified.' if ports.empty?
485
- ports
486
- end
487
-
488
- # Split specified targets and parse them ( either as IP or MAC ), will raise a
489
- # BetterCap::Error if one or more invalid addresses are specified.
490
- def parse_targets
491
- valid = []
492
- targets = @target.split(",")
493
-
494
- targets.each do |t|
495
- if Network::Validator.is_ip?(t) or Network::Validator.is_mac?(t)
496
- valid << Network::Target.new(t)
497
-
498
- elsif Network::Validator.is_range?(t)
499
- Network::Validator.each_in_range( t ) do |address|
500
- valid << Network::Target.new(address)
501
- end
502
-
503
- elsif Network::Validator.is_netmask?(t)
504
- Network::Validator.each_in_netmask(t) do |address|
505
- valid << Network::Target.new(address)
506
- end
507
-
508
- else
509
- raise BetterCap::Error, "Invalid target specified '#{t}', valid formats are IP addresses, "\
510
- "MAC addresses, IP ranges ( 192.168.1.1-30 ) or netmasks ( 192.168.1.1/24 ) ."
511
- end
512
- end
513
-
514
- valid
515
- end
516
-
517
- # Parse spoofers and return a list of BetterCap::Spoofers objects. Raise a
518
- # BetterCap::Error if an invalid spoofer name was specified.
519
- def parse_spoofers
520
- spoofers = []
521
- @spoofer.split(",").each do |module_name|
522
- spoofers << Spoofers::Base.get_by_name( module_name )
523
- end
524
- spoofers
525
- end
526
-
527
- # Helper method to create a Firewalls::Redirection object.
528
- def redir( address, port, to, proto = 'TCP' )
529
- Firewalls::Redirection.new( @iface, proto, port, address, to )
530
- end
531
-
532
- # Create a list of BetterCap::Firewalls::Redirection objects which are needed
533
- # given the specified command line arguments.
534
- def get_redirections ifconfig
535
- redirections = []
536
-
537
- if @dnsd or ( @proxy and @sslstrip )
538
- redirections << redir( ifconfig[:ip_saddr], 53, @dnsd_port )
539
- redirections << redir( ifconfig[:ip_saddr], 53, @dnsd_port, 'UDP' )
540
- end
541
-
542
- if @proxy
543
- @http_ports.each do |port|
544
- redirections << redir( ifconfig[:ip_saddr], port, @proxy_port )
545
- end
546
- end
547
-
548
- if @proxy_https
549
- @https_ports.each do |port|
550
- redirections << redir( ifconfig[:ip_saddr], port, @proxy_https_port )
551
- end
552
- end
553
-
554
- if @custom_proxy
555
- @http_ports.each do |port|
556
- redirections << redir( @custom_proxy, port, @custom_proxy_port )
557
- end
558
- end
559
-
560
- if @custom_https_proxy
561
- @https_ports.each do |port|
562
- redirections << redir( @custom_https_proxy, port, @custom_https_proxy_port )
563
- end
564
- end
565
-
566
- @custom_redirections.each do |r|
567
- redirections << redir( ifconfig[:ip_saddr], r[:from], r[:to], r[:proto] )
568
- end
569
-
570
- redirections
571
- end
572
-
573
- # Print the starting status message.
574
- def starting_message
575
- on = '✔'.green
576
- off = '✘'.red
577
- status = {
578
- 'spoofing' => ( has_spoofer? ? on : off ),
579
- 'discovery' => ( ( !target.nil? or arpcache ) ? off : on ),
580
- 'sniffer' => ( sniffer ? on : off ),
581
- 'http-proxy' => ( proxy ? on : off ),
582
- 'https-proxy' => ( proxy_https ? on : off ),
583
- 'sslstrip' => ( ( proxy and sslstrip ) ? on : off ),
584
- 'http-server' => ( httpd ? on : off ),
585
- 'dns-server' => ( ( ( proxy and sslstrip ) or dnsd ) ? on : off )
586
- }
587
-
588
- msg = "Starting [ "
589
- status.each do |k,v|
590
- msg += "#{k}:#{v} "
591
- end
592
- msg += "] ...\n\n"
593
-
594
- Logger.info msg
595
-
596
- Logger.warn "You are running an unstable/beta version of this software, please" \
597
- " update to a stable one if available." if BetterCap::VERSION =~ /[\d\.+]b/
598
- end
599
- end
600
- end