bettercap 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +42 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +25 -0
  5. data/README.md +1 -1
  6. data/Rakefile +7 -0
  7. data/TODO.md +2 -2
  8. data/bettercap.gemspec +2 -0
  9. data/bin/bettercap +48 -43
  10. data/lib/bettercap/context.rb +125 -20
  11. data/lib/bettercap/factories/firewall_factory.rb +4 -0
  12. data/lib/bettercap/factories/parser_factory.rb +2 -0
  13. data/lib/bettercap/firewalls/linux.rb +16 -10
  14. data/lib/bettercap/firewalls/osx.rb +19 -8
  15. data/lib/bettercap/logger.rb +2 -0
  16. data/lib/bettercap/network.rb +10 -4
  17. data/lib/bettercap/proxy/certstore.rb +68 -0
  18. data/lib/bettercap/proxy/proxy.rb +87 -43
  19. data/lib/bettercap/proxy/request.rb +22 -4
  20. data/lib/bettercap/proxy/response.rb +15 -0
  21. data/lib/bettercap/sniffer/sniffer.rb +22 -24
  22. data/lib/bettercap/spoofers/arp.rb +38 -6
  23. data/lib/bettercap/target.rb +1 -1
  24. data/lib/bettercap/version.rb +1 -1
  25. data/lib/bettercap.rb +1 -0
  26. data/test/factories/firewall_factory_test.rb +54 -0
  27. data/test/factories/parser_factory_test.rb +36 -0
  28. data/test/factories/spoofer_factory_test.rb +15 -0
  29. data/test/firewalls/linux_firewall_test.rb +72 -0
  30. data/test/firewalls/osx_firewall_test.rb +72 -0
  31. data/test/helpers/mock_shell.rb +17 -0
  32. data/test/logger_test.rb +12 -0
  33. data/test/network_test.rb +14 -0
  34. data/test/pcap/ftp.pcap +0 -0
  35. data/test/pcap/http.pcap +0 -0
  36. data/test/pcap/packets.pcap +0 -0
  37. data/test/proxy/response_test.rb +56 -0
  38. data/test/shell_test.rb +15 -0
  39. data/test/sniffer/parsers/base_parser_test.rb +20 -0
  40. data/test/sniffer/parsers/ftp_parser_test.rb +27 -0
  41. data/test/sniffer/parsers/url_parser_test.rb +25 -0
  42. data/test/target_test.rb +24 -0
  43. data/test/test_helper.rb +47 -0
  44. data/test_https_proxy.rb +29 -0
  45. metadata +40 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ec474a048798ccf1e1cdffd8e9cd89451664e34
4
- data.tar.gz: b7a71427a38b282296afe4ea29e4ff17544a2ae8
3
+ metadata.gz: 0302105b4b7c6f181542e22fff7662fa6b4b922b
4
+ data.tar.gz: b46e666f283922dbe0bdb09fd6f2883dee7d89b2
5
5
  SHA512:
6
- metadata.gz: 1181286df3a437f4687ad6472dec73979358f517946775f7b5b058831bdd8209505ae8efe77e2034698d7cc0952daeb4b80e072f28698e6fee2b3e46304c6105
7
- data.tar.gz: b180321825414edddc52aa36d3eee9a3c67c320aa55ed1911a1fe5c0a9758c241adc914bfab558dc1fe15c32d65574ec1b62e3dd2e993661a20b1744c11708f1
6
+ metadata.gz: ef42d62d1d051931e7b2ea84d56e09498e630628a1293bd3be5fc7a23d5457b57a2470896431171638bd59981ec0736a85847b359f592ca991ba378301831a34
7
+ data.tar.gz: ca6291a117033ab2139a616a7e8734fbf0bc5b05b57e25299b222bfceed8bcbc9785b148a988c4c059cfd4079d79b7f24d1cdfd76a439ce3c3b35f42d0c4a6d8
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,42 @@
1
+ # How To Contribute
2
+
3
+ As any other open source projects, there're many ways you can contribute to bettercap depending on your skills as a developer or will to help as a user, but first
4
+ of all let me thank you for your help! <3
5
+
6
+ ### Submitting Issues
7
+
8
+ If you find bugs or inconsistencies while using bettercap, you can create an **Issue** using the [GitHub Issue tracker](https://github.com/evilsocket/bettercap/issues), but before doing that please make sure that:
9
+
10
+ * You are using a relatively new Ruby version ( >= 1.9 ) : `ruby -v`.
11
+ * Your GEM environment is configured properly and updated : `sudo gem update`.
12
+ * You are using the latest version of bettercap : `bettercap --check-updates`.
13
+ * The bug you're reporting is actually related to bettercap and not to one of the other GEMs.
14
+
15
+ Once you've gone through this list, open an issue and please give us as much as informations as possible in order for us to fix the bug as soon as possible:
16
+
17
+ * Your OS version.
18
+ * Ruby version you're using.
19
+ * Full output of the error ( exception backtrace, error message, etc ).
20
+ * Your network configuration: `ifconfig -a`
21
+
22
+ Also, you should attach to the issue a debug log that you can generate with:
23
+
24
+ sudo bettercap [arguments you are using for testing] --debug --log=debug.log
25
+
26
+ Wait for the error to happen then close bettercap and paste the **debug.log** file inside the issue.
27
+
28
+ ### Pull Requests
29
+
30
+ If you know how to code in Ruby and have ideas to improve bettercap, you're very welcome to send us pull requests, we'll be happy to merge them whenever they comply to the following rules:
31
+
32
+ * You have at least manually tested your code, ideally you've created actual tests for it.
33
+ * Respect our coding standard, 2 spaces indentation and modular code.
34
+ * There're no conflicts with the current dev branch.
35
+ * Your commit messages are enough explanatory to us.
36
+
37
+ There're plenty of things you can to do improve the software:
38
+
39
+ * Implement a new proxy module and push it to the [dedicated repository](https://github.com/evilsocket/bettercap-proxy-modules).
40
+ * Implement a new [Spoofer module](https://github.com/evilsocket/bettercap/blob/master/lib/bettercap/spoofers/arp.rb).
41
+ * Implement a new [Sniffer credentials parser](https://github.com/evilsocket/bettercap/blob/master/lib/bettercap/sniffer/parsers/post.rb).
42
+ * Fix, extend or improve the core.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,25 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bettercap (1.1.3)
5
+ colorize (~> 0.7.5)
6
+ packetfu (~> 1.1.10)
7
+ pcaprub (~> 0.12.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ colorize (0.7.7)
13
+ minitest (5.7.0)
14
+ packetfu (1.1.10)
15
+ pcaprub (0.12.0)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ bettercap!
22
+ minitest
23
+
24
+ BUNDLED WITH
25
+ 1.10.3
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![logo](http://www.bettercap.org/images/logo_dark.png)
1
+ ![logo](http://www.bettercap.org/assets/img/navbar-logo.png)
2
2
 
3
3
  Copyleft of Simone '[evilsocket](https://twitter.com/evilsocket)' Margaritelli*.
4
4
 
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ t.libs << 'lib/bettercap'
6
+ t.pattern = "test/**/*_test.rb"
7
+ end
data/TODO.md CHANGED
@@ -7,9 +7,8 @@ This is a list of TODOs I use to keep track of tasks and upcoming features.
7
7
  - [x] BPF filters.
8
8
  - [x] BeEF proxy module ( [BeefBOX](https://github.com/evilsocket/bettercap-proxy-modules/blob/master/beefbox.rb) ).
9
9
  - [x] Use raw file arp parsing instead of "arp -a" to improve speed. ( Solved with arp -a -n )
10
+ - [x] sslmitm
10
11
  - [ ] *BSD Support.
11
- - [ ] sslstrip
12
- - [ ] sslmitm
13
12
  - [ ] HTTP/2 Support.
14
13
  - [ ] Active packet filtering/injection/etc.
15
14
 
@@ -21,3 +20,4 @@ This is a list of TODOs I use to keep track of tasks and upcoming features.
21
20
  - [ ] Windows Support? ( OMG PLZ NO! )
22
21
  - [ ] Output/actions as json for UI integration?
23
22
  - [ ] BeefBox / BeefDRONE with Raspberry PI?
23
+ - [ ] sslstrip ( not really sure, currently is quite useless )
data/bettercap.gemspec CHANGED
@@ -15,6 +15,8 @@ Gem::Specification.new do |gem|
15
15
  gem.add_dependency( 'packetfu', '~> 1.1.10' )
16
16
  gem.add_dependency( 'pcaprub', '~> 0.12.0' )
17
17
 
18
+ gem.add_development_dependency( 'minitest' )
19
+
18
20
  gem.files = `git ls-files`.split("\n")
19
21
  gem.require_paths = ["lib"]
20
22
 
data/bin/bettercap CHANGED
@@ -32,7 +32,7 @@ begin
32
32
  ctx.options[:spoofer] = v
33
33
  end
34
34
 
35
- opts.on( '-T', '--target ADDRESS', 'Target IP address, if not specified the whole subnet will be targeted.' ) do |v|
35
+ opts.on( '-T', '--target ADDRESS1,ADDRESS2', 'Target IP addresses, if not specified the whole subnet will be targeted.' ) do |v|
36
36
  ctx.options[:target] = v
37
37
  end
38
38
 
@@ -72,19 +72,40 @@ begin
72
72
  ctx.options[:arpcache] = true
73
73
  end
74
74
 
75
- opts.on( '--no-spoofing', 'Disable spoofing, alias for --spoofer NONE.' ) do |v|
75
+ opts.on( '--no-spoofing', 'Disable spoofing, alias for --spoofer NONE.' ) do
76
76
  ctx.options[:spoofer] = 'NONE'
77
77
  end
78
78
 
79
+ opts.on( '--half-duplex', 'Enable half-duplex MITM, this will make bettercap work in those cases when the router is not vulnerable.' ) do
80
+ ctx.options[:half_duplex] = true
81
+ end
82
+
79
83
  opts.on( '--proxy', 'Enable HTTP proxy and redirects all HTTP requests to it, default to false.' ) do
80
84
  ctx.options[:proxy] = true
81
85
  end
82
86
 
87
+ opts.on( '--proxy-https', 'Enable HTTPS proxy and redirects all HTTPS requests to it, default to false.' ) do
88
+ ctx.options[:proxy] = true
89
+ ctx.options[:proxy_https] = true
90
+ end
91
+
83
92
  opts.on( '--proxy-port PORT', 'Set HTTP proxy port, default to ' + ctx.options[:proxy_port].to_s + ' .' ) do |v|
84
93
  ctx.options[:proxy] = true
85
94
  ctx.options[:proxy_port] = v.to_i
86
95
  end
87
96
 
97
+ opts.on( '--proxy-https-port PORT', 'Set HTTPS proxy port, default to ' + ctx.options[:proxy_https_port].to_s + ' .' ) do |v|
98
+ ctx.options[:proxy] = true
99
+ ctx.options[:proxy_https] = true
100
+ ctx.options[:proxy_https_port] = v.to_i
101
+ end
102
+
103
+ opts.on( '--proxy-pem FILE', 'Use a custom PEM certificate file for the HTTPS proxy.' ) do |v|
104
+ ctx.options[:proxy] = true
105
+ ctx.options[:proxy_https] = true
106
+ ctx.options[:proxy_pem_file] = File.expand_path v
107
+ end
108
+
88
109
  opts.on( '--proxy-module MODULE', 'Ruby proxy module to load.' ) do |v|
89
110
  ctx.options[:proxy] = true
90
111
  ctx.options[:proxy_module] = File.expand_path v
@@ -132,17 +153,11 @@ begin
132
153
  end.parse!
133
154
 
134
155
  if ctx.options[:check_updates]
135
- begin
136
- ver = ctx.check_updates
137
- if !ver.nil?
138
- Logger.warn "New version #{ver} available!"
139
- else
140
- Logger.info 'You are running the latest version.'
141
- end
142
- rescue Exception => e
143
- Logger.error "Could not check for updates: #{e.message}"
144
- end
156
+ error_policy = lambda { |e|
157
+ Logger.error("Could not check for udpates: #{e.message}")
158
+ }
145
159
 
160
+ ctx.check_updates(error_policy)
146
161
  exit
147
162
  end
148
163
 
@@ -160,48 +175,36 @@ begin
160
175
 
161
176
  ctx.start_discovery_thread
162
177
  else
163
- raise BetterCap::Error, "Invalid target '#{ctx.options[:target]}'" unless Network.is_ip? ctx.options[:target]
178
+ targets = ctx.options[:target].split(",")
179
+ valid_targets = targets.select { |target| Network.is_ip?(target) }
164
180
 
165
- ctx.targets = [ Target.new( ctx.options[:target], nil ) ]
166
- end
181
+ raise BetterCap::Error, "Invalid target" if valid_targets.empty?
167
182
 
168
- ctx.spoofer = SpooferFactory.get_by_name( ctx.options[:spoofer] )
183
+ invalid_targets = targets - valid_targets
184
+ invalid_targets.each do |target|
185
+ Logger.warn "Invalid target #{target}"
186
+ end
169
187
 
170
- Logger.info " Local : #{ctx.ifconfig[:ip_saddr]} ( #{ctx.ifconfig[:eth_saddr]} )"
188
+ ctx.targets = valid_targets.map { |target| Target.new(target) }
189
+ end
171
190
 
172
- Logger.debug "Module: #{ctx.options[:spoofer]}"
173
191
 
174
- ctx.spoofer.start
192
+ ctx.spoofer=Array.new
193
+ spoofer_modules_names=ctx.options[:spoofer].split(",")
194
+ spoofer_modules_names.each do |module_name|
195
+ Logger.info "Loading module : #{module_name}"
196
+ ctx.spoofer << SpooferFactory.get_by_name( module_name )
197
+ ctx.spoofer.last.start
198
+ end
175
199
 
176
200
  if ctx.options[:proxy]
177
201
  if ctx.options[:sniffer] and ( ctx.options[:parsers].include?'*' or ctx.options[:parsers].include?'URL' )
178
202
  Logger.warn "WARNING: Both HTTP transparent proxy and URL parser are enabled, you're gonna see duplicated logs."
179
203
  end
180
204
 
181
- ctx.firewall.add_port_redirection( ctx.options[:iface], 'TCP', 80, ctx.ifconfig[:ip_saddr], ctx.options[:proxy_port] )
182
-
183
- if not ctx.options[:proxy_module].nil?
184
- require ctx.options[:proxy_module]
185
-
186
- Proxy::Module.register_modules
187
-
188
- raise BetterCap::Error, "#{ctx.options[:proxy_module]} is not a valid bettercap proxy module." unless !Proxy::Module.modules.empty?
189
- end
190
-
191
- ctx.proxy = Proxy::Proxy.new( ctx.ifconfig[:ip_saddr], ctx.options[:proxy_port] ) do |request,response|
192
- if Proxy::Module.modules.empty?
193
- Logger.warn 'WARNING: No proxy module loaded, skipping request.'
194
- else
195
- # loop each loaded module and execute if enabled
196
- Proxy::Module.modules.each do |mod|
197
- if mod.enabled?
198
- mod.on_request request, response
199
- end
200
- end
201
- end
202
- end
205
+ ctx.enable_port_redirection
203
206
 
204
- ctx.proxy.start
207
+ ctx.create_proxies
205
208
  end
206
209
 
207
210
  if ctx.options[:httpd]
@@ -212,7 +215,9 @@ begin
212
215
  if ctx.options[:sniffer]
213
216
  Sniffer.start ctx
214
217
  else
215
- Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this will cause the MITM to run but no data to be collected.'
218
+ if ctx.options[:spoofer] != 'NONE' and ctx.options[:spoofer] != 'none'
219
+ Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this will cause the MITM to run but no data to be collected.'
220
+ end
216
221
 
217
222
  loop do
218
223
  sleep 1
@@ -18,7 +18,8 @@ require 'json'
18
18
 
19
19
  class Context
20
20
  attr_accessor :options, :ifconfig, :network, :firewall, :gateway,
21
- :targets, :spoofer, :proxy, :httpd
21
+ :targets, :spoofer, :proxy, :https_proxy, :httpd,
22
+ :certificate
22
23
 
23
24
  @@instance = nil
24
25
 
@@ -37,6 +38,7 @@ class Context
37
38
  @options = {
38
39
  iface: iface,
39
40
  spoofer: 'ARP',
41
+ half_duplex: false,
40
42
  target: nil,
41
43
  logfile: nil,
42
44
  debug: false,
@@ -49,7 +51,10 @@ class Context
49
51
  local: false,
50
52
 
51
53
  proxy: false,
54
+ proxy_https: false,
52
55
  proxy_port: 8080,
56
+ proxy_https_port: 8083,
57
+ proxy_pem_file: nil,
53
58
  proxy_module: nil,
54
59
 
55
60
  httpd: false,
@@ -59,30 +64,49 @@ class Context
59
64
  check_updates: false
60
65
  }
61
66
 
62
- @ifconfig = nil
63
- @network = nil
64
- @firewall = nil
65
- @gateway = nil
66
- @targets = []
67
- @proxy = nil
68
- @spoofer = nil
69
- @httpd = nil
67
+ @ifconfig = nil
68
+ @network = nil
69
+ @firewall = nil
70
+ @gateway = nil
71
+ @targets = []
72
+ @proxy_processor = nil
73
+ @proxy = nil
74
+ @https_proxy = nil
75
+ @spoofer = nil
76
+ @httpd = nil
77
+ @certificate = nil
70
78
 
71
79
  @discovery_running = false
72
80
  @discovery_thread = nil
73
81
  end
74
82
 
75
- def check_updates
83
+ def check_updates(error_policy = ->{ raise })
84
+ ver = get_latest_version
85
+
86
+ case ver
87
+ when BetterCap::VERSION
88
+ Logger.info 'You are running the latest version.'
89
+ else
90
+ Logger.warn "New version '#{ver}' available!"
91
+ end
92
+ rescue Exception => e
93
+ error_policy.call(e)
94
+ end
95
+
96
+ def get_latest_version
76
97
  Logger.info 'Checking for updates ...'
77
98
 
78
- api = URI('https://api.github.com/repos/evilsocket/bettercap/releases/latest')
79
- body = Net::HTTP.get(api)
80
- json = JSON.parse(body)
99
+ api = URI('https://rubygems.org/api/v1/versions/bettercap/latest.json')
100
+ response = Net::HTTP.get_response(api)
81
101
 
82
- if json['tag_name'] != BetterCap::VERSION and json['tag_name'] != "v#{BetterCap::VERSION}"
83
- return json['tag_name']
102
+ case response
103
+ when Net::HTTPSuccess
104
+ json = JSON.parse(response.body)
105
+ else
106
+ raise response.message
84
107
  end
85
- nil
108
+
109
+ return json['version']
86
110
  end
87
111
 
88
112
  def update_network
@@ -110,7 +134,12 @@ class Context
110
134
  Logger.info 'Searching for alive targets ...'
111
135
  else
112
136
  # make sure we don't stress the logging system
113
- sleep 10
137
+ 10.times do
138
+ sleep 1
139
+ if !@discovery_running
140
+ break
141
+ end
142
+ end
114
143
  end
115
144
 
116
145
  @targets = Network.get_alive_targets self
@@ -139,17 +168,93 @@ class Context
139
168
  end
140
169
  end
141
170
 
171
+ def enable_port_redirection
172
+ Logger.info "Redirecting traffic from port 80 to #{@ifconfig[:ip_saddr]}:#{@options[:proxy_port]}"
173
+
174
+ @firewall.add_port_redirection( @options[:iface], 'TCP', 80, @ifconfig[:ip_saddr], @options[:proxy_port] )
175
+ if @options[:proxy_https]
176
+ Logger.info "Redirecting traffic from port 443 to #{@ifconfig[:ip_saddr]}:#{@options[:proxy_https_port]}"
177
+
178
+ @firewall.add_port_redirection( @options[:iface], 'TCP', 443, @ifconfig[:ip_saddr], @options[:proxy_https_port] )
179
+ end
180
+ end
181
+
182
+ def disable_port_redirection
183
+ @firewall.del_port_redirection( @options[:iface], 'TCP', 80, @ifconfig[:ip_saddr], @options[:proxy_port] )
184
+ if @options[:proxy_https]
185
+ @firewall.del_port_redirection( @options[:iface], 'TCP', 443, @ifconfig[:ip_saddr], @options[:proxy_https_port] )
186
+ end
187
+ end
188
+
189
+ def create_proxies
190
+ if not @options[:proxy_module].nil?
191
+ require @options[:proxy_module]
192
+
193
+ Proxy::Module.register_modules
194
+
195
+ raise BetterCap::Error, "#{@options[:proxy_module]} is not a valid bettercap proxy module." unless !Proxy::Module.modules.empty?
196
+ end
197
+
198
+ @proxy_processor = Proc.new do |request,response|
199
+ if Proxy::Module.modules.empty?
200
+ Logger.warn 'WARNING: No proxy module loaded, skipping request.'
201
+ else
202
+ # loop each loaded module and execute if enabled
203
+ Proxy::Module.modules.each do |mod|
204
+ if mod.enabled?
205
+ # we need to save the original response in case something
206
+ # in the module will go wrong
207
+ original = response
208
+
209
+ begin
210
+ mod.on_request request, response
211
+ rescue Exception => e
212
+ Logger.warn "Error with proxy module: #{e.message}"
213
+ response = original
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ # create HTTP proxy
221
+ @proxy = Proxy::Proxy.new( @ifconfig[:ip_saddr], @options[:proxy_port], false, @proxy_processor )
222
+ @proxy.start
223
+
224
+ # create HTTPS proxy
225
+ if @options[:proxy_https]
226
+ # We're not acting as a normal HTTPS proxy, thus we're not
227
+ # able to handle CONNECT requests, thus we don't know the
228
+ # hostname the client is going to connect to.
229
+ # We can only use a self signed certificate.
230
+ if @options[:proxy_pem_file].nil?
231
+ @certificate = Proxy::CertStore.get_selfsigned
232
+ else
233
+ @certificate = Proxy::CertStore.from_file @options[:proxy_pem_file]
234
+ end
235
+
236
+ @https_proxy = Proxy::Proxy.new( @ifconfig[:ip_saddr], @options[:proxy_https_port], true, @proxy_processor )
237
+ @https_proxy.start
238
+ end
239
+ end
240
+
142
241
  def finalize
143
242
  stop_discovery_thread
144
243
 
145
244
  # Consider !!@spoofer
146
- if !@spoofer.nil?
147
- @spoofer.stop
245
+
246
+ if !@spoofer.nil? and @spoofer.length != 0
247
+ @spoofer.each do |itr|
248
+ itr.stop
249
+ end
148
250
  end
149
251
 
150
252
  if !@proxy.nil?
151
253
  @proxy.stop
152
- @firewall.del_port_redirection( @options[:iface], 'TCP', 80, @ifconfig[:ip_saddr], @options[:proxy_port] )
254
+ if !@https_proxy.nil?
255
+ @https_proxy.stop
256
+ end
257
+ disable_port_redirection
153
258
  end
154
259
 
155
260
  if !@firewall.nil?
@@ -29,4 +29,8 @@ class FirewallFactory
29
29
 
30
30
  @@instance
31
31
  end
32
+
33
+ def FirewallFactory.clear_firewall
34
+ @@instance = nil
35
+ end
32
36
  end
@@ -28,6 +28,8 @@ class ParserFactory
28
28
  end
29
29
 
30
30
  def from_cmdline(v)
31
+ raise BetterCap::Error, "No parser names provided" if v.nil?
32
+
31
33
  avail = available
32
34
  list = v.split(',').collect(&:strip).collect(&:upcase).reject{ |c| c.empty? }
33
35
  list.each do |parser|
@@ -14,34 +14,40 @@ require 'bettercap/shell'
14
14
 
15
15
  class LinuxFirewall < IFirewall
16
16
  def enable_forwarding(enabled)
17
- Shell.execute("echo #{enabled ? 1 : 0} > /proc/sys/net/ipv4/ip_forward")
17
+ shell.execute("echo #{enabled ? 1 : 0} > /proc/sys/net/ipv4/ip_forward")
18
18
  end
19
19
 
20
20
  def forwarding_enabled?
21
- Shell.execute('cat /proc/sys/net/ipv4/ip_forward').strip == '1'
21
+ shell.execute('cat /proc/sys/net/ipv4/ip_forward').strip == '1'
22
22
  end
23
23
 
24
24
  def enable_icmp_bcast(enabled)
25
- Shell.execute("echo #{enabled ? 0 : 1} > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts")
25
+ shell.execute("echo #{enabled ? 0 : 1} > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts")
26
26
  end
27
27
 
28
28
  def add_port_redirection( iface, proto, from, addr, to )
29
29
  # clear nat
30
- Shell.execute('iptables -t nat -F')
30
+ shell.execute('iptables -t nat -F')
31
31
  # clear
32
- Shell.execute('iptables -F')
32
+ shell.execute('iptables -F')
33
33
  # post route
34
- Shell.execute('iptables -t nat -I POSTROUTING -s 0/0 -j MASQUERADE')
34
+ shell.execute('iptables -t nat -I POSTROUTING -s 0/0 -j MASQUERADE')
35
35
  # accept all
36
- Shell.execute('iptables -P FORWARD ACCEPT')
36
+ shell.execute('iptables -P FORWARD ACCEPT')
37
37
  # add redirection
38
- Shell.execute("iptables -t nat -A PREROUTING -i #{iface} -p #{proto} --dport #{from} -j REDIRECT --to #{to}")
38
+ shell.execute("iptables -t nat -A PREROUTING -i #{iface} -p #{proto} --dport #{from} -j REDIRECT --to #{to}")
39
39
  end
40
40
 
41
41
  def del_port_redirection( iface, proto, from, addr, to )
42
42
  # remove post route
43
- Shell.execute('iptables -t nat -D POSTROUTING -s 0/0 -j MASQUERADE')
43
+ shell.execute('iptables -t nat -D POSTROUTING -s 0/0 -j MASQUERADE')
44
44
  # remove redirection
45
- Shell.execute("iptables -t nat -D PREROUTING -i #{iface} -p #{proto} --dport #{from} -j REDIRECT --to #{to}")
45
+ shell.execute("iptables -t nat -D PREROUTING -i #{iface} -p #{proto} --dport #{from} -j REDIRECT --to #{to}")
46
+ end
47
+
48
+ private
49
+
50
+ def shell
51
+ Shell
46
52
  end
47
53
  end
@@ -14,20 +14,20 @@ require 'bettercap/shell'
14
14
 
15
15
  class OSXFirewall < IFirewall
16
16
  def enable_forwarding(enabled)
17
- Shell.execute("sysctl -w net.inet.ip.forwarding=#{enabled ? 1 : 0}")
17
+ shell.execute("sysctl -w net.inet.ip.forwarding=#{enabled ? 1 : 0}")
18
18
  end
19
19
 
20
20
  def enable_icmp_bcast(enabled)
21
- Shell.execute("sysctl -w net.inet.icmp.bmcastecho=#{enabled ? 1 : 0}")
21
+ shell.execute("sysctl -w net.inet.icmp.bmcastecho=#{enabled ? 1 : 0}")
22
22
  end
23
23
 
24
24
  def forwarding_enabled?
25
- Shell.execute('sysctl net.inet.ip.forwarding').strip.split(' ')[1] == '1'
25
+ shell.execute('sysctl net.inet.ip.forwarding').strip.split(' ')[1] == '1'
26
26
  end
27
27
 
28
28
  def enable(enabled)
29
29
  begin
30
- Shell.execute("pfctl -#{enabled ? ?e : ?d} >/dev/null 2>&1")
30
+ shell.execute("pfctl -#{enabled ? 'e' : 'd'} >/dev/null 2>&1")
31
31
  rescue; end
32
32
  end
33
33
 
@@ -36,11 +36,11 @@ class OSXFirewall < IFirewall
36
36
  config_file = "/tmp/bettercap_pf_#{Process.pid}.conf"
37
37
 
38
38
  File.open( config_file, 'a+t' ) do |f|
39
- f.write "rdr on #{iface} inet proto #{proto} to any port #{from} -> #{addr} port #{to}\n"
39
+ f.write "rdr pass on #{iface} proto #{proto} from any to any port #{from} -> #{addr} port #{to}\n"
40
40
  end
41
41
 
42
42
  # load the rule
43
- Shell.execute("pfctl -f #{config_file} >/dev/null 2>&1")
43
+ shell.execute("pfctl -f #{config_file} >/dev/null 2>&1")
44
44
  # enable pf
45
45
  enable true
46
46
  end
@@ -51,7 +51,18 @@ class OSXFirewall < IFirewall
51
51
 
52
52
  # disable pf
53
53
  enable false
54
- # remove the pf config file
55
- File.delete( "/tmp/bettercap_pf_#{Process.pid}.conf" )
54
+
55
+ begin
56
+ # remove the pf config file
57
+ File.delete( "/tmp/bettercap_pf_#{Process.pid}.conf" )
58
+ rescue
59
+ end
60
+
61
+ end
62
+
63
+ private
64
+
65
+ def shell
66
+ Shell
56
67
  end
57
68
  end
@@ -37,6 +37,7 @@ module Logger
37
37
  # make sure that logging is thread safe
38
38
  @@semaphore.synchronize {
39
39
  puts message
40
+
40
41
  if !@logfile.nil?
41
42
  f = File.open( @logfile, 'a+t' )
42
43
  f.puts( message.gsub( /\e\[(\d+)(;\d+)*m/, '') + "\n")
@@ -46,6 +47,7 @@ module Logger
46
47
  end
47
48
 
48
49
  private
50
+
49
51
  def formatted_message(message, message_type)
50
52
  "[#{message_type}] #{message}"
51
53
  end
@@ -24,7 +24,7 @@ require 'bettercap/discovery/arp'
24
24
  class Network
25
25
  class << self
26
26
  def is_ip?(ip)
27
- if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ ip
27
+ if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ ip.to_s
28
28
  return $~.captures.all? {|i| i.to_i < 256}
29
29
  end
30
30
  false
@@ -39,12 +39,18 @@ class Network
39
39
  gw = nil
40
40
  out.each do |line|
41
41
  if line.include?( Context.get.options[:iface] )
42
- gw = line.split[1]
43
- break if is_ip?(gw)
42
+ tmp = line.split[1]
43
+ if is_ip?(tmp)
44
+ gw = tmp
45
+ break
46
+ end
44
47
  end
45
48
  end
46
49
 
47
- raise BetterCap::Error, 'Could not detect gateway address' unless gw.nil? or is_ip?(gw)
50
+ raise BetterCap::Error, "Could not detect the gateway address for interface #{Context.get.options[:iface]}, "\
51
+ 'make sure you\'ve specified the correct network interface to use and to have the '\
52
+ 'correct network configuration, this could also happen if bettercap '\
53
+ 'is launched from a virtual environment.' unless !gw.nil? and is_ip?(gw)
48
54
  gw
49
55
  end
50
56