ssrf_proxy 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,5 @@
1
- # coding: utf-8
2
1
  #
3
- # Copyright (c) 2015-2016 Brendan Coles <bcoles@gmail.com>
2
+ # Copyright (c) 2015-2017 Brendan Coles <bcoles@gmail.com>
4
3
  # SSRF Proxy - https://github.com/bcoles/ssrf_proxy
5
4
  # See the file 'LICENSE.md' for copying permission
6
5
  #
@@ -16,18 +15,20 @@ module SSRFProxy
16
15
  include Celluloid::IO
17
16
  finalizer :shutdown
18
17
 
18
+ # @return [Logger] logger
19
+ attr_reader :logger
20
+
19
21
  #
20
22
  # SSRFProxy::Server errors
21
23
  #
22
24
  module Error
23
- # SSRFProxy::Server custom errors
25
+ # SSRFProxy::Server errors
24
26
  class Error < StandardError; end
25
- exceptions = %w(
26
- InvalidSsrf
27
- ProxyRecursion
28
- AddressInUse
29
- RemoteProxyUnresponsive
30
- RemoteHostUnresponsive )
27
+ exceptions = %w[InvalidSsrf
28
+ ProxyRecursion
29
+ AddressInUse
30
+ RemoteProxyUnresponsive
31
+ RemoteHostUnresponsive]
31
32
  exceptions.each { |e| const_set(e, Class.new(Error)) }
32
33
  end
33
34
 
@@ -51,7 +52,7 @@ module SSRFProxy
51
52
  #
52
53
  # @example Start SSRF Proxy server with the default options
53
54
  # ssrf_proxy = SSRFProxy::Server.new(
54
- # SSRFProxy::HTTP.new('http://example.local/index.php?url=xxURLxx'),
55
+ # SSRFProxy::HTTP.new('http://example.local/?url=xxURLxx'),
55
56
  # '127.0.0.1',
56
57
  # 8081)
57
58
  # ssrf_proxy.serve
@@ -59,7 +60,6 @@ module SSRFProxy
59
60
  def initialize(ssrf, interface = '127.0.0.1', port = 8081)
60
61
  @banner = 'SSRF Proxy'
61
62
  @server = nil
62
- @max_request_len = 8192
63
63
  @logger = ::Logger.new(STDOUT).tap do |log|
64
64
  log.progname = 'ssrf-proxy-server'
65
65
  log.level = ::Logger::WARN
@@ -79,20 +79,24 @@ module SSRFProxy
79
79
  "Proxy recursion error: #{@ssrf.proxy}"
80
80
  end
81
81
  if port_open?(@ssrf.proxy.host, @ssrf.proxy.port)
82
- print_good("Connected to remote proxy #{@ssrf.proxy.host}:#{@ssrf.proxy.port} successfully")
82
+ print_good('Connected to remote proxy ' \
83
+ "#{@ssrf.proxy.host}:#{@ssrf.proxy.port} successfully")
83
84
  else
84
85
  raise SSRFProxy::Server::Error::RemoteProxyUnresponsive.new,
85
- "Could not connect to remote proxy #{@ssrf.proxy.host}:#{@ssrf.proxy.port}"
86
+ 'Could not connect to remote proxy ' \
87
+ "#{@ssrf.proxy.host}:#{@ssrf.proxy.port}"
86
88
  end
87
89
  end
88
90
 
89
91
  # if no upstream proxy is set, check if the remote server is responsive
90
92
  if @ssrf.proxy.nil?
91
- if port_open?(@ssrf.host, @ssrf.port)
92
- print_good("Connected to remote host #{@ssrf.host}:#{@ssrf.port} successfully")
93
+ if port_open?(@ssrf.url.host, @ssrf.url.port)
94
+ print_good('Connected to remote host ' \
95
+ "#{@ssrf.url.host}:#{@ssrf.url.port} successfully")
93
96
  else
94
97
  raise SSRFProxy::Server::Error::RemoteHostUnresponsive.new,
95
- "Could not connect to remote host #{@ssrf.host}:#{@ssrf.port}"
98
+ 'Could not connect to remote host ' \
99
+ "#{@ssrf.url.host}:#{@ssrf.url.port}"
96
100
  end
97
101
  end
98
102
 
@@ -103,7 +107,8 @@ module SSRFProxy
103
107
  @server = TCPServer.new(interface, port.to_i)
104
108
  rescue Errno::EADDRINUSE
105
109
  raise SSRFProxy::Server::Error::AddressInUse.new,
106
- "Could not bind to #{interface}:#{port} - address already in use"
110
+ "Could not bind to #{interface}:#{port}" \
111
+ ' - address already in use'
107
112
  end
108
113
  end
109
114
 
@@ -117,14 +122,10 @@ module SSRFProxy
117
122
  #
118
123
  def port_open?(ip, port, seconds = 10)
119
124
  Timeout.timeout(seconds) do
120
- begin
121
- TCPSocket.new(ip, port).close
122
- true
123
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError
124
- false
125
- end
125
+ TCPSocket.new(ip, port).close
126
+ true
126
127
  end
127
- rescue Timeout::Error
128
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError, Timeout::Error
128
129
  false
129
130
  end
130
131
 
@@ -155,15 +156,6 @@ module SSRFProxy
155
156
  puts '[-] '.red + msg
156
157
  end
157
158
 
158
- #
159
- # Logger accessor
160
- #
161
- # @return [Logger] class logger object
162
- #
163
- def logger
164
- @logger
165
- end
166
-
167
159
  #
168
160
  # Run proxy server asynchronously
169
161
  #
@@ -172,7 +164,7 @@ module SSRFProxy
172
164
  end
173
165
 
174
166
  #
175
- # Handle shutdown of client socket
167
+ # Handle shutdown of server socket
176
168
  #
177
169
  def shutdown
178
170
  logger.info 'Shutting down'
@@ -189,8 +181,9 @@ module SSRFProxy
189
181
  start_time = Time.now
190
182
  _, port, host = socket.peeraddr
191
183
  logger.debug("Client #{host}:#{port} connected")
192
- request = socket.readpartial(@max_request_len)
193
- logger.debug("Received client request (#{request.length} bytes):\n#{request}")
184
+ request = socket.read
185
+ logger.debug("Received client request (#{request.length} bytes):\n" \
186
+ "#{request}")
194
187
 
195
188
  response = nil
196
189
  if request.to_s =~ /\ACONNECT ([_a-zA-Z0-9\.\-]+:[\d]+) .*$/
@@ -200,45 +193,62 @@ module SSRFProxy
200
193
 
201
194
  if response['code'].to_i == 502 || response['code'].to_i == 504
202
195
  logger.info("Connection to #{host} failed")
203
- socket.write("#{response['status_line']}\n#{response['headers']}\n#{response['body']}")
196
+ socket.write("#{response['status_line']}\n" \
197
+ "#{response['headers']}\n" \
198
+ "#{response['body']}")
204
199
  raise Errno::ECONNRESET
205
200
  end
206
201
 
207
202
  logger.info("Connected to #{host} successfully")
208
203
  socket.write("HTTP/1.0 200 Connection established\r\n\r\n")
209
- request = socket.readpartial(@max_request_len)
210
- logger.debug("Received client request (#{request.length} bytes):\n#{request}")
204
+ request = socket.read
205
+ logger.debug("Received client request (#{request.length} bytes):\n" \
206
+ "#{request}")
207
+
208
+ # CHANGE_CIPHER_SPEC 20 0x14
209
+ # ALERT 21 0x15
210
+ # HANDSHAKE 22 0x16
211
+ # APPLICATION_DATA 23 0x17
212
+ if request.to_s.start_with?("\x14", "\x15", "\x16", "\x17")
213
+ logger.warn("Received SSL/TLS client request. SSL/TLS tunneling is not supported. Aborted.")
214
+ raise Errno::ECONNRESET
215
+ end
211
216
  end
212
217
 
213
218
  response = send_request(request.to_s)
214
- socket.write("#{response['status_line']}\n#{response['headers']}\n#{response['body']}")
219
+ socket.write("#{response['status_line']}\n" \
220
+ "#{response['headers']}\n" \
221
+ "#{response['body']}")
215
222
  raise Errno::ECONNRESET
216
- rescue EOFError, Errno::ECONNRESET
223
+ rescue EOFError, Errno::ECONNRESET, Errno::EPIPE
217
224
  socket.close
218
225
  logger.debug("Client #{host}:#{port} disconnected")
219
226
  end_time = Time.now
220
- duration = end_time - start_time
221
- logger.info("Served #{response['body'].length} bytes in #{(duration * 1000).round(3)} ms")
227
+ duration = ((end_time - start_time) * 1000).round(3)
228
+ if response.nil?
229
+ logger.info("Served 0 bytes in #{duration} ms")
230
+ else
231
+ logger.info("Served #{response['body'].length} bytes in #{duration} ms")
232
+ end
222
233
  end
223
234
 
224
235
  #
225
236
  # Send client HTTP request
226
237
  #
227
- # @param [String] client HTTP request
238
+ # @param [String] request client HTTP request
228
239
  #
229
240
  # @return [Hash] HTTP response
230
241
  #
231
242
  def send_request(request)
232
- response_error = {
233
- 'uri' => '',
234
- 'duration' => '0',
235
- 'http_version' => '1.0',
236
- 'headers' => "Server: #{@banner}\n",
237
- 'body' => '' }
243
+ response_error = { 'uri' => '',
244
+ 'duration' => '0',
245
+ 'http_version' => '1.0',
246
+ 'headers' => "Server: #{@banner}\n",
247
+ 'body' => '' }
238
248
 
239
249
  # parse client request
240
250
  begin
241
- if request.to_s !~ %r{\A(CONNECT|GET|HEAD|DELETE|POST|PUT) https?://}
251
+ if request.to_s !~ %r{\A(CONNECT|GET|HEAD|DELETE|POST|PUT|OPTIONS) https?://}
242
252
  if request.to_s !~ /^Host: ([^\s]+)\r?\n/
243
253
  logger.warn('No host specified')
244
254
  raise SSRFProxy::HTTP::Error::InvalidClientRequest,
@@ -249,11 +259,12 @@ module SSRFProxy
249
259
  req.parse(StringIO.new(request))
250
260
  rescue => e
251
261
  logger.info('Received malformed client HTTP request.')
252
- error_msg = "Error -- Invalid request: Received malformed client HTTP request: #{e.message}"
262
+ error_msg = 'Error -- Invalid request: ' \
263
+ "Received malformed client HTTP request: #{e.message}"
253
264
  print_error(error_msg)
254
265
  response_error['code'] = '502'
255
266
  response_error['message'] = 'Bad Gateway'
256
- response_error['status_line'] = "HTTP/#{response_error['http_version']}"
267
+ response_error['status_line'] = "HTTP/#{response_error['http_version']}"
257
268
  response_error['status_line'] << " #{response_error['code']}"
258
269
  response_error['status_line'] << " #{response_error['message']}"
259
270
  return response_error
@@ -262,10 +273,10 @@ module SSRFProxy
262
273
 
263
274
  # send request
264
275
  response = nil
265
- logger.info("Sending request: #{uri}")
276
+ logger.info("Requesting URL: #{uri}")
266
277
  status_msg = "Request -> #{req.request_method}"
267
278
  status_msg << " -> PROXY[#{@ssrf.proxy.host}:#{@ssrf.proxy.port}]" unless @ssrf.proxy.nil?
268
- status_msg << " -> SSRF[#{@ssrf.host}:#{@ssrf.port}] -> URI[#{uri}]"
279
+ status_msg << " -> SSRF[#{@ssrf.url.host}:#{@ssrf.url.port}] -> URI[#{uri}]"
269
280
  print_status(status_msg)
270
281
 
271
282
  begin
@@ -276,7 +287,33 @@ module SSRFProxy
276
287
  print_error(error_msg)
277
288
  response_error['code'] = '502'
278
289
  response_error['message'] = 'Bad Gateway'
279
- response_error['status_line'] = "HTTP/#{response_error['http_version']}"
290
+ response_error['status_line'] = "HTTP/#{response_error['http_version']}"
291
+ response_error['status_line'] << " #{response_error['code']}"
292
+ response_error['status_line'] << " #{response_error['message']}"
293
+ return response_error
294
+ rescue SSRFProxy::HTTP::Error::InvalidResponse => e
295
+ logger.info(e.message)
296
+ error_msg = 'Response <- 503'
297
+ error_msg << " <- PROXY[#{@ssrf.proxy.host}:#{@ssrf.proxy.port}]" unless @ssrf.proxy.nil?
298
+ error_msg << " <- SSRF[#{@ssrf.url.host}:#{@ssrf.url.port}] <- URI[#{uri}]"
299
+ error_msg << " -- Error: #{e.message}"
300
+ print_error(error_msg)
301
+ response_error['code'] = '503'
302
+ response_error['message'] = 'Service Unavailable'
303
+ response_error['status_line'] = "HTTP/#{response_error['http_version']}"
304
+ response_error['status_line'] << " #{response_error['code']}"
305
+ response_error['status_line'] << " #{response_error['message']}"
306
+ return response_error
307
+ rescue SSRFProxy::HTTP::Error::ConnectionFailed => e
308
+ logger.info(e.message)
309
+ error_msg = 'Response <- 503'
310
+ error_msg << " <- PROXY[#{@ssrf.proxy.host}:#{@ssrf.proxy.port}]" unless @ssrf.proxy.nil?
311
+ error_msg << " <- SSRF[#{@ssrf.url.host}:#{@ssrf.url.port}] <- URI[#{uri}]"
312
+ error_msg << " -- Error: #{e.message}"
313
+ print_error(error_msg)
314
+ response_error['code'] = '503'
315
+ response_error['message'] = 'Service Unavailable'
316
+ response_error['status_line'] = "HTTP/#{response_error['http_version']}"
280
317
  response_error['status_line'] << " #{response_error['code']}"
281
318
  response_error['status_line'] << " #{response_error['message']}"
282
319
  return response_error
@@ -284,22 +321,22 @@ module SSRFProxy
284
321
  logger.info(e.message)
285
322
  error_msg = 'Response <- 504'
286
323
  error_msg << " <- PROXY[#{@ssrf.proxy.host}:#{@ssrf.proxy.port}]" unless @ssrf.proxy.nil?
287
- error_msg << " <- SSRF[#{@ssrf.host}:#{@ssrf.port}] <- URI[#{uri}]"
324
+ error_msg << " <- SSRF[#{@ssrf.url.host}:#{@ssrf.url.port}] <- URI[#{uri}]"
288
325
  error_msg << " -- Error: #{e.message}"
289
326
  print_error(error_msg)
290
327
  response_error['code'] = '504'
291
328
  response_error['message'] = 'Timeout'
292
- response_error['status_line'] = "HTTP/#{response_error['http_version']}"
329
+ response_error['status_line'] = "HTTP/#{response_error['http_version']}"
293
330
  response_error['status_line'] << " #{response_error['code']}"
294
331
  response_error['status_line'] << " #{response_error['message']}"
295
332
  return response_error
296
333
  rescue => e
297
334
  logger.warn(e.message)
298
- error_msg = "Error -- Unexpected error: #{e.message}"
335
+ error_msg = "Error -- Unexpected error: #{e.backtrace.join("\n")}"
299
336
  print_error(error_msg)
300
337
  response_error['code'] = '502'
301
338
  response_error['message'] = 'Bad Gateway'
302
- response_error['status_line'] = "HTTP/#{response_error['http_version']}"
339
+ response_error['status_line'] = "HTTP/#{response_error['http_version']}"
303
340
  response_error['status_line'] << " #{response_error['code']} "
304
341
  response_error['status_line'] << " #{response_error['message']}"
305
342
  return response_error
@@ -308,7 +345,7 @@ module SSRFProxy
308
345
  # return response
309
346
  status_msg = "Response <- #{response['code']}"
310
347
  status_msg << " <- PROXY[#{@ssrf.proxy.host}:#{@ssrf.proxy.port}]" unless @ssrf.proxy.nil?
311
- status_msg << " <- SSRF[#{@ssrf.host}:#{@ssrf.port}] <- URI[#{uri}]"
348
+ status_msg << " <- SSRF[#{@ssrf.url.host}:#{@ssrf.url.port}] <- URI[#{uri}]"
312
349
  status_msg << " -- Title[#{response['title']}]" unless response['title'].eql?('')
313
350
  status_msg << " -- [#{response['body'].size} bytes]"
314
351
  print_good(status_msg)
@@ -1,18 +1,10 @@
1
- # coding: utf-8
2
1
  #
3
- # Copyright (c) 2015-2016 Brendan Coles <bcoles@gmail.com>
2
+ # Copyright (c) 2015-2017 Brendan Coles <bcoles@gmail.com>
4
3
  # SSRF Proxy - https://github.com/bcoles/ssrf_proxy
5
4
  # See the file 'LICENSE.md' for copying permission
6
5
  #
7
6
 
8
7
  module SSRFProxy
9
8
  # Gem version
10
- VERSION = '0.0.3'.freeze
11
- # Elite font ASCII art from: http://patorjk.com/software/taag/
12
- BANNER = " \n" \
13
- " .▄▄ · .▄▄ · ▄▄▄ ·▄▄▄ ▄▄▄·▄▄▄ ▐▄• ▄ ▄· ▄▌ \n" \
14
- " ▐█ ▀. ▐█ ▀. ▀▄ █·▐▄▄· ▐█ ▄█▀▄ █·▪ █▌█▌▪▐█▪██▌ \n" \
15
- " ▄▀▀▀█▄▄▀▀▀█▄▐▀▀▄ ██▪ ██▀·▐▀▀▄ ▄█▀▄ ·██· ▐█▌▐█▪ \n" \
16
- " ▐█▄▪▐█▐█▄▪▐█▐█•█▌██▌. ▐█▪·•▐█•█▌▐█▌.▐▌▪▐█·█▌ ▐█▀·. \n" \
17
- " ▀▀▀▀ ▀▀▀▀ .▀ ▀▀▀▀ .▀ .▀ ▀ ▀█▄▀▪•▀▀ ▀▀ ▀ • \n".freeze
9
+ VERSION = '0.0.4'.freeze
18
10
  end
metadata CHANGED
@@ -1,281 +1,315 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssrf_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendan Coles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-02 00:00:00.000000000 Z
11
+ date: 2017-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '1.12'
19
+ version: '1.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: '1.12'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: coveralls
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '11.0'
33
+ version: 0.8.21
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '11.0'
40
+ version: 0.8.21
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '5.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: bundler-audit
56
+ name: minitest-reporters
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '0.5'
61
+ version: '1.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: '0.5'
68
+ version: '1.1'
69
69
  - !ruby/object:Gem::Dependency
70
- name: typhoeus
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ~>
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '12.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ~>
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '12.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rubocop
84
+ name: rdoc
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - ~>
88
88
  - !ruby/object:Gem::Version
89
- version: 0.23.0
89
+ version: '6.0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ! '>='
94
+ - - ~>
95
95
  - !ruby/object:Gem::Version
96
- version: 0.23.0
96
+ version: '6.0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rdoc
98
+ name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ! '>='
101
+ - - ~>
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: '0.52'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ! '>='
108
+ - - ~>
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: '0.52'
111
111
  - !ruby/object:Gem::Dependency
112
- name: yard
112
+ name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ! '>='
115
+ - - ~>
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '0.14'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ! '>='
122
+ - - ~>
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: '0.14'
125
125
  - !ruby/object:Gem::Dependency
126
- name: simplecov
126
+ name: terminal-table
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ! '>='
129
+ - - ~>
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: '1.6'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ! '>='
136
+ - - ~>
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: '1.6'
139
139
  - !ruby/object:Gem::Dependency
140
- name: coveralls
140
+ name: typhoeus
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - ! '>='
143
+ - - ~>
144
144
  - !ruby/object:Gem::Version
145
- version: '0'
145
+ version: '1.3'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - ! '>='
150
+ - - ~>
151
151
  - !ruby/object:Gem::Version
152
- version: '0'
152
+ version: '1.3'
153
153
  - !ruby/object:Gem::Dependency
154
- name: logger
154
+ name: yard
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - ! '>='
157
+ - - ~>
158
158
  - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :runtime
159
+ version: '0.9'
160
+ type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - ! '>='
164
+ - - ~>
165
165
  - !ruby/object:Gem::Version
166
- version: '0'
166
+ version: '0.9'
167
167
  - !ruby/object:Gem::Dependency
168
- name: colorize
168
+ name: base32
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - ! '>='
171
+ - - ~>
172
172
  - !ruby/object:Gem::Version
173
- version: '0'
173
+ version: '0.3'
174
174
  type: :runtime
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ! '>='
178
+ - - ~>
179
179
  - !ruby/object:Gem::Version
180
- version: '0'
180
+ version: '0.3'
181
181
  - !ruby/object:Gem::Dependency
182
- name: webrick
182
+ name: celluloid
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - ! '>='
185
+ - - ~>
186
186
  - !ruby/object:Gem::Version
187
- version: '0'
187
+ version: 0.17.3
188
188
  type: :runtime
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - ! '>='
192
+ - - ~>
193
193
  - !ruby/object:Gem::Version
194
- version: '0'
194
+ version: 0.17.3
195
195
  - !ruby/object:Gem::Dependency
196
- name: celluloid
196
+ name: celluloid-io
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
- - - ! '>='
199
+ - - ~>
200
200
  - !ruby/object:Gem::Version
201
201
  version: 0.17.3
202
202
  type: :runtime
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
- - - ! '>='
206
+ - - ~>
207
207
  - !ruby/object:Gem::Version
208
208
  version: 0.17.3
209
209
  - !ruby/object:Gem::Dependency
210
- name: celluloid-io
210
+ name: colorize
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
- - - ! '>='
213
+ - - ~>
214
214
  - !ruby/object:Gem::Version
215
- version: 0.17.3
215
+ version: '0.8'
216
216
  type: :runtime
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
- - - ! '>='
220
+ - - ~>
221
221
  - !ruby/object:Gem::Version
222
- version: 0.17.3
222
+ version: '0.8'
223
+ - !ruby/object:Gem::Dependency
224
+ name: htmlentities
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ~>
228
+ - !ruby/object:Gem::Version
229
+ version: '4.3'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ~>
235
+ - !ruby/object:Gem::Version
236
+ version: '4.3'
223
237
  - !ruby/object:Gem::Dependency
224
238
  name: ipaddress
225
239
  requirement: !ruby/object:Gem::Requirement
226
240
  requirements:
227
- - - ! '>='
241
+ - - ~>
228
242
  - !ruby/object:Gem::Version
229
- version: '0'
243
+ version: '0.8'
230
244
  type: :runtime
231
245
  prerelease: false
232
246
  version_requirements: !ruby/object:Gem::Requirement
233
247
  requirements:
234
- - - ! '>='
248
+ - - ~>
235
249
  - !ruby/object:Gem::Version
236
- version: '0'
250
+ version: '0.8'
237
251
  - !ruby/object:Gem::Dependency
238
- name: base32
252
+ name: logger
239
253
  requirement: !ruby/object:Gem::Requirement
240
254
  requirements:
241
- - - ! '>='
255
+ - - ~>
242
256
  - !ruby/object:Gem::Version
243
- version: '0'
257
+ version: '1.2'
244
258
  type: :runtime
245
259
  prerelease: false
246
260
  version_requirements: !ruby/object:Gem::Requirement
247
261
  requirements:
248
- - - ! '>='
262
+ - - ~>
249
263
  - !ruby/object:Gem::Version
250
- version: '0'
264
+ version: '1.2'
251
265
  - !ruby/object:Gem::Dependency
252
- name: htmlentities
266
+ name: mimemagic
253
267
  requirement: !ruby/object:Gem::Requirement
254
268
  requirements:
255
- - - ! '>='
269
+ - - ~>
256
270
  - !ruby/object:Gem::Version
257
- version: '0'
271
+ version: '0.3'
258
272
  type: :runtime
259
273
  prerelease: false
260
274
  version_requirements: !ruby/object:Gem::Requirement
261
275
  requirements:
262
- - - ! '>='
276
+ - - ~>
263
277
  - !ruby/object:Gem::Version
264
- version: '0'
278
+ version: '0.3'
265
279
  - !ruby/object:Gem::Dependency
266
280
  name: socksify
267
281
  requirement: !ruby/object:Gem::Requirement
268
282
  requirements:
283
+ - - ~>
284
+ - !ruby/object:Gem::Version
285
+ version: '1.7'
286
+ type: :runtime
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ~>
291
+ - !ruby/object:Gem::Version
292
+ version: '1.7'
293
+ - !ruby/object:Gem::Dependency
294
+ name: webrick
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ~>
298
+ - !ruby/object:Gem::Version
299
+ version: '1.3'
269
300
  - - ! '>='
270
301
  - !ruby/object:Gem::Version
271
- version: 1.7.0
302
+ version: 1.3.1
272
303
  type: :runtime
273
304
  prerelease: false
274
305
  version_requirements: !ruby/object:Gem::Requirement
275
306
  requirements:
307
+ - - ~>
308
+ - !ruby/object:Gem::Version
309
+ version: '1.3'
276
310
  - - ! '>='
277
311
  - !ruby/object:Gem::Version
278
- version: 1.7.0
312
+ version: 1.3.1
279
313
  description: SSRF Proxy is a multi-threaded HTTP proxy server designed to tunnel client
280
314
  HTTP traffic through HTTP servers vulnerable to HTTP Server-Side Request Forgery
281
315
  (SSRF).
@@ -284,7 +318,9 @@ email:
284
318
  executables:
285
319
  - ssrf-proxy
286
320
  extensions: []
287
- extra_rdoc_files: []
321
+ extra_rdoc_files:
322
+ - README.md
323
+ - LICENSE.md
288
324
  files:
289
325
  - LICENSE.md
290
326
  - README.md
@@ -292,6 +328,7 @@ files:
292
328
  - bin/setup
293
329
  - bin/ssrf-proxy
294
330
  - lib/ssrf_proxy.rb
331
+ - lib/ssrf_proxy/banner.rb
295
332
  - lib/ssrf_proxy/http.rb
296
333
  - lib/ssrf_proxy/server.rb
297
334
  - lib/ssrf_proxy/version.rb
@@ -300,14 +337,19 @@ licenses:
300
337
  - MIT
301
338
  metadata: {}
302
339
  post_install_message:
303
- rdoc_options: []
340
+ rdoc_options:
341
+ - --title
342
+ - SSRF Proxy
343
+ - --main
344
+ - README.md
345
+ - --line-numbers
304
346
  require_paths:
305
347
  - lib
306
348
  required_ruby_version: !ruby/object:Gem::Requirement
307
349
  requirements:
308
350
  - - ! '>='
309
351
  - !ruby/object:Gem::Version
310
- version: 1.9.3
352
+ version: 2.2.2
311
353
  required_rubygems_version: !ruby/object:Gem::Requirement
312
354
  requirements:
313
355
  - - ! '>='
@@ -321,4 +363,4 @@ specification_version: 4
321
363
  summary: SSRF Proxy facilitates tunneling HTTP communications through servers vulnerable
322
364
  to SSRF.
323
365
  test_files: []
324
- has_rdoc:
366
+ has_rdoc: true