wpscan 3.7.9 → 3.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -15
  3. data/app/controllers/enumeration/cli_options.rb +2 -3
  4. data/app/controllers/vuln_api.rb +4 -2
  5. data/app/finders/db_exports/known_locations.rb +1 -1
  6. data/app/finders/interesting_findings/backup_db.rb +1 -2
  7. data/app/finders/interesting_findings/debug_log.rb +1 -5
  8. data/app/finders/interesting_findings/duplicator_installer_log.rb +1 -6
  9. data/app/finders/interesting_findings/emergency_pwd_reset_script.rb +1 -4
  10. data/app/finders/interesting_findings/full_path_disclosure.rb +1 -2
  11. data/app/finders/interesting_findings/mu_plugins.rb +2 -14
  12. data/app/finders/interesting_findings/multisite.rb +1 -7
  13. data/app/finders/interesting_findings/registration.rb +1 -6
  14. data/app/finders/interesting_findings/tmm_db_migrate.rb +1 -6
  15. data/app/finders/interesting_findings/upload_directory_listing.rb +1 -6
  16. data/app/finders/interesting_findings/upload_sql_dump.rb +1 -5
  17. data/app/finders/interesting_findings/wp_cron.rb +1 -11
  18. data/app/finders/passwords/xml_rpc.rb +1 -1
  19. data/app/finders/passwords/xml_rpc_multicall.rb +13 -6
  20. data/app/finders/plugin_version/readme.rb +3 -5
  21. data/app/finders/users/wp_json_api.rb +1 -1
  22. data/app/models/interesting_finding.rb +66 -1
  23. data/app/models/timthumb.rb +6 -6
  24. data/app/models/xml_rpc.rb +1 -1
  25. data/app/views/cli/password_attack/users.erb +1 -1
  26. data/app/views/cli/vulnerability.erb +3 -0
  27. data/app/views/json/finding.erb +3 -0
  28. data/lib/wpscan/db/updater.rb +12 -14
  29. data/lib/wpscan/errors/update.rb +12 -0
  30. data/lib/wpscan/finders/dynamic_finder/finder.rb +1 -1
  31. data/lib/wpscan/finders/dynamic_finder/version/config_parser.rb +4 -6
  32. data/lib/wpscan/references.rb +1 -1
  33. data/lib/wpscan/target/platform/wordpress.rb +1 -1
  34. data/lib/wpscan/version.rb +1 -1
  35. data/lib/wpscan/vulnerability.rb +4 -3
  36. metadata +9 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8351294d3eedeff4b00824a523541cac828c5d43a1852900e606dc22c7676f5
4
- data.tar.gz: d589d01854ee40dd87e073ab636745607434d7fdd1f3e48c269276c68a3fe918
3
+ metadata.gz: '095c33e6d410081b90f0ea858284cd4c2040b551830fd1756ab7f70dcae34022'
4
+ data.tar.gz: b8f36a805212d33d7448ebba76a908a2a0cf51e72d1b3df6ce3e434987359864
5
5
  SHA512:
6
- metadata.gz: 6845cdd64b1f715a80b3c932da5e072b465dea4d1af6ec5db67de2585ce8f3366c19ba40071a0de7a6887c79b5db87631630fbad5df4e9de174e29d84afdb5f5
7
- data.tar.gz: 3bb25f129cb00c8a0087d32f88c1423de1bc2d014268d45956e7052134242c3fadeba08cdb183596ce556c76036a08534efc8ef7395a2023d0d614d49185af7c
6
+ metadata.gz: 921466d7d508f0d6f6dddd8e53bab8bf1ce0a7202c778f477ce669c724c9a5348a3e94befafc51e18a331dcc8566946c330493c69c415ba8701612bc59efe4ad
7
+ data.tar.gz: eba875df92089460d02b2bf8b4d00b47149f3d176ff203767dbe02b4a20612db0e868c3b3f17e1e5b3a1f16096f1d89d704ecbbee854cc5f2de7a3b39fea6855
data/README.md CHANGED
@@ -7,10 +7,10 @@
7
7
  <h3 align="center">WPScan</h3>
8
8
 
9
9
  <p align="center">
10
- WordPress Vulnerability Scanner
10
+ WordPress Security Scanner
11
11
  <br>
12
12
  <br>
13
- <a href="https://wpscan.org/" title="homepage" target="_blank">Homepage</a> - <a href="https://wpscan.io/" title="wpscan.io" target="_blank">WPScan.io</a> - <a href="https://wpvulndb.com/" title="vulnerability database" target="_blank">Vulnerability Database</a> - <a href="https://wordpress.org/plugins/wpscan/" title="wordpress plugin" target="_blank">WordPress Plugin</a>
13
+ <a href="https://wpscan.org/" title="homepage" target="_blank">Homepage</a> - <a href="https://wpscan.io/" title="wpscan.io" target="_blank">WPScan.io</a> - <a href="https://wpvulndb.com/" title="vulnerability database" target="_blank">Vulnerability Database</a> - <a href="https://wordpress.org/plugins/wpscan/" title="wordpress security plugin" target="_blank">WordPress Security Plugin</a>
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -31,7 +31,11 @@
31
31
  - RubyGems - Recommended: latest
32
32
  - Nokogiri might require packages to be installed via your package manager depending on your OS, see https://nokogiri.org/tutorials/installing_nokogiri.html
33
33
 
34
- ### From RubyGems (Recommended)
34
+ ### In a Pentesting distribution
35
+
36
+ When using a pentesting distubution (such as Kali Linux), it is recommended to install/update wpscan via the package manager if available.
37
+
38
+ ### From RubyGems
35
39
 
36
40
  ```shell
37
41
  gem install wpscan
@@ -39,18 +43,6 @@ gem install wpscan
39
43
 
40
44
  On MacOSX, if a ```Gem::FilePermissionError``` is raised due to the Apple's System Integrity Protection (SIP), either install RVM and install wpscan again, or run ```sudo gem install -n /usr/local/bin wpscan``` (see [#1286](https://github.com/wpscanteam/wpscan/issues/1286))
41
45
 
42
- ### From sources (NOT Recommended)
43
-
44
- Prerequisites: Git
45
-
46
- ```shell
47
- git clone https://github.com/wpscanteam/wpscan
48
-
49
- cd wpscan/
50
-
51
- bundle install && rake install
52
- ```
53
-
54
46
  # Updating
55
47
 
56
48
  You can update the local database by using ```wpscan --update```
@@ -77,6 +69,8 @@ docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u1-1
77
69
 
78
70
  # Usage
79
71
 
72
+ Full user documentation can be found here; https://github.com/wpscanteam/wpscan/wiki/WPScan-User-Documentation
73
+
80
74
  ```wpscan --url blog.tld``` This will scan the blog using default options with a good compromise between speed and accuracy. For example, the plugins will be checked passively but their version with a mixed detection mode (passively + aggressively). Potential config backup files will also be checked, along with other interesting findings.
81
75
 
82
76
  If a more stealthy approach is required, then ```wpscan --stealthy --url blog.tld``` can be used.
@@ -130,6 +124,11 @@ cli_options:
130
124
  api_token: YOUR_API_TOKEN
131
125
  ```
132
126
 
127
+ ## Load API Token From ENV (since v3.7.10)
128
+
129
+ The API Token will be automatically loaded from the ENV variable `WPSCAN_API_TOKEN` if present. If the `--api-token` CLI option is also provided, the value from the CLI will be used.
130
+
131
+
133
132
  ## Enumerating usernames
134
133
 
135
134
  ```shell
@@ -51,7 +51,7 @@ module WPScan
51
51
  OptSmartList.new(['--plugins-list LIST', 'List of plugins to enumerate'], advanced: true),
52
52
  OptChoice.new(
53
53
  ['--plugins-detection MODE',
54
- 'Use the supplied mode to enumerate Plugins, instead of the global (--detection-mode) mode.'],
54
+ 'Use the supplied mode to enumerate Plugins.'],
55
55
  choices: %w[mixed passive aggressive], normalize: :to_sym, default: :passive
56
56
  ),
57
57
  OptBoolean.new(
@@ -62,8 +62,7 @@ module WPScan
62
62
  ),
63
63
  OptChoice.new(
64
64
  ['--plugins-version-detection MODE',
65
- 'Use the supplied mode to check plugins versions instead of the --detection-mode ' \
66
- 'or --plugins-detection modes.'],
65
+ 'Use the supplied mode to check plugins\' versions.'],
67
66
  choices: %w[mixed passive aggressive], normalize: :to_sym, default: :mixed
68
67
  ),
69
68
  OptInteger.new(
@@ -4,6 +4,8 @@ module WPScan
4
4
  module Controller
5
5
  # Controller to handle the API token
6
6
  class VulnApi < CMSScanner::Controller::Base
7
+ ENV_KEY = 'WPSCAN_API_TOKEN'
8
+
7
9
  def cli_options
8
10
  [
9
11
  OptString.new(['--api-token TOKEN', 'The WPVulnDB API Token to display vulnerability data'])
@@ -11,9 +13,9 @@ module WPScan
11
13
  end
12
14
 
13
15
  def before_scan
14
- return unless ParsedCli.api_token
16
+ return unless ParsedCli.api_token || ENV.key?(ENV_KEY)
15
17
 
16
- DB::VulnApi.token = ParsedCli.api_token
18
+ DB::VulnApi.token = ParsedCli.api_token || ENV[ENV_KEY]
17
19
 
18
20
  api_status = DB::VulnApi.status
19
21
 
@@ -40,7 +40,7 @@ module WPScan
40
40
  # @return [ Hash ]
41
41
  def potential_urls(opts = {})
42
42
  urls = {}
43
- domain_name = PublicSuffix.domain(target.uri.host)[/(^[\w|-]+)/, 1]
43
+ domain_name = (PublicSuffix.domain(target.uri.host) || target.uri.host)[/(^[\w|-]+)/, 1]
44
44
 
45
45
  File.open(opts[:list]).each_with_index do |path, index|
46
46
  path.gsub!('{domain_name}', domain_name)
@@ -16,8 +16,7 @@ module WPScan
16
16
  target.url(path),
17
17
  confidence: 70,
18
18
  found_by: DIRECT_ACCESS,
19
- interesting_entries: target.directory_listing_entries(path),
20
- references: { url: 'https://github.com/wpscanteam/wpscan/issues/422' }
19
+ interesting_entries: target.directory_listing_entries(path)
21
20
  )
22
21
  end
23
22
  end
@@ -11,11 +11,7 @@ module WPScan
11
11
 
12
12
  return unless target.debug_log?(path)
13
13
 
14
- Model::DebugLog.new(
15
- target.url(path),
16
- confidence: 100, found_by: DIRECT_ACCESS,
17
- references: { url: 'https://codex.wordpress.org/Debugging_in_WordPress' }
18
- )
14
+ Model::DebugLog.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
19
15
  end
20
16
  end
21
17
  end
@@ -11,12 +11,7 @@ module WPScan
11
11
 
12
12
  return unless /DUPLICATOR INSTALL-LOG/.match?(target.head_and_get(path).body)
13
13
 
14
- Model::DuplicatorInstallerLog.new(
15
- target.url(path),
16
- confidence: 100,
17
- found_by: DIRECT_ACCESS,
18
- references: { url: 'https://www.exploit-db.com/ghdb/3981/' }
19
- )
14
+ Model::DuplicatorInstallerLog.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
20
15
  end
21
16
  end
22
17
  end
@@ -15,10 +15,7 @@ module WPScan
15
15
  Model::EmergencyPwdResetScript.new(
16
16
  target.url(path),
17
17
  confidence: /password/i.match?(res.body) ? 100 : 40,
18
- found_by: DIRECT_ACCESS,
19
- references: {
20
- url: 'https://codex.wordpress.org/Resetting_Your_Password#Using_the_Emergency_Password_Reset_Script'
21
- }
18
+ found_by: DIRECT_ACCESS
22
19
  )
23
20
  end
24
21
  end
@@ -16,8 +16,7 @@ module WPScan
16
16
  target.url(path),
17
17
  confidence: 100,
18
18
  found_by: DIRECT_ACCESS,
19
- interesting_entries: fpd_entries,
20
- references: { url: 'https://www.owasp.org/index.php/Full_Path_Disclosure' }
19
+ interesting_entries: fpd_entries
21
20
  )
22
21
  end
23
22
  end
@@ -16,13 +16,7 @@ module WPScan
16
16
 
17
17
  target.mu_plugins = true
18
18
 
19
- return Model::MuPlugins.new(
20
- url,
21
- confidence: 70,
22
- found_by: 'URLs In Homepage (Passive Detection)',
23
- to_s: "This site has 'Must Use Plugins': #{url}",
24
- references: { url: 'http://codex.wordpress.org/Must_Use_Plugins' }
25
- )
19
+ return Model::MuPlugins.new(url, confidence: 70, found_by: 'URLs In Homepage (Passive Detection)')
26
20
  end
27
21
  nil
28
22
  end
@@ -37,13 +31,7 @@ module WPScan
37
31
 
38
32
  target.mu_plugins = true
39
33
 
40
- Model::MuPlugins.new(
41
- url,
42
- confidence: 80,
43
- found_by: DIRECT_ACCESS,
44
- to_s: "This site has 'Must Use Plugins': #{url}",
45
- references: { url: 'http://codex.wordpress.org/Must_Use_Plugins' }
46
- )
34
+ Model::MuPlugins.new(url, confidence: 80, found_by: DIRECT_ACCESS)
47
35
  end
48
36
  end
49
37
  end
@@ -17,13 +17,7 @@ module WPScan
17
17
 
18
18
  target.multisite = true
19
19
 
20
- Model::Multisite.new(
21
- url,
22
- confidence: 100,
23
- found_by: DIRECT_ACCESS,
24
- to_s: 'This site seems to be a multisite',
25
- references: { url: 'http://codex.wordpress.org/Glossary#Multisite' }
26
- )
20
+ Model::Multisite.new(url, confidence: 100, found_by: DIRECT_ACCESS)
27
21
  end
28
22
  end
29
23
  end
@@ -20,12 +20,7 @@ module WPScan
20
20
 
21
21
  target.registration_enabled = true
22
22
 
23
- Model::Registration.new(
24
- res.effective_url,
25
- confidence: 100,
26
- found_by: DIRECT_ACCESS,
27
- to_s: "Registration is enabled: #{res.effective_url}"
28
- )
23
+ Model::Registration.new(res.effective_url, confidence: 100, found_by: DIRECT_ACCESS)
29
24
  end
30
25
  end
31
26
  end
@@ -13,12 +13,7 @@ module WPScan
13
13
 
14
14
  return unless res.code == 200 && res.headers['Content-Type'] =~ %r{\Aapplication/zip}i
15
15
 
16
- Model::TmmDbMigrate.new(
17
- url,
18
- confidence: 100,
19
- found_by: DIRECT_ACCESS,
20
- references: { packetstorm: 131_957 }
21
- )
16
+ Model::TmmDbMigrate.new(url, confidence: 100, found_by: DIRECT_ACCESS)
22
17
  end
23
18
  end
24
19
  end
@@ -13,12 +13,7 @@ module WPScan
13
13
 
14
14
  url = target.url(path)
15
15
 
16
- Model::UploadDirectoryListing.new(
17
- url,
18
- confidence: 100,
19
- found_by: DIRECT_ACCESS,
20
- to_s: "Upload directory has listing enabled: #{url}"
21
- )
16
+ Model::UploadDirectoryListing.new(url, confidence: 100, found_by: DIRECT_ACCESS)
22
17
  end
23
18
  end
24
19
  end
@@ -14,11 +14,7 @@ module WPScan
14
14
 
15
15
  return unless SQL_PATTERN.match?(res.body)
16
16
 
17
- Model::UploadSQLDump.new(
18
- target.url(path),
19
- confidence: 100,
20
- found_by: DIRECT_ACCESS
21
- )
17
+ Model::UploadSQLDump.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
22
18
  end
23
19
  end
24
20
  end
@@ -11,17 +11,7 @@ module WPScan
11
11
 
12
12
  return unless res.code == 200
13
13
 
14
- Model::WPCron.new(
15
- wp_cron_url,
16
- confidence: 60,
17
- found_by: DIRECT_ACCESS,
18
- references: {
19
- url: [
20
- 'https://www.iplocation.net/defend-wordpress-from-ddos',
21
- 'https://github.com/wpscanteam/wpscan/issues/1299'
22
- ]
23
- }
24
- )
14
+ Model::WPCron.new(wp_cron_url, confidence: 60, found_by: DIRECT_ACCESS)
25
15
  end
26
16
 
27
17
  def wp_cron_url
@@ -16,7 +16,7 @@ module WPScan
16
16
  end
17
17
 
18
18
  def errored_response?(response)
19
- response.code != 200 && response.body !~ /login_error/i
19
+ response.code != 200 && response.body !~ /Incorrect username or password/i
20
20
  end
21
21
  end
22
22
  end
@@ -75,17 +75,20 @@ module WPScan
75
75
  progress_bar.stop
76
76
  break
77
77
  end
78
-
79
- progress_bar.total = progress_bar.progress + ((passwords.size - wordlist_index) / current_passwords_size.round(1)).ceil
78
+
79
+ begin
80
+ progress_bar.total = progress_bar.progress + ((passwords.size - wordlist_index) / current_passwords_size.round(1)).ceil
81
+ rescue ProgressBar::InvalidProgressError
82
+ end
80
83
  end
81
84
  end
82
85
  # Maybe a progress_bar.stop ?
83
86
  end
84
- # rubocop:disable all
87
+ # rubocop:enable all
85
88
 
86
89
  def passwords_size(max_passwords, users_size)
87
90
  return 1 if max_passwords < users_size
88
- return 0 if users_size == 0
91
+ return 0 if users_size.zero?
89
92
 
90
93
  max_passwords / users_size
91
94
  end
@@ -94,9 +97,13 @@ module WPScan
94
97
  def check_and_output_errors(res)
95
98
  progress_bar.log("Incorrect response: #{res.code} / #{res.return_message}") unless res.code == 200
96
99
 
97
- progress_bar.log('Parsing error, might be caused by a too high --max-passwords value (such as >= 2k)') if res.body =~ /parse error. not well formed/i
100
+ if /parse error. not well formed/i.match?(res.body)
101
+ progress_bar.log('Parsing error, might be caused by a too high --max-passwords value (such as >= 2k)')
102
+ end
103
+
104
+ return unless /requested method [^ ]+ does not exist/i.match?(res.body)
98
105
 
99
- progress_bar.log('The requested method is not supported') if res.body =~ /requested method [^ ]+ does not exist/i
106
+ progress_bar.log('The requested method is not supported')
100
107
  end
101
108
  end
102
109
  end
@@ -68,11 +68,9 @@ module WPScan
68
68
  extracted_versions = extracted_versions.select { |x| x =~ /[0-9]+/ }
69
69
 
70
70
  sorted = extracted_versions.sort do |x, y|
71
- begin
72
- Gem::Version.new(x) <=> Gem::Version.new(y)
73
- rescue StandardError
74
- 0
75
- end
71
+ Gem::Version.new(x) <=> Gem::Version.new(y)
72
+ rescue StandardError
73
+ 0
76
74
  end
77
75
 
78
76
  sorted.last
@@ -21,7 +21,7 @@ module WPScan
21
21
  loop do
22
22
  current_page += 1
23
23
 
24
- res = Typhoeus.get(api_url, params: { per_page: MAX_PER_PAGE, page: current_page })
24
+ res = Browser.get(api_url, params: { per_page: MAX_PER_PAGE, page: current_page })
25
25
 
26
26
  total_pages ||= res.headers['X-WP-TotalPages'].to_i
27
27
 
@@ -8,45 +8,110 @@ module WPScan
8
8
  end
9
9
 
10
10
  #
11
- # Empty classes for the #type to be correctly displayed (as taken from the self.class from the parent)
11
+ # Some classes are empty for the #type to be correctly displayed (as taken from the self.class from the parent)
12
12
  #
13
13
  class BackupDB < InterestingFinding
14
+ # @return [ Hash ]
15
+ def references
16
+ @references ||= { url: ['https://github.com/wpscanteam/wpscan/issues/422'] }
17
+ end
14
18
  end
15
19
 
16
20
  class DebugLog < InterestingFinding
21
+ # @ return [ Hash ]
22
+ def references
23
+ @references ||= { url: ['https://codex.wordpress.org/Debugging_in_WordPress'] }
24
+ end
17
25
  end
18
26
 
19
27
  class DuplicatorInstallerLog < InterestingFinding
28
+ # @return [ Hash ]
29
+ def references
30
+ @references ||= { url: ['https://www.exploit-db.com/ghdb/3981/'] }
31
+ end
20
32
  end
21
33
 
22
34
  class EmergencyPwdResetScript < InterestingFinding
35
+ def references
36
+ @references ||= {
37
+ url: ['https://codex.wordpress.org/Resetting_Your_Password#Using_the_Emergency_Password_Reset_Script']
38
+ }
39
+ end
23
40
  end
24
41
 
25
42
  class FullPathDisclosure < InterestingFinding
43
+ # @return [ Hash ]
44
+ def references
45
+ @references ||= { url: ['https://www.owasp.org/index.php/Full_Path_Disclosure'] }
46
+ end
26
47
  end
27
48
 
28
49
  class MuPlugins < InterestingFinding
50
+ # @return [ String ]
51
+ def to_s
52
+ @to_s ||= "This site has 'Must Use Plugins': #{url}"
53
+ end
54
+
55
+ # @return [ Hash ]
56
+ def references
57
+ @references ||= { url: ['http://codex.wordpress.org/Must_Use_Plugins'] }
58
+ end
29
59
  end
30
60
 
31
61
  class Multisite < InterestingFinding
62
+ # @return [ String ]
63
+ def to_s
64
+ @to_s ||= 'This site seems to be a multisite'
65
+ end
66
+
67
+ # @return [ Hash ]
68
+ def references
69
+ @references ||= { url: ['http://codex.wordpress.org/Glossary#Multisite'] }
70
+ end
32
71
  end
33
72
 
34
73
  class Readme < InterestingFinding
35
74
  end
36
75
 
37
76
  class Registration < InterestingFinding
77
+ # @return [ String ]
78
+ def to_s
79
+ @to_s ||= "Registration is enabled: #{url}"
80
+ end
38
81
  end
39
82
 
40
83
  class TmmDbMigrate < InterestingFinding
84
+ # @return [ Hash ]
85
+ def references
86
+ @references ||= { packetstorm: [131_957] }
87
+ end
41
88
  end
42
89
 
43
90
  class UploadDirectoryListing < InterestingFinding
91
+ # @return [ String ]
92
+ def to_s
93
+ @to_s ||= "Upload directory has listing enabled: #{url}"
94
+ end
44
95
  end
45
96
 
46
97
  class UploadSQLDump < InterestingFinding
47
98
  end
48
99
 
49
100
  class WPCron < InterestingFinding
101
+ # @return [ String ]
102
+ def to_s
103
+ @to_s ||= "The external WP-Cron seems to be enabled: #{url}"
104
+ end
105
+
106
+ # @return [ Hash ]
107
+ def references
108
+ @references ||= {
109
+ url: [
110
+ 'https://www.iplocation.net/defend-wordpress-from-ddos',
111
+ 'https://github.com/wpscanteam/wpscan/issues/1299'
112
+ ]
113
+ }
114
+ end
50
115
  end
51
116
  end
52
117
  end
@@ -40,9 +40,9 @@ module WPScan
40
40
  def rce_132_vuln
41
41
  Vulnerability.new(
42
42
  'Timthumb <= 1.32 Remote Code Execution',
43
- { exploitdb: ['17602'] },
44
- 'RCE',
45
- '1.33'
43
+ references: { exploitdb: ['17602'] },
44
+ type: 'RCE',
45
+ fixed_in: '1.33'
46
46
  )
47
47
  end
48
48
 
@@ -50,12 +50,12 @@ module WPScan
50
50
  def rce_webshot_vuln
51
51
  Vulnerability.new(
52
52
  'Timthumb <= 2.8.13 WebShot Remote Code Execution',
53
- {
53
+ references: {
54
54
  url: ['http://seclists.org/fulldisclosure/2014/Jun/117', 'https://github.com/wpscanteam/wpscan/issues/519'],
55
55
  cve: '2014-4663'
56
56
  },
57
- 'RCE',
58
- '2.8.14'
57
+ type: 'RCE',
58
+ fixed_in: '2.8.14'
59
59
  )
60
60
  end
61
61
 
@@ -8,7 +8,7 @@ module WPScan
8
8
 
9
9
  # @return [ Hash ]
10
10
  def references
11
- {
11
+ @references ||= {
12
12
  url: ['http://codex.wordpress.org/XML-RPC_Pingback_API'],
13
13
  metasploit: [
14
14
  'auxiliary/scanner/http/wordpress_ghost_scanner',
@@ -2,7 +2,7 @@
2
2
  <% if @users.empty? -%>
3
3
  <%= notice_icon %> No Valid Passwords Found.
4
4
  <% else -%>
5
- <%= notice_icon %> Valid Combinations Found:
5
+ <%= critical_icon %> Valid Combinations Found:
6
6
  <% @users.each do |user| -%>
7
7
  | Username: <%= user.username %>, Password: <%= user.password %>
8
8
  <% end -%>
@@ -1,4 +1,7 @@
1
1
  | <%= critical_icon %> Title: <%= @v.title %>
2
+ <% if @v.cvss -%>
3
+ | CVSS: <%= @v.cvss[:score] %> (<%= @v.cvss[:vector] %>)
4
+ <% end -%>
2
5
  <% if @v.fixed_in -%>
3
6
  | Fixed in: <%= @v.fixed_in %>
4
7
  <% end -%>
@@ -19,6 +19,9 @@
19
19
  <% vulns.each_with_index do |v, index| -%>
20
20
  {
21
21
  "title": <%= v.title.to_json %>,
22
+ <% if v.cvss -%>
23
+ "cvss": <%= v.cvss.to_json %>,
24
+ <% end -%>
22
25
  "fixed_in": <%= v.fixed_in.to_json %>,
23
26
  "references": <%= v.references.to_json %>
24
27
  }<% unless index == last_index -%>,<% end -%>
@@ -139,24 +139,22 @@ module WPScan
139
139
  updated = []
140
140
 
141
141
  FILES.each do |filename|
142
- begin
143
- db_checksum = remote_file_checksum(filename)
142
+ db_checksum = remote_file_checksum(filename)
144
143
 
145
- # Checking if the file needs to be updated
146
- next if File.exist?(local_file_path(filename)) && db_checksum == local_file_checksum(filename)
144
+ # Checking if the file needs to be updated
145
+ next if File.exist?(local_file_path(filename)) && db_checksum == local_file_checksum(filename)
147
146
 
148
- create_backup(filename)
149
- dl_checksum = download(filename)
147
+ create_backup(filename)
148
+ dl_checksum = download(filename)
150
149
 
151
- raise "#{filename}: checksums do not match" unless dl_checksum == db_checksum
150
+ raise Error::ChecksumsMismatch, filename unless dl_checksum == db_checksum
152
151
 
153
- updated << filename
154
- rescue StandardError => e
155
- restore_backup(filename)
156
- raise e
157
- ensure
158
- delete_backup(filename) if File.exist?(backup_file_path(filename))
159
- end
152
+ updated << filename
153
+ rescue StandardError => e
154
+ restore_backup(filename)
155
+ raise e
156
+ ensure
157
+ delete_backup(filename) if File.exist?(backup_file_path(filename))
160
158
  end
161
159
 
162
160
  File.write(last_update_file, Time.now)
@@ -8,5 +8,17 @@ module WPScan
8
8
  'Update required, you can not run a scan if a database file is missing.'
9
9
  end
10
10
  end
11
+
12
+ class ChecksumsMismatch < Standard
13
+ attr_reader :db_file
14
+
15
+ def initialize(db_file)
16
+ @db_file = db_file
17
+ end
18
+
19
+ def to_s
20
+ "#{db_file}: checksums do not match. Please try again in a few minutes."
21
+ end
22
+ end
11
23
  end
12
24
  end
@@ -17,7 +17,7 @@ module WPScan
17
17
  end
18
18
 
19
19
  # Needed to have inheritance of the @child_class_constants
20
- # If inheritance is not needed, then the #child_class_constant can be used in the classe definition, ie
20
+ # If inheritance is not needed, then the #child_class_constant can be used in the class definition, ie
21
21
  # child_class_constant :FILES, PATTERN: /aaa/i
22
22
  # @return [ Hash ]
23
23
  def self.child_class_constants
@@ -21,13 +21,11 @@ module WPScan
21
21
  parsers = ALLOWED_PARSERS.include?(self.class::PARSER) ? [self.class::PARSER] : ALLOWED_PARSERS
22
22
 
23
23
  parsers.each do |parser|
24
- begin
25
- parsed = parser.respond_to?(:safe_load) ? parser.safe_load(body) : parser.load(body)
24
+ parsed = parser.respond_to?(:safe_load) ? parser.safe_load(body) : parser.load(body)
26
25
 
27
- return parsed if parsed.is_a?(Hash) || parsed.is_a?(Array)
28
- rescue StandardError
29
- next
30
- end
26
+ return parsed if parsed.is_a?(Hash) || parsed.is_a?(Array)
27
+ rescue StandardError
28
+ next
31
29
  end
32
30
 
33
31
  nil # Make sure nil is returned in case none of the parsers managed to parse the body correctly
@@ -2,7 +2,7 @@
2
2
 
3
3
  module WPScan
4
4
  # References module (which should be included along with the CMSScanner::References)
5
- # to allow the use of the wpvulndb reference
5
+ # to allow the use of the wpvulndb reference.
6
6
  module References
7
7
  extend ActiveSupport::Concern
8
8
 
@@ -48,7 +48,7 @@ module WPScan
48
48
  # @param [ Typhoeus::Response ] response
49
49
  # @return [ Boolean ]
50
50
  def wordpress_from_meta_comments_or_scripts?(response)
51
- in_scope_uris(response, '//link/@href|//script/@src|//img/@src') do |uri|
51
+ in_scope_uris(response, '//link/@href|//script/@src') do |uri|
52
52
  return true if WORDPRESS_PATTERN.match?(uri.path) || WP_JSON_OEMBED_PATTERN.match?(uri.path)
53
53
  end
54
54
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version
4
4
  module WPScan
5
- VERSION = '3.7.9'
5
+ VERSION = '3.8.2'
6
6
  end
@@ -18,9 +18,10 @@ module WPScan
18
18
 
19
19
  new(
20
20
  json_data['title'],
21
- references,
22
- json_data['vuln_type'],
23
- json_data['fixed_in']
21
+ references: references,
22
+ type: json_data['vuln_type'],
23
+ fixed_in: json_data['fixed_in'],
24
+ cvss: json_data['cvss']&.symbolize_keys
24
25
  )
25
26
  end
26
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wpscan
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.9
4
+ version: 3.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - WPScanTeam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-29 00:00:00.000000000 Z
11
+ date: 2020-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cms_scanner
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.8.3
19
+ version: 0.10.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.8.3
26
+ version: 0.10.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -100,28 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.80.0
103
+ version: 0.85.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.80.0
110
+ version: 0.85.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-performance
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.5.0
117
+ version: 1.6.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 1.5.0
124
+ version: 1.6.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: simplecov
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -388,7 +388,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
388
388
  requirements:
389
389
  - - ">="
390
390
  - !ruby/object:Gem::Version
391
- version: '2.4'
391
+ version: '2.5'
392
392
  required_rubygems_version: !ruby/object:Gem::Requirement
393
393
  requirements:
394
394
  - - ">="