bettercap 1.4.2 → 1.4.3

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: b2645aedfa3e74db2c01d8856b6c0149302317d5
4
- data.tar.gz: 3e891382aec5781ff109d8e2e7705c48bc6cb3a7
3
+ metadata.gz: 004df8ac9f02a6075dffa69038fb4b8fd02b8e8b
4
+ data.tar.gz: 720d7f1c5bcc08ad97eb917291d9a8c8463cc892
5
5
  SHA512:
6
- metadata.gz: a704b2a1156afa0a087a48d64041d3197f86664f778172acdf299fc34da6c6b602091961d86e484ca576f5c06408f3a91ec9610d324800285eb85747a1235d21
7
- data.tar.gz: 33f2ed1ea9e4e643d196269f7015f4d47be69e175859355ca797bba1597d2bd8763cbe6bb011f6687a3725243d1f448a1e34bcc2318a42da410df8f4db4693bf
6
+ metadata.gz: c9a2e1722001bef5dbe99bc80e7c87b1ebfb3f2d93e85de449d272525332f04e098ad92d530b1b2e263da6e32a095c5044bb51bf543b6465e494da5b7dd249cd
7
+ data.tar.gz: eb475421115056754c756550a5379970532fc2b018a321a50bd1a3fdec16929f7cef71393ea37c722df4574ca68eec4f1a62cfc77a369b13ff6395c6bf7f9891
data/lib/bettercap.rb CHANGED
@@ -28,9 +28,11 @@ Object.send :remove_const, :Config rescue nil
28
28
  Config = RbConfig
29
29
 
30
30
  def bettercap_autoload( path = '' )
31
- dir = File.dirname(__FILE__) + "/bettercap/#{path}"
32
- deps = []
33
- files = []
31
+ dir = File.dirname(__FILE__) + "/bettercap/#{path}"
32
+ deps = []
33
+ files = []
34
+ monkey = []
35
+
34
36
  Dir[dir+"**/*.rb"].each do |filename|
35
37
  filename = filename.gsub( dir, '' ).gsub('.rb', '')
36
38
  filename = "bettercap/#{path}#{filename}"
@@ -38,13 +40,15 @@ def bettercap_autoload( path = '' )
38
40
  unless filename =~ /.+\/inject[a-z]+$/i
39
41
  if filename.end_with?('/base')
40
42
  deps << filename
43
+ elsif filename.include?('monkey')
44
+ monkey << filename
41
45
  else
42
46
  files << filename
43
47
  end
44
48
  end
45
49
  end
46
50
 
47
- ( deps + files ).each do |file|
51
+ ( deps + files + monkey ).each do |file|
48
52
  require file
49
53
  end
50
54
  end
@@ -0,0 +1,28 @@
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
+ # Monkey patching fix for https://github.com/evilsocket/bettercap/issues/154
15
+ module Celluloid
16
+ module IO
17
+ class UDPSocket
18
+ def initialize(address_family = ::Socket::AF_INET)
19
+ begin
20
+ @socket = ::UDPSocket.new(address_family)
21
+ rescue Errno::EMFILE
22
+ sleep 0.5
23
+ retry
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -38,6 +38,7 @@ class Target
38
38
  NBNS_REQUEST = "\x82\x28\x0\x0\x0\x1\x0\x0\x0\x0\x0\x0\x20\x43\x4B\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x0\x0\x21\x0\x1"
39
39
 
40
40
  @@prefixes = nil
41
+ @@lock = Mutex.new
41
42
 
42
43
  # Create a +Target+ object given its +ip+ and (optional) +mac+ address.
43
44
  # The +ip+ argument could also be a MAC address itself, in this case the
@@ -143,17 +144,19 @@ private
143
144
 
144
145
  # Lookup the given +mac+ address in order to find its vendor.
145
146
  def self.lookup_vendor( mac )
146
- if @@prefixes == nil
147
- Logger.debug 'Preloading hardware vendor prefixes ...'
148
-
149
- @@prefixes = {}
150
- filename = File.dirname(__FILE__) + '/hw-prefixes'
151
- File.open( filename ).each do |line|
152
- if line =~ /^([A-F0-9]{6})\s(.+)$/
153
- @@prefixes[$1] = $2
147
+ @@lock.synchronize {
148
+ if @@prefixes.nil?
149
+ Logger.debug 'Preloading hardware vendor prefixes ...'
150
+
151
+ @@prefixes = {}
152
+ filename = File.dirname(__FILE__) + '/hw-prefixes'
153
+ File.open( filename ).each do |line|
154
+ if line =~ /^([A-F0-9]{6})\s(.+)$/
155
+ @@prefixes[$1] = $2
156
+ end
154
157
  end
155
158
  end
156
- end
159
+ }
157
160
 
158
161
  @@prefixes[ mac.split(':')[0,3].join('').upcase ]
159
162
  end
@@ -79,6 +79,8 @@ class Options
79
79
  attr_accessor :custom_https_proxy
80
80
  # Custom HTTPS transparent proxy port.
81
81
  attr_accessor :custom_https_proxy_port
82
+ # Custom list of redirections.
83
+ attr_accessor :custom_redirections
82
84
  # If true, BetterCap::Network::Servers::HTTPD will be enabled.
83
85
  attr_accessor :httpd
84
86
  # The port to bind HTTP server to.
@@ -145,6 +147,8 @@ class Options
145
147
  @custom_https_proxy = nil
146
148
  @custom_https_proxy_port = 8083
147
149
 
150
+ @custom_redirections = []
151
+
148
152
  @sslstrip = true
149
153
 
150
154
  @httpd = false
@@ -312,6 +316,10 @@ class Options
312
316
  ctx.options.custom_https_proxy_port = v.to_i
313
317
  end
314
318
 
319
+ opts.on( '--custom-redirection RULE', 'Apply a custom port redirection, the format of the rule is "PROTOCOL ORIGINAL_PORT NEW_PORT". For instance "TCP 21 2100" will redirect all TCP traffic going to port 21, to port 2100.' ) do |v|
320
+ ctx.options.parse_redirection!( v )
321
+ end
322
+
315
323
  opts.on( '--httpd', 'Enable HTTP server, default to false.' ) do
316
324
  ctx.options.httpd = true
317
325
  end
@@ -448,6 +456,19 @@ class Options
448
456
  end
449
457
  end
450
458
 
459
+ # Parse a custom redirection rule.
460
+ def parse_redirection!(rule)
461
+ if rule =~ /^((TCP)|(UDP))\s+(\d+)\s+(\d+)$/i
462
+ @custom_redirections << {
463
+ :proto => $1.upcase,
464
+ :from => $4.to_i,
465
+ :to => $5.to_i
466
+ }
467
+ else
468
+ raise BetterCap::Error, 'Invalid custom redirection rule specified.'
469
+ end
470
+ end
471
+
451
472
  # Parse a comma separated list of ports and return an array containing only
452
473
  # valid ports, raise BetterCap::Error if that array is empty.
453
474
  def parse_ports(value)
@@ -511,7 +532,7 @@ class Options
511
532
  def get_redirections ifconfig
512
533
  redirections = []
513
534
 
514
- if @dnsd or @proxy
535
+ if @dnsd or ( @proxy and @sslstrip )
515
536
  redirections << redir( ifconfig[:ip_saddr], 53, @dnsd_port )
516
537
  redirections << redir( ifconfig[:ip_saddr], 53, @dnsd_port, 'UDP' )
517
538
  end
@@ -540,6 +561,10 @@ class Options
540
561
  end
541
562
  end
542
563
 
564
+ @custom_redirections.each do |r|
565
+ redirections << redir( ifconfig[:ip_saddr], r[:from], r[:to], r[:proto] )
566
+ end
567
+
543
568
  redirections
544
569
  end
545
570
 
@@ -555,7 +580,7 @@ class Options
555
580
  'https-proxy' => ( proxy_https ? on : off ),
556
581
  'sslstrip' => ( ( proxy and sslstrip ) ? on : off ),
557
582
  'http-server' => ( httpd ? on : off ),
558
- 'dns-server' => ( ( sslstrip or dnsd ) ? on : off )
583
+ 'dns-server' => ( ( ( proxy and sslstrip ) or dnsd ) ? on : off )
559
584
  }
560
585
 
561
586
  msg = "Starting [ "
@@ -22,18 +22,19 @@ class Proxy
22
22
  # use the specified +processor+ routine for each request.
23
23
  # If +is_https+ is true a HTTPS proxy will be created, otherwise a HTTP one.
24
24
  def initialize( address, port, is_https, processor )
25
- @socket = nil
26
- @address = address
27
- @port = port
28
- @is_https = is_https
29
- @type = is_https ? 'HTTPS' : 'HTTP'
30
- @sslserver = nil
31
- @sslcontext = nil
32
- @server = nil
33
- @main_thread = nil
34
- @running = false
35
- @streamer = Streamer.new processor
36
- @local_ips = []
25
+ @socket = nil
26
+ @address = address
27
+ @port = port
28
+ @is_https = is_https
29
+ @type = is_https ? 'HTTPS' : 'HTTP'
30
+ @upstream_port = is_https ? 443 : 80
31
+ @sslserver = nil
32
+ @sslcontext = nil
33
+ @server = nil
34
+ @main_thread = nil
35
+ @running = false
36
+ @streamer = Streamer.new processor
37
+ @local_ips = []
37
38
 
38
39
  begin
39
40
  @local_ips = Socket.ip_address_list.collect { |x| x.ip_address }
@@ -49,7 +50,7 @@ class Proxy
49
50
  begin
50
51
  client_worker client
51
52
  rescue Exception => e
52
- Logger.warn "Client worker errort: #{e.message}"
53
+ Logger.warn "Client worker error: #{e.message}"
53
54
  Logger.exception e
54
55
  end
55
56
  end
@@ -125,7 +126,7 @@ class Proxy
125
126
 
126
127
  # Handle a new +client+.
127
128
  def client_worker( client )
128
- request = Request.new @is_https ? 443 : 80
129
+ request = Request.new @upstream_port
129
130
 
130
131
  begin
131
132
  Logger.debug 'Reading request ...'
@@ -15,6 +15,12 @@ module BetterCap
15
15
  module Proxy
16
16
  # HTTP response parser.
17
17
  class Response
18
+ # HTTP protocol version
19
+ attr_accessor :version
20
+ # Response status code.
21
+ attr_accessor :code
22
+ # Response status message
23
+ attr_accessor :status
18
24
  # Response content type.
19
25
  attr_reader :content_type
20
26
  # Response charset, default to UTF-8.
@@ -25,10 +31,6 @@ class Response
25
31
  attr_reader :chunked
26
32
  # A list of response headers.
27
33
  attr_accessor :headers
28
- # Response status code.
29
- attr_accessor :code
30
- # True if the parser finished to parse the headers, otherwise false.
31
- attr_reader :headers_done
32
34
  # Response body.
33
35
  attr_accessor :body
34
36
 
@@ -67,12 +69,14 @@ class Response
67
69
 
68
70
  # Initialize this response object state.
69
71
  def initialize
72
+ @version = '1.1'
73
+ @code = 200
74
+ @status = 'OK'
70
75
  @content_type = nil
71
76
  @charset = 'UTF-8'
72
77
  @content_length = nil
73
- @body = ''
74
- @code = nil
75
- @headers = []
78
+ @body = nil
79
+ @headers = {}
76
80
  @headers_done = false
77
81
  @chunked = false
78
82
  end
@@ -100,37 +104,53 @@ class Response
100
104
  def <<(line)
101
105
  # we already parsed the heders, collect response body
102
106
  if @headers_done
107
+ @body = '' if @body.nil?
103
108
  @body << line.force_encoding( @charset )
104
109
  else
105
- Logger.debug " RESPONSE LINE: '#{line.chomp}'"
106
-
107
- # parse the response status
108
- if @code.nil? and line =~ /^HTTP\/[\d\.]+\s+(.+)/
109
- @code = $1.chomp
110
-
111
- # parse the content type
112
- elsif line =~ /^Content-Type:\s*([^;]+).*/i
113
- @content_type = $1.chomp
114
- if line =~ /^.+;\s*charset=(.+)/i
115
- @charset = $1.chomp
110
+ chomped = line.chomp
111
+ Logger.debug " RESPONSE LINE: '#{chomped}'"
112
+
113
+ # is this the first line 'HTTP/<VERSION> <CODE> <STATUS>' ?
114
+ if chomped =~ /^HTTP\/([\d\.]+)\s+(\d+)\s+(.+)$/
115
+ @version = $1
116
+ @code = $2.to_i
117
+ @status = $3
118
+
119
+ # collect and fix headers
120
+ elsif chomped =~ /^([^:\s]+)\s*:\s*(.+)$/i
121
+ name = $1
122
+ value = $2
123
+
124
+ if name == 'Content-Type'
125
+ @content_type = value
126
+ if value =~ /^(.+);\s*charset=(.+)/i
127
+ @content_type = $1
128
+ @charset = $2.chomp
129
+ end
130
+ elsif name == 'Content-Length'
131
+ @content_length = value.to_i
132
+ # check if we have a chunked encoding
133
+ elsif name == 'Transfer-Encoding' and value == 'chunked'
134
+ @chunked = true
135
+ name = nil
136
+ value = nil
116
137
  end
117
138
 
118
- # parse content length
119
- elsif line =~ /^Content-Length:\s+(\d+)\s*$/i
120
- @content_length = $1.to_i
121
-
122
- # check if we have a chunked encoding
123
- elsif line =~ /^Transfer-Encoding:\s*chunked.*$/i
124
- @chunked = true
125
- line = nil
126
-
139
+ unless name.nil? or value.nil?
140
+ if @headers.has_key?(name)
141
+ if @headers[name].is_a?(Array)
142
+ @headers[name] << value
143
+ else
144
+ @headers[name] = [ @headers[name], value ]
145
+ end
146
+ else
147
+ @headers[name] = value
148
+ end
149
+ end
127
150
  # last line, we're done with the headers
128
- elsif line.chomp.empty?
151
+ elsif chomped.empty?
129
152
  @headers_done = true
130
-
131
153
  end
132
-
133
- @headers << line.chomp unless line.nil?
134
154
  end
135
155
  end
136
156
 
@@ -141,62 +161,61 @@ class Response
141
161
 
142
162
  # Return the value of header with +name+ or an empty string.
143
163
  def [](name)
144
- @headers.each do |header|
145
- if header =~ /^#{name}:\s*(.+)$/i
146
- return $1
147
- end
148
- end
149
- ""
164
+ ( @headers.has_key?(name) ? @headers[name] : "" )
150
165
  end
151
166
 
152
167
  # If the header with +name+ is found, then a +value+ is assigned to it,
153
168
  # otherwise it's created.
154
169
  def []=(name, value)
155
- found = false
156
- @headers.each_with_index do |header,i|
157
- if header =~ /^#{name}:\s*.+$/i
158
- if value.nil?
159
- @headers.delete(i)
160
- else
161
- @headers[i] = "#{name}: #{value}"
162
- end
163
-
164
- found = true
165
- break
170
+ if @headers.has_key?(name)
171
+ if value.nil?
172
+ @headers.delete(name)
173
+ else
174
+ @headers[name] = value
166
175
  end
167
- end
168
-
169
- unless found or value.nil?
170
- @headers << "#{name}: #{value}"
176
+ elsif !value.nil?
177
+ @headers[name] = value
171
178
  end
172
179
  end
173
180
 
174
- def each_header(name)
175
- @headers.each_with_index do |header,i|
176
- if header =~ /^#{name}:\s*(.+)$/i
177
- yield( $1, i )
181
+ # Search for header +name+ and apply a gsub substitution:
182
+ # value.gsub( +search+, +replace+ )
183
+ def patch_header!( name, search, replace )
184
+ value = self[name]
185
+ unless value.empty?
186
+ patched = []
187
+ if value.is_a?(Array)
188
+ value.each do |v|
189
+ patched << v.gsub( search, replace )
190
+ end
191
+ else
192
+ patched << value.gsub( search, replace )
178
193
  end
194
+
195
+ self[name] = patched
179
196
  end
180
197
  end
181
198
 
182
199
  # Return a string representation of this response object, patching the
183
200
  # Content-Length header if the #body was modified.
184
201
  def to_s
185
- if textual?
186
- @headers.map! do |header|
187
- # update content length in case the body was
188
- # modified
189
- if header =~ /Content-Length:\s*(\d+)/i
190
- Logger.debug "Updating response content length from #{$1} to #{@body.bytesize}"
191
-
192
- "Content-Length: #{@body.bytesize}"
193
- else
194
- header
202
+ # update content length in case the body was modified.
203
+ if @headers.has_key?('Content-Length')
204
+ @headers['Content-Length'] = @body.nil?? 0 : @body.bytesize
205
+ end
206
+
207
+ s = "HTTP/#{@version} #{@code} #{@status}\n"
208
+ @headers.each do |name,value|
209
+ if value.is_a?(Array)
210
+ value.each do |v|
211
+ s << "#{name}: #{v}\n"
195
212
  end
213
+ else
214
+ s << "#{name}: #{value}\n"
196
215
  end
197
216
  end
198
-
199
- @headers.join("\n") + "\n" + ( @body || "\n" )
217
+ s << "\n" + ( @body.nil?? "\n" : @body )
218
+ s
200
219
  end
201
220
  end
202
221
 
@@ -101,11 +101,12 @@ class Strip
101
101
  HTTPS_URL_RE = /(https:\/\/[^"'\/]+)/i
102
102
 
103
103
  # Create an instance of this object.
104
- def initialize
104
+ def initialize( ctx )
105
105
  @stripped = []
106
106
  @cookies = CookieMonitor.new
107
107
  @favicon = Response.from_file( File.dirname(__FILE__) + '/lock.ico', 'image/x-icon' )
108
- @resolver = BetterCap::Network::Servers::DNSD.new
108
+ @resolver = BetterCap::Network::Servers::DNSD.new( nil, ctx.ifconfig[:ip_saddr], ctx.options.dnsd_port )
109
+
109
110
  @resolver.start
110
111
  end
111
112
 
@@ -162,22 +163,30 @@ class Strip
162
163
 
163
164
  private
164
165
 
166
+ # Headers to patch both in requests and responses.
167
+ HEADERS_TO_PATCH = {
168
+ :req => {
169
+ 'Accept-Encoding' => nil,
170
+ 'If-None-Match' => nil,
171
+ 'If-Modified-Since' => nil,
172
+ 'Upgrade-Insecure-Requests' => nil,
173
+ 'Pragma' => 'no-cache'
174
+ },
175
+
176
+ :res => {
177
+ 'X-Frame-Options' => nil,
178
+ 'X-Content-Type-Options' => nil,
179
+ 'X-Xss-Protection' => nil,
180
+ 'Strict-Transport-Security' => nil,
181
+ 'Content-Security-Policy' => nil
182
+ }
183
+ }.freeze
184
+
165
185
  # Clean some headers from +r+.
166
186
  def process_headers!(r)
167
- # clean request
168
- if r.is_a?(BetterCap::Proxy::Request)
169
- r['Accept-Encoding'] = nil
170
- r['If-None-Match'] = nil
171
- r['If-Modified-Since'] = nil
172
- r['Upgrade-Insecure-Requests'] = nil
173
- r['Pragma'] = 'no-cache'
174
- # clean response
175
- else
176
- r['X-Frame-Options'] = nil
177
- r['X-Content-Type-Options'] = nil
178
- r['X-Xss-Protection'] = nil
179
- r['Strict-Transport-Security'] = nil
180
- r['Content-Security-Policy'] = nil
187
+ what = r.is_a?(BetterCap::Proxy::Request) ? :req : :res
188
+ HEADERS_TO_PATCH[what].each do |key,value|
189
+ r[key] = value;
181
190
  end
182
191
  end
183
192
 
@@ -247,7 +256,6 @@ class Strip
247
256
  # no cookies set, just a normal http -> https redirect
248
257
  if response['Set-Cookie'].empty?
249
258
  Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Found redirect to HTTPS '#{original}' -> '#{stripped}'."
250
-
251
259
  # The request will be retried on port 443 if MAX_REDIRECTS is not reached.
252
260
  request.port = 443
253
261
  # retry the request if possible
@@ -257,11 +265,9 @@ class Strip
257
265
  Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Found redirect to HTTPS ( with cookies ) '#{original}' -> '#{stripped}'."
258
266
  # we know this session, do not kill it!
259
267
  @cookies.add!( request )
260
- # remove the 'secure' descriptor from every cookie
261
- response.each_header('Set-Cookie') do |value,i|
262
- response.headers[i] = "Set-Cookie: #{value.gsub( /secure/, '' )}"
263
- end
264
-
268
+ # remove the 'secure' flag from every cookie.
269
+ # ref: https://www.owasp.org/index.php/SecureFlag
270
+ response.patch_header!( 'Set-Cookie', /secure/, '' )
265
271
  # do not retry request
266
272
  return false
267
273
  end
@@ -276,6 +282,10 @@ class Strip
276
282
  begin
277
283
  response.body.scan( HTTPS_URL_RE ).uniq.each do |link|
278
284
  if link[0].include?('.')
285
+ # yeah, some idiots are using \ instead of / as a path -.-
286
+ if link[0].end_with?('\\')
287
+ link[0][-1] = '/'
288
+ end
279
289
  links << StrippedObject.process( link[0] )
280
290
  end
281
291
  end
@@ -296,9 +306,15 @@ class Strip
296
306
  private
297
307
 
298
308
  def add_stripped_object( o )
299
- @stripped << o
300
- # make sure we're able to resolve the stripped domain
301
- @resolver.add_rule( o.stripped_hostname, IPSocket.getaddress( o.original_hostname ) )
309
+ begin
310
+ stripped_hostname = o.stripped_hostname
311
+ original_address = IPSocket.getaddress( o.original_hostname )
312
+ @stripped << o
313
+ # make sure we're able to resolve the stripped domain
314
+ @resolver.add_rule( stripped_hostname, original_address )
315
+ rescue Exception => e
316
+ Logger.exception(e)
317
+ end
302
318
  end
303
319
  end
304
320
 
@@ -27,6 +27,7 @@ class StreamLogger
27
27
  }
28
28
 
29
29
  @@services = nil
30
+ @@lock = Mutex.new
30
31
 
31
32
  # Search for the +addr+ IP address inside the list of collected targets and return
32
33
  # its compact string representation ( @see BetterCap::Target#to_s_compact ).
@@ -47,15 +48,17 @@ class StreamLogger
47
48
 
48
49
  # Given +proto+ and +port+ return the network service name if possible.
49
50
  def self.service( proto, port )
50
- if @@services.nil?
51
- @@services = { :tcp => {}, :udp => {} }
52
- filename = File.dirname(__FILE__) + '/../network/services'
53
- File.open( filename ).each do |line|
54
- if line =~ /([^\s]+)\s+(\d+)\/([a-z]+).*/i
55
- @@services[$3.to_sym][$2.to_i] = $1
51
+ @@lock.synchronize {
52
+ if @@services.nil?
53
+ @@services = { :tcp => {}, :udp => {} }
54
+ filename = File.dirname(__FILE__) + '/../network/services'
55
+ File.open( filename ).each do |line|
56
+ if line =~ /([^\s]+)\s+(\d+)\/([a-z]+).*/i
57
+ @@services[$3.to_sym][$2.to_i] = $1
58
+ end
56
59
  end
57
60
  end
58
- end
61
+ }
59
62
 
60
63
  if @@services.has_key?(proto) and @@services[proto].has_key?(port)
61
64
  @@services[proto][port]
@@ -146,7 +149,7 @@ class StreamLogger
146
149
  def self.log_http( request, response )
147
150
  response_s = "( #{response.content_type} )"
148
151
  request_s = request.to_url( request.post?? nil : @@MAX_REQ_SIZE )
149
- code = response.code[0]
152
+ code = response.code.to_s[0]
150
153
 
151
154
  if @@CODE_COLORS.has_key? code
152
155
  response_s += " [#{response.code}]".send( @@CODE_COLORS[ code ] )
@@ -20,7 +20,7 @@ class Streamer
20
20
  def initialize( processor )
21
21
  @processor = processor
22
22
  @ctx = Context.get
23
- @sslstrip = SSLStrip::Strip.new if @ctx.options.sslstrip
23
+ @sslstrip = SSLStrip::Strip.new( @ctx ) if @ctx.options.sslstrip
24
24
  end
25
25
 
26
26
  # Return true if the +request+ was stripped.
@@ -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.2'
15
+ VERSION = '1.4.3'
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.2
4
+ version: 1.4.3
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-02-17 00:00:00.000000000 Z
11
+ date: 2016-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -115,7 +115,6 @@ executables:
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
- - CONTRIBUTING.md
119
118
  - LICENSE.md
120
119
  - README.md
121
120
  - bin/bettercap
@@ -134,6 +133,7 @@ files:
134
133
  - lib/bettercap/firewalls/redirection.rb
135
134
  - lib/bettercap/loader.rb
136
135
  - lib/bettercap/logger.rb
136
+ - lib/bettercap/monkey/celluloid/io/udp_socket.rb
137
137
  - lib/bettercap/monkey/packetfu/utils.rb
138
138
  - lib/bettercap/network/arp_reader.rb
139
139
  - lib/bettercap/network/hw-prefixes
data/CONTRIBUTING.md DELETED
@@ -1,42 +0,0 @@
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|rvmsudo] 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.