ronin-web 0.1.3 → 0.2.0

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.
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