bettercap 1.4.6 → 1.5.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 (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