ronin-web 0.2.0 → 0.2.1
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.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
|