ronin-web 0.2.1 → 0.3.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/.document +4 -0
  2. data/.gemtest +0 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -0
  5. data/COPYING.txt +674 -0
  6. data/{History.txt → ChangeLog.md} +39 -8
  7. data/Gemfile +49 -0
  8. data/{README.txt → README.md} +56 -40
  9. data/Rakefile +25 -24
  10. data/bin/ronin-web +18 -5
  11. data/gemspec.yml +30 -0
  12. data/lib/ronin/network/{helpers → mixins}/web.rb +74 -39
  13. data/lib/ronin/web.rb +7 -6
  14. data/lib/ronin/web/extensions.rb +7 -6
  15. data/lib/ronin/web/extensions/nokogiri.rb +22 -0
  16. data/lib/ronin/web/extensions/nokogiri/xml.rb +22 -0
  17. data/lib/ronin/web/extensions/nokogiri/xml/attr.rb +35 -1
  18. data/lib/ronin/web/extensions/nokogiri/xml/document.rb +34 -4
  19. data/lib/ronin/web/extensions/nokogiri/xml/element.rb +36 -2
  20. data/lib/ronin/web/extensions/nokogiri/xml/node.rb +59 -20
  21. data/lib/ronin/web/extensions/nokogiri/xml/text.rb +36 -2
  22. data/lib/ronin/web/middleware.rb +27 -0
  23. data/lib/ronin/web/middleware/base.rb +144 -0
  24. data/lib/ronin/web/middleware/directories.rb +177 -0
  25. data/lib/ronin/web/middleware/files.rb +142 -0
  26. data/lib/ronin/web/middleware/filters.rb +28 -0
  27. data/lib/ronin/web/middleware/filters/campaign_filter.rb +77 -0
  28. data/lib/ronin/web/middleware/filters/ip_filter.rb +73 -0
  29. data/lib/ronin/web/middleware/filters/path_filter.rb +73 -0
  30. data/lib/ronin/web/middleware/filters/referer_filter.rb +71 -0
  31. data/lib/ronin/web/middleware/filters/user_agent_filter.rb +71 -0
  32. data/lib/ronin/web/middleware/filters/vhost_filter.rb +71 -0
  33. data/lib/ronin/web/middleware/helpers.rb +145 -0
  34. data/lib/ronin/web/middleware/proxy.rb +265 -0
  35. data/lib/ronin/web/middleware/proxy_request.rb +262 -0
  36. data/lib/ronin/web/middleware/request.rb +58 -0
  37. data/lib/ronin/web/middleware/response.rb +33 -0
  38. data/lib/ronin/web/middleware/router.rb +167 -0
  39. data/lib/ronin/web/middleware/rule.rb +103 -0
  40. data/lib/ronin/web/proxy.rb +7 -6
  41. data/lib/ronin/web/proxy/app.rb +7 -6
  42. data/lib/ronin/web/proxy/base.rb +14 -9
  43. data/lib/ronin/web/proxy/web.rb +9 -6
  44. data/lib/ronin/web/server.rb +7 -6
  45. data/lib/ronin/web/server/app.rb +7 -6
  46. data/lib/ronin/web/server/base.rb +209 -82
  47. data/lib/ronin/web/server/web.rb +10 -6
  48. data/lib/ronin/web/spider.rb +38 -26
  49. data/lib/ronin/web/version.rb +8 -7
  50. data/lib/ronin/web/web.rb +122 -80
  51. data/ronin-web.gemspec +15 -0
  52. data/spec/helpers/output.rb +3 -0
  53. data/spec/spec_helper.rb +2 -3
  54. data/spec/web/extensions/nokogiri_spec.rb +7 -7
  55. data/spec/web/{server/helpers/server.rb → helpers/rack_app.rb} +3 -14
  56. data/spec/web/helpers/root.rb +15 -0
  57. data/spec/web/helpers/root/test1.txt +1 -0
  58. data/spec/web/helpers/root/test1/index.html +1 -0
  59. data/spec/web/helpers/root/test1/test1.txt +1 -0
  60. data/spec/web/helpers/root/test2.txt +1 -0
  61. data/spec/web/helpers/root/test2/test2.txt +1 -0
  62. data/spec/web/helpers/root/test3.txt +1 -0
  63. data/spec/web/helpers/root/test3/test3.txt +1 -0
  64. data/spec/web/middleware/directories_spec.rb +86 -0
  65. data/spec/web/middleware/files_spec.rb +57 -0
  66. data/spec/web/middleware/filters/campaign_filter_spec.rb +30 -0
  67. data/spec/web/middleware/filters/ip_filter_spec.rb +25 -0
  68. data/spec/web/middleware/filters/path_filter_spec.rb +29 -0
  69. data/spec/web/middleware/filters/referer_filter_spec.rb +25 -0
  70. data/spec/web/middleware/filters/user_agent_filter_spec.rb +25 -0
  71. data/spec/web/middleware/filters/vhost_filter_spec.rb +23 -0
  72. data/spec/web/middleware/proxy_spec.rb +67 -0
  73. data/spec/web/middleware/response_spec.rb +20 -0
  74. data/spec/web/middleware/router_spec.rb +65 -0
  75. data/spec/web/middleware/rule_spec.rb +37 -0
  76. data/spec/web/proxy/base_spec.rb +1 -2
  77. data/spec/web/server/base_spec.rb +4 -13
  78. data/spec/web/server/classes/sub_app.rb +2 -2
  79. data/spec/web/server/classes/test_app.rb +1 -1
  80. data/spec/web/web_spec.rb +57 -67
  81. metadata +171 -146
  82. data.tar.gz.sig +0 -0
  83. data/Manifest.txt +0 -64
  84. data/lib/ronin/scanners/web.rb +0 -52
  85. data/lib/ronin/web/server/files.rb +0 -92
  86. data/lib/ronin/web/server/helpers.rb +0 -25
  87. data/lib/ronin/web/server/helpers/files.rb +0 -126
  88. data/lib/ronin/web/server/helpers/hosts.rb +0 -72
  89. data/lib/ronin/web/server/helpers/proxy.rb +0 -153
  90. data/lib/ronin/web/server/helpers/rendering.rb +0 -36
  91. data/lib/ronin/web/server/hosts.rb +0 -86
  92. data/lib/ronin/web/server/proxy.rb +0 -116
  93. data/spec/scanners/web_spec.rb +0 -24
  94. data/spec/web/helpers/root/index.html +0 -1
  95. data/spec/web/helpers/root/test.txt +0 -1
  96. data/spec/web/helpers/server.rb +0 -10
  97. data/spec/web/server/classes/files/dir/file.txt +0 -1
  98. data/spec/web/server/classes/files/dir/index.html +0 -1
  99. data/spec/web/server/classes/files/dir2/file2.txt +0 -1
  100. data/spec/web/server/classes/files/dir3/page.xml +0 -4
  101. data/spec/web/server/classes/files/file.txt +0 -1
  102. data/spec/web/server/classes/files_app.rb +0 -27
  103. data/spec/web/server/classes/hosts_app.rb +0 -40
  104. data/spec/web/server/classes/proxy_app.rb +0 -45
  105. data/spec/web/server/files_spec.rb +0 -74
  106. data/spec/web/server/hosts_spec.rb +0 -55
  107. data/spec/web/server/proxy_spec.rb +0 -49
  108. data/tasks/spec.rb +0 -10
  109. data/tasks/yard.rb +0 -13
  110. metadata.gz.sig +0 -3
@@ -0,0 +1,71 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This file is part of Ronin Web.
8
+ #
9
+ # Ronin is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # Ronin is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+
23
+ module Ronin
24
+ module Web
25
+ module Middleware
26
+ module Filters
27
+ #
28
+ # A Filter to match requests based on the User Agent header.
29
+ #
30
+ class UserAgentFilter
31
+
32
+ #
33
+ # Creates a new User Agent filter.
34
+ #
35
+ # @param [String, Regexp] user_agent
36
+ # The User Agent pattern to match against.
37
+ #
38
+ # @since 0.3.0
39
+ #
40
+ # @api private
41
+ #
42
+ def initialize(user_agent)
43
+ @user_agent = user_agent
44
+ end
45
+
46
+ #
47
+ # Matches the filter against the request.
48
+ #
49
+ # @param [Rack::Request] request
50
+ # The incoming request.
51
+ #
52
+ # @return [Boolean]
53
+ # Specifies whether the filter matched the request.
54
+ #
55
+ # @since 0.3.0
56
+ #
57
+ # @api private
58
+ #
59
+ def match?(request)
60
+ if @user_agent.kind_of?(Regexp)
61
+ !((request.user_agent =~ @user_agent).nil?)
62
+ else
63
+ request.user_agent.include?(@user_agent)
64
+ end
65
+ end
66
+
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,71 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This file is part of Ronin Web.
8
+ #
9
+ # Ronin is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # Ronin is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+
23
+ module Ronin
24
+ module Web
25
+ module Middleware
26
+ module Filters
27
+ #
28
+ # A Filter to match requests by their HTTP Host header.
29
+ #
30
+ class VHostFilter
31
+
32
+ #
33
+ # Creates a new vhost filter.
34
+ #
35
+ # @param [String, Regexp] vhost
36
+ # The virtual host pattern to match against.
37
+ #
38
+ # @since 0.3.0
39
+ #
40
+ # @api private
41
+ #
42
+ def initialize(vhost)
43
+ @vhost = vhost
44
+ end
45
+
46
+ #
47
+ # Matches the filter against the request.
48
+ #
49
+ # @param [Rack::Request] request
50
+ # The incoming request.
51
+ #
52
+ # @return [Boolean]
53
+ # Specifies whether the filter matched the request.
54
+ #
55
+ # @since 0.3.0
56
+ #
57
+ # @api private
58
+ #
59
+ def match?(request)
60
+ if @vhost.kind_of?(Regexp)
61
+ !((request.host =~ @vhost).nil?)
62
+ else
63
+ request.host == @vhost
64
+ end
65
+ end
66
+
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,145 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This file is part of Ronin Web.
8
+ #
9
+ # Ronin is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # Ronin is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+
23
+ require 'ronin/web/middleware/request'
24
+ require 'ronin/web/middleware/response'
25
+
26
+ require 'rack'
27
+
28
+ module Ronin
29
+ module Web
30
+ module Middleware
31
+ #
32
+ # A module containing helper methods that can be used in Rack
33
+ # Middleware and Rack Apps.
34
+ #
35
+ module Helpers
36
+ include Rack::Utils
37
+
38
+ alias h escape_html
39
+
40
+ #
41
+ # Sanitizes a path received by the middleware.
42
+ #
43
+ # @param [String] path
44
+ # The unsanitized path.
45
+ #
46
+ # @return [String]
47
+ # The unescaped and absolute path.
48
+ #
49
+ # @since 0.3.0
50
+ #
51
+ # @api semipublic
52
+ #
53
+ def sanitize_path(path)
54
+ File.expand_path(unescape(path))
55
+ end
56
+
57
+ #
58
+ # Returns the MIME type for a path.
59
+ #
60
+ # @param [String] path
61
+ # The path to determine the MIME type for.
62
+ #
63
+ # @return [String]
64
+ # The MIME type for the path.
65
+ #
66
+ # @since 0.3.0
67
+ #
68
+ # @api semipublic
69
+ #
70
+ def mime_type_for(path)
71
+ Rack::Mime.mime_type(File.extname(path))
72
+ end
73
+
74
+ alias content_type_for mime_type_for
75
+
76
+ #
77
+ # Creates a new response.
78
+ #
79
+ # @param [String, Array, IO] body
80
+ # The body for the response.
81
+ #
82
+ # @param [Hash] headers
83
+ # Additional headers for the response.
84
+ #
85
+ # @param [Integer] status
86
+ # The HTTP Status Code for the response.
87
+ #
88
+ # @yield [response]
89
+ # If a block is given, it will be passed the new response.
90
+ #
91
+ # @yieldparam [Response] response
92
+ # The new response.
93
+ #
94
+ # @return [Array]
95
+ # The new response.
96
+ #
97
+ # @example Create a response.
98
+ # response ['Hello'], {'Content-Type' => 'text/txt'}, 200
99
+ #
100
+ # @example Create a response with just a String.
101
+ # response 'Hello'
102
+ #
103
+ # @since 0.3.0
104
+ #
105
+ # @api semipublic
106
+ #
107
+ def response(body=[],headers={},status=200)
108
+ response = Response.new(body,status,headers)
109
+
110
+ yield(response) if block_given?
111
+ return response
112
+ end
113
+
114
+ #
115
+ # Creates a new response for a file.
116
+ #
117
+ # @param [String] path
118
+ # The path to the file.
119
+ #
120
+ # @param [Hash] headers
121
+ # Additional headers for the response.
122
+ #
123
+ # @param [Integer] status
124
+ # The HTTP Status Code for the response.
125
+ #
126
+ # @return [Response]
127
+ # The new response object.
128
+ #
129
+ # @see #response
130
+ #
131
+ # @since 0.3.0
132
+ #
133
+ # @api semipublic
134
+ #
135
+ def response_for(path,headers={},status=200)
136
+ response(
137
+ File.new(path),
138
+ headers.merge('Content-Type' => mime_type_for(path)),
139
+ status
140
+ )
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,265 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This file is part of Ronin Web.
8
+ #
9
+ # Ronin is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # Ronin is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+
23
+ require 'ronin/web/middleware/base'
24
+ require 'ronin/web/middleware/rule'
25
+ require 'ronin/web/middleware/proxy_request'
26
+
27
+ require 'ronin/network/http'
28
+ require 'set'
29
+
30
+ module Ronin
31
+ module Web
32
+ module Middleware
33
+ #
34
+ # A Rack middleware for proxying requests.
35
+ #
36
+ # use Ronin::Web::Middleware::Proxy do |proxy|
37
+ # proxy.every_request do |request|
38
+ # puts request.url
39
+ # end
40
+ #
41
+ # proxy.every_response do |response|
42
+ # response.headers.each do |name,value|
43
+ # puts "#{name}: #{value}"
44
+ # end
45
+ #
46
+ # puts response.body
47
+ # end
48
+ # end
49
+ #
50
+ class Proxy < Base
51
+
52
+ # Blacklisted HTTP response Headers.
53
+ HEADERS_BLACKLIST = Set[
54
+ 'Transfer-Encoding'
55
+ ]
56
+
57
+ #
58
+ # Creates a new {Proxy} middleware.
59
+ #
60
+ # @param [#call] app
61
+ # The application that the proxy middleware sits in front of.
62
+ #
63
+ # @param [Hash] options
64
+ # Additional options.
65
+ #
66
+ # @option options [String] :campaign
67
+ # The name of the campaign who's targetted hosts will be
68
+ # filtered by.
69
+ #
70
+ # @option options [String, Regexp] :vhost
71
+ # The Virtual-Host to filter.
72
+ #
73
+ # @option options [String, IPAddr] :ip
74
+ # The IP address or IP range to filter.
75
+ #
76
+ # @option options [String, Regexp] :referer
77
+ # The Referer URL or pattern to filter.
78
+ #
79
+ # @option options [String, Regexp] :user_agent
80
+ # The User-Agent string to filter.
81
+ #
82
+ # @option options [Proc] :when
83
+ # Custom logic to filter requests by.
84
+ #
85
+ # @yield [proxy]
86
+ # If a block is given, it will be passed the new proxy middleware.
87
+ #
88
+ # @yieldparam [Proxy] proxy
89
+ # The new proxy middleware object.
90
+ #
91
+ # @since 0.3.0
92
+ #
93
+ # @api public
94
+ #
95
+ def initialize(app,options={},&block)
96
+ intercept(options)
97
+
98
+ super(app,options,&block)
99
+ end
100
+
101
+ #
102
+ # Specifies which requests will be intercepted.
103
+ #
104
+ # @param [Hash] options
105
+ # Additional options.
106
+ #
107
+ # @option options [String] :campaign
108
+ # The name of the campaign who's targetted hosts will be
109
+ # filtered by.
110
+ #
111
+ # @option options [String, Regexp] :vhost
112
+ # The Virtual-Host to filter.
113
+ #
114
+ # @option options [String, IPAddr] :ip
115
+ # The IP address or IP range to filter.
116
+ #
117
+ # @option options [String, Regexp] :referer
118
+ # The Referer URL or pattern to filter.
119
+ #
120
+ # @option options [String, Regexp] :user_agent
121
+ # The User-Agent string to filter.
122
+ #
123
+ # @option options [Proc] :when
124
+ # Custom logic to filter requests by.
125
+ #
126
+ # @since 0.3.0
127
+ #
128
+ # @api public
129
+ #
130
+ def intercept(options={})
131
+ @rule = Rule.new(options)
132
+ end
133
+
134
+ #
135
+ # Uses the given block to intercept incoming requests.
136
+ #
137
+ # @yield [request]
138
+ # The given block will receive every incoming request, before it
139
+ # is proxied.
140
+ #
141
+ # @yieldparam [ProxyRequest] request
142
+ # A proxied request.
143
+ #
144
+ # @return [Proxy]
145
+ # The proxy middleware.
146
+ #
147
+ # @since 0.3.0
148
+ #
149
+ # @api public
150
+ #
151
+ def every_request(&block)
152
+ @every_request_block = block
153
+ return self
154
+ end
155
+
156
+ #
157
+ # Uses the given block to intercept proxied responses.
158
+ #
159
+ # @yield [response]
160
+ # The given block will receive every proxied response.
161
+ #
162
+ # @yieldparam [Response] response
163
+ # A proxied response.
164
+ #
165
+ # @return [Proxy]
166
+ # The proxy middleware.
167
+ #
168
+ # @since 0.3.0
169
+ #
170
+ # @api public
171
+ #
172
+ def every_response(&block)
173
+ @every_response_block = block
174
+ return self
175
+ end
176
+
177
+ #
178
+ # Receives incoming requests, proxies them, allowing manipulation
179
+ # of the requests and their responses.
180
+ #
181
+ # @param [Hash, Rack::Request] env
182
+ # The request.
183
+ #
184
+ # @return [Array, Response]
185
+ # The response.
186
+ #
187
+ # @since 0.3.0
188
+ #
189
+ # @api public
190
+ #
191
+ def call(env)
192
+ request = ProxyRequest.new(env)
193
+
194
+ if @rule.match?(request)
195
+ @every_request_block.call(request) if @every_request_block
196
+ else
197
+ return super(env)
198
+ end
199
+
200
+ print_info "Proxying #{request.url}"
201
+ request.headers.each do |name,value|
202
+ print_debug " #{name}: #{value}"
203
+ end
204
+
205
+ response = proxy(request)
206
+
207
+ @every_response_block.call(response) if @every_response_block
208
+
209
+ print_info "Returning proxied response."
210
+ response.headers.each do |name,value|
211
+ print_debug " #{name}: #{value}"
212
+ end
213
+
214
+ return response
215
+ end
216
+
217
+ protected
218
+
219
+ #
220
+ # Proxies a request.
221
+ #
222
+ # @param [ProxyRequest] request
223
+ # The request to send.
224
+ #
225
+ # @return [Response]
226
+ # The response from the request.
227
+ #
228
+ # @api private
229
+ #
230
+ def proxy(request)
231
+ options = {
232
+ :ssl => (request.scheme == 'https'),
233
+ :host => request.host,
234
+ :port => request.port,
235
+ :method => request.request_method,
236
+ :path => request.path_info,
237
+ :query => request.query_string,
238
+ :content_type => request.content_type,
239
+ :headers => request.headers
240
+ }
241
+
242
+ if request.form_data?
243
+ options[:form_data] = request.POST
244
+ end
245
+
246
+ http_response = Net.http_request(options)
247
+ http_headers = {}
248
+
249
+ http_response.each_capitalized do |name,value|
250
+ unless HEADERS_BLACKLIST.include?(name)
251
+ http_headers[name] = value
252
+ end
253
+ end
254
+
255
+ return Response.new(
256
+ (http_response.body || ''),
257
+ http_response.code,
258
+ http_headers
259
+ )
260
+ end
261
+
262
+ end
263
+ end
264
+ end
265
+ end