ronin-web 0.1.3 → 0.2.0
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 +25 -0
- data/Manifest.txt +36 -4
- data/README.txt +67 -64
- data/Rakefile +12 -3
- data/bin/ronin-web +1 -1
- data/lib/ronin/network/helpers/web.rb +221 -0
- data/lib/ronin/web.rb +1 -2
- data/lib/ronin/web/extensions.rb +0 -2
- data/lib/ronin/web/extensions/nokogiri.rb +0 -23
- data/lib/ronin/web/proxy.rb +3 -103
- data/lib/ronin/web/proxy/app.rb +31 -0
- data/lib/ronin/web/proxy/base.rb +41 -0
- data/lib/ronin/web/proxy/web.rb +42 -0
- data/lib/ronin/web/server.rb +3 -530
- data/lib/ronin/web/server/app.rb +31 -0
- data/lib/ronin/web/server/base.rb +334 -0
- data/lib/ronin/web/server/files.rb +92 -0
- data/lib/ronin/web/server/helpers.rb +25 -0
- data/lib/ronin/web/server/helpers/files.rb +126 -0
- data/lib/ronin/web/server/helpers/hosts.rb +72 -0
- data/lib/ronin/web/server/helpers/proxy.rb +153 -0
- data/lib/ronin/web/server/helpers/rendering.rb +36 -0
- data/lib/ronin/web/server/hosts.rb +86 -0
- data/lib/ronin/web/server/proxy.rb +116 -0
- data/lib/ronin/web/server/web.rb +62 -0
- data/lib/ronin/web/spider.rb +53 -26
- data/lib/ronin/web/version.rb +1 -3
- data/lib/ronin/web/web.rb +253 -95
- data/spec/spec_helper.rb +1 -1
- data/spec/web/proxy/base_spec.rb +9 -0
- data/spec/web/server/base_spec.rb +86 -0
- data/spec/web/server/classes/files/dir/file.txt +1 -0
- data/spec/web/server/classes/files/dir/index.html +1 -0
- data/spec/web/server/classes/files/dir2/file2.txt +1 -0
- data/spec/web/server/classes/files/dir3/page.xml +4 -0
- data/spec/web/server/classes/files/file.txt +1 -0
- data/spec/web/server/classes/files_app.rb +27 -0
- data/spec/web/server/classes/hosts_app.rb +40 -0
- data/spec/web/server/classes/proxy_app.rb +45 -0
- data/spec/web/server/classes/public1/static1.txt +1 -0
- data/spec/web/server/classes/public2/static2.txt +1 -0
- data/spec/web/server/classes/sub_app.rb +13 -0
- data/spec/web/server/classes/test_app.rb +20 -0
- data/spec/web/server/files_spec.rb +74 -0
- data/spec/web/server/helpers/server.rb +42 -0
- data/spec/web/server/hosts_spec.rb +55 -0
- data/spec/web/server/proxy_spec.rb +49 -0
- data/tasks/spec.rb +1 -0
- data/tasks/yard.rb +13 -0
- metadata +76 -17
- metadata.gz.sig +0 -0
- data/TODO.txt +0 -7
- data/lib/ronin/sessions/web.rb +0 -80
- data/lib/ronin/web/fingerprint.rb +0 -76
- data/spec/web/server_spec.rb +0 -142
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'ronin/web/server/base'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'web/server/classes/test_app'
|
5
|
+
require 'web/server/helpers/server'
|
6
|
+
|
7
|
+
describe Web::Server::Base do
|
8
|
+
include Helpers::Web::Server
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
self.app = TestApp
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should define a set of index file-names to search for" do
|
15
|
+
TestApp.indices.should == TestApp::DEFAULT_INDICES.to_set
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should allow for defining new index file-names to search for" do
|
19
|
+
TestApp.index 'index.xml'
|
20
|
+
TestApp.indices.include?('index.xml').should == true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should find a suitable Rack::Handler for the web server" do
|
24
|
+
TestApp.handler_class.should_not be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should still bind blocks to paths" do
|
28
|
+
get '/tests/get'
|
29
|
+
|
30
|
+
last_response.should be_ok
|
31
|
+
last_response.body.should == 'block tested'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should bind a block to a path for all request types" do
|
35
|
+
post '/tests/any'
|
36
|
+
|
37
|
+
last_response.should be_ok
|
38
|
+
last_response.body.should == 'any tested'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have a default response" do
|
42
|
+
get '/totally/non/existant/path'
|
43
|
+
|
44
|
+
last_response.should_not be_ok
|
45
|
+
last_response.body.should be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow for defining custom responses" do
|
49
|
+
TestApp.default do
|
50
|
+
halt 404, 'nothing to see here'
|
51
|
+
end
|
52
|
+
|
53
|
+
get '/whats/here'
|
54
|
+
|
55
|
+
last_response.should_not be_ok
|
56
|
+
last_response.body.should == 'nothing to see here'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should map paths to sub-apps" do
|
60
|
+
get '/tests/subapp/'
|
61
|
+
|
62
|
+
last_response.should be_ok
|
63
|
+
last_response.body.should == 'SubApp'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should modify the path_info as it maps paths to sub-apps" do
|
67
|
+
get '/tests/subapp/hello'
|
68
|
+
|
69
|
+
last_response.should be_ok
|
70
|
+
last_response.body.should == 'SubApp greets you'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should host static content from public directories" do
|
74
|
+
get '/static1.txt'
|
75
|
+
|
76
|
+
last_response.should be_ok
|
77
|
+
last_response.body.should == "Static file1.\n"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should host static content from multiple public directories" do
|
81
|
+
get '/static2.txt'
|
82
|
+
|
83
|
+
last_response.should be_ok
|
84
|
+
last_response.body.should == "Static file2.\n"
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Another file.
|
@@ -0,0 +1 @@
|
|
1
|
+
The index.
|
@@ -0,0 +1 @@
|
|
1
|
+
Second file.
|
@@ -0,0 +1 @@
|
|
1
|
+
A file.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'ronin/web/server/base'
|
2
|
+
|
3
|
+
class FilesApp < Ronin::Web::Server::Base
|
4
|
+
|
5
|
+
file '/tests/file',
|
6
|
+
File.join(File.dirname(__FILE__),'files','file.txt')
|
7
|
+
|
8
|
+
file '/tests/file/missing', 'should_be_missing'
|
9
|
+
|
10
|
+
get '/tests/content_type/custom' do
|
11
|
+
return_file File.join(File.dirname(__FILE__),'files','dir3','page.xml'),
|
12
|
+
'text/plain'
|
13
|
+
end
|
14
|
+
|
15
|
+
file '/tests/content_type',
|
16
|
+
File.join(File.dirname(__FILE__),'files','dir3','page.xml')
|
17
|
+
|
18
|
+
directory '/tests/directory',
|
19
|
+
File.join(File.dirname(__FILE__),'files','dir')
|
20
|
+
|
21
|
+
directory '/tests/directory',
|
22
|
+
File.join(File.dirname(__FILE__),'files','dir2')
|
23
|
+
|
24
|
+
directory '/tests/directory/no_index',
|
25
|
+
File.join(File.dirname(__FILE__),'files','dir3')
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'ronin/web/server/base'
|
2
|
+
|
3
|
+
class FTPApp < Ronin::Web::Server::Base
|
4
|
+
|
5
|
+
get '/file' do
|
6
|
+
'FTP File'
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class WWWApp < Ronin::Web::Server::Base
|
12
|
+
|
13
|
+
get '/file' do
|
14
|
+
'WWW File'
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class HostsApp < Ronin::Web::Server::Base
|
20
|
+
|
21
|
+
get '/tests/for_host' do
|
22
|
+
for_host('localhost') do
|
23
|
+
'Admin Response'
|
24
|
+
end
|
25
|
+
|
26
|
+
for_host(/downloads/) do
|
27
|
+
'Download Response'
|
28
|
+
end
|
29
|
+
|
30
|
+
'Generic Response'
|
31
|
+
end
|
32
|
+
|
33
|
+
host 'example.com', WWWApp
|
34
|
+
hosts_like /^ftp\./, FTPApp
|
35
|
+
|
36
|
+
get '/file' do
|
37
|
+
'Generic File'
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'ronin/web/server/base'
|
2
|
+
|
3
|
+
class ProxyApp < Ronin::Web::Server::Base
|
4
|
+
|
5
|
+
get '/' do
|
6
|
+
proxy
|
7
|
+
end
|
8
|
+
|
9
|
+
get '/reddit/erlang' do
|
10
|
+
proxy(:host => 'www.reddit.com', :path => '/r/erlang')
|
11
|
+
end
|
12
|
+
|
13
|
+
get '/r/erlang' do
|
14
|
+
proxy do |body|
|
15
|
+
for_host(/reddit\./) do
|
16
|
+
body.gsub(/erlang/i,'Fixed Gear Bicycle')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/r/ruby' do
|
22
|
+
proxy_doc do |response,doc|
|
23
|
+
for_host(/reddit\.com/) do
|
24
|
+
doc.search('div.link').each do |link|
|
25
|
+
if link.at('a.title').inner_text =~ /rails/i
|
26
|
+
link.remove
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
get '/rss.php' do
|
34
|
+
proxy_doc do |response,doc|
|
35
|
+
for_host('milworm.com') do
|
36
|
+
doc.search('//item').each do |item|
|
37
|
+
if item.inner_text =~ /(XSS|SQLi|SQL\s+Injection)/i
|
38
|
+
item.remove
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Static file1.
|
@@ -0,0 +1 @@
|
|
1
|
+
Static file2.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'ronin/web/server/base'
|
2
|
+
|
3
|
+
require 'web/server/classes/sub_app'
|
4
|
+
|
5
|
+
class TestApp < Ronin::Web::Server::Base
|
6
|
+
|
7
|
+
get '/tests/get' do
|
8
|
+
'block tested'
|
9
|
+
end
|
10
|
+
|
11
|
+
any '/tests/any' do
|
12
|
+
'any tested'
|
13
|
+
end
|
14
|
+
|
15
|
+
map '/tests/subapp', SubApp
|
16
|
+
|
17
|
+
public_dir File.join(File.dirname(__FILE__),'public1')
|
18
|
+
public_dir File.join(File.dirname(__FILE__),'public2')
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'ronin/web/server/files'
|
2
|
+
require 'ronin/web/server/base'
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
require 'web/server/helpers/server'
|
6
|
+
require 'web/server/classes/files_app'
|
7
|
+
|
8
|
+
describe Web::Server::Files do
|
9
|
+
include Helpers::Web::Server
|
10
|
+
|
11
|
+
before(:all) do
|
12
|
+
self.app = FilesApp
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should host individual files" do
|
16
|
+
get '/tests/file'
|
17
|
+
|
18
|
+
last_response.should be_ok
|
19
|
+
last_response.body.should == "A file.\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should automatically set the content_type for files" do
|
23
|
+
get '/tests/content_type'
|
24
|
+
|
25
|
+
last_response.should be_ok
|
26
|
+
last_response.content_type.should =~ /\/xml$/
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow overriding the content_type of files" do
|
30
|
+
get '/tests/content_type/custom'
|
31
|
+
|
32
|
+
last_response.should be_ok
|
33
|
+
last_response.content_type.should == 'text/plain'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should ignore missing files that are hosted" do
|
37
|
+
get '/test/missing'
|
38
|
+
|
39
|
+
last_response.should_not be_ok
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should host the contents of a directory" do
|
43
|
+
get '/tests/directory/file.txt'
|
44
|
+
|
45
|
+
last_response.should be_ok
|
46
|
+
last_response.body.should == "Another file.\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should prevent directory traversal when hosting a directory" do
|
50
|
+
get '/test/directory/./././//..///.///..///./../files_spec.rb'
|
51
|
+
|
52
|
+
last_response.should_not be_ok
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should host the contents of directories that share a common path" do
|
56
|
+
get '/tests/directory/file2.txt'
|
57
|
+
|
58
|
+
last_response.should be_ok
|
59
|
+
last_response.body.should == "Second file.\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should search for index files within a directory" do
|
63
|
+
get '/tests/directory/'
|
64
|
+
|
65
|
+
last_response.should be_ok
|
66
|
+
last_response.body.should == "The index.\n"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not return anything if there is no index file was found" do
|
70
|
+
get '/tests/directory/no_index/'
|
71
|
+
|
72
|
+
last_response.should_not be_ok
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec/interop/test'
|
3
|
+
rescue Gem::LoadError => e
|
4
|
+
raise(e)
|
5
|
+
rescue ::LoadError
|
6
|
+
STDERR.puts "Error: please install the test-unit gem in order to run the spec tests"
|
7
|
+
exit -1
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'rack/test'
|
12
|
+
rescue Gem::LoadError => e
|
13
|
+
raise(e)
|
14
|
+
rescue ::LoadError
|
15
|
+
STDERR.puts "Error: please install the rack-test gem in order to run the spec tests"
|
16
|
+
exit -1
|
17
|
+
end
|
18
|
+
|
19
|
+
module Helpers
|
20
|
+
module Web
|
21
|
+
module Server
|
22
|
+
include Rack::Test::Methods
|
23
|
+
|
24
|
+
def app=(server)
|
25
|
+
@app = server
|
26
|
+
@app.set :environment, :test
|
27
|
+
end
|
28
|
+
|
29
|
+
def app
|
30
|
+
@app
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_host(path,host,params={},headers={})
|
34
|
+
get(path,params,headers.merge('HTTP_HOST' => host))
|
35
|
+
end
|
36
|
+
|
37
|
+
def post_host(path,host,params={},headers={})
|
38
|
+
post(path,params,headers.merge('HTTP_HOST' => host))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'ronin/web/server/hosts'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'web/server/classes/hosts_app'
|
5
|
+
require 'web/server/helpers/server'
|
6
|
+
|
7
|
+
describe Web::Server::Hosts do
|
8
|
+
include Helpers::Web::Server
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
self.app = HostsApp
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should allow routes to respond to specific hosts" do
|
15
|
+
get_host '/tests/for_host', 'localhost'
|
16
|
+
|
17
|
+
last_response.should be_ok
|
18
|
+
last_response.body.should == 'Admin Response'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should allow routes to respond to hosts matching a pattern" do
|
22
|
+
get_host '/tests/for_host', 'downloads.example.com'
|
23
|
+
|
24
|
+
last_response.should be_ok
|
25
|
+
last_response.body.should == 'Download Response'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should fallback to the normal response if the host is not recognized" do
|
29
|
+
get '/tests/for_host'
|
30
|
+
|
31
|
+
last_response.should be_ok
|
32
|
+
last_response.body.should == 'Generic Response'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should route requests for specific hosts" do
|
36
|
+
get_host '/file', 'example.com'
|
37
|
+
|
38
|
+
last_response.should be_ok
|
39
|
+
last_response.body.should == 'WWW File'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should route requests for hosts matching a pattern" do
|
43
|
+
get_host '/file', 'ftp.example.com'
|
44
|
+
|
45
|
+
last_response.should be_ok
|
46
|
+
last_response.body.should == 'FTP File'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should not route requests for unrecognized hosts" do
|
50
|
+
get '/file'
|
51
|
+
|
52
|
+
last_response.should be_ok
|
53
|
+
last_response.body.should == 'Generic File'
|
54
|
+
end
|
55
|
+
end
|