cms_scanner 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/core.rb +4 -3
  3. data/app/views/cli/core/finished.erb +1 -0
  4. data/app/views/json/core/finished.erb +1 -0
  5. data/cms_scanner.gemspec +13 -3
  6. data/lib/cms_scanner.rb +14 -2
  7. data/lib/cms_scanner/finders/finder.rb +16 -7
  8. data/lib/cms_scanner/finders/finder/enumerator.rb +4 -28
  9. data/lib/cms_scanner/finders/finder/fingerprinter.rb +60 -0
  10. data/lib/cms_scanner/finders/finding.rb +1 -1
  11. data/lib/cms_scanner/target/scope.rb +4 -1
  12. data/lib/cms_scanner/target/server/generic.rb +1 -1
  13. data/lib/cms_scanner/typhoeus/hydra.rb +10 -0
  14. data/lib/cms_scanner/version.rb +1 -1
  15. metadata +5 -203
  16. data/.gitignore +0 -7
  17. data/.rspec +0 -2
  18. data/.rubocop.yml +0 -10
  19. data/.travis.yml +0 -17
  20. data/Gemfile +0 -6
  21. data/Rakefile +0 -9
  22. data/spec/app/controllers/core_spec.rb +0 -167
  23. data/spec/app/controllers/interesting_files_spec.rb +0 -70
  24. data/spec/app/finders/interesting_files/fantastico_fileslist_spec.rb +0 -66
  25. data/spec/app/finders/interesting_files/headers_spec.rb +0 -36
  26. data/spec/app/finders/interesting_files/robots_txt_spec.rb +0 -54
  27. data/spec/app/finders/interesting_files/search_replace_db_2_spec.rb +0 -53
  28. data/spec/app/finders/interesting_files/xml_rpc_spec.rb +0 -136
  29. data/spec/app/finders/interesting_files_spec.rb +0 -12
  30. data/spec/app/formatters/cli_no_colour_spec.rb +0 -14
  31. data/spec/app/formatters/cli_spec.rb +0 -30
  32. data/spec/app/formatters/json_spec.rb +0 -30
  33. data/spec/app/models/fantastico_fileslist_spec.rb +0 -31
  34. data/spec/app/models/headers_spec.rb +0 -51
  35. data/spec/app/models/interesting_file_spec.rb +0 -69
  36. data/spec/app/models/robots_txt_spec.rb +0 -27
  37. data/spec/app/models/version_spec.rb +0 -51
  38. data/spec/app/models/xml_rpc_spec.rb +0 -46
  39. data/spec/app/views_spec.rb +0 -35
  40. data/spec/cache/.gitignore +0 -4
  41. data/spec/dummy_finding.rb +0 -25
  42. data/spec/dummy_independent_finders.rb +0 -26
  43. data/spec/dummy_unique_finders.rb +0 -33
  44. data/spec/fixtures/finders/interesting_files/fantastico_fileslist/fantastico_fileslist.txt +0 -12
  45. data/spec/fixtures/finders/interesting_files/file.txt +0 -4
  46. data/spec/fixtures/finders/interesting_files/headers/interesting.txt +0 -16
  47. data/spec/fixtures/finders/interesting_files/headers/no_interesting.txt +0 -12
  48. data/spec/fixtures/finders/interesting_files/robots_txt/robots.txt +0 -10
  49. data/spec/fixtures/finders/interesting_files/search_replace_db_2/searchreplacedb2.php +0 -188
  50. data/spec/fixtures/finders/interesting_files/xml_rpc/homepage_in_scope_pingback.html +0 -7
  51. data/spec/fixtures/finders/interesting_files/xml_rpc/homepage_out_of_scope_pingback.html +0 -7
  52. data/spec/fixtures/finders/interesting_files/xml_rpc/xmlrpc.php +0 -1
  53. data/spec/fixtures/output.txt +0 -0
  54. data/spec/fixtures/target/comments.html +0 -29
  55. data/spec/fixtures/target/platform/php/debug_log/debug.log +0 -2
  56. data/spec/fixtures/target/platform/php/fpd/wp_rss_functions.php +0 -2
  57. data/spec/fixtures/target/scope/index.html +0 -23
  58. data/spec/fixtures/target/server/apache/directory_listing/2.2.16.html +0 -15
  59. data/spec/fixtures/target/server/generic/server/apache/basic.txt +0 -5
  60. data/spec/fixtures/target/server/generic/server/iis/basic.txt +0 -6
  61. data/spec/fixtures/target/server/generic/server/not_detected.txt +0 -3
  62. data/spec/fixtures/target/server/iis/directory_listing/no_parent.html +0 -3
  63. data/spec/fixtures/target/server/iis/directory_listing/with_parent.html +0 -3
  64. data/spec/fixtures/views/base/ctrl/local.erb +0 -1
  65. data/spec/fixtures/views/base/ctrl/test.erb +0 -3
  66. data/spec/fixtures/views/base/global.erb +0 -1
  67. data/spec/fixtures/views/base/test.erb +0 -2
  68. data/spec/fixtures/views/based_format/test.erb +0 -1
  69. data/spec/fixtures/views/json/render_me.erb +0 -4
  70. data/spec/lib/browser_spec.rb +0 -140
  71. data/spec/lib/cache/file_store_spec.rb +0 -100
  72. data/spec/lib/cache/typhoeus_spec.rb +0 -28
  73. data/spec/lib/cms_scanner_spec.rb +0 -49
  74. data/spec/lib/controller_spec.rb +0 -30
  75. data/spec/lib/controllers_spec.rb +0 -48
  76. data/spec/lib/finders/confidence_spec.rb +0 -39
  77. data/spec/lib/finders/finder/enumerator_spec.rb +0 -89
  78. data/spec/lib/finders/finder/smart_url_checker/findings_spec.rb +0 -39
  79. data/spec/lib/finders/finder/smart_url_checker_spec.rb +0 -50
  80. data/spec/lib/finders/finder_spec.rb +0 -11
  81. data/spec/lib/finders/findings_spec.rb +0 -36
  82. data/spec/lib/finders/independent_finders_spec.rb +0 -134
  83. data/spec/lib/finders/same_type_finder_spec.rb +0 -24
  84. data/spec/lib/finders/same_type_finders_spec.rb +0 -126
  85. data/spec/lib/finders/unique_finder_spec.rb +0 -24
  86. data/spec/lib/finders/unique_finders_spec.rb +0 -222
  87. data/spec/lib/formatter_spec.rb +0 -145
  88. data/spec/lib/public_suffix/domain_spec.rb +0 -49
  89. data/spec/lib/sub_scanner_spec.rb +0 -45
  90. data/spec/lib/target/hashes_spec.rb +0 -90
  91. data/spec/lib/target/platforms_spec.rb +0 -13
  92. data/spec/lib/target/scope_spec.rb +0 -103
  93. data/spec/lib/target/servers_spec.rb +0 -13
  94. data/spec/lib/target_spec.rb +0 -69
  95. data/spec/lib/vulnerability/references_spec.rb +0 -75
  96. data/spec/lib/vulnerability_spec.rb +0 -27
  97. data/spec/lib/web_site_spec.rb +0 -121
  98. data/spec/output/core/finished.cli_no_colour +0 -3
  99. data/spec/output/core/finished.json +0 -5
  100. data/spec/output/core/started.cli_no_colour +0 -3
  101. data/spec/output/core/started.json +0 -5
  102. data/spec/output/interesting_files/empty.cli_no_colour +0 -2
  103. data/spec/output/interesting_files/empty.json +0 -5
  104. data/spec/output/interesting_files/findings.cli_no_colour +0 -30
  105. data/spec/output/interesting_files/findings.json +0 -75
  106. data/spec/shared_examples.rb +0 -11
  107. data/spec/shared_examples/browser_actions.rb +0 -30
  108. data/spec/shared_examples/finding.rb +0 -54
  109. data/spec/shared_examples/formatter_buffer.rb +0 -6
  110. data/spec/shared_examples/formatter_class_methods.rb +0 -26
  111. data/spec/shared_examples/independent_finder.rb +0 -31
  112. data/spec/shared_examples/target/platform/php.rb +0 -56
  113. data/spec/shared_examples/target/server/apache.rb +0 -32
  114. data/spec/shared_examples/target/server/generic.rb +0 -33
  115. data/spec/shared_examples/target/server/iis.rb +0 -37
  116. data/spec/shared_examples/views/core.rb +0 -26
  117. data/spec/shared_examples/views/interesting_files.rb +0 -36
  118. data/spec/spec_helper.rb +0 -43
@@ -1,53 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Finders::InterestingFiles::SearchReplaceDB2 do
4
- subject(:finder) { described_class.new(target) }
5
- let(:target) { CMSScanner::Target.new(url) }
6
- let(:url) { 'http://example.com/' }
7
- let(:file) { url + 'searchreplacedb2.php' }
8
- let(:fixtures) { File.join(FIXTURES_FINDERS, 'interesting_files', 'search_replace_db_2') }
9
-
10
- describe '#url' do
11
- its(:url) { should eq file }
12
- end
13
-
14
- describe '#aggressive' do
15
- after do
16
- stub_request(:get, file).to_return(status: status, body: body)
17
-
18
- expect(finder.aggressive).to eql @expected
19
- end
20
-
21
- let(:body) { '' }
22
-
23
- context 'when 404' do
24
- let(:status) { 404 }
25
-
26
- it 'returns nil' do
27
- @expected = nil
28
- end
29
- end
30
-
31
- context 'when 200' do
32
- let(:status) { 200 }
33
-
34
- context 'when the body is empty' do
35
- it 'returns nil' do
36
- @expected = nil
37
- end
38
- end
39
-
40
- context 'when the body matches' do
41
- let(:body) { File.new(File.join(fixtures, 'searchreplacedb2.php')).read }
42
-
43
- it 'returns the InterestingFile result' do
44
- @expected = CMSScanner::InterestingFile.new(
45
- file,
46
- confidence: 100,
47
- found_by: 'Search Replace Db2 (Aggressive Detection)'
48
- )
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,136 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Finders::InterestingFiles::XMLRPC do
4
- subject(:finder) { described_class.new(target) }
5
- let(:target) { CMSScanner::Target.new(url) }
6
- let(:url) { 'http://e.org/' }
7
- let(:xml_rpc_url) { url + 'xmlrpc.php' }
8
- let(:fixtures) { File.join(FIXTURES_FINDERS, 'interesting_files', 'xml_rpc') }
9
-
10
- describe '#potential_urls' do
11
- its(:potential_urls) { should be_empty }
12
- end
13
-
14
- describe '#passive' do
15
- before do
16
- expect(finder).to receive(:passive_headers).and_return(headers_stub)
17
- expect(finder).to receive(:passive_body).and_return(body_stub)
18
- end
19
-
20
- context 'when both passives return nil' do
21
- let(:headers_stub) { nil }
22
- let(:body_stub) { nil }
23
-
24
- its(:passive) { should be_empty }
25
- end
26
-
27
- context 'when one passive is not nil' do
28
- let(:headers_stub) { nil }
29
- let(:body_stub) { 'test' }
30
-
31
- its(:passive) { should eq %w(test) }
32
- end
33
- end
34
-
35
- describe '#passive_headers' do
36
- before { stub_request(:get, url).to_return(headers: headers) }
37
-
38
- let(:headers) { {} }
39
-
40
- context 'when no headers' do
41
- its(:passive_headers) { should be_nil }
42
- end
43
-
44
- context 'when headers' do
45
- context 'when URL is out of scope' do
46
- let(:headers) { { 'X-Pingback' => 'http://ex.org/yolo' } }
47
-
48
- its(:passive_headers) { should be_nil }
49
- end
50
-
51
- context 'when URL is in scope' do
52
- let(:headers) { { 'X-Pingback' => xml_rpc_url } }
53
-
54
- it 'adds the url to #potential_urls and returns the XMLRPC' do
55
- result = finder.passive_headers
56
-
57
- expect(finder.potential_urls).to eq [xml_rpc_url]
58
-
59
- expect(result).to be_a CMSScanner::XMLRPC
60
- expect(result).to eql CMSScanner::XMLRPC.new(
61
- xml_rpc_url,
62
- confidence: 30,
63
- found_by: 'Headers (passive detection)'
64
- )
65
- end
66
- end
67
- end
68
- end
69
-
70
- describe '#passive_body' do
71
- before { stub_request(:get, url).to_return(body: body) }
72
-
73
- context 'when no link rel="pingback" tag' do
74
- let(:body) { '' }
75
-
76
- its(:passive_body) { should be_nil }
77
- end
78
-
79
- context 'when the tag is present' do
80
- context 'when the URL is out of scope' do
81
- let(:body) { File.new(File.join(fixtures, 'homepage_out_of_scope_pingback.html')).read }
82
-
83
- its(:passive_body) { should be_nil }
84
- end
85
-
86
- context 'when URL is in scope' do
87
- let(:body) { File.new(File.join(fixtures, 'homepage_in_scope_pingback.html')).read }
88
- let(:expected_url) { 'http://e.org/wp/xmlrpc.php' }
89
-
90
- it 'adds the URL to the #potential_urls and returns the XMLRPC' do
91
- result = finder.passive_body
92
-
93
- expect(finder.potential_urls).to eq [expected_url]
94
-
95
- expect(result).to be_a CMSScanner::XMLRPC
96
- expect(result).to eql CMSScanner::XMLRPC.new(
97
- expected_url,
98
- confidence: 30,
99
- found_by: 'Link Tag (passive detection)'
100
- )
101
- end
102
- end
103
- end
104
- end
105
-
106
- describe '#aggressive' do
107
- # Adds an out of scope URL which should be ignored
108
- before { finder.potential_urls << 'htpp://ex.org' }
109
-
110
- after do
111
- stub_request(:get, xml_rpc_url).to_return(body: body)
112
-
113
- expect(finder.aggressive).to eql @expected
114
- end
115
-
116
- context 'when the body does not match' do
117
- let(:body) { '' }
118
-
119
- it 'returns nil' do
120
- @expected = nil
121
- end
122
- end
123
-
124
- context 'when the body matches' do
125
- let(:body) { File.new(File.join(fixtures, 'xmlrpc.php')).read }
126
-
127
- it 'returns the InterestingFile result' do
128
- @expected = CMSScanner::XMLRPC.new(
129
- xml_rpc_url,
130
- confidence: 100,
131
- found_by: described_class::DIRECT_ACCESS
132
- )
133
- end
134
- end
135
- end
136
- end
@@ -1,12 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Finders::InterestingFiles::Base do
4
- it_behaves_like CMSScanner::Finders::IndependentFinder do
5
- let(:expected_finders) { %w(Headers RobotsTxt FantasticoFileslist SearchReplaceDB2 XMLRPC) }
6
- let(:expected_finders_class) { CMSScanner::Finders::IndependentFinders }
7
- end
8
-
9
- subject(:files) { described_class.new(target) }
10
- let(:target) { CMSScanner::Target.new(url) }
11
- let(:url) { 'http://example.com/' }
12
- end
@@ -1,14 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Formatter::CliNoColour do
4
- subject(:formatter) { described_class.new }
5
-
6
- its(:format) { should eq 'cli' }
7
- its(:user_interaction?) { should be true }
8
-
9
- describe '#colorize' do
10
- it 'returns the text w/o any colour' do
11
- expect(formatter.red('Text')).to eq 'Text'
12
- end
13
- end
14
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Formatter::Cli do
4
- subject(:formatter) { described_class.new }
5
-
6
- its(:format) { should eq 'cli' }
7
- its(:user_interaction?) { should be true }
8
-
9
- describe '#bold, #red, #green, #amber, #blue, #colorize' do
10
- it 'returns the correct bold string' do
11
- expect(formatter.bold('Text')).to eq "\e[1mText\e[0m"
12
- end
13
-
14
- it 'returns the correct red string' do
15
- expect(formatter.red('Text')).to eq "\e[31mText\e[0m"
16
- end
17
-
18
- it 'returns the correct green string' do
19
- expect(formatter.green('Another Text')).to eq "\e[32mAnother Text\e[0m"
20
- end
21
-
22
- it 'returns the correct amber string' do
23
- expect(formatter.amber('Text')).to eq "\e[33mText\e[0m"
24
- end
25
-
26
- it 'returns the correct blue string' do
27
- expect(formatter.blue('Text')).to eq "\e[34mText\e[0m"
28
- end
29
- end
30
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Formatter::Json do
4
- it_behaves_like CMSScanner::Formatter::Buffer
5
-
6
- subject(:formatter) { described_class.new }
7
- let(:output_file) { File.join(FIXTURES, 'output.txt') }
8
-
9
- before { formatter.views_directories << FIXTURES_VIEWS }
10
-
11
- its(:format) { should eq 'json' }
12
- its(:user_interaction?) { should be false }
13
-
14
- describe '#output' do
15
- it 'puts the rendered text in the buffer' do
16
- 2.times { formatter.output('@render_me', test: 'Working') }
17
-
18
- expect(formatter.buffer).to eq "\"test\": \"Working\",\n" * 2
19
- end
20
- end
21
-
22
- describe '#beautify' do
23
- it 'writes the buffer in the file' do
24
- 2.times { formatter.output('@render_me', test: 'yolo') }
25
-
26
- expect($stdout).to receive(:puts).with(JSON.pretty_generate(JSON.parse('{"test": "yolo"}')))
27
- formatter.beautify
28
- end
29
- end
30
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::FantasticoFileslist do
4
- subject(:file) { described_class.new(url) }
5
- let(:url) { 'http://example.com/robots.txt' }
6
- let(:fixtures) { File.join(FIXTURES_FINDERS, 'interesting_files', 'fantastico_fileslist') }
7
-
8
- describe '#interesting_entries' do
9
- let(:headers) { { 'Content-Type' => 'text/plain; charset=utf-8' } }
10
-
11
- after do
12
- body = File.new(File.join(fixtures, fixture)).read
13
-
14
- stub_request(:get, file.url).to_return(headers: headers, body: body)
15
-
16
- expect(file.interesting_entries).to eq @expected
17
- end
18
-
19
- context 'when empty or / entries' do
20
- let(:fixture) { 'fantastico_fileslist.txt' }
21
-
22
- it 'ignores them and only returns the others' do
23
- @expected = %w(data.sql admin.txt)
24
- end
25
- end
26
- end
27
-
28
- describe '#references' do
29
- its(:references) { should_not be_nil }
30
- end
31
- end
@@ -1,51 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::Headers do
4
- subject(:file) { described_class.new(url) }
5
- let(:url) { 'http://example.com/' }
6
- let(:fixtures) { File.join(FIXTURES_FINDERS, 'interesting_files', 'headers') }
7
- let(:fixture) { File.join(fixtures, 'interesting.txt') }
8
- let(:headers) { {} }
9
-
10
- before { stub_request(:get, file.url).to_return(headers: headers) }
11
-
12
- describe '#known_headers' do
13
- it 'does not contains dupliactes' do
14
- expect(file.known_headers).to eql file.known_headers.uniq
15
- end
16
- end
17
-
18
- describe '#entries' do
19
- after { expect(file.entries).to eq @expected if @expected }
20
-
21
- context 'when no headers' do
22
- its(:entries) { should eq({}) }
23
- end
24
-
25
- context 'when headers' do
26
- let(:headers) { parse_headers_file(fixture) }
27
-
28
- it 'returns the headers' do
29
- @expected = headers
30
- end
31
- end
32
- end
33
-
34
- describe '#interesting_entries' do
35
- after { expect(file.interesting_entries).to eq @expected if @expected }
36
-
37
- context 'when interesting headers' do
38
- let(:headers) { parse_headers_file(fixture) }
39
-
40
- it 'returns an array with the headers' do
41
- @expected = ['Server: nginx/1.1.19', 'X-Powered-By: ASP.NET, PHP', 'X-Article-Id: 12']
42
- end
43
- end
44
-
45
- context 'when no interesting headers' do
46
- let(:headers) { parse_headers_file(File.join(fixtures, 'no_interesting.txt')) }
47
-
48
- its(:interesting_entries) { should eq [] }
49
- end
50
- end
51
- end
@@ -1,69 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::InterestingFile do
4
- it_behaves_like CMSScanner::Finders::Finding
5
-
6
- subject(:file) { described_class.new(url, opts) }
7
- let(:opts) { {} }
8
- let(:url) { 'http://example.com/' }
9
- let(:fixtures) { File.join(FIXTURES_FINDERS, 'interesting_files') }
10
-
11
- describe '#entries' do
12
- after do
13
- stub_request(:get, file.url).to_return(headers: headers, body: @body)
14
-
15
- expect(file.entries).to eq @expected
16
- end
17
-
18
- context 'when content-type matches text/plain' do
19
- let(:headers) { { 'Content-Type' => 'text/plain; charset=utf-8' } }
20
-
21
- it 'returns the file content as an array w/o empty strings' do
22
- @body = File.new(File.join(fixtures, 'file.txt')).read
23
- @expected = ['This is', 'a test file', 'with some content']
24
- end
25
- end
26
-
27
- context 'when other content-type' do
28
- let(:headers) { { 'Content-Type' => 'text.html; charset=utf-8' } }
29
-
30
- it 'returns an empty array' do
31
- @expected = []
32
- end
33
- end
34
- end
35
-
36
- describe '#==' do
37
- context 'when same URL' do
38
- it 'returns true' do
39
- expect(file == described_class.new(url)).to be true
40
- end
41
- end
42
-
43
- context 'when not the same URL' do
44
- it 'returns false' do
45
- expect(file == described_class.new('http://e.org')).to be false
46
- end
47
- end
48
- end
49
-
50
- describe '#<=>' do
51
- context 'when same URL' do
52
- it 'returns 0' do
53
- expect(file <=> described_class.new(url)).to eql 0
54
- end
55
- end
56
-
57
- context 'when the other URL <= current one' do
58
- it 'returns 1' do
59
- expect(file <=> described_class.new('http://e.org')).to eql 1
60
- end
61
- end
62
-
63
- context 'when the other URL >= current one' do
64
- it 'returns -1' do
65
- expect(file <=> described_class.new('http://exi.org/')).to eql(-1)
66
- end
67
- end
68
- end
69
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CMSScanner::RobotsTxt do
4
- subject(:file) { described_class.new(url) }
5
- let(:url) { 'http://example.com/robots.txt' }
6
- let(:fixtures) { File.join(FIXTURES_FINDERS, 'interesting_files', 'robots_txt') }
7
-
8
- describe '#interesting_entries' do
9
- let(:headers) { { 'Content-Type' => 'text/plain; charset=utf-8' } }
10
-
11
- after do
12
- body = File.new(File.join(fixtures, fixture)).read
13
-
14
- stub_request(:get, file.url).to_return(headers: headers, body: body)
15
-
16
- expect(file.interesting_entries).to eq @expected
17
- end
18
-
19
- context 'when empty or / entries' do
20
- let(:fixture) { 'robots.txt' }
21
-
22
- it 'ignores them and only returns the others' do
23
- @expected = %w(/admin /public/home)
24
- end
25
- end
26
- end
27
- end