wpscan 3.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 +7 -0
- data/Gemfile.lock +139 -0
- data/LICENSE +74 -0
- data/README.md +146 -0
- data/app/app.rb +3 -0
- data/app/controllers.rb +6 -0
- data/app/controllers/brute_force.rb +126 -0
- data/app/controllers/core.rb +104 -0
- data/app/controllers/custom_directories.rb +23 -0
- data/app/controllers/enumeration.rb +53 -0
- data/app/controllers/enumeration/cli_options.rb +126 -0
- data/app/controllers/enumeration/enum_methods.rb +157 -0
- data/app/controllers/main_theme.rb +27 -0
- data/app/controllers/wp_version.rb +30 -0
- data/app/finders.rb +13 -0
- data/app/finders/config_backups.rb +17 -0
- data/app/finders/config_backups/known_filenames.rb +46 -0
- data/app/finders/interesting_findings.rb +33 -0
- data/app/finders/interesting_findings/backup_db.rb +25 -0
- data/app/finders/interesting_findings/debug_log.rb +20 -0
- data/app/finders/interesting_findings/duplicator_installer_log.rb +23 -0
- data/app/finders/interesting_findings/full_path_disclosure.rb +23 -0
- data/app/finders/interesting_findings/mu_plugins.rb +48 -0
- data/app/finders/interesting_findings/multisite.rb +29 -0
- data/app/finders/interesting_findings/readme.rb +26 -0
- data/app/finders/interesting_findings/registration.rb +31 -0
- data/app/finders/interesting_findings/tmm_db_migrate.rb +24 -0
- data/app/finders/interesting_findings/upload_directory_listing.rb +24 -0
- data/app/finders/interesting_findings/upload_sql_dump.rb +28 -0
- data/app/finders/main_theme.rb +22 -0
- data/app/finders/main_theme/css_style.rb +43 -0
- data/app/finders/main_theme/urls_in_homepage.rb +25 -0
- data/app/finders/main_theme/woo_framework_meta_generator.rb +22 -0
- data/app/finders/medias.rb +17 -0
- data/app/finders/medias/attachment_brute_forcing.rb +44 -0
- data/app/finders/plugin_version.rb +44 -0
- data/app/finders/plugin_version/layer_slider/translation_file.rb +40 -0
- data/app/finders/plugin_version/readme.rb +79 -0
- data/app/finders/plugin_version/revslider/release_log.rb +35 -0
- data/app/finders/plugin_version/sitepress_multilingual_cms/meta_generator.rb +27 -0
- data/app/finders/plugin_version/sitepress_multilingual_cms/version_parameter.rb +31 -0
- data/app/finders/plugin_version/w3_total_cache/headers.rb +28 -0
- data/app/finders/plugins.rb +24 -0
- data/app/finders/plugins/comments.rb +31 -0
- data/app/finders/plugins/headers.rb +36 -0
- data/app/finders/plugins/known_locations.rb +48 -0
- data/app/finders/plugins/urls_in_homepage.rb +29 -0
- data/app/finders/theme_version.rb +41 -0
- data/app/finders/theme_version/style.rb +43 -0
- data/app/finders/theme_version/woo_framework_meta_generator.rb +19 -0
- data/app/finders/themes.rb +20 -0
- data/app/finders/themes/known_locations.rb +48 -0
- data/app/finders/themes/urls_in_homepage.rb +23 -0
- data/app/finders/timthumb_version.rb +17 -0
- data/app/finders/timthumb_version/bad_request.rb +21 -0
- data/app/finders/timthumbs.rb +17 -0
- data/app/finders/timthumbs/known_locations.rb +56 -0
- data/app/finders/users.rb +24 -0
- data/app/finders/users/author_id_brute_forcing.rb +111 -0
- data/app/finders/users/author_posts.rb +61 -0
- data/app/finders/users/login_error_messages.rb +50 -0
- data/app/finders/users/wp_json_api.rb +31 -0
- data/app/finders/wp_items.rb +1 -0
- data/app/finders/wp_items/urls_in_homepage.rb +68 -0
- data/app/finders/wp_version.rb +34 -0
- data/app/finders/wp_version/atom_generator.rb +40 -0
- data/app/finders/wp_version/meta_generator.rb +27 -0
- data/app/finders/wp_version/opml_generator.rb +23 -0
- data/app/finders/wp_version/rdf_generator.rb +38 -0
- data/app/finders/wp_version/readme.rb +28 -0
- data/app/finders/wp_version/rss_generator.rb +43 -0
- data/app/finders/wp_version/sitemap_generator.rb +23 -0
- data/app/finders/wp_version/stylesheets.rb +55 -0
- data/app/finders/wp_version/unique_fingerprinting.rb +64 -0
- data/app/models.rb +10 -0
- data/app/models/config_backup.rb +5 -0
- data/app/models/interesting_finding.rb +6 -0
- data/app/models/media.rb +5 -0
- data/app/models/plugin.rb +25 -0
- data/app/models/theme.rb +99 -0
- data/app/models/timthumb.rb +74 -0
- data/app/models/user.rb +31 -0
- data/app/models/wp_item.rb +142 -0
- data/app/models/wp_version.rb +49 -0
- data/app/models/xml_rpc.rb +19 -0
- data/app/views/cli/brute_force/error.erb +1 -0
- data/app/views/cli/brute_force/found.erb +2 -0
- data/app/views/cli/brute_force/users.erb +9 -0
- data/app/views/cli/core/banner.erb +14 -0
- data/app/views/cli/core/db_update_finished.erb +8 -0
- data/app/views/cli/core/db_update_started.erb +1 -0
- data/app/views/cli/core/not_fully_configured.erb +1 -0
- data/app/views/cli/enumeration/config_backups.erb +11 -0
- data/app/views/cli/enumeration/medias.erb +11 -0
- data/app/views/cli/enumeration/plugins.erb +35 -0
- data/app/views/cli/enumeration/themes.erb +11 -0
- data/app/views/cli/enumeration/timthumbs.erb +18 -0
- data/app/views/cli/enumeration/users.erb +11 -0
- data/app/views/cli/finding.erb +32 -0
- data/app/views/cli/info.erb +1 -0
- data/app/views/cli/main_theme/theme.erb +6 -0
- data/app/views/cli/notice.erb +1 -0
- data/app/views/cli/theme.erb +64 -0
- data/app/views/cli/usage.erb +3 -0
- data/app/views/cli/vulnerability.erb +14 -0
- data/app/views/cli/wp_version/version.erb +6 -0
- data/app/views/json/brute_force/users.erb +10 -0
- data/app/views/json/core/banner.erb +12 -0
- data/app/views/json/core/db_update_finished.erb +2 -0
- data/app/views/json/core/db_update_started.erb +1 -0
- data/app/views/json/core/not_fully_configured.erb +1 -0
- data/app/views/json/enumeration/config_backups.erb +10 -0
- data/app/views/json/enumeration/medias.erb +10 -0
- data/app/views/json/enumeration/plugins.erb +25 -0
- data/app/views/json/enumeration/themes.erb +10 -0
- data/app/views/json/enumeration/timthumbs.erb +19 -0
- data/app/views/json/enumeration/users.erb +11 -0
- data/app/views/json/finding.erb +26 -0
- data/app/views/json/main_theme/theme.erb +7 -0
- data/app/views/json/theme.erb +38 -0
- data/app/views/json/wp_version/version.erb +8 -0
- data/bin/wpscan +15 -0
- data/coverage/assets/0.10.0/application.css +799 -0
- data/coverage/assets/0.10.0/application.js +1707 -0
- data/coverage/assets/0.10.0/colorbox/border.png +0 -0
- data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
- data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
- data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
- data/coverage/assets/0.10.0/favicon_green.png +0 -0
- data/coverage/assets/0.10.0/favicon_red.png +0 -0
- data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
- data/coverage/assets/0.10.0/loading.gif +0 -0
- data/coverage/assets/0.10.0/magnify.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/index.html +27510 -0
- data/lib/wpscan.rb +44 -0
- data/lib/wpscan/browser.rb +16 -0
- data/lib/wpscan/controller.rb +8 -0
- data/lib/wpscan/controllers.rb +8 -0
- data/lib/wpscan/db.rb +28 -0
- data/lib/wpscan/db/dynamic_finders.rb +63 -0
- data/lib/wpscan/db/plugin.rb +11 -0
- data/lib/wpscan/db/plugins.rb +11 -0
- data/lib/wpscan/db/schema.rb +39 -0
- data/lib/wpscan/db/theme.rb +11 -0
- data/lib/wpscan/db/themes.rb +11 -0
- data/lib/wpscan/db/updater.rb +148 -0
- data/lib/wpscan/db/wp_item.rb +18 -0
- data/lib/wpscan/db/wp_items.rb +21 -0
- data/lib/wpscan/db/wp_version.rb +11 -0
- data/lib/wpscan/errors/http.rb +34 -0
- data/lib/wpscan/errors/update.rb +8 -0
- data/lib/wpscan/errors/wordpress.rb +22 -0
- data/lib/wpscan/finders.rb +14 -0
- data/lib/wpscan/finders/finder/plugin_version/comments.rb +25 -0
- data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +23 -0
- data/lib/wpscan/helper.rb +6 -0
- data/lib/wpscan/references.rb +31 -0
- data/lib/wpscan/target.rb +81 -0
- data/lib/wpscan/target/platform/wordpress.rb +74 -0
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +93 -0
- data/lib/wpscan/version.rb +4 -0
- data/lib/wpscan/vulnerability.rb +25 -0
- data/lib/wpscan/vulnerable.rb +10 -0
- data/wpscan-v3.sublime-project +8 -0
- data/wpscan-v3.sublime-workspace +895 -0
- data/wpscan.gemspec +55 -0
- metadata +419 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Controller
|
|
3
|
+
# Main Theme Controller
|
|
4
|
+
class MainTheme < CMSScanner::Controller::Base
|
|
5
|
+
def cli_options
|
|
6
|
+
[
|
|
7
|
+
OptChoice.new(
|
|
8
|
+
['--main-theme-detection MODE',
|
|
9
|
+
'Use the supplied mode for the Main theme detection, instead of the global (--detection-mode) mode.'],
|
|
10
|
+
choices: %w(mixed passive aggressive),
|
|
11
|
+
normalize: :to_sym
|
|
12
|
+
)
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def run
|
|
17
|
+
output(
|
|
18
|
+
'theme',
|
|
19
|
+
theme: target.main_theme(
|
|
20
|
+
mode: parsed_options[:main_theme_detection] || parsed_options[:detection_mode]
|
|
21
|
+
),
|
|
22
|
+
verbose: parsed_options[:verbose]
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Controller
|
|
3
|
+
# Wp Version Controller
|
|
4
|
+
class WpVersion < CMSScanner::Controller::Base
|
|
5
|
+
def cli_options
|
|
6
|
+
[
|
|
7
|
+
OptBoolean.new(['--wp-version-all', 'Check all the version locations']),
|
|
8
|
+
OptChoice.new(
|
|
9
|
+
['--wp-version-detection MODE',
|
|
10
|
+
'Use the supplied mode for the WordPress version detection, ' \
|
|
11
|
+
'instead of the global (--detection-mode) mode.'],
|
|
12
|
+
choices: %w(mixed passive aggressive),
|
|
13
|
+
normalize: :to_sym
|
|
14
|
+
)
|
|
15
|
+
]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run
|
|
19
|
+
output(
|
|
20
|
+
'version',
|
|
21
|
+
version: target.wp_version(
|
|
22
|
+
mode: parsed_options[:wp_version_detection] || parsed_options[:detection_mode],
|
|
23
|
+
confidence_threshold: parsed_options[:wp_version_all] ? 0 : 100,
|
|
24
|
+
show_progression: user_interaction?
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/app/finders.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require_relative 'finders/interesting_findings'
|
|
2
|
+
require_relative 'finders/wp_items'
|
|
3
|
+
require_relative 'finders/wp_version'
|
|
4
|
+
require_relative 'finders/main_theme'
|
|
5
|
+
require_relative 'finders/timthumb_version'
|
|
6
|
+
require_relative 'finders/timthumbs'
|
|
7
|
+
require_relative 'finders/config_backups'
|
|
8
|
+
require_relative 'finders/medias'
|
|
9
|
+
require_relative 'finders/users'
|
|
10
|
+
require_relative 'finders/plugins'
|
|
11
|
+
require_relative 'finders/plugin_version'
|
|
12
|
+
require_relative 'finders/theme_version'
|
|
13
|
+
require_relative 'finders/themes'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative 'config_backups/known_filenames'
|
|
2
|
+
|
|
3
|
+
module WPScan
|
|
4
|
+
module Finders
|
|
5
|
+
module ConfigBackups
|
|
6
|
+
# Config Backup Finder
|
|
7
|
+
class Base
|
|
8
|
+
include CMSScanner::Finders::SameTypeFinder
|
|
9
|
+
|
|
10
|
+
# @param [ WPScan::Target ] target
|
|
11
|
+
def initialize(target)
|
|
12
|
+
finders << ConfigBackups::KnownFilenames.new(target)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module ConfigBackups
|
|
4
|
+
# Config Backup finder
|
|
5
|
+
class KnownFilenames < CMSScanner::Finders::Finder
|
|
6
|
+
include CMSScanner::Finders::Finder::Enumerator
|
|
7
|
+
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
# @option opts [ String ] :list
|
|
10
|
+
# @option opts [ Boolean ] :show_progression
|
|
11
|
+
#
|
|
12
|
+
# @return [ Array<InterestingFinding> ]
|
|
13
|
+
def aggressive(opts = {})
|
|
14
|
+
found = []
|
|
15
|
+
|
|
16
|
+
enumerate(potential_urls(opts), opts) do |res|
|
|
17
|
+
# Might need to improve that
|
|
18
|
+
next unless res.body =~ /define/i && res.body !~ /<\s?html/i
|
|
19
|
+
|
|
20
|
+
found << WPScan::ConfigBackup.new(res.request.url, found_by: DIRECT_ACCESS, confidence: 100)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
found
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param [ Hash ] opts
|
|
27
|
+
# @option opts [ String ] :list Mandatory
|
|
28
|
+
#
|
|
29
|
+
# @return [ Hash ]
|
|
30
|
+
def potential_urls(opts = {})
|
|
31
|
+
urls = {}
|
|
32
|
+
|
|
33
|
+
File.open(opts[:list]).each_with_index do |file, index|
|
|
34
|
+
urls[target.url(file.chomp)] = index
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
urls
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def create_progress_bar(opts = {})
|
|
41
|
+
super(opts.merge(title: ' Checking Config Backups -'))
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require_relative 'interesting_findings/readme'
|
|
2
|
+
require_relative 'interesting_findings/multisite'
|
|
3
|
+
require_relative 'interesting_findings/debug_log'
|
|
4
|
+
require_relative 'interesting_findings/backup_db'
|
|
5
|
+
require_relative 'interesting_findings/mu_plugins'
|
|
6
|
+
require_relative 'interesting_findings/registration'
|
|
7
|
+
require_relative 'interesting_findings/tmm_db_migrate'
|
|
8
|
+
require_relative 'interesting_findings/upload_sql_dump'
|
|
9
|
+
require_relative 'interesting_findings/full_path_disclosure'
|
|
10
|
+
require_relative 'interesting_findings/duplicator_installer_log'
|
|
11
|
+
require_relative 'interesting_findings/upload_directory_listing'
|
|
12
|
+
|
|
13
|
+
module WPScan
|
|
14
|
+
module Finders
|
|
15
|
+
module InterestingFindings
|
|
16
|
+
# Interesting Files Finder
|
|
17
|
+
class Base < CMSScanner::Finders::InterestingFindings::Base
|
|
18
|
+
# @param [ WPScan::Target ] target
|
|
19
|
+
def initialize(target)
|
|
20
|
+
super(target)
|
|
21
|
+
|
|
22
|
+
%w(
|
|
23
|
+
Readme DebugLog FullPathDisclosure BackupDB DuplicatorInstallerLog
|
|
24
|
+
Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate
|
|
25
|
+
UploadSQLDump
|
|
26
|
+
).each do |f|
|
|
27
|
+
finders << InterestingFindings.const_get(f).new(target)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# BackupDB finder
|
|
5
|
+
class BackupDB < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
path = 'wp-content/backup-db/'
|
|
9
|
+
url = target.url(path)
|
|
10
|
+
res = Browser.get(url)
|
|
11
|
+
|
|
12
|
+
return unless [200, 403].include?(res.code) && !target.homepage_or_404?(res)
|
|
13
|
+
|
|
14
|
+
WPScan::InterestingFinding.new(
|
|
15
|
+
url,
|
|
16
|
+
confidence: 70,
|
|
17
|
+
found_by: DIRECT_ACCESS,
|
|
18
|
+
interesting_entries: target.directory_listing_entries(path),
|
|
19
|
+
references: { url: 'https://github.com/wpscanteam/wpscan/issues/422' }
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# debug.log finder
|
|
5
|
+
class DebugLog < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
path = 'wp-content/debug.log'
|
|
9
|
+
|
|
10
|
+
return unless target.debug_log?(path)
|
|
11
|
+
|
|
12
|
+
WPScan::InterestingFinding.new(
|
|
13
|
+
target.url(path),
|
|
14
|
+
confidence: 100, found_by: DIRECT_ACCESS
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# DuplicatorInstallerLog finder
|
|
5
|
+
class DuplicatorInstallerLog < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
url = target.url('installer-log.txt')
|
|
9
|
+
res = Browser.get(url)
|
|
10
|
+
|
|
11
|
+
return unless res.body =~ /DUPLICATOR INSTALL-LOG/
|
|
12
|
+
|
|
13
|
+
WPScan::InterestingFinding.new(
|
|
14
|
+
url,
|
|
15
|
+
confidence: 100,
|
|
16
|
+
found_by: DIRECT_ACCESS,
|
|
17
|
+
references: { url: 'https://www.exploit-db.com/ghdb/3981/' }
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# Full Path Disclosure finder
|
|
5
|
+
class FullPathDisclosure < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
path = 'wp-includes/rss-functions.php'
|
|
9
|
+
fpd_entries = target.full_path_disclosure_entries(path)
|
|
10
|
+
|
|
11
|
+
return if fpd_entries.empty?
|
|
12
|
+
|
|
13
|
+
WPScan::InterestingFinding.new(
|
|
14
|
+
target.url(path),
|
|
15
|
+
confidence: 100,
|
|
16
|
+
found_by: DIRECT_ACCESS,
|
|
17
|
+
interesting_entries: fpd_entries
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# Must Use Plugins Directory checker
|
|
5
|
+
class MuPlugins < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def passive(_opts = {})
|
|
8
|
+
pattern = %r{#{target.content_dir}/mu\-plugins/}i
|
|
9
|
+
|
|
10
|
+
target.in_scope_urls(target.homepage_res) do |url|
|
|
11
|
+
next unless Addressable::URI.parse(url).path =~ pattern
|
|
12
|
+
|
|
13
|
+
url = target.url('wp-content/mu-plugins/')
|
|
14
|
+
|
|
15
|
+
return WPScan::InterestingFinding.new(
|
|
16
|
+
url,
|
|
17
|
+
confidence: 70,
|
|
18
|
+
found_by: 'URLs In Homepage (Passive Detection)',
|
|
19
|
+
to_s: "This site has 'Must Use Plugins': #{url}",
|
|
20
|
+
references: { url: 'http://codex.wordpress.org/Must_Use_Plugins' }
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [ InterestingFinding ]
|
|
27
|
+
def aggressive(_opts = {})
|
|
28
|
+
url = target.url('wp-content/mu-plugins/')
|
|
29
|
+
res = Browser.get_and_follow_location(url)
|
|
30
|
+
|
|
31
|
+
return unless [200, 401, 403].include?(res.code)
|
|
32
|
+
return if target.homepage_or_404?(res)
|
|
33
|
+
# TODO: add the check for --exclude-content once implemented ?
|
|
34
|
+
|
|
35
|
+
target.mu_plugins = true
|
|
36
|
+
|
|
37
|
+
WPScan::InterestingFinding.new(
|
|
38
|
+
url,
|
|
39
|
+
confidence: 80,
|
|
40
|
+
found_by: DIRECT_ACCESS,
|
|
41
|
+
to_s: "This site has 'Must Use Plugins': #{url}",
|
|
42
|
+
references: { url: 'http://codex.wordpress.org/Must_Use_Plugins' }
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# Multisite checker
|
|
5
|
+
class Multisite < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
url = target.url('wp-signup.php')
|
|
9
|
+
res = Browser.get(url)
|
|
10
|
+
location = res.headers_hash['location']
|
|
11
|
+
|
|
12
|
+
return unless [200, 302].include?(res.code)
|
|
13
|
+
return if res.code == 302 && location =~ /wp-login\.php\?action=register/
|
|
14
|
+
return unless res.code == 200 || res.code == 302 && location =~ /wp-signup\.php/
|
|
15
|
+
|
|
16
|
+
target.multisite = true
|
|
17
|
+
|
|
18
|
+
WPScan::InterestingFinding.new(
|
|
19
|
+
url,
|
|
20
|
+
confidence: 100,
|
|
21
|
+
found_by: DIRECT_ACCESS,
|
|
22
|
+
to_s: 'This site seems to be a multisite',
|
|
23
|
+
references: { url: 'http://codex.wordpress.org/Glossary#Multisite' }
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# Readme.html finder
|
|
5
|
+
class Readme < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
potential_files.each do |file|
|
|
9
|
+
url = target.url(file)
|
|
10
|
+
res = Browser.get(url)
|
|
11
|
+
|
|
12
|
+
if res.code == 200 && res.body =~ /wordpress/i
|
|
13
|
+
return WPScan::InterestingFinding.new(url, confidence: 100, found_by: DIRECT_ACCESS)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @retun [ Array<String> ] The list of potential readme files
|
|
20
|
+
def potential_files
|
|
21
|
+
%w(readme.html olvasdel.html lisenssi.html liesmich.html)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# Registration Enabled checker
|
|
5
|
+
class Registration < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def passive(_opts = {})
|
|
8
|
+
# Maybe check in the homepage if there is the registration url ?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [ InterestingFinding ]
|
|
12
|
+
def aggressive(_opts = {})
|
|
13
|
+
res = Browser.get_and_follow_location(target.registration_url)
|
|
14
|
+
|
|
15
|
+
return unless res.code == 200
|
|
16
|
+
return if res.html.css('form#setupform').empty? &&
|
|
17
|
+
res.html.css('form#registerform').empty?
|
|
18
|
+
|
|
19
|
+
target.registration_enabled = true
|
|
20
|
+
|
|
21
|
+
WPScan::InterestingFinding.new(
|
|
22
|
+
res.effective_url,
|
|
23
|
+
confidence: 100,
|
|
24
|
+
found_by: DIRECT_ACCESS,
|
|
25
|
+
to_s: "Registration is enabled: #{res.effective_url}"
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# Tmm DB Migrate finder
|
|
5
|
+
class TmmDbMigrate < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
path = 'wp-content/uploads/tmm_db_migrate/tmm_db_migrate.zip'
|
|
9
|
+
url = target.url(path)
|
|
10
|
+
res = Browser.get(url)
|
|
11
|
+
|
|
12
|
+
return unless res.code == 200 && res.headers['Content-Type'] =~ %r{\Aapplication/zip}i
|
|
13
|
+
|
|
14
|
+
WPScan::InterestingFinding.new(
|
|
15
|
+
url,
|
|
16
|
+
confidence: 100,
|
|
17
|
+
found_by: DIRECT_ACCESS,
|
|
18
|
+
references: { packetstorm: 131_957 }
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module InterestingFindings
|
|
4
|
+
# UploadDirectoryListing finder
|
|
5
|
+
class UploadDirectoryListing < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ InterestingFinding ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
path = 'wp-content/uploads/'
|
|
9
|
+
|
|
10
|
+
return unless target.directory_listing?(path)
|
|
11
|
+
|
|
12
|
+
url = target.url(path)
|
|
13
|
+
|
|
14
|
+
WPScan::InterestingFinding.new(
|
|
15
|
+
url,
|
|
16
|
+
confidence: 100,
|
|
17
|
+
found_by: DIRECT_ACCESS,
|
|
18
|
+
to_s: "Upload directory has listing enabled: #{url}"
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|