wpscan 3.7.9 → 3.8.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.
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
  - - ">="