wpscan 3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|