wpscan 3.8.28 → 4.0.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.
- checksums.yaml +4 -4
- data/README.md +104 -30
- data/app/app.rb +26 -0
- data/app/controllers/aliases.rb +2 -2
- data/app/controllers/authenticated_inventory.rb +43 -0
- data/app/controllers/core/cli_options.rb +151 -0
- data/app/controllers/core.rb +200 -25
- data/app/controllers/custom_directories.rb +1 -1
- data/app/controllers/enumeration/cli_options.rb +21 -31
- data/app/controllers/enumeration/enum_methods.rb +145 -38
- data/app/controllers/enumeration.rb +26 -3
- data/app/controllers/interesting_findings.rb +25 -0
- data/app/controllers/main_theme.rb +1 -1
- data/app/controllers/password_attack.rb +14 -6
- data/app/controllers/vuln_api.rb +9 -3
- data/app/controllers/wp_version.rb +1 -1
- data/app/controllers.rb +1 -0
- data/app/finders/backup_folders/known_locations.rb +66 -0
- data/app/finders/backup_folders.rb +19 -0
- data/app/finders/config_backups/known_filenames.rb +6 -4
- data/app/finders/config_backups.rb +1 -1
- data/app/finders/db_exports/known_locations.rb +16 -14
- data/app/finders/db_exports.rb +1 -1
- data/app/finders/interesting_findings/backup_db.rb +1 -1
- data/app/finders/interesting_findings/debug_log.rb +1 -1
- data/app/finders/interesting_findings/duplicator_installer_log.rb +1 -1
- data/app/finders/interesting_findings/emergency_pwd_reset_script.rb +1 -1
- data/app/finders/interesting_findings/fantastico_fileslist.rb +21 -0
- data/app/finders/interesting_findings/full_path_disclosure.rb +1 -1
- data/app/finders/interesting_findings/headers.rb +17 -0
- data/app/finders/interesting_findings/mu_plugins.rb +1 -1
- data/app/finders/interesting_findings/multisite.rb +1 -1
- data/app/finders/interesting_findings/php_disabled.rb +2 -2
- data/app/finders/interesting_findings/readme.rb +1 -1
- data/app/finders/interesting_findings/registration.rb +1 -1
- data/app/finders/interesting_findings/robots_txt.rb +20 -0
- data/app/finders/interesting_findings/search_replace_db_2.rb +19 -0
- data/app/finders/interesting_findings/tmm_db_migrate.rb +1 -1
- data/app/finders/interesting_findings/upload_directory_listing.rb +1 -1
- data/app/finders/interesting_findings/upload_sql_dump.rb +2 -2
- data/app/finders/interesting_findings/wp_cron.rb +1 -1
- data/app/finders/interesting_findings/xml_rpc.rb +61 -0
- data/app/finders/interesting_findings.rb +13 -4
- data/app/finders/main_theme/css_style_in_homepage.rb +1 -1
- data/app/finders/main_theme/urls_in_homepage.rb +3 -7
- data/app/finders/main_theme/woo_framework_meta_generator.rb +4 -4
- data/app/finders/main_theme.rb +1 -1
- data/app/finders/medias/attachment_brute_forcing.rb +2 -2
- data/app/finders/medias.rb +1 -1
- data/app/finders/passwords/wp_login.rb +2 -2
- data/app/finders/passwords/xml_rpc.rb +2 -2
- data/app/finders/passwords/xml_rpc_multicall.rb +1 -1
- data/app/finders/plugin_version/readme.rb +1 -1
- data/app/finders/plugin_version.rb +1 -1
- data/app/finders/plugins/known_locations.rb +17 -7
- data/app/finders/plugins/urls_in_homepage.rb +3 -7
- data/app/finders/plugins/wp_json_api.rb +85 -0
- data/app/finders/plugins.rb +2 -1
- data/app/finders/theme_version/style.rb +1 -1
- data/app/finders/theme_version/woo_framework_meta_generator.rb +1 -1
- data/app/finders/theme_version.rb +1 -1
- data/app/finders/themes/known_locations.rb +12 -6
- data/app/finders/themes/urls_in_homepage.rb +3 -7
- data/app/finders/themes/wp_json_api.rb +74 -0
- data/app/finders/themes.rb +2 -1
- data/app/finders/timthumb_version/bad_request.rb +1 -1
- data/app/finders/timthumb_version.rb +1 -1
- data/app/finders/timthumbs/known_locations.rb +6 -4
- data/app/finders/timthumbs.rb +1 -1
- data/app/finders/users/author_id_brute_forcing.rb +11 -7
- data/app/finders/users/author_posts.rb +1 -1
- data/app/finders/users/author_sitemap.rb +1 -1
- data/app/finders/users/login_error_messages.rb +1 -1
- data/app/finders/users/oembed_api.rb +3 -1
- data/app/finders/users/wp_json_api.rb +11 -7
- data/app/finders/users.rb +1 -1
- data/app/finders/wp_version/atom_generator.rb +1 -1
- data/app/finders/wp_version/rdf_generator.rb +1 -1
- data/app/finders/wp_version/readme.rb +1 -1
- data/app/finders/wp_version/rss_generator.rb +1 -1
- data/app/finders/wp_version/unique_fingerprinting.rb +2 -2
- data/app/finders/wp_version.rb +1 -1
- data/app/finders.rb +1 -0
- data/app/formatters/cli.rb +79 -0
- data/app/formatters/cli_no_color.rb +9 -0
- data/app/formatters/cli_no_colour.rb +17 -0
- data/app/formatters/json.rb +14 -0
- data/app/formatters/jsonl.rb +29 -0
- data/app/formatters/sarif.rb +311 -0
- data/app/models/backup_folder.rb +39 -0
- data/app/models/fantastico_fileslist.rb +34 -0
- data/app/models/headers.rb +44 -0
- data/app/models/interesting_finding.rb +41 -2
- data/app/models/plugin.rb +8 -2
- data/app/models/robots_txt.rb +31 -0
- data/app/models/search_replace_db_2.rb +17 -0
- data/app/models/theme.rb +9 -2
- data/app/models/timthumb.rb +2 -2
- data/app/models/user.rb +35 -0
- data/app/models/version.rb +49 -0
- data/app/models/wp_item/wordpress_org_data.rb +55 -0
- data/app/models/wp_item.rb +109 -9
- data/app/models/wp_version.rb +2 -2
- data/app/models/xml_rpc.rb +73 -3
- data/app/models.rb +2 -1
- data/app/user_agents.txt +46 -0
- data/app/views/cli/core/banner.erb +3 -3
- data/app/views/cli/core/finished.erb +15 -0
- data/app/views/cli/core/help.erb +4 -0
- data/app/views/cli/core/started.erb +11 -0
- data/app/views/cli/enumeration/backup_folders.erb +11 -0
- data/app/views/cli/enumeration/plugin.erb +13 -0
- data/app/views/cli/enumeration/plugins.erb +1 -12
- data/app/views/cli/enumeration/theme.erb +4 -0
- data/app/views/cli/enumeration/themes.erb +1 -3
- data/app/views/cli/enumeration/user.erb +4 -0
- data/app/views/cli/enumeration/users.erb +1 -3
- data/app/views/cli/finding.erb +1 -1
- data/app/views/cli/interesting_findings/_array.erb +10 -0
- data/app/views/cli/interesting_findings/findings.erb +23 -0
- data/app/views/cli/scan_aborted.erb +5 -0
- data/app/views/cli/update_aborted.erb +5 -0
- data/app/views/cli/vuln_api/status.erb +2 -0
- data/app/views/cli/vulnerability.erb +6 -0
- data/app/views/cli/wp_item.erb +4 -1
- data/app/views/json/core/banner.erb +2 -8
- data/app/views/json/core/finished.erb +13 -0
- data/app/views/json/core/help.erb +4 -0
- data/app/views/json/core/started.erb +10 -0
- data/app/views/json/enumeration/backup_folders.erb +11 -0
- data/app/views/json/enumeration/plugin.erb +15 -0
- data/app/views/json/enumeration/theme.erb +5 -0
- data/app/views/json/enumeration/user.erb +6 -0
- data/app/views/json/finding.erb +8 -2
- data/app/views/json/interesting_findings/findings.erb +24 -0
- data/app/views/json/notice.erb +1 -0
- data/app/views/json/scan_aborted.erb +5 -0
- data/app/views/json/update_aborted.erb +5 -0
- data/app/views/json/vuln_api/status.erb +2 -0
- data/app/views/json/wp_item.erb +4 -1
- data/bin/wpscan +1 -0
- data/lib/opt_parse_validator/config_files_loader_merger/base.rb +26 -0
- data/lib/opt_parse_validator/config_files_loader_merger/json.rb +17 -0
- data/lib/opt_parse_validator/config_files_loader_merger/yml.rb +17 -0
- data/lib/opt_parse_validator/config_files_loader_merger.rb +62 -0
- data/lib/opt_parse_validator/errors.rb +9 -0
- data/lib/opt_parse_validator/hacks.rb +19 -0
- data/lib/opt_parse_validator/opts/alias.rb +28 -0
- data/lib/opt_parse_validator/opts/array.rb +34 -0
- data/lib/opt_parse_validator/opts/base.rb +142 -0
- data/lib/opt_parse_validator/opts/boolean.rb +19 -0
- data/lib/opt_parse_validator/opts/choice.rb +43 -0
- data/lib/opt_parse_validator/opts/credentials.rb +15 -0
- data/lib/opt_parse_validator/opts/directory_path.rb +17 -0
- data/lib/opt_parse_validator/opts/file_path.rb +34 -0
- data/lib/opt_parse_validator/opts/headers.rb +33 -0
- data/lib/opt_parse_validator/opts/integer.rb +15 -0
- data/lib/opt_parse_validator/opts/integer_range.rb +37 -0
- data/lib/opt_parse_validator/opts/multi_choices.rb +135 -0
- data/lib/opt_parse_validator/opts/path.rb +78 -0
- data/lib/opt_parse_validator/opts/positive_integer.rb +16 -0
- data/lib/opt_parse_validator/opts/proxy.rb +7 -0
- data/lib/opt_parse_validator/opts/regexp.rb +14 -0
- data/lib/opt_parse_validator/opts/smart_list.rb +30 -0
- data/lib/opt_parse_validator/opts/string.rb +8 -0
- data/lib/opt_parse_validator/opts/uri.rb +41 -0
- data/lib/opt_parse_validator/opts/url.rb +11 -0
- data/lib/opt_parse_validator/opts.rb +9 -0
- data/lib/opt_parse_validator/version.rb +6 -0
- data/lib/opt_parse_validator.rb +161 -0
- data/lib/wpscan/browser/actions.rb +48 -0
- data/lib/wpscan/browser/options.rb +92 -0
- data/lib/wpscan/browser.rb +87 -2
- data/lib/wpscan/browser_authenticator.rb +64 -0
- data/lib/wpscan/cache/file_store.rb +77 -0
- data/lib/wpscan/cache/typhoeus.rb +25 -0
- data/lib/wpscan/controller.rb +100 -4
- data/lib/wpscan/controllers.rb +78 -3
- data/lib/wpscan/db/dynamic_finders/base.rb +3 -7
- data/lib/wpscan/db/dynamic_finders/plugin.rb +2 -2
- data/lib/wpscan/db/dynamic_finders/wordpress.rb +1 -1
- data/lib/wpscan/db/fingerprints.rb +2 -2
- data/lib/wpscan/db/updater.rb +23 -13
- data/lib/wpscan/db/vuln_api.rb +19 -7
- data/lib/wpscan/db/wp_item.rb +2 -2
- data/lib/wpscan/errors/enumeration.rb +4 -4
- data/lib/wpscan/errors/http.rb +82 -3
- data/lib/wpscan/errors/saml.rb +28 -0
- data/lib/wpscan/errors/scan.rb +14 -0
- data/lib/wpscan/errors/update.rb +11 -3
- data/lib/wpscan/errors/vuln_api.rb +24 -0
- data/lib/wpscan/errors/wordpress.rb +2 -2
- data/lib/wpscan/errors/wp_auth.rb +37 -0
- data/lib/wpscan/errors.rb +4 -3
- data/lib/wpscan/exit_code.rb +25 -0
- data/lib/wpscan/finders/base_finders.rb +45 -0
- data/lib/wpscan/finders/dynamic_finder/finder.rb +1 -1
- data/lib/wpscan/finders/dynamic_finder/version/body_pattern.rb +1 -1
- data/lib/wpscan/finders/dynamic_finder/version/comment.rb +1 -1
- data/lib/wpscan/finders/dynamic_finder/version/header_pattern.rb +1 -1
- data/lib/wpscan/finders/dynamic_finder/version/javascript_var.rb +1 -1
- data/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +3 -5
- data/lib/wpscan/finders/dynamic_finder/version/xpath.rb +1 -1
- data/lib/wpscan/finders/dynamic_finder/wp_items/finder.rb +3 -3
- data/lib/wpscan/finders/dynamic_finder/wp_version.rb +1 -1
- data/lib/wpscan/finders/finder/breadth_first_dictionary_attack.rb +257 -0
- data/lib/wpscan/finders/finder/enumerator.rb +77 -0
- data/lib/wpscan/finders/finder/fingerprinter.rb +48 -0
- data/lib/wpscan/finders/finder/smart_url_checker/findings.rb +33 -0
- data/lib/wpscan/finders/finder/smart_url_checker.rb +60 -0
- data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +1 -1
- data/lib/wpscan/finders/finder.rb +78 -0
- data/lib/wpscan/finders/finding.rb +54 -0
- data/lib/wpscan/finders/findings.rb +33 -0
- data/lib/wpscan/finders/independent_finder.rb +33 -0
- data/lib/wpscan/finders/independent_finders.rb +26 -0
- data/lib/wpscan/finders/same_type_finder.rb +19 -0
- data/lib/wpscan/finders/same_type_finders.rb +28 -0
- data/lib/wpscan/finders/unique_finder.rb +19 -0
- data/lib/wpscan/finders/unique_finders.rb +47 -0
- data/lib/wpscan/finders.rb +11 -12
- data/lib/wpscan/formatter/buffer.rb +17 -0
- data/lib/wpscan/formatter.rb +152 -0
- data/lib/wpscan/helper.rb +7 -1
- data/lib/wpscan/http_status_tracking.rb +128 -0
- data/lib/wpscan/numeric.rb +13 -0
- data/lib/wpscan/parsed_cli.rb +31 -2
- data/lib/wpscan/progressbar_null_output.rb +23 -0
- data/lib/wpscan/public_suffix/domain.rb +44 -0
- data/lib/wpscan/references.rb +118 -4
- data/lib/wpscan/scan.rb +127 -0
- data/lib/wpscan/target/hashes.rb +45 -0
- data/lib/wpscan/target/platform/php.rb +124 -0
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +3 -3
- data/lib/wpscan/target/platform/wordpress.rb +7 -8
- data/lib/wpscan/target/platform.rb +3 -0
- data/lib/wpscan/target/scope.rb +103 -0
- data/lib/wpscan/target/server/apache.rb +27 -0
- data/lib/wpscan/target/server/generic.rb +72 -0
- data/lib/wpscan/target/server/iis.rb +29 -0
- data/lib/wpscan/target/server/nginx.rb +27 -0
- data/lib/wpscan/target/server.rb +6 -0
- data/lib/wpscan/target.rb +129 -9
- data/lib/wpscan/typhoeus/hydra.rb +12 -0
- data/lib/wpscan/typhoeus/response.rb +24 -1
- data/lib/wpscan/version.rb +1 -1
- data/lib/wpscan/vulnerability.rb +49 -3
- data/lib/wpscan/vulnerability_filter.rb +68 -0
- data/lib/wpscan/vulnerable.rb +13 -1
- data/lib/wpscan/web_site.rb +152 -0
- data/lib/wpscan.rb +126 -29
- metadata +362 -20
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WPScan
|
|
4
|
+
module Model
|
|
5
|
+
class WpItem
|
|
6
|
+
# Fetches and exposes the public wordpress.org info API response for a
|
|
7
|
+
# plugin or theme. The HTTP call is performed at most once per item.
|
|
8
|
+
module WordpressOrgData
|
|
9
|
+
# Timeout (in seconds) for the wordpress.org API lookup. Kept low so a
|
|
10
|
+
# slow or unreachable wordpress.org does not noticeably stall the scan.
|
|
11
|
+
WORDPRESS_ORG_API_TIMEOUT = 5
|
|
12
|
+
|
|
13
|
+
# @return [ String, nil ] The wordpress.org API URL returning info for
|
|
14
|
+
# this item. Subclasses override this; nil disables the lookup.
|
|
15
|
+
def wordpress_org_api_url
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [ Hash ] Empty hash if the item is not on wordpress.org or the
|
|
20
|
+
# lookup fails.
|
|
21
|
+
def wordpress_org_data
|
|
22
|
+
return @wordpress_org_data if defined?(@wordpress_org_data)
|
|
23
|
+
|
|
24
|
+
@wordpress_org_data = fetch_wordpress_org_data
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Number of active installs as reported by the wordpress.org API.
|
|
28
|
+
# See https://codex.wordpress.org/WordPress.org_API
|
|
29
|
+
#
|
|
30
|
+
# @return [ Integer, nil ]
|
|
31
|
+
def active_installs
|
|
32
|
+
wordpress_org_data['active_installs']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# @return [ Hash ]
|
|
38
|
+
def fetch_wordpress_org_data
|
|
39
|
+
url = wordpress_org_api_url
|
|
40
|
+
return {} unless url
|
|
41
|
+
|
|
42
|
+
res = Browser.get(url, connecttimeout: WORDPRESS_ORG_API_TIMEOUT, timeout: WORDPRESS_ORG_API_TIMEOUT)
|
|
43
|
+
return {} unless res.code == 200
|
|
44
|
+
|
|
45
|
+
data = JSON.parse(res.body)
|
|
46
|
+
data.is_a?(Hash) ? data : {}
|
|
47
|
+
rescue StandardError
|
|
48
|
+
{}
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
include WordpressOrgData
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/app/models/wp_item.rb
CHANGED
|
@@ -6,8 +6,8 @@ module WPScan
|
|
|
6
6
|
class WpItem
|
|
7
7
|
include Vulnerable
|
|
8
8
|
include Finders::Finding
|
|
9
|
-
include
|
|
10
|
-
include
|
|
9
|
+
include WPScan::Target::Platform::PHP
|
|
10
|
+
include WPScan::Target::Server::Generic
|
|
11
11
|
|
|
12
12
|
# Most common readme filenames, based on checking all public plugins and themes.
|
|
13
13
|
READMES = %w[readme.txt README.txt README.md readme.md Readme.txt].freeze
|
|
@@ -71,9 +71,109 @@ module WPScan
|
|
|
71
71
|
@popular ||= metadata['popular'] ? true : false
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
# @return [ String ]
|
|
74
|
+
# @return [ String, nil ]
|
|
75
75
|
def last_updated
|
|
76
|
-
|
|
76
|
+
resolve_last_updated unless defined?(@last_updated)
|
|
77
|
+
@last_updated
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @return [ String, nil ] 'db', 'wordpress.org', or nil when last_updated is unknown
|
|
81
|
+
def last_updated_source
|
|
82
|
+
resolve_last_updated unless defined?(@last_updated_source)
|
|
83
|
+
@last_updated_source
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# WordPress.org takes precedence over local DB metadata since the WPScan
|
|
87
|
+
# DB is not synced in real time and may be stale.
|
|
88
|
+
def resolve_last_updated
|
|
89
|
+
if (api_value = wordpress_org_data['last_updated'])
|
|
90
|
+
@last_updated = api_value
|
|
91
|
+
@last_updated_source = 'WordPress.org'
|
|
92
|
+
elsif (db_value = metadata['last_updated'])
|
|
93
|
+
@last_updated = db_value
|
|
94
|
+
@last_updated_source = 'db'
|
|
95
|
+
else
|
|
96
|
+
@last_updated = nil
|
|
97
|
+
@last_updated_source = nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @return [ String, nil ] Human-friendly relative time hint for last_updated
|
|
102
|
+
# (e.g. "3 months ago"). nil when last_updated cannot be parsed.
|
|
103
|
+
def last_updated_relative
|
|
104
|
+
@last_updated_relative ||= relative_time_for(last_updated)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Parenthesized annotation appended to the CLI "Last Updated" line, e.g.
|
|
108
|
+
# " (3 months ago, per wordpress.org)". Empty string when there is nothing
|
|
109
|
+
# to annotate.
|
|
110
|
+
#
|
|
111
|
+
# @return [ String ]
|
|
112
|
+
def last_updated_cli_suffix
|
|
113
|
+
parts = []
|
|
114
|
+
parts << last_updated_relative if last_updated_relative
|
|
115
|
+
parts << 'per WordPress.org' if last_updated_source == 'WordPress.org'
|
|
116
|
+
parts.empty? ? '' : " (#{parts.join(', ')})"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# ISO 8601 (UTC) representation of last_updated, used by the JSON output so
|
|
120
|
+
# downstream consumers always see a consistent format regardless of whether
|
|
121
|
+
# the value came from the local DB or the wordpress.org API.
|
|
122
|
+
#
|
|
123
|
+
# @return [ String, nil ]
|
|
124
|
+
def last_updated_iso
|
|
125
|
+
return @last_updated_iso if defined?(@last_updated_iso)
|
|
126
|
+
|
|
127
|
+
@last_updated_iso = parse_last_updated&.iso8601
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Friendly representation of last_updated, used in CLI output, matching the
|
|
131
|
+
# wordpress.org API style (e.g. "2026-04-14 12:01pm GMT"). Falls back to the
|
|
132
|
+
# raw string when the value cannot be parsed.
|
|
133
|
+
#
|
|
134
|
+
# @return [ String, nil ]
|
|
135
|
+
def last_updated_display
|
|
136
|
+
return @last_updated_display if defined?(@last_updated_display)
|
|
137
|
+
|
|
138
|
+
time = parse_last_updated
|
|
139
|
+
@last_updated_display = time ? time.strftime('%Y-%m-%d %-l:%M%P GMT') : last_updated
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# @return [ Time, nil ] last_updated parsed as UTC Time, or nil
|
|
143
|
+
def parse_last_updated
|
|
144
|
+
value = last_updated
|
|
145
|
+
return nil if value.nil? || value.to_s.strip.empty?
|
|
146
|
+
|
|
147
|
+
Time.parse(value.to_s).utc
|
|
148
|
+
rescue ArgumentError, TypeError
|
|
149
|
+
nil
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# @param [ String, nil ] value A timestamp parseable by Time.parse
|
|
153
|
+
# @return [ String, nil ]
|
|
154
|
+
def relative_time_for(value)
|
|
155
|
+
return nil if value.nil? || value.to_s.strip.empty?
|
|
156
|
+
|
|
157
|
+
time = Time.parse(value.to_s).utc
|
|
158
|
+
delta = Time.now.utc - time
|
|
159
|
+
return 'in the future' if delta.negative?
|
|
160
|
+
|
|
161
|
+
seconds = delta.to_i
|
|
162
|
+
case seconds
|
|
163
|
+
when 0...60 then 'just now'
|
|
164
|
+
when 60...3600 then pluralize_unit(seconds / 60, 'minute')
|
|
165
|
+
when 3600...86_400 then pluralize_unit(seconds / 3600, 'hour')
|
|
166
|
+
when 86_400...2_592_000 then pluralize_unit(seconds / 86_400, 'day')
|
|
167
|
+
when 2_592_000...31_536_000 then pluralize_unit(seconds / 2_592_000, 'month')
|
|
168
|
+
else pluralize_unit(seconds / 31_536_000, 'year')
|
|
169
|
+
end
|
|
170
|
+
rescue ArgumentError, TypeError
|
|
171
|
+
nil
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @return [ String ]
|
|
175
|
+
def pluralize_unit(count, unit)
|
|
176
|
+
"#{count} #{unit}#{'s' if count != 1} ago"
|
|
77
177
|
end
|
|
78
178
|
|
|
79
179
|
# @return [ Boolean ]
|
|
@@ -133,9 +233,9 @@ module WPScan
|
|
|
133
233
|
#
|
|
134
234
|
# @return [ Boolean ]
|
|
135
235
|
def directory_listing?(path = nil, params = {})
|
|
136
|
-
return if detection_opts[:mode] == :passive
|
|
236
|
+
return false if detection_opts[:mode] == :passive
|
|
137
237
|
|
|
138
|
-
super
|
|
238
|
+
super
|
|
139
239
|
end
|
|
140
240
|
|
|
141
241
|
# @param [ String ] path
|
|
@@ -143,12 +243,12 @@ module WPScan
|
|
|
143
243
|
#
|
|
144
244
|
# @return [ Boolean ]
|
|
145
245
|
def error_log?(path = 'error_log', params = {})
|
|
146
|
-
return if detection_opts[:mode] == :passive
|
|
246
|
+
return false if detection_opts[:mode] == :passive
|
|
147
247
|
|
|
148
|
-
super
|
|
248
|
+
super
|
|
149
249
|
end
|
|
150
250
|
|
|
151
|
-
# See
|
|
251
|
+
# See WPScan::Target#head_and_get
|
|
152
252
|
#
|
|
153
253
|
# This is used by the error_log? above in the super()
|
|
154
254
|
# to have the correct path (ie readme.txt checked from the plugin/theme location
|
data/app/models/wp_version.rb
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
module WPScan
|
|
4
4
|
module Model
|
|
5
5
|
# WP Version
|
|
6
|
-
class WpVersion <
|
|
6
|
+
class WpVersion < WPScan::Model::Version
|
|
7
7
|
include Vulnerable
|
|
8
8
|
|
|
9
9
|
def initialize(number, opts = {})
|
|
10
10
|
raise Error::InvalidWordPressVersion unless WpVersion.valid?(number.to_s)
|
|
11
11
|
|
|
12
|
-
super
|
|
12
|
+
super
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# @param [ String ] number
|
data/app/models/xml_rpc.rb
CHANGED
|
@@ -2,9 +2,79 @@
|
|
|
2
2
|
|
|
3
3
|
module WPScan
|
|
4
4
|
module Model
|
|
5
|
-
#
|
|
6
|
-
class XMLRPC <
|
|
7
|
-
include References
|
|
5
|
+
# XML-RPC interface.
|
|
6
|
+
class XMLRPC < InterestingFinding
|
|
7
|
+
include References
|
|
8
|
+
|
|
9
|
+
# @return [ String ]
|
|
10
|
+
def to_s
|
|
11
|
+
@to_s ||= "XML-RPC seems to be enabled: #{url}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [ Browser ]
|
|
15
|
+
def browser
|
|
16
|
+
@browser ||= WPScan::Browser.instance
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [ Array<String> ]
|
|
20
|
+
def available_methods
|
|
21
|
+
return @available_methods if @available_methods
|
|
22
|
+
|
|
23
|
+
@available_methods = []
|
|
24
|
+
|
|
25
|
+
res = method_call('system.listMethods').run
|
|
26
|
+
doc = Nokogiri::XML.parse(res.body)
|
|
27
|
+
|
|
28
|
+
doc.search('methodResponse params param value array data value string').each do |s|
|
|
29
|
+
@available_methods << s.text
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@available_methods
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [ Boolean ] Whether or not the XMLRPC is enabled
|
|
36
|
+
def enabled?
|
|
37
|
+
!available_methods.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @param [ String ] method_name
|
|
41
|
+
# @param [ Array ] method_params
|
|
42
|
+
# @param [ Hash ] request_params
|
|
43
|
+
#
|
|
44
|
+
# @return [ Typhoeus::Request ]
|
|
45
|
+
def method_call(method_name, method_params = [], request_params = {})
|
|
46
|
+
browser.forge_request(
|
|
47
|
+
url,
|
|
48
|
+
request_params.merge(
|
|
49
|
+
method: :post,
|
|
50
|
+
body: ::XMLRPC::Create.new.methodCall(method_name, *method_params)
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @param [ Array<Array> ] methods_and_params
|
|
56
|
+
# @param [ Hash ] request_params
|
|
57
|
+
#
|
|
58
|
+
# Example of methods_and_params:
|
|
59
|
+
# [
|
|
60
|
+
# [method1, param1, param2],
|
|
61
|
+
# [method2, param1],
|
|
62
|
+
# [method3]
|
|
63
|
+
# ]
|
|
64
|
+
#
|
|
65
|
+
# @return [ Typhoeus::Request ]
|
|
66
|
+
def multi_call(methods_and_params = [], request_params = {})
|
|
67
|
+
browser.forge_request(
|
|
68
|
+
url,
|
|
69
|
+
request_params.merge(
|
|
70
|
+
method: :post,
|
|
71
|
+
body: ::XMLRPC::Create.new.methodCall(
|
|
72
|
+
'system.multicall',
|
|
73
|
+
methods_and_params.collect { |m| { methodName: m[0], params: m[1..] } }
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
end
|
|
8
78
|
|
|
9
79
|
# @return [ Hash ]
|
|
10
80
|
def references
|
data/app/models.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module WPScan
|
|
4
4
|
module Model
|
|
5
|
-
include CMSScanner::Model
|
|
6
5
|
end
|
|
7
6
|
end
|
|
8
7
|
|
|
@@ -10,9 +9,11 @@ require_relative 'models/interesting_finding'
|
|
|
10
9
|
require_relative 'models/wp_version'
|
|
11
10
|
require_relative 'models/xml_rpc'
|
|
12
11
|
require_relative 'models/wp_item'
|
|
12
|
+
require_relative 'models/wp_item/wordpress_org_data'
|
|
13
13
|
require_relative 'models/timthumb'
|
|
14
14
|
require_relative 'models/media'
|
|
15
15
|
require_relative 'models/plugin'
|
|
16
16
|
require_relative 'models/theme'
|
|
17
17
|
require_relative 'models/config_backup'
|
|
18
18
|
require_relative 'models/db_export'
|
|
19
|
+
require_relative 'models/backup_folder'
|
data/app/user_agents.txt
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Windows
|
|
2
|
+
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5
|
|
3
|
+
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14
|
|
4
|
+
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.27 (KHTML, like Gecko) Chrome/12.0.712.0 Safari/534.27
|
|
5
|
+
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.24 Safari/535.1
|
|
6
|
+
Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0E)
|
|
7
|
+
Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
|
|
8
|
+
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
|
|
9
|
+
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
|
|
10
|
+
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6
|
|
11
|
+
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.1) Gecko/20100101 Firefox/10.0.1
|
|
12
|
+
Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0
|
|
13
|
+
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20120427 Firefox/15.0a1
|
|
14
|
+
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)
|
|
15
|
+
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
|
|
16
|
+
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0)
|
|
17
|
+
Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00
|
|
18
|
+
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
|
|
19
|
+
|
|
20
|
+
# MAC
|
|
21
|
+
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.15 Safari/534.13
|
|
22
|
+
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15
|
|
23
|
+
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
|
|
24
|
+
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418.8 (KHTML, like Gecko) Safari/419.3
|
|
25
|
+
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3
|
|
26
|
+
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2; rv:10.0.1) Gecko/20100101 Firefox/10.0.1
|
|
27
|
+
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10
|
|
28
|
+
|
|
29
|
+
# Linux
|
|
30
|
+
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.20 Safari/535.1
|
|
31
|
+
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24
|
|
32
|
+
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100915 Gentoo Firefox/3.6.9
|
|
33
|
+
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.16) Gecko/20120421 Gecko Firefox/11.0
|
|
34
|
+
Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
|
|
35
|
+
Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00
|
|
36
|
+
Mozilla/5.0 (X11; U; Linux x86_64; us; rv:1.9.1.19) Gecko/20110430 shadowfox/7.0 (like Firefox/7.0
|
|
37
|
+
|
|
38
|
+
# iPad
|
|
39
|
+
Mozilla/5.0 (iPad; CPU OS 7_1_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D201 Safari/9537.53
|
|
40
|
+
Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53
|
|
41
|
+
Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25
|
|
42
|
+
|
|
43
|
+
# iPhone
|
|
44
|
+
Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53
|
|
45
|
+
Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B511 Safari/9537.53
|
|
46
|
+
Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D201 Safari/9537.53
|
|
@@ -6,9 +6,9 @@ _______________________________________________________________
|
|
|
6
6
|
\ /\ / | | ____) | (__| (_| | | | |
|
|
7
7
|
\/ \/ |_| |_____/ \___|\__,_|_| |_|
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
WordPress Security Scanner
|
|
10
10
|
Version <%= WPScan::VERSION %>
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
An Automattic endeavor
|
|
12
|
+
https://automattic.com
|
|
13
13
|
_______________________________________________________________
|
|
14
14
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%= info_icon %> Finished: <%= @stop_time.asctime %>
|
|
2
|
+
<%= info_icon %> Requests Done: <%= @requests_done %>
|
|
3
|
+
<%= info_icon %> Cached Requests: <%= @cached_requests %>
|
|
4
|
+
<% if @response_status_codes && !@response_status_codes.empty? -%>
|
|
5
|
+
<%= info_icon %> Most response codes received: <%= @response_status_codes.map { |label, count| "#{label}: #{count}" }.join(', ') %>
|
|
6
|
+
<% end -%>
|
|
7
|
+
<% if @response_status_codes_warnings && !@response_status_codes_warnings.empty? -%>
|
|
8
|
+
<% @response_status_codes_warnings.each do |warning| -%>
|
|
9
|
+
<%= warning_icon %> <%= warning %>
|
|
10
|
+
<% end -%>
|
|
11
|
+
<% end -%>
|
|
12
|
+
<%= info_icon %> Data Sent: <%= @data_sent.bytes_to_human %>
|
|
13
|
+
<%= info_icon %> Data Received: <%= @data_received.bytes_to_human %>
|
|
14
|
+
<%= info_icon %> Memory used: <%= @used_memory.bytes_to_human %>
|
|
15
|
+
<%= info_icon %> Elapsed time: <%= Time.at(@elapsed).utc.strftime('%H:%M:%S') %>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<%= info_icon %> URL: <%= @url %> [<%= @ip %>]
|
|
2
|
+
<% if @url != @effective_url -%>
|
|
3
|
+
<%= info_icon %> Effective URL: <%= @effective_url %>
|
|
4
|
+
<% end -%>
|
|
5
|
+
<%= info_icon %> Started: <%= @start_time.asctime %>
|
|
6
|
+
<%= info_icon %> Command Line: wpscan <%= @command_line %>
|
|
7
|
+
<%= info_icon %> Hostname: <%= @hostname %>
|
|
8
|
+
<% if WPScan::ParsedCli.exclude_vulns && !WPScan::ParsedCli.exclude_vulns.empty? -%>
|
|
9
|
+
<%= warning_icon %> Excluded vulnerabilities: <%= Array(WPScan::ParsedCli.exclude_vulns).join(', ') %>
|
|
10
|
+
<% end -%>
|
|
11
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<% if @backup_folders.empty? -%>
|
|
2
|
+
<%= notice_icon %> No Backup Folders Found.
|
|
3
|
+
<% else -%>
|
|
4
|
+
<%= notice_icon %> Backup Folder(s) Identified:
|
|
5
|
+
<% @backup_folders.each do |backup_folder| -%>
|
|
6
|
+
|
|
7
|
+
<% icon = backup_folder.severity == :high ? critical_icon : warning_icon -%>
|
|
8
|
+
<%= icon %> <%= backup_folder %>
|
|
9
|
+
<%= render('@finding', item: backup_folder) -%>
|
|
10
|
+
<% end -%>
|
|
11
|
+
<% end %>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<%= bar_clear -%>
|
|
2
|
+
|
|
3
|
+
<%= info_icon %> <%= @plugin %>
|
|
4
|
+
<%= render('@wp_item', wp_item: @plugin) -%>
|
|
5
|
+
|
|
|
6
|
+
<%= render('@finding', item: @plugin) -%>
|
|
7
|
+
|
|
|
8
|
+
<% if @plugin.version -%>
|
|
9
|
+
| Version: <%= @plugin.version %> (<%= @plugin.version.confidence %>% confidence)
|
|
10
|
+
<%= render('@finding', item: @plugin.version) -%>
|
|
11
|
+
<% else -%>
|
|
12
|
+
| The version could not be determined.
|
|
13
|
+
<% end -%>
|
|
@@ -4,17 +4,6 @@
|
|
|
4
4
|
<% else -%>
|
|
5
5
|
<%= notice_icon %> Plugin(s) Identified:
|
|
6
6
|
<% @plugins.each do |plugin| -%>
|
|
7
|
-
|
|
8
|
-
<%= info_icon %> <%= plugin %>
|
|
9
|
-
<%= render('@wp_item', wp_item: plugin) -%>
|
|
10
|
-
|
|
|
11
|
-
<%= render('@finding', item: plugin) -%>
|
|
12
|
-
|
|
|
13
|
-
<% if plugin.version -%>
|
|
14
|
-
| Version: <%= plugin.version %> (<%= plugin.version.confidence %>% confidence)
|
|
15
|
-
<%= render('@finding', item: plugin.version) -%>
|
|
16
|
-
<% else -%>
|
|
17
|
-
| The version could not be determined.
|
|
18
|
-
<% end -%>
|
|
7
|
+
<%= render('plugin', plugin: plugin) -%>
|
|
19
8
|
<% end -%>
|
|
20
9
|
<% end %>
|
data/app/views/cli/finding.erb
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<% end -%>
|
|
19
19
|
<% end -%>
|
|
20
20
|
<% end -%>
|
|
21
|
-
<% if @item.respond_to?(:
|
|
21
|
+
<% if @item.respond_to?(:filtered_vulnerabilities) && !(vulns = @item.filtered_vulnerabilities).empty? -%>
|
|
22
22
|
<% vulns_size = vulns.size -%>
|
|
23
23
|
|
|
|
24
24
|
| <%= critical_icon %> <%= vulns_size %> <%= vulns_size == 1 ? 'vulnerability' : 'vulnerabilities' %> identified:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<% unless @findings.empty? -%>
|
|
2
|
+
Interesting Finding(s):
|
|
3
|
+
<% @findings.each do |finding| -%>
|
|
4
|
+
|
|
5
|
+
<%= info_icon %> <%= finding %>
|
|
6
|
+
<%= render('_array', a: finding.interesting_entries, s: 'Interesting Entry', p: 'Interesting Entries') -%>
|
|
7
|
+
| Found By: <%= finding.found_by %>
|
|
8
|
+
<% if finding.confidence > 0 -%>
|
|
9
|
+
| Confidence: <%= finding.confidence %>%
|
|
10
|
+
<% end -%>
|
|
11
|
+
<% unless (confirmed = finding.confirmed_by).empty? -%>
|
|
12
|
+
<% if confirmed.size == 1 -%>
|
|
13
|
+
| Confirmed By: <%= confirmed.first.found_by %><% if confirmed.first.confidence > 0 %>, <%= confirmed.first.confidence %>% confidence<% end %>
|
|
14
|
+
<% else -%>
|
|
15
|
+
| Confirmed By:
|
|
16
|
+
<% confirmed.each do |c| -%>
|
|
17
|
+
| - <%= c.found_by %><% if c.confidence > 0 %>, <%= c.confidence %>% confidence<% end %>
|
|
18
|
+
<% end -%>
|
|
19
|
+
<% end -%>
|
|
20
|
+
<% end -%>
|
|
21
|
+
<%= render('_array', a: finding.references_urls, s: 'Reference', p: 'References') -%>
|
|
22
|
+
<% end -%>
|
|
23
|
+
<% end %>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<% unless @status.empty? -%>
|
|
2
2
|
<% if @status['http_error'] -%>
|
|
3
3
|
<%= critical_icon %> WPScan DB API, <%= @status['http_error'].to_s %>
|
|
4
|
+
<% elsif @status['parse_error'] -%>
|
|
5
|
+
<%= critical_icon %> WPScan DB API returned an invalid response. Please check your network/proxy configuration or try again later.
|
|
4
6
|
<% else -%>
|
|
5
7
|
<%= info_icon %> WPScan DB API OK
|
|
6
8
|
| Plan: <%= @status['plan'] %>
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
| <%= critical_icon %> Title: <%= @v.title %>
|
|
2
|
+
<% if @v.uuid -%>
|
|
3
|
+
| UUID: <%= @v.uuid %>
|
|
4
|
+
<% end -%>
|
|
2
5
|
<% if @v.cvss -%>
|
|
3
6
|
| CVSS: <%= @v.cvss[:score] %> (<%= @v.cvss[:vector] %>)
|
|
4
7
|
<% end -%>
|
|
5
8
|
<% if @v.fixed_in -%>
|
|
6
9
|
| Fixed in: <%= @v.fixed_in %>
|
|
7
10
|
<% end -%>
|
|
11
|
+
<% if @v.poc -%>
|
|
12
|
+
| PoC: available
|
|
13
|
+
<% end -%>
|
|
8
14
|
<% unless (references = @v.references_urls).empty? -%>
|
|
9
15
|
<% if references.size == 1 -%>
|
|
10
16
|
| Reference: <%= references.first %>
|
data/app/views/cli/wp_item.erb
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
| Latest Version: <%= @wp_item.latest_version %><% if @wp_item.version %> (up to date)<% end %>
|
|
4
4
|
<% end -%>
|
|
5
5
|
<% if @wp_item.last_updated -%>
|
|
6
|
-
| Last Updated: <%= @wp_item.
|
|
6
|
+
| Last Updated: <%= @wp_item.last_updated_display %><%= @wp_item.last_updated_cli_suffix %>
|
|
7
|
+
<% end -%>
|
|
8
|
+
<% if @wp_item.active_installs -%>
|
|
9
|
+
| Active Installs: <%= ActiveSupport::NumberHelper.number_to_delimited(@wp_item.active_installs) %> (per WordPress.org)
|
|
7
10
|
<% end -%>
|
|
8
11
|
<% if @wp_item.readme_url -%>
|
|
9
12
|
| Readme: <%= @wp_item.readme_url %>
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
"banner": {
|
|
2
|
-
"description": "WordPress Security Scanner
|
|
2
|
+
"description": "WordPress Security Scanner",
|
|
3
3
|
"version": <%= WPScan::VERSION.to_json %>,
|
|
4
|
-
"
|
|
5
|
-
"@_WPScan_",
|
|
6
|
-
"@ethicalhack3r",
|
|
7
|
-
"@erwan_lr",
|
|
8
|
-
"@firefart"
|
|
9
|
-
],
|
|
10
|
-
"sponsor": <%= WPScan::DB::Sponsor.text.to_json %>
|
|
4
|
+
"sponsor": "An Automattic endeavor"
|
|
11
5
|
},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"stop_time": <%= @stop_time.to_i %>,
|
|
2
|
+
"elapsed": <%= @elapsed.to_i %>,
|
|
3
|
+
"requests_done": <%= @requests_done.to_i %>,
|
|
4
|
+
"cached_requests": <%= @cached_requests.to_i %>,
|
|
5
|
+
"response_status_codes": <%= @response_status_codes.to_json %>,
|
|
6
|
+
"response_status_codes_warning": <%= @response_status_codes_warning %>,
|
|
7
|
+
"response_status_codes_warnings": <%= @response_status_codes_warnings.to_json %>,
|
|
8
|
+
"data_sent": <%= @data_sent.to_i %>,
|
|
9
|
+
"data_sent_humanised": <%= @data_sent.bytes_to_human.to_json %>,
|
|
10
|
+
"data_received": <%= @data_received.to_i %>,
|
|
11
|
+
"data_received_humanised": <%= @data_received.bytes_to_human.to_json %>,
|
|
12
|
+
"used_memory": <%= @used_memory.to_i %>,
|
|
13
|
+
"used_memory_humanised": <%= @used_memory.bytes_to_human.to_json %>,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"start_time": <%= @start_time.to_i %>,
|
|
2
|
+
"start_memory": <%= @start_memory.to_i %>,
|
|
3
|
+
"command_line": <%= "wpscan #{@command_line}".to_json %>,
|
|
4
|
+
"hostname": <%= @hostname.to_s.to_json %>,
|
|
5
|
+
"target_url": <%= @url.to_s.to_json %>,
|
|
6
|
+
"target_ip": <%= @ip.to_s.to_json %>,
|
|
7
|
+
"effective_url": <%= @effective_url.to_s.to_json %>,
|
|
8
|
+
<% if WPScan::ParsedCli.exclude_vulns && !WPScan::ParsedCli.exclude_vulns.empty? -%>
|
|
9
|
+
"excluded_vulnerabilities": <%= Array(WPScan::ParsedCli.exclude_vulns).to_json %>,
|
|
10
|
+
<% end -%>
|