bettercap 1.1.7 → 1.1.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99ec69d1a1e157a94b36b3f9162d807a2dea9238
4
- data.tar.gz: 616717ef0f681792c14ba6ff5dd4341462f175c2
3
+ metadata.gz: 851e88dcce552dfe264421c42fd1ad02c4ef0160
4
+ data.tar.gz: 25e6d2a981d6113e86c150f833405c417594d613
5
5
  SHA512:
6
- metadata.gz: f0cfae6e9605ffe0226b3d5bb3a85dafb2d808fd9e1ca3f3f020961769b3ba10fb5d87c9c7747de0fa2e4c3fc3a7a03fd3c0eca3f4710f9b19c1ffd9e5171fdf
7
- data.tar.gz: 62981206dccd1fbaa956db5f2316dfe29f2a5e05dd495334f740c408adaf64ab1eb64da925cebe171f16ba00691131135cb26c0f3cffaec1abd967882a341b56
6
+ metadata.gz: 1d58eeb378e71ed4ef0059f5380763a4559d3c7f17d80da9ef54c415b760cfe47e38f52a9ea2cd2ba282ff326e87441c0b863790fa5b5b5b07ac0dd282246f3d
7
+ data.tar.gz: d19bc791b7cedf8f64527a981f248dd9c5b35ce1c8937df7cf1878f97c1ca0c79722c91f7c914968e288a34c798c22b385d070daa9bea686861844a1904d4ab9
data/.gitignore CHANGED
@@ -7,4 +7,6 @@ cert.crt
7
7
  cert.key
8
8
  cert.pem
9
9
  test_https_proxy.rb
10
- mkchangelog.rb
10
+ test_chunked.rb
11
+ mkchangelog.rb
12
+ .tags*
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  ![logo](http://www.bettercap.org/assets/img/navbar-logo.png)
2
2
 
3
- Copyleft of Simone '[evilsocket](https://twitter.com/evilsocket)' Margaritelli*.
4
-
5
3
  http://www.bettercap.org/
6
4
 
7
5
  [![Gem Version](https://badge.fury.io/rb/bettercap.svg)](http://badge.fury.io/rb/bettercap) [![Code Climate](https://codeclimate.com/github/evilsocket/bettercap/badges/gpa.svg)](https://codeclimate.com/github/evilsocket/bettercap)
@@ -10,32 +8,38 @@ http://www.bettercap.org/
10
8
  **bettercap** is a complete, modular, portable and easily extensible **MITM** tool and framework with every kind of diagnostic
11
9
  and offensive feature you could need in order to perform a man in the middle attack.
12
10
 
13
- HOW TO INSTALL
14
- ===
11
+ Contact me at:
12
+
13
+ - Twitter: [@evilsocket](https://twitter.com/evilsocket)
14
+ - Email: evilsocket@gmail.com
15
+
16
+ Before submitting issues, please read the relevant [section](http://www.bettercap.org/docs/contribute/) in the documentation.
17
+
18
+ Installation
19
+ ============
15
20
 
16
21
  **Stable Release ( GEM )**
17
-
22
+
18
23
  gem install bettercap
19
-
24
+
20
25
  **From Source**
21
-
26
+
22
27
  git clone https://github.com/evilsocket/bettercap
23
28
  cd bettercap
24
29
  gem build bettercap.gemspec
25
30
  sudo gem install bettercap*.gem
26
31
 
27
- DEPENDS
28
- ===
32
+ Dependencies
33
+ ============
29
34
 
30
35
  All dependencies will be automatically installed through the GEM system, in some case you might need to install some system
31
36
  dependency in order to make everything work:
32
37
 
33
38
  sudo apt-get install ruby-dev libpcap-dev
34
-
35
- This should solve issues such as [this one](https://github.com/evilsocket/bettercap/issues/22).
36
39
 
40
+ This should solve issues such as [this one](https://github.com/evilsocket/bettercap/issues/22).
37
41
 
38
- EXAMPLES & INSTRUCTIONS
39
- ===
42
+ Documentation and Examples
43
+ ============
40
44
 
41
- Please refer to the [official website](http://bettercap.org).
45
+ Please refer to the [official website](http://www.bettercap.org/docs/).
data/TODO.md CHANGED
@@ -3,15 +3,22 @@ This is a list of TODOs I use to keep track of tasks and upcoming features.
3
3
  ---
4
4
 
5
5
  - [x] Implement `--ignore ADDR,ADDR,ADDR` option to filter out specific addresses from the targets list.
6
+ - [x] HTTP 1.1 chunked response support.
7
+ - [x] Ip address to hostname resolution.
8
+ - [ ] Implement event-driven core plugin infrastructure ( for webui, etc ).
9
+ - [ ] Implement web-ui core plugin.
6
10
  - [ ] Rewrite proxy class using [em-proxy](https://github.com/igrigorik/em-proxy) library.
7
- - [ ] [Active packet filtering/injection/etc](https://github.com/evilsocket/bettercap/issues/75) ( maybe using [this](https://github.com/gdelugre/ruby-nfqueue) ).
8
- - [ ] *BSD Support.
9
11
  - [ ] HTTP/2 Support.
12
+ - [ ] IPV6 Support.
13
+
14
+ **Platform Specific**
15
+
16
+ - [ ] *BSD Support.
17
+ - [ ] Windows Support? ( OMG PLZ NO! )
18
+ - [ ] GNU/Linux [Active packet filtering/injection/etc](https://github.com/evilsocket/bettercap/issues/75) ( maybe using [this](https://github.com/gdelugre/ruby-nfqueue) ).
10
19
 
11
20
  **Maybe**
12
21
 
13
22
  - [ ] ICMP Redirect ? ( only half duplex and filtered by many firewalls anyway ... dunno ).
14
23
  - [ ] DNS Spoofing ( not sure if it actually makes any sense ).
15
- - [ ] Windows Support? ( OMG PLZ NO! )
16
- - [ ] Output/actions as json for UI integration?
17
24
  - [ ] sslstrip ( not really sure, currently is quite useless )
@@ -16,6 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.add_dependency( 'colorize', '~> 0.7.5' )
17
17
  gem.add_dependency( 'packetfu', '~> 1.1.10' )
18
18
  gem.add_dependency( 'pcaprub', '~> 0.12.0' )
19
+ gem.add_dependency( 'network_interface', '~> 0.0.1' )
19
20
 
20
21
  gem.add_development_dependency( 'minitest' )
21
22
 
@@ -23,149 +23,149 @@ begin
23
23
  OptionParser.new do |opts|
24
24
  opts.banner = "Usage: #{$0} [options]"
25
25
  opts.version = BetterCap::VERSION
26
-
26
+
27
27
  opts.on( '-G', '--gateway ADDRESS', 'Manually specify the gateway address, if not specified the current gateway will be retrieved and used. ' ) do |v|
28
- ctx.options[:gateway] = v
28
+ ctx.options.gateway = v
29
29
  end
30
30
 
31
- opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options[:iface].to_s ) do |v|
32
- ctx.options[:iface] = v
31
+ opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options.iface.to_s ) do |v|
32
+ ctx.options.iface = v
33
33
  end
34
34
 
35
- opts.on( '-S', '--spoofer NAME', 'Spoofer module to use, available: ' + SpooferFactory.available.join(', ') + ' - default: ' + ctx.options[:spoofer] ) do |v|
36
- ctx.options[:spoofer] = v
35
+ opts.on( '-S', '--spoofer NAME', 'Spoofer module to use, available: ' + SpooferFactory.available.join(', ') + ' - default: ' + ctx.options.spoofer ) do |v|
36
+ ctx.options.spoofer = v
37
37
  end
38
38
 
39
39
  opts.on( '-T', '--target ADDRESS1,ADDRESS2', 'Target IP addresses, if not specified the whole subnet will be targeted.' ) do |v|
40
- ctx.options[:target] = v
40
+ ctx.options.target = v
41
41
  end
42
42
 
43
43
  opts.on( '--ignore ADDRESS1,ADDRESS2', 'Ignore these addresses if found while searching for targets.' ) do |v|
44
- ctx.options[:ignore] = v
44
+ ctx.options.ignore = v
45
45
  end
46
46
 
47
47
  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|
48
- ctx.options[:logfile] = v
48
+ ctx.options.logfile = v
49
49
  end
50
50
 
51
51
  opts.on( '-D', '--debug', 'Enable debug logging.' ) do
52
- ctx.options[:debug] = true
52
+ ctx.options.debug = true
53
53
  end
54
54
 
55
55
  opts.on( '-L', '--local', 'Parse packets coming from/to the address of this computer ( NOTE: Will set -X to true ), default to false.' ) do
56
- ctx.options[:local] = true
57
- ctx.options[:sniffer] = true
56
+ ctx.options.local = true
57
+ ctx.options.sniffer = true
58
58
  end
59
59
 
60
60
  opts.on( '-X', '--sniffer', 'Enable sniffer.' ) do
61
- ctx.options[:sniffer] = true
61
+ ctx.options.sniffer = true
62
62
  end
63
63
 
64
64
  opts.on( '--sniffer-source FILE', 'Load packets from the specified PCAP file instead of the interface ( will enable sniffer ).' ) do |v|
65
- ctx.options[:sniffer] = true
66
- ctx.options[:sniffer_src] = File.expand_path v
65
+ ctx.options.sniffer = true
66
+ ctx.options.sniffer_src = File.expand_path v
67
67
  end
68
68
 
69
69
  opts.on( '--sniffer-pcap FILE', 'Save all packets to the specified PCAP file ( will enable sniffer ).' ) do |v|
70
- ctx.options[:sniffer] = true
71
- ctx.options[:sniffer_pcap] = File.expand_path v
70
+ ctx.options.sniffer = true
71
+ ctx.options.sniffer_pcap = File.expand_path v
72
72
  end
73
73
 
74
74
  opts.on( '--sniffer-filter EXPRESSION', 'Configure the sniffer to use this BPF filter ( will enable sniffer ).' ) do |v|
75
- ctx.options[:sniffer] = true
76
- ctx.options[:sniffer_filter] = v
75
+ ctx.options.sniffer = true
76
+ ctx.options.sniffer_filter = v
77
77
  end
78
78
 
79
79
  opts.on( '-P', '--parsers PARSERS', 'Comma separated list of packet parsers to enable, "*" for all ( NOTE: Will set -X to true ), available: ' + ParserFactory.available.join(', ') + ' - default: *' ) do |v|
80
- ctx.options[:sniffer] = true
81
- ctx.options[:parsers] = ParserFactory.from_cmdline(v)
80
+ ctx.options.sniffer = true
81
+ ctx.options.parsers = ParserFactory.from_cmdline(v)
82
82
  end
83
83
 
84
84
  opts.on( '--no-discovery', 'Do not actively search for hosts, just use the current ARP cache, default to false.' ) do
85
- ctx.options[:arpcache] = true
85
+ ctx.options.arpcache = true
86
86
  end
87
87
 
88
88
  opts.on( '--no-spoofing', 'Disable spoofing, alias for --spoofer NONE.' ) do
89
- ctx.options[:spoofer] = 'NONE'
89
+ ctx.options.spoofer = 'NONE'
90
90
  end
91
91
 
92
92
  opts.on( '--half-duplex', 'Enable half-duplex MITM, this will make bettercap work in those cases when the router is not vulnerable.' ) do
93
- ctx.options[:half_duplex] = true
93
+ ctx.options.half_duplex = true
94
94
  end
95
95
 
96
96
  opts.on( '--proxy', 'Enable HTTP proxy and redirects all HTTP requests to it, default to false.' ) do
97
- ctx.options[:proxy] = true
97
+ ctx.options.proxy = true
98
98
  end
99
99
 
100
100
  opts.on( '--proxy-https', 'Enable HTTPS proxy and redirects all HTTPS requests to it, default to false.' ) do
101
- ctx.options[:proxy] = true
102
- ctx.options[:proxy_https] = true
101
+ ctx.options.proxy = true
102
+ ctx.options.proxy_https = true
103
103
  end
104
104
 
105
- opts.on( '--proxy-port PORT', 'Set HTTP proxy port, default to ' + ctx.options[:proxy_port].to_s + ' .' ) do |v|
106
- ctx.options[:proxy] = true
107
- ctx.options[:proxy_port] = v.to_i
105
+ opts.on( '--proxy-port PORT', 'Set HTTP proxy port, default to ' + ctx.options.proxy_port.to_s + ' .' ) do |v|
106
+ ctx.options.proxy = true
107
+ ctx.options.proxy_port = v.to_i
108
108
  end
109
109
 
110
- opts.on( '--proxy-https-port PORT', 'Set HTTPS proxy port, default to ' + ctx.options[:proxy_https_port].to_s + ' .' ) do |v|
111
- ctx.options[:proxy] = true
112
- ctx.options[:proxy_https] = true
113
- ctx.options[:proxy_https_port] = v.to_i
110
+ opts.on( '--proxy-https-port PORT', 'Set HTTPS proxy port, default to ' + ctx.options.proxy_https_port.to_s + ' .' ) do |v|
111
+ ctx.options.proxy = true
112
+ ctx.options.proxy_https = true
113
+ ctx.options.proxy_https_port = v.to_i
114
114
  end
115
115
 
116
116
  opts.on( '--proxy-pem FILE', 'Use a custom PEM certificate file for the HTTPS proxy.' ) do |v|
117
- ctx.options[:proxy] = true
118
- ctx.options[:proxy_https] = true
119
- ctx.options[:proxy_pem_file] = File.expand_path v
117
+ ctx.options.proxy = true
118
+ ctx.options.proxy_https = true
119
+ ctx.options.proxy_pem_file = File.expand_path v
120
120
  end
121
121
 
122
122
  opts.on( '--proxy-module MODULE', 'Ruby proxy module to load.' ) do |v|
123
- ctx.options[:proxy] = true
124
- ctx.options[:proxy_module] = File.expand_path v
123
+ ctx.options.proxy = true
124
+ ctx.options.proxy_module = File.expand_path v
125
125
  end
126
126
 
127
127
  opts.on( '--custom-proxy ADDRESS', 'Use a custom HTTP upstream proxy instead of the builtin one.' ) do |v|
128
- ctx.options[:custom_proxy] = v
128
+ ctx.options.custom_proxy = v
129
129
  end
130
130
 
131
- opts.on( '--custom-proxy-port PORT', 'Specify a port for the custom HTTP upstream proxy, default to ' + ctx.options[:custom_proxy_port].to_s + ' .' ) do |v|
132
- ctx.options[:custom_proxy_port] = v.to_i
131
+ opts.on( '--custom-proxy-port PORT', 'Specify a port for the custom HTTP upstream proxy, default to ' + ctx.options.custom_proxy_port.to_s + ' .' ) do |v|
132
+ ctx.options.custom_proxy_port = v.to_i
133
133
  end
134
134
 
135
135
  opts.on( '--custom-https-proxy ADDRESS', 'Use a custom HTTPS upstream proxy instead of the builtin one.' ) do |v|
136
- ctx.options[:custom_https_proxy] = v
136
+ ctx.options.custom_https_proxy = v
137
137
  end
138
138
 
139
- 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 + ' .' ) do |v|
140
- ctx.options[:custom_https_proxy_port] = v.to_i
139
+ 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 + ' .' ) do |v|
140
+ ctx.options.custom_https_proxy_port = v.to_i
141
141
  end
142
142
 
143
143
  opts.on( '--httpd', 'Enable HTTP server, default to false.' ) do
144
- ctx.options[:httpd] = true
144
+ ctx.options.httpd = true
145
145
  end
146
146
 
147
- opts.on( '--httpd-port PORT', 'Set HTTP server port, default to ' + ctx.options[:httpd_port].to_s + '.' ) do |v|
148
- ctx.options[:httpd] = true
149
- ctx.options[:httpd_port] = v.to_i
147
+ opts.on( '--httpd-port PORT', 'Set HTTP server port, default to ' + ctx.options.httpd_port.to_s + '.' ) do |v|
148
+ ctx.options.httpd = true
149
+ ctx.options.httpd_port = v.to_i
150
150
  end
151
151
 
152
- opts.on( '--httpd-path PATH', 'Set HTTP server path, default to ' + ctx.options[:httpd_path] + '.' ) do |v|
153
- ctx.options[:httpd] = true
154
- ctx.options[:httpd_path] = v
152
+ opts.on( '--httpd-path PATH', 'Set HTTP server path, default to ' + ctx.options.httpd_path + '.' ) do |v|
153
+ ctx.options.httpd = true
154
+ ctx.options.httpd_path = v
155
155
  end
156
156
 
157
157
  opts.on( '--check-updates', 'Will check if any update is available and then exit.' ) do
158
- ctx.options[:check_updates] = true
158
+ ctx.options.check_updates = true
159
159
  end
160
160
 
161
161
  opts.on('-h', '--help', 'Display the available options.') do
162
162
  puts opts
163
- puts "\nFor examples & instructions please visit " + "http://bettercap.org/features/".bold
163
+ puts "\nFor examples & docs please visit " + "http://bettercap.org/docs/".bold
164
164
  exit
165
165
  end
166
166
  end.parse!
167
167
 
168
- if ctx.options[:check_updates]
168
+ if ctx.options.check_updates
169
169
  error_policy = lambda { |e|
170
170
  Logger.error("Could not check for udpates: #{e.message}")
171
171
  }
@@ -175,90 +175,53 @@ begin
175
175
  end
176
176
 
177
177
  raise BetterCap::Error, 'This software must run as root.' unless Process.uid == 0
178
- raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' unless !ctx.options[:iface].nil?
178
+ raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' unless !ctx.options.iface.nil?
179
179
 
180
- Logger.debug_enabled = true unless !ctx.options[:debug]
180
+ Logger.debug_enabled = true unless !ctx.options.debug
181
181
 
182
- Logger.logfile = ctx.options[:logfile]
182
+ Logger.logfile = ctx.options.logfile
183
183
 
184
184
 
185
- if !ctx.options[:gateway].nil?
186
- raise BetterCap::Error, "Invalid gateway" if !Network.is_ip?(ctx.options[:gateway])
187
- ctx.gateway = ctx.options[:gateway]
185
+ unless ctx.options.gateway.nil?
186
+ raise BetterCap::Error, "Invalid gateway" if !Network.is_ip?(ctx.options.gateway)
187
+ ctx.gateway = ctx.options.gateway
188
188
  Logger.info("Targetting manual gateway #{ctx.gateway}")
189
189
  end
190
-
190
+
191
191
  ctx.update_network
192
192
 
193
- if ctx.options[:target].nil?
194
- Logger.info( "Targeting the whole subnet #{ctx.network.to_range} ..." ) unless \
195
- ctx.options[:spoofer] == 'NONE' or ctx.options[:spoofer] == 'none'
193
+ if ctx.options.target.nil?
194
+ Logger.info( "Targeting the whole subnet #{ctx.network.to_range} ..." ) unless ctx.options.has_spoofer?
196
195
 
197
196
  ctx.start_discovery_thread
198
197
  else
199
- targets = ctx.options[:target].split(",")
200
- valid_targets = targets.select { |target| Network.is_ip?(target) }
201
-
202
- raise BetterCap::Error, "Invalid target" if valid_targets.empty?
203
-
204
- invalid_targets = targets - valid_targets
205
- invalid_targets.each do |target|
206
- Logger.warn "Invalid target #{target}"
207
- end
208
-
209
- ctx.targets = valid_targets.map { |target| Target.new(target) }
210
- end
211
-
212
- unless ctx.options[:ignore].nil?
213
- ignore = ctx.options[:ignore].split(",")
214
- valid = ignore.select { |target| Network.is_ip?(target) }
215
-
216
- raise BetterCap::Error, "Invalid ignore addresses specified." if valid.empty?
217
-
218
- invalid = ignore - valid
219
- invalid.each do |target|
220
- Logger.warn "Not a valid address: #{target}"
221
- end
222
-
223
- ctx.options[:ignore] = valid
224
-
225
- Logger.warn "Ignoring #{valid.join(", ")} ."
198
+ ctx.targets = ctx.options.to_targets
226
199
  end
227
200
 
228
- ctx.spoofer = []
229
- spoofer_modules_names = ctx.options[:spoofer].split(",")
230
- spoofer_modules_names.each do |module_name|
231
- ctx.spoofer << SpooferFactory.get_by_name( module_name )
232
- ctx.spoofer.last.start
201
+ ctx.spoofer = ctx.options.to_spoofers
202
+ ctx.spoofer.each do |spoofer|
203
+ spoofer.start
233
204
  end
234
205
 
235
- if ctx.options[:proxy]
236
- if ctx.options[:sniffer] and ( ctx.options[:parsers].include?'*' or ctx.options[:parsers].include?'URL' )
206
+ if ctx.options.proxy
207
+ if ctx.options.has_http_sniffer_enabled?
237
208
  Logger.warn "WARNING: Both HTTP transparent proxy and URL parser are enabled, you're gonna see duplicated logs."
238
209
  end
239
210
 
240
211
  ctx.create_proxies
241
212
  end
242
213
 
243
- if ctx.options[:custom_proxy]
244
- raise BetterCap::Error, 'Invalid custom HTTP upstream proxy address specified.' unless Network.is_ip? ctx.options[:custom_proxy]
245
- end
246
-
247
- if ctx.options[:custom_https_proxy]
248
- raise BetterCap::Error, 'Invalid custom HTTPS upstream proxy address specified.' unless Network.is_ip? ctx.options[:custom_https_proxy]
249
- end
250
-
251
214
  ctx.enable_port_redirection
252
-
253
- if ctx.options[:httpd]
254
- ctx.httpd = HTTPD::Server.new( ctx.options[:httpd_port], ctx.options[:httpd_path] )
215
+
216
+ if ctx.options.httpd
217
+ ctx.httpd = HTTPD::Server.new( ctx.options.httpd_port, ctx.options.httpd_path )
255
218
  ctx.httpd.start
256
219
  end
257
220
 
258
- if ctx.options[:sniffer]
221
+ if ctx.options.sniffer
259
222
  Sniffer.start ctx
260
223
  else
261
- if ctx.options[:spoofer] != 'NONE' and ctx.options[:spoofer] != 'none'
224
+ unless ctx.options.has_spoofer?
262
225
  Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this will cause the MITM to run but no data to be collected.'
263
226
  end
264
227
 
@@ -25,6 +25,7 @@ Object.send :remove_const, :Config rescue nil
25
25
  Config = RbConfig
26
26
 
27
27
  require 'bettercap/error'
28
+ require 'bettercap/options'
28
29
  require 'bettercap/context'
29
30
  require 'bettercap/monkey/packetfu/utils'
30
31
  require 'bettercap/factories/firewall_factory'
@@ -18,7 +18,7 @@ require 'json'
18
18
 
19
19
  class Context
20
20
  attr_accessor :options, :ifconfig, :network, :firewall, :gateway,
21
- :targets, :spoofer, :proxy, :https_proxy, :httpd,
21
+ :targets, :spoofer, :httpd,
22
22
  :certificate
23
23
 
24
24
  @@instance = nil
@@ -35,58 +35,18 @@ class Context
35
35
  Logger.debug e.message
36
36
  end
37
37
 
38
- @options = {
39
- gateway: nil,
40
- iface: iface,
41
- spoofer: 'ARP',
42
- half_duplex: false,
43
- target: nil,
44
- logfile: nil,
45
- debug: false,
46
- arpcache: false,
47
-
48
- ignore: nil,
49
-
50
- sniffer: false,
51
- sniffer_pcap: nil,
52
- sniffer_filter: nil,
53
- sniffer_src: nil,
54
- parsers: ['*'],
55
- local: false,
56
-
57
- proxy: false,
58
- proxy_https: false,
59
- proxy_port: 8080,
60
- proxy_https_port: 8083,
61
- proxy_pem_file: nil,
62
- proxy_module: nil,
63
-
64
- custom_proxy: nil,
65
- custom_proxy_port: 8080,
66
-
67
- custom_https_proxy: nil,
68
- custom_https_proxy_port: 8083,
69
-
70
- httpd: false,
71
- httpd_port: 8081,
72
- httpd_path: './',
73
-
74
- check_updates: false
75
- }
76
-
77
- @ifconfig = nil
78
- @network = nil
79
- @firewall = nil
80
- @gateway = nil
81
- @targets = []
82
- @proxy_processor = nil
83
- @proxy = nil
84
- @https_proxy = nil
85
- @spoofer = nil
86
- @httpd = nil
87
- @certificate = nil
88
- @redirections = []
89
-
38
+ @options = Options.new iface
39
+ @ifconfig = nil
40
+ @network = nil
41
+ @firewall = nil
42
+ @gateway = nil
43
+ @targets = []
44
+ @proxy_processor = nil
45
+ @spoofer = nil
46
+ @httpd = nil
47
+ @certificate = nil
48
+ @proxies = []
49
+ @redirections = []
90
50
  @discovery_running = false
91
51
  @discovery_thread = nil
92
52
  end
@@ -122,25 +82,34 @@ class Context
122
82
 
123
83
  def update_network
124
84
  @firewall = FirewallFactory.get_firewall
125
- @ifconfig = PacketFu::Utils.ifconfig @options[:iface]
85
+ @ifconfig = PacketFu::Utils.ifconfig @options.iface
126
86
  @network = @ifconfig[:ip4_obj]
127
87
  @gateway = Network.get_gateway if @gateway.nil?
128
88
 
129
- raise BetterCap::Error, "Could not determine IPv4 address of '#{@options[:iface]}' interface." unless !@network.nil?
89
+ raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.iface}' interface." unless !@network.nil?
130
90
 
131
91
  Logger.debug "network=#{@network} gateway=#{@gateway} local_ip=#{@ifconfig[:ip_saddr]}"
132
92
  Logger.debug "IFCONFIG: #{@ifconfig.inspect}"
133
93
  end
134
94
 
95
+ def find_target ip, mac
96
+ @targets.each do |target|
97
+ if target.ip == ip && ( mac.nil? || target.mac == mac )
98
+ return target
99
+ end
100
+ end
101
+ nil
102
+ end
103
+
135
104
  def start_discovery_thread
136
105
  @discovery_running = true
137
106
  @discovery_thread = Thread.new {
138
- Logger.info( 'Network discovery thread started.' ) unless @options[:arpcache]
107
+ Logger.info( 'Network discovery thread started.' ) unless @options.arpcache
139
108
 
140
109
  while @discovery_running
141
110
  empty_list = false
142
111
 
143
- if @targets.empty? and !@options[:arpcache]
112
+ if @targets.empty? and @options.should_discover_hosts?
144
113
  empty_list = true
145
114
  Logger.info 'Searching for alive targets ...'
146
115
  else
@@ -155,7 +124,7 @@ class Context
155
124
 
156
125
  @targets = Network.get_alive_targets self
157
126
 
158
- if empty_list and !@options[:arpcache]
127
+ if empty_list and @options.should_discover_hosts?
159
128
  Logger.info "Collected #{@targets.size} total targets."
160
129
  @targets.each do |target|
161
130
  Logger.info " #{target}"
@@ -169,7 +138,7 @@ class Context
169
138
  @discovery_running = false
170
139
 
171
140
  if @discovery_thread != nil
172
- Logger.info( 'Stopping network discovery thread ...' ) unless @options[:arpcache]
141
+ Logger.info( 'Stopping network discovery thread ...' ) unless @options.arpcache
173
142
 
174
143
  begin
175
144
  @discovery_thread.exit
@@ -179,44 +148,11 @@ class Context
179
148
  end
180
149
 
181
150
  def enable_port_redirection
182
- @redirections = []
183
-
184
- if @options[:proxy]
185
- @redirections << Redirection.new( @options[:iface],
186
- 'TCP',
187
- 80,
188
- @ifconfig[:ip_saddr],
189
- @options[:proxy_port] )
190
- end
191
-
192
- if @options[:proxy_https]
193
- @redirections << Redirection.new( @options[:iface],
194
- 'TCP',
195
- 443,
196
- @ifconfig[:ip_saddr],
197
- @options[:proxy_https_port] )
198
- end
199
-
200
- if @options[:custom_proxy]
201
- @redirections << Redirection.new( @options[:iface],
202
- 'TCP',
203
- 80,
204
- @options[:custom_proxy],
205
- @options[:custom_proxy_port] )
206
- end
207
-
208
- if @options[:custom_https_proxy]
209
- @redirections << Redirection.new( @options[:iface],
210
- 'TCP',
211
- 443,
212
- @options[:custom_https_proxy],
213
- @options[:custom_https_proxy_port] )
214
- end
215
-
151
+ @redirections = @options.to_redirections @ifconfig
216
152
  @redirections.each do |r|
217
153
  Logger.warn "Redirecting #{r.protocol} traffic from port #{r.src_port} to #{r.dst_address}:#{r.dst_port}"
218
154
 
219
- @firewall.add_port_redirection( r.interface, r.protocol, r.src_port, r.dst_address, r.dst_port )
155
+ @firewall.add_port_redirection( r.interface, r.protocol, r.src_port, r.dst_address, r.dst_port )
220
156
  end
221
157
  end
222
158
 
@@ -224,19 +160,19 @@ class Context
224
160
  @redirections.each do |r|
225
161
  Logger.debug "Removing #{r.protocol} port redirect from port #{r.src_port} to #{r.dst_address}:#{r.dst_port}"
226
162
 
227
- @firewall.del_port_redirection( r.interface, r.protocol, r.src_port, r.dst_address, r.dst_port )
163
+ @firewall.del_port_redirection( r.interface, r.protocol, r.src_port, r.dst_address, r.dst_port )
228
164
  end
229
165
 
230
166
  @redirections = []
231
167
  end
232
168
 
233
169
  def create_proxies
234
- if not @options[:proxy_module].nil?
235
- require @options[:proxy_module]
170
+ if @options.has_proxy_module?
171
+ require @options.proxy_module
236
172
 
237
173
  Proxy::Module.register_modules
238
174
 
239
- raise BetterCap::Error, "#{@options[:proxy_module]} is not a valid bettercap proxy module." unless !Proxy::Module.modules.empty?
175
+ raise BetterCap::Error, "#{@options.proxy_module} is not a valid bettercap proxy module." unless !Proxy::Module.modules.empty?
240
176
  end
241
177
 
242
178
  @proxy_processor = Proc.new do |request,response|
@@ -262,44 +198,42 @@ class Context
262
198
  end
263
199
 
264
200
  # create HTTP proxy
265
- @proxy = Proxy::Proxy.new( @ifconfig[:ip_saddr], @options[:proxy_port], false, @proxy_processor )
266
- @proxy.start
267
-
201
+ @proxies << Proxy::Proxy.new( @ifconfig[:ip_saddr], @options.proxy_port, false, @proxy_processor )
268
202
  # create HTTPS proxy
269
- if @options[:proxy_https]
203
+ if @options.proxy_https
270
204
  # We're not acting as a normal HTTPS proxy, thus we're not
271
205
  # able to handle CONNECT requests, thus we don't know the
272
206
  # hostname the client is going to connect to.
273
207
  # We can only use a self signed certificate.
274
- if @options[:proxy_pem_file].nil?
208
+ if @options.proxy_pem_file.nil?
275
209
  @certificate = Proxy::CertStore.get_selfsigned
276
210
  else
277
- @certificate = Proxy::CertStore.from_file @options[:proxy_pem_file]
211
+ @certificate = Proxy::CertStore.from_file @options.proxy_pem_file
278
212
  end
279
213
 
280
- @https_proxy = Proxy::Proxy.new( @ifconfig[:ip_saddr], @options[:proxy_https_port], true, @proxy_processor )
281
- @https_proxy.start
214
+ @proxies << Proxy::Proxy.new( @ifconfig[:ip_saddr], @options.proxy_https_port, true, @proxy_processor )
215
+ end
216
+
217
+ @proxies.each do |proxy|
218
+ proxy.start
282
219
  end
283
220
  end
284
221
 
285
222
  def finalize
286
223
  stop_discovery_thread
287
224
 
288
- if !@spoofer.nil? and @spoofer.length != 0
225
+ if !@spoofer.nil? and @spoofer.length != 0
289
226
  @spoofer.each do |itr|
290
227
  itr.stop
291
228
  end
292
229
  end
293
230
 
294
- if !@proxy.nil?
295
- @proxy.stop
296
- if !@https_proxy.nil?
297
- @https_proxy.stop
298
- end
231
+ @proxies.each do |proxy|
232
+ proxy.stop
299
233
  end
300
-
234
+
301
235
  disable_port_redirection
302
-
236
+
303
237
  if !@firewall.nil?
304
238
  @firewall.restore
305
239
  end