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.
Files changed (56) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +25 -0
  3. data/Manifest.txt +36 -4
  4. data/README.txt +67 -64
  5. data/Rakefile +12 -3
  6. data/bin/ronin-web +1 -1
  7. data/lib/ronin/network/helpers/web.rb +221 -0
  8. data/lib/ronin/web.rb +1 -2
  9. data/lib/ronin/web/extensions.rb +0 -2
  10. data/lib/ronin/web/extensions/nokogiri.rb +0 -23
  11. data/lib/ronin/web/proxy.rb +3 -103
  12. data/lib/ronin/web/proxy/app.rb +31 -0
  13. data/lib/ronin/web/proxy/base.rb +41 -0
  14. data/lib/ronin/web/proxy/web.rb +42 -0
  15. data/lib/ronin/web/server.rb +3 -530
  16. data/lib/ronin/web/server/app.rb +31 -0
  17. data/lib/ronin/web/server/base.rb +334 -0
  18. data/lib/ronin/web/server/files.rb +92 -0
  19. data/lib/ronin/web/server/helpers.rb +25 -0
  20. data/lib/ronin/web/server/helpers/files.rb +126 -0
  21. data/lib/ronin/web/server/helpers/hosts.rb +72 -0
  22. data/lib/ronin/web/server/helpers/proxy.rb +153 -0
  23. data/lib/ronin/web/server/helpers/rendering.rb +36 -0
  24. data/lib/ronin/web/server/hosts.rb +86 -0
  25. data/lib/ronin/web/server/proxy.rb +116 -0
  26. data/lib/ronin/web/server/web.rb +62 -0
  27. data/lib/ronin/web/spider.rb +53 -26
  28. data/lib/ronin/web/version.rb +1 -3
  29. data/lib/ronin/web/web.rb +253 -95
  30. data/spec/spec_helper.rb +1 -1
  31. data/spec/web/proxy/base_spec.rb +9 -0
  32. data/spec/web/server/base_spec.rb +86 -0
  33. data/spec/web/server/classes/files/dir/file.txt +1 -0
  34. data/spec/web/server/classes/files/dir/index.html +1 -0
  35. data/spec/web/server/classes/files/dir2/file2.txt +1 -0
  36. data/spec/web/server/classes/files/dir3/page.xml +4 -0
  37. data/spec/web/server/classes/files/file.txt +1 -0
  38. data/spec/web/server/classes/files_app.rb +27 -0
  39. data/spec/web/server/classes/hosts_app.rb +40 -0
  40. data/spec/web/server/classes/proxy_app.rb +45 -0
  41. data/spec/web/server/classes/public1/static1.txt +1 -0
  42. data/spec/web/server/classes/public2/static2.txt +1 -0
  43. data/spec/web/server/classes/sub_app.rb +13 -0
  44. data/spec/web/server/classes/test_app.rb +20 -0
  45. data/spec/web/server/files_spec.rb +74 -0
  46. data/spec/web/server/helpers/server.rb +42 -0
  47. data/spec/web/server/hosts_spec.rb +55 -0
  48. data/spec/web/server/proxy_spec.rb +49 -0
  49. data/tasks/spec.rb +1 -0
  50. data/tasks/yard.rb +13 -0
  51. metadata +76 -17
  52. metadata.gz.sig +0 -0
  53. data/TODO.txt +0 -7
  54. data/lib/ronin/sessions/web.rb +0 -80
  55. data/lib/ronin/web/fingerprint.rb +0 -76
  56. data/spec/web/server_spec.rb +0 -142
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- gem 'rspec', '>=1.1.12'
2
+ gem 'rspec', '>=1.2.8'
3
3
  require 'spec'
4
4
 
5
5
  require 'ronin/web/version'
@@ -0,0 +1,9 @@
1
+ require 'ronin/web/proxy/base'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Web::Proxy::Base do
6
+ it "should run on a different port than Web::Server::Base" do
7
+ Web::Proxy::Base.port.should_not == Web::Server::Base.port
8
+ end
9
+ end
@@ -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
+ Second file.
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <page>
3
+ <title>XML document</title>
4
+ </page>
@@ -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,13 @@
1
+ require 'ronin/web/server/base'
2
+
3
+ class SubApp < Ronin::Web::Server::Base
4
+
5
+ get '/hello' do
6
+ 'SubApp greets you'
7
+ end
8
+
9
+ get '/' do
10
+ 'SubApp'
11
+ end
12
+
13
+ end
@@ -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