ronin-web 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +8 -0
- data/Manifest.txt +3 -0
- data/README.txt +3 -3
- data/Rakefile +1 -1
- data/lib/ronin/scanners/web.rb +52 -0
- data/lib/ronin/web/proxy/web.rb +4 -3
- data/lib/ronin/web/version.rb +1 -1
- data/lib/ronin/web/web.rb +43 -12
- data/spec/scanners/web_spec.rb +24 -0
- data/spec/web/server/classes/proxy_app.rb +2 -2
- data/spec/web/server/proxy_spec.rb +1 -1
- data/spec/web/web_spec.rb +167 -0
- metadata +6 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 0.2.1 / 2009-10-18
|
2
|
+
|
3
|
+
* Require spidr >= 0.2.0.
|
4
|
+
* Added Ronin::Scanners::Web.
|
5
|
+
* Added more specs for Ronin::Web and Ronin::Scanners::Web.
|
6
|
+
* Renamed Ronin::Web.proxy to Ronin::Web.proxy_server, to not conflict
|
7
|
+
with the original Ronin::Web.proxy method.
|
8
|
+
|
1
9
|
=== 0.2.0 / 2009-09-24
|
2
10
|
|
3
11
|
* Require ronin >= 0.3.0.
|
data/Manifest.txt
CHANGED
@@ -34,12 +34,14 @@ lib/ronin/web/spider.rb
|
|
34
34
|
lib/ronin/web/web.rb
|
35
35
|
lib/ronin/web/version.rb
|
36
36
|
lib/ronin/network/helpers/web.rb
|
37
|
+
lib/ronin/scanners/web.rb
|
37
38
|
tasks/spec.rb
|
38
39
|
tasks/yard.rb
|
39
40
|
spec/spec_helper.rb
|
40
41
|
spec/web/helpers/server.rb
|
41
42
|
spec/web/helpers/root/index.html
|
42
43
|
spec/web/helpers/root/test.txt
|
44
|
+
spec/web/web_spec.rb
|
43
45
|
spec/web/extensions/nokogiri_spec.rb
|
44
46
|
spec/web/server/classes/public1/static1.txt
|
45
47
|
spec/web/server/classes/public2/static2.txt
|
@@ -59,3 +61,4 @@ spec/web/server/files_spec.rb
|
|
59
61
|
spec/web/server/hosts_spec.rb
|
60
62
|
spec/web/server/proxy_spec.rb
|
61
63
|
spec/web/proxy/base_spec.rb
|
64
|
+
spec/scanners/web_spec.rb
|
data/README.txt
CHANGED
@@ -53,11 +53,11 @@ install or update Overlays.
|
|
53
53
|
|
54
54
|
* Get a web-page:
|
55
55
|
|
56
|
-
Web.get('http://www.
|
56
|
+
Web.get('http://www.rubyinside.com/')
|
57
57
|
|
58
58
|
* Get only the body of the web-page:
|
59
59
|
|
60
|
-
Web.get_body('http://www.
|
60
|
+
Web.get_body('http://www.rubyinside.com/')
|
61
61
|
|
62
62
|
* Get a WWW::Mechanize agent:
|
63
63
|
|
@@ -151,7 +151,7 @@ install or update Overlays.
|
|
151
151
|
== REQUIREMENTS:
|
152
152
|
|
153
153
|
* {mechanize}[http://mechanize.rubyforge.org/] >= 0.9.3
|
154
|
-
* {spidr}[http://spidr.rubyforge.org/] >= 0.
|
154
|
+
* {spidr}[http://spidr.rubyforge.org/] >= 0.2.0
|
155
155
|
* {sinatra}[http://www.sinatrarb.com/] >= 0.9.4
|
156
156
|
* {ronin}[http://ronin.rubyforge.org/] >= 0.3.0
|
157
157
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
#
|
2
|
+
# Ronin Web - A Ruby library for Ronin that provides support for web
|
3
|
+
# scraping and spidering functionality.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation; either version 2 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'ronin/web/spider'
|
23
|
+
require 'ronin/scanners/scanner'
|
24
|
+
|
25
|
+
module Ronin
|
26
|
+
module Scanners
|
27
|
+
class Web < Web::Spider
|
28
|
+
|
29
|
+
include Scanner
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def each_target(&block)
|
34
|
+
print_info "Started web spidering ..."
|
35
|
+
|
36
|
+
history.clear
|
37
|
+
|
38
|
+
unless visit_hosts.empty?
|
39
|
+
enqueue("http://#{visit_hosts.first}/")
|
40
|
+
end
|
41
|
+
|
42
|
+
run do |page|
|
43
|
+
print_info "Scanning page: #{page.url}"
|
44
|
+
block.call(page)
|
45
|
+
end
|
46
|
+
|
47
|
+
print_info "Finished web spidering."
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/ronin/web/proxy/web.rb
CHANGED
@@ -25,10 +25,11 @@ module Ronin
|
|
25
25
|
module Web
|
26
26
|
#
|
27
27
|
# Returns the Ronin Web Proxy. When called for the first time
|
28
|
-
# the proxy will be started in the background
|
29
|
-
# _options_.
|
28
|
+
# the proxy will be started in the background.
|
30
29
|
#
|
31
|
-
|
30
|
+
# @see Server::Base.run!
|
31
|
+
#
|
32
|
+
def Web.proxy_server(options={},&block)
|
32
33
|
unless class_variable_defined?('@@ronin_web_proxy')
|
33
34
|
@@ronin_web_proxy = Proxy::App
|
34
35
|
@@ronin_web_proxy.run!(options.merge(:background => true))
|
data/lib/ronin/web/version.rb
CHANGED
data/lib/ronin/web/web.rb
CHANGED
@@ -61,9 +61,11 @@ module Ronin
|
|
61
61
|
#
|
62
62
|
# @example
|
63
63
|
# Web.build_html do
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
64
|
+
# html {
|
65
|
+
# body {
|
66
|
+
# div(:style => 'display:none;') {
|
67
|
+
# object(:classid => 'blabla')
|
68
|
+
# }
|
67
69
|
# }
|
68
70
|
# }
|
69
71
|
# end
|
@@ -106,8 +108,8 @@ module Ronin
|
|
106
108
|
# @example
|
107
109
|
# Web.build_xml do
|
108
110
|
# post(:id => 2) {
|
109
|
-
# title { text(
|
110
|
-
# body { text(
|
111
|
+
# title { text('some example') }
|
112
|
+
# body { text('this is one contrived example.') }
|
111
113
|
# }
|
112
114
|
# end
|
113
115
|
#
|
@@ -130,15 +132,33 @@ module Ronin
|
|
130
132
|
#
|
131
133
|
# Creates a HTTP URI based on a Hash of proxy information.
|
132
134
|
#
|
133
|
-
# @param [Network::HTTP::Proxy, Hash] proxy_info
|
135
|
+
# @param [Network::HTTP::Proxy, Hash, String] proxy_info
|
134
136
|
# The proxy information.
|
135
137
|
#
|
136
138
|
# @return [URI::HTTP, nil]
|
137
139
|
# The HTTP URI that represents the proxy. If the proxy is diabled,
|
138
140
|
# +nil+ will be returned.
|
139
141
|
#
|
142
|
+
# @example
|
143
|
+
# Web.proxy_url
|
144
|
+
# # => "http://www.example.com:8080"
|
145
|
+
#
|
146
|
+
# @example
|
147
|
+
# Web.proxy_url({:host => 'www.example.com', :port => 8081})
|
148
|
+
# # => "http://www.example.com:8081"
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# Web.proxy_url('www.example.com:9000')
|
152
|
+
# # => "http://www.example.com:9000"
|
153
|
+
#
|
140
154
|
def Web.proxy_url(proxy_info=Web.proxy)
|
141
|
-
|
155
|
+
proxy = if proxy_info.kind_of?(Hash)
|
156
|
+
Network::HTTP::Proxy.new(proxy_info)
|
157
|
+
else
|
158
|
+
Network::HTTP::Proxy.parse(proxy_info)
|
159
|
+
end
|
160
|
+
|
161
|
+
return proxy.url
|
142
162
|
end
|
143
163
|
|
144
164
|
#
|
@@ -195,7 +215,8 @@ module Ronin
|
|
195
215
|
# @option options [String] :user_agent
|
196
216
|
# The User-Agent string to use.
|
197
217
|
#
|
198
|
-
# @option options [Network::HTTP::Proxy, Hash] :proxy
|
218
|
+
# @option options [Network::HTTP::Proxy, Hash, String] :proxy
|
219
|
+
# (Web.proxy)
|
199
220
|
# Proxy information.
|
200
221
|
#
|
201
222
|
# @option options [String] :user
|
@@ -216,7 +237,7 @@ module Ronin
|
|
216
237
|
# The contents of the URL.
|
217
238
|
#
|
218
239
|
# @example Open a given URL.
|
219
|
-
# Web.open('http://
|
240
|
+
# Web.open('http://rubyflow.com/')
|
220
241
|
#
|
221
242
|
# @example Open a given URL, using a custom User-Agent alias.
|
222
243
|
# Web.open('http://tenderlovemaking.com/',
|
@@ -270,7 +291,8 @@ module Ronin
|
|
270
291
|
# @option options [String] :user_agent
|
271
292
|
# The User-Agent string to use.
|
272
293
|
#
|
273
|
-
# @option options [Network::HTTP::Proxy, Hash] :proxy
|
294
|
+
# @option options [Network::HTTP::Proxy, Hash, String] :proxy
|
295
|
+
# (Web.proxy)
|
274
296
|
# Proxy information.
|
275
297
|
#
|
276
298
|
# @yield [agent]
|
@@ -305,7 +327,16 @@ module Ronin
|
|
305
327
|
agent.user_agent = Web.user_agent
|
306
328
|
end
|
307
329
|
|
308
|
-
proxy =
|
330
|
+
proxy = if options[:proxy].kind_of?(Hash)
|
331
|
+
options[:proxy]
|
332
|
+
elsif options[:proxy].kind_of?(String)
|
333
|
+
Network::HTTP::Proxy.parse(options[:proxy])
|
334
|
+
elsif options[:proxy].nil?
|
335
|
+
Web.proxy
|
336
|
+
else
|
337
|
+
raise(RuntimeError,"the given :proxy option is neither a Proxy, Hash or String",caller)
|
338
|
+
end
|
339
|
+
|
309
340
|
if proxy[:host]
|
310
341
|
agent.set_proxy(proxy[:host],proxy[:port],proxy[:user],proxy[:password])
|
311
342
|
end
|
@@ -343,7 +374,7 @@ module Ronin
|
|
343
374
|
# The requested page.
|
344
375
|
#
|
345
376
|
# @example
|
346
|
-
# Web.get('http://www.
|
377
|
+
# Web.get('http://www.rubyinside.com')
|
347
378
|
# # => WWW::Mechanize::Page
|
348
379
|
#
|
349
380
|
# @example
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'ronin/scanners/web'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Scanners::Web do
|
6
|
+
before(:all) do
|
7
|
+
Scanners::Web.class_eval do
|
8
|
+
scanner(:test) do |page,results,options|
|
9
|
+
results.call(page.url)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
@scanner = Scanners::Web.new(:host => 'www.example.com')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should spider every page on a website" do
|
17
|
+
@scanner.enqueue('http://www.example.com/')
|
18
|
+
@scanner.scan.should == {:test => [URI('http://www.example.com/')]}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should start spidering the first acceptable host" do
|
22
|
+
@scanner.scan.should == {:test => [URI('http://www.example.com/')]}
|
23
|
+
end
|
24
|
+
end
|
@@ -30,9 +30,9 @@ class ProxyApp < Ronin::Web::Server::Base
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
get '/rss
|
33
|
+
get '/feed/vulnerabilities/latest.rss' do
|
34
34
|
proxy_doc do |response,doc|
|
35
|
-
for_host('
|
35
|
+
for_host('osvdb.org') do
|
36
36
|
doc.search('//item').each do |item|
|
37
37
|
if item.inner_text =~ /(XSS|SQLi|SQL\s+Injection)/i
|
38
38
|
item.remove
|
@@ -41,7 +41,7 @@ describe Web::Server::Helpers::Proxy do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should allow modification of proxied XML documents" do
|
44
|
-
get_host '/rss
|
44
|
+
get_host '/feed/vulnerabilities/latest.rss', 'osvdb.org'
|
45
45
|
|
46
46
|
last_response.should be_ok
|
47
47
|
last_response.body.should_not =~ /(XSS|SQLi|SQL\s+Injection)/i
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'ronin/web/web'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Web do
|
6
|
+
it "should have a VERSION constant" do
|
7
|
+
Web.const_defined?('VERSION').should == true
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be able to parse HTML" do
|
11
|
+
doc = Web.html(%{
|
12
|
+
<html>
|
13
|
+
<body>Hello</body>
|
14
|
+
</html>
|
15
|
+
})
|
16
|
+
|
17
|
+
doc.at('body').inner_text.should == "Hello"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be able to build HTML documents" do
|
21
|
+
doc = Web.build_html do
|
22
|
+
html {
|
23
|
+
body {
|
24
|
+
div { text("hello") }
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
doc.to_html.include?("<html><body><div>hello</div></body></html>").should == true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be able to parse XML" do
|
33
|
+
doc = Web.html(%{
|
34
|
+
<?xml version="1.0"?>
|
35
|
+
<root>
|
36
|
+
<stuff>Hello</stuff>
|
37
|
+
</root>
|
38
|
+
})
|
39
|
+
|
40
|
+
doc.at('stuff').inner_text.should == "Hello"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to build XML documents" do
|
44
|
+
doc = Web.build_xml do
|
45
|
+
root {
|
46
|
+
stuff(:name => 'bla') { text("hello") }
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
doc.to_xml.include?("<root>\n <stuff name=\"bla\">hello</stuff>\n</root>").should == true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have a default proxy" do
|
54
|
+
Web.proxy.should_not be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should disable the proxy by default" do
|
58
|
+
Web.proxy.should_not be_enabled
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "proxy_url" do
|
62
|
+
before(:all) do
|
63
|
+
@uri = URI('http://www.example.com:9001')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should convert Network::HTTP::Proxy objects into a URI" do
|
67
|
+
Web.proxy_url(Network::HTTP::Proxy.new(
|
68
|
+
:host => 'www.example.com',
|
69
|
+
:port => 9001
|
70
|
+
)).should == @uri
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should convert a Hash into a URI" do
|
74
|
+
Web.proxy_url(
|
75
|
+
:host => 'www.example.com',
|
76
|
+
:port => 9001
|
77
|
+
).should == @uri
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should convert a String into a valid URI" do
|
81
|
+
Web.proxy_url("www.example.com:9001").should == @uri
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should provide User-Agent aliases" do
|
86
|
+
Web.user_agent_aliases.should_not be_empty
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should provide a default User-Agent" do
|
90
|
+
Web.user_agent.should be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should allow setting of the User-Agent string using an alias" do
|
94
|
+
Web.user_agent_alias = 'Mac FireFox'
|
95
|
+
|
96
|
+
Web.user_agent.should == "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should open URLs as temporary files" do
|
100
|
+
file = Web.open('http://www.example.com/')
|
101
|
+
|
102
|
+
file.read.should =~ /Example Web Page/
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "agent" do
|
106
|
+
after(:each) do
|
107
|
+
Web.user_agent = nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should provide WWW::Mechanize agents" do
|
111
|
+
Web.agent.class.should == WWW::Mechanize
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should use the Ronin User-Agent string" do
|
115
|
+
Web.user_agent = 'test'
|
116
|
+
Web.agent.user_agent.should == 'test'
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should support using a custom User-Agent string" do
|
120
|
+
agent = Web.agent(:user_agent => 'test2')
|
121
|
+
|
122
|
+
agent.user_agent.should == 'test2'
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should support using a custom User-Agent alias" do
|
126
|
+
agent = Web.agent(:user_agent_alias => 'iPhone')
|
127
|
+
|
128
|
+
agent.user_agent.should == 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C28 Safari/419.3'
|
129
|
+
end
|
130
|
+
|
131
|
+
describe ":proxy" do
|
132
|
+
it "should accept Proxy values" do
|
133
|
+
pending "WWW::Mechanize needs reader methods for the proxy settings"
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should accept Hash values" do
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should accept String values" do
|
140
|
+
pending "WWW::Mechanize needs reader methods for the proxy settings"
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should default to Web.proxy" do
|
144
|
+
pending "WWW::Mechanize needs reader methods for the proxy settings"
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should raise a RuntimeError exception for bad :proxy options" do
|
148
|
+
lambda {
|
149
|
+
Web.agent(:proxy => 42)
|
150
|
+
}.should raise_error(RuntimeError)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should be able to get WWW::Mechanize pages" do
|
156
|
+
page = Web.get('http://www.example.com/')
|
157
|
+
|
158
|
+
page.class.should == WWW::Mechanize::Page
|
159
|
+
page.at('title').inner_text.should == 'Example Web Page'
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should be able to get the bodies of WWW::Mechanize pages" do
|
163
|
+
body = Web.get_body('http://www.example.com/')
|
164
|
+
|
165
|
+
body.should =~ /Example Web Page/
|
166
|
+
end
|
167
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ronin-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
pDj+ws7QjtH/Qcrr1l9jfN0ehDs=
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2009-
|
33
|
+
date: 2009-10-18 00:00:00 -07:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -51,7 +51,7 @@ dependencies:
|
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.2.0
|
55
55
|
version:
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: sinatra
|
@@ -165,12 +165,14 @@ files:
|
|
165
165
|
- lib/ronin/web/web.rb
|
166
166
|
- lib/ronin/web/version.rb
|
167
167
|
- lib/ronin/network/helpers/web.rb
|
168
|
+
- lib/ronin/scanners/web.rb
|
168
169
|
- tasks/spec.rb
|
169
170
|
- tasks/yard.rb
|
170
171
|
- spec/spec_helper.rb
|
171
172
|
- spec/web/helpers/server.rb
|
172
173
|
- spec/web/helpers/root/index.html
|
173
174
|
- spec/web/helpers/root/test.txt
|
175
|
+
- spec/web/web_spec.rb
|
174
176
|
- spec/web/extensions/nokogiri_spec.rb
|
175
177
|
- spec/web/server/classes/public1/static1.txt
|
176
178
|
- spec/web/server/classes/public2/static2.txt
|
@@ -190,6 +192,7 @@ files:
|
|
190
192
|
- spec/web/server/hosts_spec.rb
|
191
193
|
- spec/web/server/proxy_spec.rb
|
192
194
|
- spec/web/proxy/base_spec.rb
|
195
|
+
- spec/scanners/web_spec.rb
|
193
196
|
has_rdoc: yard
|
194
197
|
homepage: http://ronin.rubyforge.org/web/
|
195
198
|
licenses: []
|
metadata.gz.sig
CHANGED
Binary file
|