ssrf_proxy 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/ssrf-proxy CHANGED
@@ -1,40 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (c) 2015 Brendan Coles <bcoles@gmail.com>
3
+ # Copyright (c) 2015-2016 Brendan Coles <bcoles@gmail.com>
4
4
  # SSRF Proxy - https://github.com/bcoles/ssrf_proxy
5
- # See the file 'LICENSE' for copying permission
5
+ # See the file 'LICENSE.md' for copying permission
6
6
  #
7
7
 
8
- require 'getoptlong'
9
8
  require 'ssrf_proxy'
10
9
 
11
10
  #
12
11
  # @note output banner
13
12
  #
14
13
  def banner
15
- puts "
16
- _______________________________________________
17
- ___
18
- ___ ___ ___| _| ___ ___ ___ _ _ _ _
19
- |_ -|_ -| _| _| | . | _| . |_'_| | |
20
- |___|___|_| |_| | _|_| |___|_,_|_ |
21
- |_| |___| ".blue
22
- puts "
23
- SSRF Proxy v0.0.2
24
- https://github.com/bcoles/ssrf_proxy"
25
- puts "
26
- _______________________________________________
27
- ".blue
14
+ puts "\n_________________________________________________________".blue
15
+ puts SSRFProxy::BANNER.blue
16
+ puts "\n SSRF Proxy v#{SSRFProxy::VERSION}"
17
+ puts " https://github.com/bcoles/ssrf_proxy\n"
18
+ puts "\n_________________________________________________________\n".blue
28
19
  end
29
20
 
30
21
  #
31
22
  # @note output usage
32
23
  #
33
24
  def usage
34
-
35
- puts "Usage: ssrf-proxy [options] -u <SSRF URL>"
36
- puts "Example: ssrf-proxy -u http://target/?url=xxURLxx"
37
- puts "Options:"
25
+ puts 'Usage: ssrf-proxy [options] -u <SSRF URL>'
26
+ puts 'Example: ssrf-proxy -u http://target/?url=xxURLxx'
27
+ puts 'Options:'
38
28
  puts "
39
29
  -h, --help Help
40
30
  -v, --verbose Verbose output
@@ -43,38 +33,48 @@ def usage
43
33
  Server options:
44
34
  -p, --port=PORT Listen port (Default: 8081)
45
35
  --interface=IP Listen interface (Default: 127.0.0.1)
46
- --proxy=PROXY Upstream HTTP proxy
47
36
 
48
37
  SSRF request options:
49
38
  -u, --url=URL SSRF URL with 'xxURLxx' placeholder
50
- --method=METHOD HTTP method (GET/POST/HEAD) (Default: GET)
39
+ --method=METHOD HTTP method (GET/HEAD/DELETE/POST/PUT)
40
+ (Default: GET)
51
41
  --post-data=DATA HTTP post data
52
42
  --cookie=COOKIE HTTP cookies (separated by ';')
53
43
  --user-agent=AGENT HTTP user-agent (Default: Mozilla/5.0)
54
- --timeout=SECONDS Connection timeout in seconds (Default: 10)
55
- --ip-encoding=MODE Encode IP address for blacklist evasion.
56
- (Modes: int, ipv6, oct, hex) (Default: none)
57
44
  --rules=RULES Rules for parsing client request for xxURLxx
58
45
  (separated by ',') (Default: none)
59
46
 
47
+ SSRF connection options:
48
+ --proxy=PROXY Use a proxy to connect to the server.
49
+ (Supported proxies: http, https, socks)
50
+ --insecure Skip server SSL certificate validation.
51
+ --timeout=SECONDS Connection timeout in seconds (Default: 10)
52
+
60
53
  HTTP response modification:
61
54
  --match=REGEX Regex to match response body content.
62
- (Default: \\A(.+)\\z)
55
+ (Default: \\A(.*)\\z)
63
56
  --strip=HEADERS Headers to remove from the response.
64
57
  (separated by ',') (Default: none)
58
+ --decode-html Decode HTML entities in response body.
65
59
  --guess-status Replaces response status code and message
66
60
  headers (determined by common strings in the
67
61
  response body, such as 404 Not Found.)
68
62
  --guess-mime Replaces response content-type header with the
69
63
  appropriate mime type (determined by the file
70
64
  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.
71
68
 
72
69
  Client request modification:
73
70
  --forward-cookies Forward client HTTP cookies through proxy to
74
71
  SSRF server.
75
- --body-to-uri Convert POST parameters to GET parameters.
76
- --auth-to-uri Move HTTP basic authentication credentials
77
- to URI. (Example: http://[user:pass]@host/)
72
+ --cookies-to-uri Add client request cookies to URI query.
73
+ --body-to-uri Add client request body to URI query.
74
+ --auth-to-uri Use client request basic authentication
75
+ credentials in request URI.
76
+ --ip-encoding=MODE Encode client request host IP address.
77
+ (Modes: int, ipv6, oct, hex, dotted_hex)
78
78
 
79
79
  "
80
80
  exit 1
@@ -84,144 +84,161 @@ end
84
84
  # @note parse options and start server
85
85
  #
86
86
  def start_server
87
-
88
- # get args
89
- opts = GetoptLong.new(
90
- [ '-h', '--help', GetoptLong::NO_ARGUMENT ],
91
- [ '-v', '--verbose', GetoptLong::NO_ARGUMENT ],
92
- [ '-d', '--debug', GetoptLong::NO_ARGUMENT ],
93
-
94
- [ '-p', '--port', GetoptLong::REQUIRED_ARGUMENT ],
95
- [ '--interface', GetoptLong::REQUIRED_ARGUMENT ],
96
- [ '--proxy', GetoptLong::REQUIRED_ARGUMENT ],
97
-
98
- [ '-u', '--url', GetoptLong::REQUIRED_ARGUMENT ],
99
- [ '--method', GetoptLong::REQUIRED_ARGUMENT ],
100
- [ '--post-data', GetoptLong::REQUIRED_ARGUMENT ],
101
- [ '--cookie', GetoptLong::REQUIRED_ARGUMENT ],
102
- [ '--user-agent', GetoptLong::REQUIRED_ARGUMENT ],
103
- [ '--timeout', GetoptLong::REQUIRED_ARGUMENT ],
104
-
105
- [ '--ip-encoding', GetoptLong::REQUIRED_ARGUMENT ],
106
- [ '--rules', GetoptLong::REQUIRED_ARGUMENT ],
107
- [ '--forward-cookies', GetoptLong::NO_ARGUMENT ],
108
- [ '--body-to-uri', GetoptLong::NO_ARGUMENT ],
109
- [ '--auth-to-uri', GetoptLong::NO_ARGUMENT ],
110
-
111
- [ '--match', GetoptLong::REQUIRED_ARGUMENT ],
112
- [ '--strip', GetoptLong::REQUIRED_ARGUMENT ],
113
- [ '--guess-status', GetoptLong::NO_ARGUMENT ],
114
- [ '--guess-mime', GetoptLong::NO_ARGUMENT ]
115
- )
116
-
117
- # local proxy server defaults
118
- interface = '127.0.0.1'
119
- port = 8081
120
-
121
- # ssrf defaults
122
- url = nil
123
- rules = ''
124
- ip_encoding = ''
125
- method = 'GET'
126
- post_data = ''
127
- match = "\\A(.+)\\z"
128
- strip = ''
129
- guess_status = false
130
- guess_mime = false
131
- forward_cookies = false
132
- body_to_uri = false
133
- auth_to_uri = false
134
-
135
- # http connection defaults
136
- cookie = ''
137
- timeout = 10
138
- upstream_proxy = nil
139
- user_agent = 'Mozilla/5.0'
140
-
141
- # logging
142
- log_level = ::Logger::WARN
143
-
144
- # handle args
145
- opts.each do |opt, arg|
146
- case opt
147
- when '-p','--port'
148
- port=arg
149
- when '--interface'
150
- interface=arg
151
- when '-u','--url'
152
- url = arg
153
- when '--ip-encoding'
154
- ip_encoding=arg
155
- when '--rules'
156
- rules=arg
157
- when '--proxy'
158
- upstream_proxy = URI::parse(arg)
159
- when '--cookie'
160
- cookie=arg
161
- when '--timeout'
162
- timeout=arg.to_i
163
- when '--user-agent'
164
- user_agent=arg
165
- when '--method'
166
- method=arg
167
- when '--post-data'
168
- post_data=arg
169
- when '--match'
170
- match=arg
171
- when '--strip'
172
- strip=arg
173
- when '--guess-status'
174
- guess_status = true
175
- when '--guess-mime'
176
- guess_mime = true
177
- when '--forward-cookies'
178
- forward_cookies = true
179
- when '--body-to-uri'
180
- body_to_uri = true
181
- when '--auth-to-uri'
182
- auth_to_uri = true
183
- when '-h','--help'
184
- usage
185
- when '-v','--verbose'
186
- log_level = ::Logger::INFO unless log_level == ::Logger::DEBUG
187
- when '-d','--debug'
188
- log_level = ::Logger::DEBUG
87
+ # get args
88
+ opts = GetoptLong.new(
89
+ ['-h', '--help', GetoptLong::NO_ARGUMENT],
90
+ ['-v', '--verbose', GetoptLong::NO_ARGUMENT],
91
+ ['-d', '--debug', GetoptLong::NO_ARGUMENT],
92
+
93
+ ['-p', '--port', GetoptLong::REQUIRED_ARGUMENT],
94
+ ['--interface', GetoptLong::REQUIRED_ARGUMENT],
95
+ ['--proxy', GetoptLong::REQUIRED_ARGUMENT],
96
+
97
+ ['-u', '--url', GetoptLong::REQUIRED_ARGUMENT],
98
+ ['--method', GetoptLong::REQUIRED_ARGUMENT],
99
+ ['--post-data', GetoptLong::REQUIRED_ARGUMENT],
100
+ ['--cookie', GetoptLong::REQUIRED_ARGUMENT],
101
+ ['--user-agent', GetoptLong::REQUIRED_ARGUMENT],
102
+ ['--insecure', GetoptLong::NO_ARGUMENT],
103
+ ['--timeout', GetoptLong::REQUIRED_ARGUMENT],
104
+
105
+ ['--ip-encoding', GetoptLong::REQUIRED_ARGUMENT],
106
+ ['--rules', GetoptLong::REQUIRED_ARGUMENT],
107
+ ['--forward-cookies', GetoptLong::NO_ARGUMENT],
108
+ ['--body-to-uri', GetoptLong::NO_ARGUMENT],
109
+ ['--auth-to-uri', GetoptLong::NO_ARGUMENT],
110
+ ['--cookies-to-uri', GetoptLong::NO_ARGUMENT],
111
+
112
+ ['--match', GetoptLong::REQUIRED_ARGUMENT],
113
+ ['--strip', GetoptLong::REQUIRED_ARGUMENT],
114
+ ['--decode-html', GetoptLong::NO_ARGUMENT],
115
+ ['--guess-status', GetoptLong::NO_ARGUMENT],
116
+ ['--guess-mime', GetoptLong::NO_ARGUMENT],
117
+ ['--ask-password', GetoptLong::NO_ARGUMENT]
118
+ )
119
+
120
+ # local proxy server defaults
121
+ interface = '127.0.0.1'
122
+ port = 8081
123
+
124
+ # ssrf defaults
125
+ url = nil
126
+ rules = ''
127
+ ip_encoding = ''
128
+ method = 'GET'
129
+ post_data = ''
130
+ match = '\\A(.*)\\z'
131
+ strip = ''
132
+ decode_html = false
133
+ guess_status = false
134
+ guess_mime = false
135
+ ask_password = false
136
+ forward_cookies = false
137
+ body_to_uri = false
138
+ auth_to_uri = false
139
+ cookies_to_uri = false
140
+
141
+ # http connection defaults
142
+ cookie = ''
143
+ timeout = 10
144
+ upstream_proxy = nil
145
+ user_agent = 'Mozilla/5.0'
146
+ insecure = false
147
+
148
+ # logging
149
+ log_level = ::Logger::WARN
150
+
151
+ # 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
204
+ end
189
205
  end
190
- end
191
206
 
192
- opts = {
193
- 'proxy' => "#{upstream_proxy}",
194
- 'method' => "#{method}",
195
- 'post_data' => "#{post_data}",
196
- 'rules' => "#{rules}",
197
- 'ip_encoding' => "#{ip_encoding}",
198
- 'match' => "#{match}",
199
- 'strip' => "#{strip}",
200
- 'guess_mime' => guess_mime,
201
- 'guess_status' => guess_status,
202
- 'forward_cookies'=> forward_cookies,
203
- 'body_to_uri' => body_to_uri,
204
- 'auth_to_uri' => auth_to_uri,
205
- 'cookie' => "#{cookie}",
206
- 'timeout' => "#{timeout}",
207
- 'user_agent' => "#{user_agent}"
208
- }
207
+ 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
227
+ }
209
228
 
210
229
  # setup ssrf
211
230
  ssrf = SSRFProxy::HTTP.new(url, opts)
212
231
  ssrf.logger.level = log_level
213
232
  # start server
214
233
  begin
215
- ssrf_proxy = SSRFProxy::Server.new(interface, port, ssrf)
234
+ ssrf_proxy = SSRFProxy::Server.new(ssrf, interface, port)
216
235
  ssrf_proxy.logger.level = log_level
217
236
  ssrf_proxy.serve
218
237
  rescue => e
219
238
  puts "Error: #{e.message}"
220
239
  end
221
-
222
240
  end
223
241
 
224
242
  banner
225
- usage if ARGV.length == 0
243
+ usage if ARGV.empty?
226
244
  start_server
227
-