bettercap 1.1.7 → 1.1.8

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