cms_scanner 0.10.0 → 0.12.2
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.
- checksums.yaml +4 -4
- data/app/models/fantastico_fileslist.rb +12 -2
- data/app/models/headers.rb +1 -1
- data/app/models/robots_txt.rb +5 -0
- data/app/models/search_replace_db_2.rb +5 -0
- data/lib/cms_scanner/cache/file_store.rb +1 -1
- data/lib/cms_scanner/finders/base_finders.rb +2 -2
- data/lib/cms_scanner/finders/finder.rb +3 -1
- data/lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb +12 -8
- data/lib/cms_scanner/finders/finder/enumerator.rb +1 -1
- data/lib/cms_scanner/numeric.rb +1 -1
- data/lib/cms_scanner/progressbar_null_output.rb +1 -1
- data/lib/cms_scanner/references.rb +2 -2
- data/lib/cms_scanner/target.rb +6 -6
- data/lib/cms_scanner/target/platform/php.rb +1 -1
- data/lib/cms_scanner/target/scope.rb +4 -4
- data/lib/cms_scanner/target/server/generic.rb +1 -1
- data/lib/cms_scanner/version.rb +1 -1
- data/lib/cms_scanner/web_site.rb +1 -1
- metadata +36 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 943549919eeec0dc993e93789c543064401359f1673b030e7520ac49eddd8b67
|
4
|
+
data.tar.gz: db1524123914c10872586742d1b52bb50550391c5b6b2c56ceaae541b9ff27ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a70bd9df89f08639549c44c5611bcd1cdab4712d85e02cd2a9b2fe37cb31ab61fe5bb407464686b8abd1a68f7b3986675b17ffe287a967acbe536a6153f5a5c9
|
7
|
+
data.tar.gz: 48e01f3d443bd2b78e0ad4fd5e63c8d80ecc4c3bbc40886b5355d4d604a14d985734d90ed3707a22addf7b45fd8c8bcee8e00898bbe4caf7e3fe2cc0025f4093
|
@@ -2,8 +2,16 @@
|
|
2
2
|
|
3
3
|
module CMSScanner
|
4
4
|
module Model
|
5
|
-
#
|
5
|
+
# Fantastico is a commercial script library that automates the installation of web applications to a website.
|
6
|
+
# Fantastico scripts are executed from the administration area of a website control panel such as cPanel.
|
7
|
+
# It creates a file named fantastico_fileslist.txt that is publicly available and contains a list of all the
|
8
|
+
# files from the current directory. The contents of this file may expose sensitive information to an attacker.
|
6
9
|
class FantasticoFileslist < InterestingFinding
|
10
|
+
# @return [ String ]
|
11
|
+
def to_s
|
12
|
+
@to_s ||= "Fantastico list found: #{url}"
|
13
|
+
end
|
14
|
+
|
7
15
|
# @return [ Array<String> ] The interesting files/dirs detected
|
8
16
|
def interesting_entries
|
9
17
|
results = []
|
@@ -17,7 +25,9 @@ module CMSScanner
|
|
17
25
|
end
|
18
26
|
|
19
27
|
def references
|
20
|
-
@references ||= {
|
28
|
+
@references ||= {
|
29
|
+
url: ['https://web.archive.org/web/20140518040021/http://www.acunetix.com/vulnerabilities/fantastico-fileslist/']
|
30
|
+
}
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
data/app/models/headers.rb
CHANGED
data/app/models/robots_txt.rb
CHANGED
@@ -4,6 +4,11 @@ module CMSScanner
|
|
4
4
|
module Model
|
5
5
|
# Robots.txt
|
6
6
|
class RobotsTxt < InterestingFinding
|
7
|
+
# @return [ String ]
|
8
|
+
def to_s
|
9
|
+
@to_s ||= "robots.txt found: #{url}"
|
10
|
+
end
|
11
|
+
|
7
12
|
# @todo Better detection, currently everything not empty or / is returned
|
8
13
|
#
|
9
14
|
# @return [ Array<String> ] The interesting Allow/Disallow rules detected
|
@@ -4,6 +4,11 @@ module CMSScanner
|
|
4
4
|
module Model
|
5
5
|
# SearchReplaceDB2
|
6
6
|
class SearchReplaceDB2 < InterestingFinding
|
7
|
+
# @return [ String ]
|
8
|
+
def to_s
|
9
|
+
@to_s ||= "Search Replace DB script found: #{url}"
|
10
|
+
end
|
11
|
+
|
7
12
|
def references
|
8
13
|
@references ||= { url: ['https://interconnectit.com/products/search-and-replace-for-wordpress-databases/'] }
|
9
14
|
end
|
@@ -21,14 +21,14 @@ module CMSScanner
|
|
21
21
|
|
22
22
|
return symbols if mode.nil? || mode == :mixed
|
23
23
|
|
24
|
-
symbols.include?(mode) ?
|
24
|
+
symbols.include?(mode) ? Array(mode) : []
|
25
25
|
end
|
26
26
|
|
27
27
|
# @param [ CMSScanner::Finders::Finder ] finder
|
28
28
|
# @param [ Symbol ] symbol See return values of #symbols_from_mode
|
29
29
|
# @param [ Hash ] opts
|
30
30
|
def run_finder(finder, symbol, opts)
|
31
|
-
|
31
|
+
Array(finder.send(symbol, opts.merge(found: findings))).compact.each do |found|
|
32
32
|
findings << found
|
33
33
|
end
|
34
34
|
end
|
@@ -57,10 +57,12 @@ module CMSScanner
|
|
57
57
|
# @param [String, Class ] klass
|
58
58
|
# @return [ String ]
|
59
59
|
def found_by(klass = self.class)
|
60
|
+
labels = %w[aggressive passive]
|
61
|
+
|
60
62
|
caller_locations.each do |call|
|
61
63
|
label = call.label
|
62
64
|
|
63
|
-
next unless
|
65
|
+
next unless labels.include? label
|
64
66
|
|
65
67
|
title = klass.to_s.demodulize.gsub(/(\d+)[a-z]+/i, '_\0').titleize(keep_id_suffix: true)
|
66
68
|
|
@@ -6,20 +6,22 @@ module CMSScanner
|
|
6
6
|
# Module to provide an easy way to perform password attacks
|
7
7
|
module BreadthFirstDictionaryAttack
|
8
8
|
# @param [ Array<CMSScanner::Model::User> ] users
|
9
|
-
# @param [
|
9
|
+
# @param [ String ] wordlist_path
|
10
10
|
# @param [ Hash ] opts
|
11
11
|
# @option opts [ Boolean ] :show_progression
|
12
12
|
#
|
13
13
|
# @yield [ CMSScanner::User ] When a valid combination is found
|
14
14
|
#
|
15
15
|
# Due to Typhoeus threads shenanigans, in rare cases the progress-bar might
|
16
|
-
# be
|
16
|
+
# be incorrectly updated, hence the 'rescue ProgressBar::InvalidProgressError'
|
17
17
|
#
|
18
18
|
# TODO: Make rubocop happy about metrics etc
|
19
19
|
#
|
20
20
|
# rubocop:disable all
|
21
|
-
def attack(users,
|
22
|
-
|
21
|
+
def attack(users, wordlist_path, opts = {})
|
22
|
+
wordlist = File.open(wordlist_path)
|
23
|
+
|
24
|
+
create_progress_bar(total: users.size * wordlist.count, show_progression: opts[:show_progression])
|
23
25
|
|
24
26
|
queue_count = 0
|
25
27
|
# Keep the number of requests sent for each users
|
@@ -28,7 +30,7 @@ module CMSScanner
|
|
28
30
|
|
29
31
|
users.each { |u| user_requests_count[u.username] = 0 }
|
30
32
|
|
31
|
-
|
33
|
+
File.foreach(wordlist, chomp: true) do |password|
|
32
34
|
remaining_users = users.select { |u| u.password.nil? }
|
33
35
|
|
34
36
|
break if remaining_users.empty?
|
@@ -47,7 +49,7 @@ module CMSScanner
|
|
47
49
|
user.password = password
|
48
50
|
|
49
51
|
begin
|
50
|
-
progress_bar.total -=
|
52
|
+
progress_bar.total -= wordlist.count - user_requests_count[user.username]
|
51
53
|
rescue ProgressBar::InvalidProgressError
|
52
54
|
end
|
53
55
|
|
@@ -103,10 +105,12 @@ module CMSScanner
|
|
103
105
|
'Request timed out.'
|
104
106
|
elsif response.code.zero?
|
105
107
|
"No response from remote server. WAF/IPS? (#{response.return_message})"
|
106
|
-
elsif
|
108
|
+
elsif response.code.to_s.start_with?('50')
|
107
109
|
'Server error, try reducing the number of threads.'
|
108
|
-
|
110
|
+
elsif NS::ParsedCli.verbose?
|
109
111
|
"Unknown response received Code: #{response.code}\nBody: #{response.body}"
|
112
|
+
else
|
113
|
+
"Unknown response received Code: #{response.code}"
|
110
114
|
end
|
111
115
|
|
112
116
|
progress_bar.log("Error: #{error}")
|
@@ -55,7 +55,7 @@ module CMSScanner
|
|
55
55
|
# @return [ Typhoeus::Response, nil ]
|
56
56
|
def maybe_get_full_response(head_res, opts)
|
57
57
|
return head_res unless opts[:check_full_response] == true ||
|
58
|
-
|
58
|
+
Array(opts[:check_full_response]).include?(head_res.code)
|
59
59
|
|
60
60
|
full_res = NS::Browser.get(head_res.effective_url, full_request_params)
|
61
61
|
|
data/lib/cms_scanner/numeric.rb
CHANGED
@@ -21,9 +21,9 @@ module CMSScanner
|
|
21
21
|
next unless refs.key?(key)
|
22
22
|
|
23
23
|
@references[key] = if key == :youtube
|
24
|
-
|
24
|
+
Array(refs[:youtube]).map { |id| youtube_url(id) }
|
25
25
|
else
|
26
|
-
|
26
|
+
Array(refs[key]).map(&:to_s)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
data/lib/cms_scanner/target.rb
CHANGED
@@ -18,7 +18,7 @@ module CMSScanner
|
|
18
18
|
super(url, opts)
|
19
19
|
|
20
20
|
scope << uri.host
|
21
|
-
|
21
|
+
Array(opts[:scope]).each { |s| scope << s }
|
22
22
|
end
|
23
23
|
|
24
24
|
# @param [ Hash ] opts
|
@@ -105,11 +105,11 @@ module CMSScanner
|
|
105
105
|
next unless attr_value && !attr_value.empty?
|
106
106
|
|
107
107
|
node_uri = begin
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
uri.join(attr_value.strip)
|
109
|
+
rescue StandardError
|
110
|
+
# Skip potential malformed URLs etc.
|
111
|
+
next
|
112
|
+
end
|
113
113
|
|
114
114
|
next unless node_uri.host
|
115
115
|
|
@@ -5,7 +5,7 @@ module CMSScanner
|
|
5
5
|
module Platform
|
6
6
|
# Some PHP specific implementation
|
7
7
|
module PHP
|
8
|
-
DEBUG_LOG_PATTERN = /(?:\[\d{2}
|
8
|
+
DEBUG_LOG_PATTERN = /(?:\[\d{2}-[a-zA-Z]{3}-\d{4}\s\d{2}:\d{2}:\d{2}\s[A-Z]{3}\]|
|
9
9
|
PHP\s(?:Fatal|Warning|Strict|Error|Notice):)/x.freeze
|
10
10
|
FPD_PATTERN = /Fatal error:.+? in (.+?) on/.freeze
|
11
11
|
ERROR_LOG_PATTERN = /PHP Fatal error/i.freeze
|
@@ -53,14 +53,14 @@ module CMSScanner
|
|
53
53
|
domains = [uri.host + uri.path]
|
54
54
|
|
55
55
|
domains += if scope.domains.empty?
|
56
|
-
|
56
|
+
Array(scope.invalid_domains[1..-1])
|
57
57
|
else
|
58
|
-
|
58
|
+
Array(scope.domains[1..-1]).map(&:to_s) + scope.invalid_domains
|
59
59
|
end
|
60
60
|
|
61
|
-
domains.map! { |d| Regexp.escape(d.
|
61
|
+
domains.map! { |d| Regexp.escape(d.delete_suffix('/')).gsub('\*', '.*').gsub('/', '\\\\\?/') }
|
62
62
|
|
63
|
-
domains[0].gsub!(Regexp.escape(uri.host), Regexp.escape(uri.host)
|
63
|
+
domains[0].gsub!(Regexp.escape(uri.host), "#{Regexp.escape(uri.host)}(?::\\d+)?") if uri.port
|
64
64
|
|
65
65
|
@scope_url_pattern = %r{https?:\\?/\\?/(?:#{domains.join('|')})\\?/?}i
|
66
66
|
end
|
@@ -41,7 +41,7 @@ module CMSScanner
|
|
41
41
|
def directory_listing?(path = nil, params = {})
|
42
42
|
res = NS::Browser.get(url(path), params)
|
43
43
|
|
44
|
-
res.code == 200 && res.body
|
44
|
+
res.code == 200 && res.body.include?('<h1>Index of') ? true : false
|
45
45
|
end
|
46
46
|
|
47
47
|
# @param [ String ] path
|
data/lib/cms_scanner/version.rb
CHANGED
data/lib/cms_scanner/web_site.rb
CHANGED
@@ -62,7 +62,7 @@ module CMSScanner
|
|
62
62
|
|
63
63
|
# @return [ String ] The URL of an unlikely existant page
|
64
64
|
def error_404_url
|
65
|
-
@error_404_url ||= uri.join(Digest::MD5.hexdigest(rand(999_999).to_s)[0..6]
|
65
|
+
@error_404_url ||= uri.join("#{Digest::MD5.hexdigest(rand(999_999).to_s)[0..6]}.html").to_s
|
66
66
|
end
|
67
67
|
|
68
68
|
# Checks if the remote website is up.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cms_scanner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WPScanTeam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: get_process_mem
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.11.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.11.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: opt_parse_validator
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.9.
|
47
|
+
version: 1.9.3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.9.
|
54
|
+
version: 1.9.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: public_suffix
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,30 +70,42 @@ dependencies:
|
|
70
70
|
name: ruby-progressbar
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.10'
|
76
|
+
- - "<"
|
74
77
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.
|
78
|
+
version: '1.12'
|
76
79
|
type: :runtime
|
77
80
|
prerelease: false
|
78
81
|
version_requirements: !ruby/object:Gem::Requirement
|
79
82
|
requirements:
|
80
|
-
- - "
|
83
|
+
- - ">="
|
81
84
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.10
|
85
|
+
version: '1.10'
|
86
|
+
- - "<"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.12'
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
90
|
name: typhoeus
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
86
92
|
requirements:
|
87
|
-
- - "
|
93
|
+
- - ">="
|
88
94
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.3
|
95
|
+
version: '1.3'
|
96
|
+
- - "<"
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '1.5'
|
90
99
|
type: :runtime
|
91
100
|
prerelease: false
|
92
101
|
version_requirements: !ruby/object:Gem::Requirement
|
93
102
|
requirements:
|
94
|
-
- - "
|
103
|
+
- - ">="
|
95
104
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.3
|
105
|
+
version: '1.3'
|
106
|
+
- - "<"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '1.5'
|
97
109
|
- !ruby/object:Gem::Dependency
|
98
110
|
name: xmlrpc
|
99
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,14 +182,14 @@ dependencies:
|
|
170
182
|
requirements:
|
171
183
|
- - "~>"
|
172
184
|
- !ruby/object:Gem::Version
|
173
|
-
version: 3.
|
185
|
+
version: 3.10.0
|
174
186
|
type: :development
|
175
187
|
prerelease: false
|
176
188
|
version_requirements: !ruby/object:Gem::Requirement
|
177
189
|
requirements:
|
178
190
|
- - "~>"
|
179
191
|
- !ruby/object:Gem::Version
|
180
|
-
version: 3.
|
192
|
+
version: 3.10.0
|
181
193
|
- !ruby/object:Gem::Dependency
|
182
194
|
name: rspec-its
|
183
195
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,42 +210,42 @@ dependencies:
|
|
198
210
|
requirements:
|
199
211
|
- - "~>"
|
200
212
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
213
|
+
version: 1.7.0
|
202
214
|
type: :development
|
203
215
|
prerelease: false
|
204
216
|
version_requirements: !ruby/object:Gem::Requirement
|
205
217
|
requirements:
|
206
218
|
- - "~>"
|
207
219
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
220
|
+
version: 1.7.0
|
209
221
|
- !ruby/object:Gem::Dependency
|
210
222
|
name: rubocop-performance
|
211
223
|
requirement: !ruby/object:Gem::Requirement
|
212
224
|
requirements:
|
213
225
|
- - "~>"
|
214
226
|
- !ruby/object:Gem::Version
|
215
|
-
version: 1.
|
227
|
+
version: 1.9.0
|
216
228
|
type: :development
|
217
229
|
prerelease: false
|
218
230
|
version_requirements: !ruby/object:Gem::Requirement
|
219
231
|
requirements:
|
220
232
|
- - "~>"
|
221
233
|
- !ruby/object:Gem::Version
|
222
|
-
version: 1.
|
234
|
+
version: 1.9.0
|
223
235
|
- !ruby/object:Gem::Dependency
|
224
236
|
name: simplecov
|
225
237
|
requirement: !ruby/object:Gem::Requirement
|
226
238
|
requirements:
|
227
239
|
- - "~>"
|
228
240
|
- !ruby/object:Gem::Version
|
229
|
-
version: 0.
|
241
|
+
version: 0.21.0
|
230
242
|
type: :development
|
231
243
|
prerelease: false
|
232
244
|
version_requirements: !ruby/object:Gem::Requirement
|
233
245
|
requirements:
|
234
246
|
- - "~>"
|
235
247
|
- !ruby/object:Gem::Version
|
236
|
-
version: 0.
|
248
|
+
version: 0.21.0
|
237
249
|
- !ruby/object:Gem::Dependency
|
238
250
|
name: simplecov-lcov
|
239
251
|
requirement: !ruby/object:Gem::Requirement
|
@@ -254,14 +266,14 @@ dependencies:
|
|
254
266
|
requirements:
|
255
267
|
- - "~>"
|
256
268
|
- !ruby/object:Gem::Version
|
257
|
-
version: 3.
|
269
|
+
version: 3.11.0
|
258
270
|
type: :development
|
259
271
|
prerelease: false
|
260
272
|
version_requirements: !ruby/object:Gem::Requirement
|
261
273
|
requirements:
|
262
274
|
- - "~>"
|
263
275
|
- !ruby/object:Gem::Version
|
264
|
-
version: 3.
|
276
|
+
version: 3.11.0
|
265
277
|
description: Framework to provide an easy way to implement CMS Scanners
|
266
278
|
email:
|
267
279
|
- team@wpscan.org
|