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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OWNjNWNkNjA2ZjI0NjQ4MWNkMzhhMTM2ZWIxZDQzNTFiMjg1ZmNhZg==
4
+ ZGJhNjA3ZTRkODE5YTNlZmQyYTY3MGJjM2Q1YWE1NTNhOThhYmE2ZA==
5
5
  data.tar.gz: !binary |-
6
- MThiZTIzYzZjOGZlMDMzNzdhZjFiYWEzNGMyZDVlNjBhYTM5MTVhYg==
6
+ YzZlMmY0ODI2NGM0MmNiNzk0MjcxZTAwMDM5YjZhNWNmMTA1ZDVlOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YTY0N2I2YWFhNjUzODYyODQzN2QyOTliMjZlN2Y1YjJmYzQ4ZTZhNjQxNmNh
10
- MGM2Y2RiZThmY2I5YzBlOTE4Nzk2ZWU5YTI1YzViOGNhMTE4YjUzMjYwOTc5
11
- NjVmOGVjYTJhYThmYjZkZDYxNmIzYzk5N2I2NTVhMzhiZDcxMjA=
9
+ MGI5ZTA1NDAyNGJiMGM3ODdlMmU3M2VlZGRlODAwN2MwNmM0YzIzZjllM2Qw
10
+ ZjBlM2RjMzc5ODZhNDYwNTk2MTgwN2NmOTJiNWJjYmFlZjI2YTM0YjNlMzc2
11
+ MWEwZWYwMDI5YjFiNmUyM2I5ODY1NWE2OTY0Y2M5NTY5ODBjMDA=
12
12
  data.tar.gz: !binary |-
13
- NWY4ZjI4NTllZTViYzZlYzZmNDhjNzMzYzgxNjY1YjU1OWUyNzcwMmM3OWFi
14
- N2FjZGU4ZTc2OGUxOWVlYWNlMjlmY2I1ZmI4YzBlMjZkZThlZjkxMzIwYTli
15
- ZWU4YzIxYzI4MDAyNGFjYmNiOWFhNDIxZTJjYTE4YjlmN2NjMGE=
13
+ MWVmZTJlYTRmZDk3NjdjOWNmYjY0MGZhYzM3ODhiMjRhZGJkN2Q0ZDEzODQ5
14
+ MzI0ZjkwNzMwYTllZjVlNmVjMWJjZWUxOThlMTg2OWUxZDhmOGJhZjlkODc0
15
+ OTA3ZmZjODRiYTYxMTQwNjY3YjE3NWQwODBjYWYyYTZhNTJkYzc=
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2016 Brendan Coles <bcoles@gmail.com>
3
+ Copyright (c) 2015-2017 Brendan Coles <bcoles@gmail.com>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # SSRF Proxy
2
2
 
3
3
  <a href="https://github.com/bcoles/ssrf_proxy" target="_blank">
4
- <img src="https://img.shields.io/badge/version-0.0.3-brightgreen.svg"/>
4
+ <img alt="Version 0.0.4" src="https://img.shields.io/badge/version-0.0.4-brightgreen.svg"/>
5
5
  </a>
6
6
  <a href="https://travis-ci.org/bcoles-ci/ssrf_proxy" target="_blank">
7
7
  <img src="https://api.travis-ci.org/bcoles-ci/ssrf_proxy.svg?branch=master"/>
@@ -22,12 +22,13 @@
22
22
  <img src="https://inch-ci.org/github/bcoles/ssrf_proxy.svg?branch=master"/>
23
23
  </a>
24
24
  <a href="https://github.com/bcoles/ssrf_proxy/blob/master/LICENSE.md" target="_blank">
25
- <img src="https://img.shields.io/badge/license-MIT-brightgreen.svg"/>
25
+ <img alt="MIT License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg"/>
26
26
  </a>
27
27
 
28
+
28
29
  **SSRF Proxy** is a multi-threaded HTTP proxy server designed
29
30
  to tunnel client HTTP traffic through HTTP servers vulnerable
30
- to HTTP Server-Side Request Forgery (SSRF).
31
+ to Server-Side Request Forgery (SSRF).
31
32
 
32
33
  Once configured, SSRF Proxy attempts to format client HTTP
33
34
  requests appropriately for the vulnerable server. Likewise,
@@ -35,8 +36,8 @@ the server's response is parsed and formatted for the client.
35
36
 
36
37
  By correctly formatting the client request and stripping
37
38
  unwanted junk from the response it is possible to use
38
- SSRF Proxy as a HTTP proxy for web browsers and scanning
39
- tools such as sqlmap and nikto.
39
+ SSRF Proxy as a HTTP proxy for web browsers, proxychains,
40
+ and scanning tools such as sqlmap, nmap, dirb and nikto.
40
41
 
41
42
  SSRF Proxy also assists with leveraging blind SSRF
42
43
  vulnerabilities to perform time-based attacks, such
@@ -45,7 +46,11 @@ as blind time-based SQL injection with sqlmap.
45
46
  <table>
46
47
  <tr>
47
48
  <th>Version</th>
48
- <td>0.0.3</td>
49
+ <td>
50
+ <a href="https://github.com/bcoles/ssrf_proxy" target="_blank">
51
+ <img alt="Version 0.0.4" src="https://img.shields.io/badge/version-0.0.4-brightgreen.svg"/>
52
+ </a>
53
+ </td>
49
54
  </tr>
50
55
  <tr>
51
56
  <th>Github</th>
@@ -55,7 +60,9 @@ as blind time-based SQL injection with sqlmap.
55
60
  </tr>
56
61
  <tr>
57
62
  <th>Wiki</th>
58
- <td><a href="https://github.com/bcoles/ssrf_proxy/wiki">https://github.com/bcoles/ssrf_proxy/wiki</a></td>
63
+ <td>
64
+ <a href="https://github.com/bcoles/ssrf_proxy/wiki">https://github.com/bcoles/ssrf_proxy/wiki</a>
65
+ </td>
59
66
  </tr>
60
67
  <tr>
61
68
  <th>Documentation</th>
@@ -69,18 +76,22 @@ as blind time-based SQL injection with sqlmap.
69
76
  </tr>
70
77
  <tr>
71
78
  <th>Copyright</th>
72
- <td>2015-2016 Brendan Coles</td>
79
+ <td>2015-2017 Brendan Coles</td>
73
80
  </tr>
74
81
  <tr>
75
82
  <th>License</th>
76
- <td>MIT - (see <a href="https://github.com/bcoles/ssrf_proxy/blob/master/LICENSE.md">LICENSE.md</a> file)</td>
83
+ <td>
84
+ <a href="https://github.com/bcoles/ssrf_proxy/blob/master/LICENSE.md" target="_blank">
85
+ <img alt="MIT License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg"/>
86
+ </a>
87
+ </td>
77
88
  </tr>
78
89
  </table>
79
90
 
80
91
 
81
92
  ## Requirements
82
93
 
83
- Ruby 1.9.3 or newer
94
+ Ruby 2.2.2 or newer.
84
95
 
85
96
  Ruby Gems:
86
97
 
@@ -92,6 +103,7 @@ Ruby Gems:
92
103
  - base32
93
104
  - htmlentities
94
105
  - socksify
106
+ - mimemagic
95
107
 
96
108
  ## Installation
97
109
 
@@ -107,24 +119,34 @@ Example: ssrf-proxy -u http://target/?url=xxURLxx
107
119
  Options:
108
120
 
109
121
  -h, --help Help
122
+ --version Display version
123
+
124
+ Output options:
110
125
  -v, --verbose Verbose output
111
126
  -d, --debug Debugging output
127
+ --no-color Disable colored output
112
128
 
113
129
  Server options:
114
130
  -p, --port=PORT Listen port (Default: 8081)
115
131
  --interface=IP Listen interface (Default: 127.0.0.1)
116
132
 
117
133
  SSRF request options:
118
- -u, --url=URL SSRF URL with 'xxURLxx' placeholder
119
- --method=METHOD HTTP method (GET/HEAD/DELETE/POST/PUT)
134
+ -u, --url=URL Target URL vulnerable to SSRF.
135
+ -f, --file=FILE Load HTTP request from a file.
136
+ --placeholder=STR Placeholder indicating SSRF insertion point.
137
+ (Default: xxURLxx)
138
+ --method=METHOD HTTP method (GET/HEAD/DELETE/POST/PUT/OPTIONS)
120
139
  (Default: GET)
121
140
  --post-data=DATA HTTP post data
122
141
  --cookie=COOKIE HTTP cookies (separated by ';')
123
- --user-agent=AGENT HTTP user-agent (Default: Mozilla/5.0)
124
- --rules=RULES Rules for parsing client request for xxURLxx
142
+ --user=USER[:PASS] HTTP basic authentication credentials.
143
+ --user-agent=AGENT HTTP user-agent (Default: none)
144
+ --rules=RULES Rules for parsing client request
125
145
  (separated by ',') (Default: none)
146
+ --no-urlencode Do not URL encode client request
126
147
 
127
148
  SSRF connection options:
149
+ --ssl Connect using SSL/TLS.
128
150
  --proxy=PROXY Use a proxy to connect to the server.
129
151
  (Supported proxies: http, https, socks)
130
152
  --insecure Skip server SSL certificate validation.
@@ -136,83 +158,85 @@ Options:
136
158
  --strip=HEADERS Headers to remove from the response.
137
159
  (separated by ',') (Default: none)
138
160
  --decode-html Decode HTML entities in response body.
161
+ --unescape Unescape special characters in response body.
139
162
  --guess-status Replaces response status code and message
140
163
  headers (determined by common strings in the
141
164
  response body, such as 404 Not Found.)
142
165
  --guess-mime Replaces response content-type header with the
143
166
  appropriate mime type (determined by the file
144
167
  extension of the requested resource.)
145
- --ask-password Prompt for password on authentication failure.
146
- Adds a 'WWW-Authenticate' HTTP header to the
147
- response if the response code is 401.
168
+ --sniff-mime Replaces response content-type header with the
169
+ appropriate mime type (determined by magic bytes
170
+ in the response body.)
171
+ --timeout-ok Replaces timeout HTTP status code 504 with 200.
172
+ --detect-headers Replaces response headers if response headers
173
+ are identified in the response body.
174
+ --fail-no-content Return HTTP status 502 if the response body
175
+ is empty.
176
+ --cors Adds a 'Access-Control-Allow-Origin: *' header.
148
177
 
149
178
  Client request modification:
150
- --forward-cookies Forward client HTTP cookies through proxy to
151
- SSRF server.
152
- --cookies-to-uri Add client request cookies to URI query.
153
- --body-to-uri Add client request body to URI query.
179
+ --forward-method Forward client request method.
180
+ --forward-headers Forward all client request headers.
181
+ --forward-body Forward client request body.
182
+ --forward-cookies Forward client request cookies.
183
+ --cookies-to-uri Add client request cookies to URI query string.
184
+ --body-to-uri Add client request body to URI query string.
154
185
  --auth-to-uri Use client request basic authentication
155
186
  credentials in request URI.
156
187
  --ip-encoding=MODE Encode client request host IP address.
157
188
  (Modes: int, ipv6, oct, hex, dotted_hex)
158
-
189
+ --cache-buster Append a random value to the client request
190
+ query string.
159
191
 
160
192
  ```
161
193
 
162
194
 
163
195
  ## Usage (ruby)
164
196
 
165
- First, create a new SSRFProxy::HTTP object:
197
+ Load the ```ssrf_proxy``` library:
166
198
 
199
+ ```ruby
200
+ require 'ssrf_proxy'
167
201
  ```
168
- # SSRF URL with 'xxURLxx' placeholder
169
- url = 'http://example.local/index.php?url=xxURLxx'
170
- # options
171
- opts = {
172
- 'proxy' => '',
173
- 'method' => 'GET',
174
- 'post_data' => '',
175
- 'rules' => '',
176
- 'ip_encoding' => '',
177
- 'match' => "\\A(.+)\\z",
178
- 'strip' => '',
179
- 'decode_html' => false,
180
- 'guess_mime' => false,
181
- 'guess_status' => false,
182
- 'ask_password' => false,
183
- 'forward_cookies'=> false,
184
- 'body_to_uri' => false,
185
- 'auth_to_uri' => false,
186
- 'cookies_to_uri' => false,
187
- 'cookie' => '',
188
- 'timeout' => 10,
189
- 'user_agent' => 'Mozilla/5.0',
190
- 'insecure' => false
191
- }
192
- # create SSRFProxy::HTTP object
193
- ssrf = SSRFProxy::HTTP.new(url, opts)
194
- # set log level (optional)
195
- ssrf.logger.level = Logger::DEBUG
196
- ```
197
202
 
198
- Then send HTTP requests via the SSRF:
203
+ Initialize the `SSRFProxy::HTTP` object:
204
+
205
+ ```ruby
206
+ # Initialize with a URL containing 'xxURLxx' placeholder
207
+ ssrf = SSRFProxy::HTTP.new(url: 'http://example.local/?url=xxURLxx')
208
+
209
+ # Or, provide the placeholder elsewhere in the request
210
+ ssrf = SSRFProxy::HTTP.new(url: 'http://example.local/', method: 'POST', post_data: 'xxURLxx')
211
+
212
+ # Alternatively, the object can be initialized
213
+ # with a file containing a raw HTTP request:
214
+ ssrf = SSRFProxy::HTTP.new(file: 'ssrf.txt')
199
215
 
216
+ # Or, initialized with a StringIO object containing a raw HTTP request:
217
+ http = StringIO.new("GET http://example.local/?url=xxURLxx HTTP/1.1\n\n")
218
+ ssrf = SSRFProxy::HTTP.new(file: http)
200
219
  ```
201
- # fetch http://127.0.0.1/ via SSRF by String
202
- uri = 'http://127.0.0.1/'
203
- ssrf.send_uri(uri)
204
220
 
221
+ Refer to the documentation for additional configuration options.
205
222
 
206
- # fetch http://127.0.0.1/ via SSRF by URI
207
- uri = URI.parse('http://127.0.0.1/')
208
- ssrf.send_uri(uri)
223
+ Once initialized, the `SSRFProxy::HTTP` object can be used to send HTTP
224
+ requests via the SSRF using the ```send_uri``` and ```send_request``` methods.
209
225
 
226
+ ```ruby
227
+ # GET via SSRF
228
+ ssrf.send_uri('http://127.0.0.1/')
210
229
 
211
- # fetch http://127.0.0.1/ via SSRF using a raw HTTP request
212
- http = "GET http://127.0.0.1/ HTTP/1.1\n\n"
213
- ssrf.send_request(http)
230
+ # POST via SSRF
231
+ ssrf.send_uri('http://127.0.0.1/', method: 'POST', headers: {}, body: '')
232
+
233
+ # GET via SSRF (using a raw HTTP request)
234
+ ssrf.send_request("GET http://127.0.0.1/ HTTP/1.1\n\n")
214
235
  ```
215
236
 
237
+ Refer to the documentation for additional request options.
238
+
239
+
216
240
  ## Documentation
217
241
 
218
242
  Refer to the wiki for more information and example usage:
@@ -220,3 +244,4 @@ https://github.com/bcoles/ssrf_proxy/wiki
220
244
 
221
245
  Refer to RubyDoc for code documentation:
222
246
  http://www.rubydoc.info/github/bcoles/ssrf_proxy
247
+
@@ -1,24 +1,26 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (c) 2015-2016 Brendan Coles <bcoles@gmail.com>
3
+ # Copyright (c) 2015-2017 Brendan Coles <bcoles@gmail.com>
4
4
  # SSRF Proxy - https://github.com/bcoles/ssrf_proxy
5
5
  # See the file 'LICENSE.md' for copying permission
6
6
  #
7
7
 
8
8
  require 'irb'
9
9
  require 'irb/completion'
10
+ require 'ssrf_proxy'
10
11
 
11
12
  begin
12
- puts "\n_________________________________________________________\n"
13
- puts SSRFProxy::BANNER
13
+ puts "\n_________________________________________________________".blue
14
+ puts SSRFProxy::BANNER.blue
14
15
  puts "\n SSRF Proxy v#{SSRFProxy::VERSION}"
15
16
  puts " https://github.com/bcoles/ssrf_proxy\n"
16
- puts "\n_________________________________________________________\n\n"
17
+ puts "\n_________________________________________________________\n".blue
17
18
 
18
- puts "SSRFProxy[#{SSRFProxy::VERSION}], " \
19
- "Ruby[#{RUBY_VERSION}], " \
20
- "Platform[#{RUBY_PLATFORM}]"
19
+ puts "SSRFProxy[#{SSRFProxy::VERSION.yellow}], " \
20
+ "Ruby[#{RUBY_VERSION.yellow}], " \
21
+ "Platform[#{RUBY_PLATFORM.yellow}]"
22
+ puts
21
23
  rescue => e
22
- puts "Error: Could not load SSRFProxy: #{e.message}"
24
+ puts "Error: Could not load SSRF Proxy: #{e.message}"
23
25
  end
24
26
  IRB.start
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (c) 2015-2016 Brendan Coles <bcoles@gmail.com>
3
+ # Copyright (c) 2015-2017 Brendan Coles <bcoles@gmail.com>
4
4
  # SSRF Proxy - https://github.com/bcoles/ssrf_proxy
5
5
  # See the file 'LICENSE.md' for copying permission
6
6
  #
@@ -22,29 +22,40 @@ end
22
22
  # @note output usage
23
23
  #
24
24
  def usage
25
+ banner
25
26
  puts 'Usage: ssrf-proxy [options] -u <SSRF URL>'
26
27
  puts 'Example: ssrf-proxy -u http://target/?url=xxURLxx'
27
28
  puts 'Options:'
28
29
  puts "
29
30
  -h, --help Help
31
+ --version Display version
32
+
33
+ Output options:
30
34
  -v, --verbose Verbose output
31
35
  -d, --debug Debugging output
36
+ --no-color Disable colored output
32
37
 
33
38
  Server options:
34
39
  -p, --port=PORT Listen port (Default: 8081)
35
40
  --interface=IP Listen interface (Default: 127.0.0.1)
36
41
 
37
42
  SSRF request options:
38
- -u, --url=URL SSRF URL with 'xxURLxx' placeholder
39
- --method=METHOD HTTP method (GET/HEAD/DELETE/POST/PUT)
43
+ -u, --url=URL Target URL vulnerable to SSRF.
44
+ -f, --file=FILE Load HTTP request from a file.
45
+ --placeholder=STR Placeholder indicating SSRF insertion point.
46
+ (Default: xxURLxx)
47
+ --method=METHOD HTTP method (GET/HEAD/DELETE/POST/PUT/OPTIONS)
40
48
  (Default: GET)
41
49
  --post-data=DATA HTTP post data
42
50
  --cookie=COOKIE HTTP cookies (separated by ';')
43
- --user-agent=AGENT HTTP user-agent (Default: Mozilla/5.0)
44
- --rules=RULES Rules for parsing client request for xxURLxx
51
+ --user=USER[:PASS] HTTP basic authentication credentials.
52
+ --user-agent=AGENT HTTP user-agent (Default: none)
53
+ --rules=RULES Rules for parsing client request
45
54
  (separated by ',') (Default: none)
55
+ --no-urlencode Do not URL encode client request
46
56
 
47
57
  SSRF connection options:
58
+ --ssl Connect using SSL/TLS.
48
59
  --proxy=PROXY Use a proxy to connect to the server.
49
60
  (Supported proxies: http, https, socks)
50
61
  --insecure Skip server SSL certificate validation.
@@ -56,25 +67,36 @@ def usage
56
67
  --strip=HEADERS Headers to remove from the response.
57
68
  (separated by ',') (Default: none)
58
69
  --decode-html Decode HTML entities in response body.
70
+ --unescape Unescape special characters in response body.
59
71
  --guess-status Replaces response status code and message
60
72
  headers (determined by common strings in the
61
73
  response body, such as 404 Not Found.)
62
74
  --guess-mime Replaces response content-type header with the
63
75
  appropriate mime type (determined by the file
64
76
  extension of the requested resource.)
65
- --ask-password Prompt for password on authentication failure.
66
- Adds a 'WWW-Authenticate' HTTP header to the
67
- response if the response code is 401.
77
+ --sniff-mime Replaces response content-type header with the
78
+ appropriate mime type (determined by magic bytes
79
+ in the response body.)
80
+ --timeout-ok Replaces timeout HTTP status code 504 with 200.
81
+ --detect-headers Replaces response headers if response headers
82
+ are identified in the response body.
83
+ --fail-no-content Return HTTP status 502 if the response body
84
+ is empty.
85
+ --cors Adds a 'Access-Control-Allow-Origin: *' header.
68
86
 
69
87
  Client request modification:
70
- --forward-cookies Forward client HTTP cookies through proxy to
71
- SSRF server.
72
- --cookies-to-uri Add client request cookies to URI query.
73
- --body-to-uri Add client request body to URI query.
88
+ --forward-method Forward client request method.
89
+ --forward-headers Forward all client request headers.
90
+ --forward-body Forward client request body.
91
+ --forward-cookies Forward client request cookies.
92
+ --cookies-to-uri Add client request cookies to URI query string.
93
+ --body-to-uri Add client request body to URI query string.
74
94
  --auth-to-uri Use client request basic authentication
75
95
  credentials in request URI.
76
96
  --ip-encoding=MODE Encode client request host IP address.
77
97
  (Modes: int, ipv6, oct, hex, dotted_hex)
98
+ --cache-buster Append a random value to the client request
99
+ query string.
78
100
 
79
101
  "
80
102
  exit 1
@@ -87,34 +109,52 @@ def start_server
87
109
  # get args
88
110
  opts = GetoptLong.new(
89
111
  ['-h', '--help', GetoptLong::NO_ARGUMENT],
112
+ ['--version', GetoptLong::NO_ARGUMENT],
113
+
90
114
  ['-v', '--verbose', GetoptLong::NO_ARGUMENT],
91
115
  ['-d', '--debug', GetoptLong::NO_ARGUMENT],
116
+ ['--no-color', GetoptLong::NO_ARGUMENT],
92
117
 
93
118
  ['-p', '--port', GetoptLong::REQUIRED_ARGUMENT],
94
119
  ['--interface', GetoptLong::REQUIRED_ARGUMENT],
95
- ['--proxy', GetoptLong::REQUIRED_ARGUMENT],
96
120
 
97
121
  ['-u', '--url', GetoptLong::REQUIRED_ARGUMENT],
122
+ ['-f', '--file', GetoptLong::REQUIRED_ARGUMENT],
123
+ ['--placeholder', GetoptLong::REQUIRED_ARGUMENT],
98
124
  ['--method', GetoptLong::REQUIRED_ARGUMENT],
99
125
  ['--post-data', GetoptLong::REQUIRED_ARGUMENT],
100
126
  ['--cookie', GetoptLong::REQUIRED_ARGUMENT],
127
+ ['--user', GetoptLong::REQUIRED_ARGUMENT],
101
128
  ['--user-agent', GetoptLong::REQUIRED_ARGUMENT],
129
+
130
+ ['--ssl', GetoptLong::NO_ARGUMENT],
131
+ ['--proxy', GetoptLong::REQUIRED_ARGUMENT],
102
132
  ['--insecure', GetoptLong::NO_ARGUMENT],
103
133
  ['--timeout', GetoptLong::REQUIRED_ARGUMENT],
104
134
 
105
- ['--ip-encoding', GetoptLong::REQUIRED_ARGUMENT],
106
135
  ['--rules', GetoptLong::REQUIRED_ARGUMENT],
136
+ ['--no-urlencode', GetoptLong::NO_ARGUMENT],
137
+ ['--forward-method', GetoptLong::NO_ARGUMENT],
138
+ ['--forward-headers', GetoptLong::NO_ARGUMENT],
139
+ ['--forward-body', GetoptLong::NO_ARGUMENT],
107
140
  ['--forward-cookies', GetoptLong::NO_ARGUMENT],
141
+ ['--cookies-to-uri', GetoptLong::NO_ARGUMENT],
108
142
  ['--body-to-uri', GetoptLong::NO_ARGUMENT],
109
143
  ['--auth-to-uri', GetoptLong::NO_ARGUMENT],
110
- ['--cookies-to-uri', GetoptLong::NO_ARGUMENT],
144
+ ['--cache-buster', GetoptLong::NO_ARGUMENT],
145
+ ['--ip-encoding', GetoptLong::REQUIRED_ARGUMENT],
111
146
 
112
147
  ['--match', GetoptLong::REQUIRED_ARGUMENT],
113
148
  ['--strip', GetoptLong::REQUIRED_ARGUMENT],
114
149
  ['--decode-html', GetoptLong::NO_ARGUMENT],
150
+ ['--unescape', GetoptLong::NO_ARGUMENT],
115
151
  ['--guess-status', GetoptLong::NO_ARGUMENT],
116
152
  ['--guess-mime', GetoptLong::NO_ARGUMENT],
117
- ['--ask-password', GetoptLong::NO_ARGUMENT]
153
+ ['--sniff-mime', GetoptLong::NO_ARGUMENT],
154
+ ['--cors', GetoptLong::NO_ARGUMENT],
155
+ ['--detect-headers', GetoptLong::NO_ARGUMENT],
156
+ ['--fail-no-content', GetoptLong::NO_ARGUMENT],
157
+ ['--timeout-ok', GetoptLong::NO_ARGUMENT]
118
158
  )
119
159
 
120
160
  # local proxy server defaults
@@ -123,114 +163,188 @@ def start_server
123
163
 
124
164
  # ssrf defaults
125
165
  url = nil
126
- rules = ''
127
- ip_encoding = ''
166
+ file = nil
167
+ rules = nil
168
+ ip_encoding = nil
169
+ placeholder = 'xxURLxx'
128
170
  method = 'GET'
129
- post_data = ''
171
+ post_data = nil
130
172
  match = '\\A(.*)\\z'
131
- strip = ''
173
+ strip = nil
174
+ no_urlencode = false
132
175
  decode_html = false
176
+ unescape = false
133
177
  guess_status = false
134
178
  guess_mime = false
135
- ask_password = false
179
+ sniff_mime = false
180
+ cors = false
181
+ timeout_ok = false
182
+ detect_headers = false
183
+ fail_no_content = false
184
+ forward_method = false
185
+ forward_headers = false
186
+ forward_body = false
136
187
  forward_cookies = false
137
188
  body_to_uri = false
138
189
  auth_to_uri = false
139
190
  cookies_to_uri = false
191
+ cache_buster = false
140
192
 
141
193
  # http connection defaults
142
- cookie = ''
194
+ cookie = nil
195
+ user = nil
143
196
  timeout = 10
197
+ ssl = false
144
198
  upstream_proxy = nil
145
- user_agent = 'Mozilla/5.0'
199
+ user_agent = nil
146
200
  insecure = false
147
201
 
148
202
  # logging
149
203
  log_level = ::Logger::WARN
150
204
 
151
205
  # handle args
152
- opts.each do |opt, arg|
153
- case opt
154
- when '-p', '--port'
155
- port = arg
156
- when '--interface'
157
- interface = arg
158
- when '-u', '--url'
159
- url = arg
160
- when '--ip-encoding'
161
- ip_encoding = arg
162
- when '--rules'
163
- rules = arg
164
- when '--proxy'
165
- upstream_proxy = URI.parse(arg)
166
- when '--cookie'
167
- cookie = arg
168
- when '--timeout'
169
- timeout = arg.to_i
170
- when '--user-agent'
171
- user_agent = arg
172
- when '--insecure'
173
- insecure = true
174
- when '--method'
175
- method = arg
176
- when '--post-data'
177
- post_data = arg
178
- when '--match'
179
- match = arg
180
- when '--strip'
181
- strip = arg
182
- when '--decode-html'
183
- decode_html = true
184
- when '--guess-status'
185
- guess_status = true
186
- when '--guess-mime'
187
- guess_mime = true
188
- when '--ask-password'
189
- ask_password = true
190
- when '--forward-cookies'
191
- forward_cookies = true
192
- when '--body-to-uri'
193
- body_to_uri = true
194
- when '--auth-to-uri'
195
- auth_to_uri = true
196
- when '--cookies-to-uri'
197
- cookies_to_uri = true
198
- when '-h', '--help'
199
- usage
200
- when '-v', '--verbose'
201
- log_level = ::Logger::INFO unless log_level == ::Logger::DEBUG
202
- when '-d', '--debug'
203
- log_level = ::Logger::DEBUG
206
+ begin
207
+ opts.each do |opt, arg|
208
+ case opt
209
+ when '-p', '--port'
210
+ port = arg
211
+ when '--interface'
212
+ interface = arg
213
+ when '-u', '--url'
214
+ url = arg
215
+ when '-f', '--file'
216
+ file = arg
217
+ when '--ip-encoding'
218
+ ip_encoding = arg
219
+ when '--rules'
220
+ rules = arg
221
+ when '--no-urlencode'
222
+ no_urlencode = true
223
+ when '--ssl'
224
+ ssl = true
225
+ when '--proxy'
226
+ upstream_proxy = URI.parse(arg)
227
+ when '--cookie'
228
+ cookie = arg
229
+ when '--user'
230
+ user = arg
231
+ when '--timeout'
232
+ timeout = arg.to_i
233
+ when '--user-agent'
234
+ user_agent = arg
235
+ when '--insecure'
236
+ insecure = true
237
+ when '--placeholder'
238
+ placeholder = arg
239
+ when '--method'
240
+ method = arg
241
+ when '--post-data'
242
+ post_data = arg
243
+ when '--match'
244
+ match = arg
245
+ when '--strip'
246
+ strip = arg
247
+ when '--decode-html'
248
+ decode_html = true
249
+ when '--unescape'
250
+ unescape = true
251
+ when '--guess-status'
252
+ guess_status = true
253
+ when '--guess-mime'
254
+ guess_mime = true
255
+ when '--sniff-mime'
256
+ sniff_mime = true
257
+ when '--cors'
258
+ cors = true
259
+ when '--timeout-ok'
260
+ timeout_ok = true
261
+ when '--detect-headers'
262
+ detect_headers = true
263
+ when '--fail-no-content'
264
+ fail_no_content = true
265
+ when '--forward-method'
266
+ forward_method = true
267
+ when '--forward-headers'
268
+ forward_headers = true
269
+ when '--forward-body'
270
+ forward_body = true
271
+ when '--forward-cookies'
272
+ forward_cookies = true
273
+ when '--body-to-uri'
274
+ body_to_uri = true
275
+ when '--auth-to-uri'
276
+ auth_to_uri = true
277
+ when '--cookies-to-uri'
278
+ cookies_to_uri = true
279
+ when '--cache-buster'
280
+ cache_buster = true
281
+ when '-h', '--help'
282
+ usage
283
+ when '-v', '--verbose'
284
+ log_level = ::Logger::INFO unless log_level == ::Logger::DEBUG
285
+ when '-d', '--debug'
286
+ log_level = ::Logger::DEBUG
287
+ when '--no-color'
288
+ String.disable_colorization = true
289
+ when '--version'
290
+ puts "SSRF Proxy v#{SSRFProxy::VERSION}"
291
+ exit
292
+ end
204
293
  end
294
+ rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument
295
+ puts "Error: Invalid usage. Try '#{$PROGRAM_NAME} --help' for usage information."
296
+ exit 1
205
297
  end
206
298
 
207
299
  opts = {
208
- 'proxy' => upstream_proxy.to_s,
209
- 'method' => method.to_s,
210
- 'post_data' => post_data.to_s,
211
- 'rules' => rules.to_s,
212
- 'ip_encoding' => ip_encoding.to_s,
213
- 'match' => match.to_s,
214
- 'strip' => strip.to_s,
215
- 'decode_html' => decode_html,
216
- 'guess_mime' => guess_mime,
217
- 'guess_status' => guess_status,
218
- 'ask_password' => ask_password,
219
- 'forward_cookies' => forward_cookies,
220
- 'body_to_uri' => body_to_uri,
221
- 'auth_to_uri' => auth_to_uri,
222
- 'cookies_to_uri' => cookies_to_uri,
223
- 'cookie' => cookie.to_s,
224
- 'timeout' => timeout.to_s,
225
- 'user_agent' => user_agent.to_s,
226
- 'insecure' => insecure.to_s
300
+ url: url,
301
+ file: file,
302
+ proxy: upstream_proxy,
303
+ ssl: ssl,
304
+ method: method,
305
+ placeholder: placeholder,
306
+ post_data: post_data,
307
+ rules: rules,
308
+ no_urlencode: no_urlencode,
309
+ ip_encoding: ip_encoding,
310
+ match: match,
311
+ strip: strip,
312
+ decode_html: decode_html,
313
+ unescape: unescape,
314
+ guess_mime: guess_mime,
315
+ sniff_mime: sniff_mime,
316
+ guess_status: guess_status,
317
+ cors: cors,
318
+ timeout_ok: timeout_ok,
319
+ detect_headers: detect_headers,
320
+ fail_no_content: fail_no_content,
321
+ forward_method: forward_method,
322
+ forward_headers: forward_headers,
323
+ forward_body: forward_body,
324
+ forward_cookies: forward_cookies,
325
+ body_to_uri: body_to_uri,
326
+ auth_to_uri: auth_to_uri,
327
+ cookies_to_uri: cookies_to_uri,
328
+ cache_buster: cache_buster,
329
+ cookie: cookie,
330
+ user: user,
331
+ timeout: timeout,
332
+ user_agent: user_agent,
333
+ insecure: insecure
227
334
  }
228
335
 
229
- # setup ssrf
230
- ssrf = SSRFProxy::HTTP.new(url, opts)
231
- ssrf.logger.level = log_level
232
- # start server
233
336
  begin
337
+ banner
338
+
339
+ %w[INT QUIT TERM].each do |s|
340
+ Signal.trap(s) { exit }
341
+ end
342
+
343
+ # setup ssrf
344
+ ssrf = SSRFProxy::HTTP.new(opts)
345
+ ssrf.logger.level = log_level
346
+
347
+ # start server
234
348
  ssrf_proxy = SSRFProxy::Server.new(ssrf, interface, port)
235
349
  ssrf_proxy.logger.level = log_level
236
350
  ssrf_proxy.serve
@@ -239,6 +353,5 @@ def start_server
239
353
  end
240
354
  end
241
355
 
242
- banner
243
356
  usage if ARGV.empty?
244
357
  start_server