From a53f88b62673ea2b31244b572c6e38aae0b08a61 Mon Sep 17 00:00:00 2001 From: erwanlr Date: Sun, 6 Oct 2019 16:47:05 +0100 Subject: [PATCH] Improves WP detection --- lib/wpscan/target/platform/wordpress.rb | 20 +++++++++++++------ .../wordpress/detection/wp_admin.html | 5 +++++ .../wordpress/detection/wp_json_oembed.html | 2 ++ .../target/platform/wordpress.rb | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 spec/fixtures/target/platform/wordpress/detection/wp_admin.html create mode 100644 spec/fixtures/target/platform/wordpress/detection/wp_json_oembed.html diff --git a/lib/wpscan/target/platform/wordpress.rb b/lib/wpscan/target/platform/wordpress.rb index 69e6d6a5..3fe01432 100644 --- a/lib/wpscan/target/platform/wordpress.rb +++ b/lib/wpscan/target/platform/wordpress.rb @@ -11,7 +11,9 @@ module WPScan module WordPress include CMSScanner::Target::Platform::PHP - WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze + WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze + WP_JSON_OEMBED_PATTERN = %r{/wp\-json/oembed/}i.freeze + WP_ADMIN_AJAX_PATTERN = %r{\\?/wp\-admin\\?/admin\-ajax\.php}i.freeze # These methods are used in the associated interesting_findings finders # to keep the boolean state of the finding rather than re-check the whole thing again @@ -23,27 +25,33 @@ module WPScan # @param [ Symbol ] detection_mode # # @return [ Boolean ] + # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity def wordpress?(detection_mode) in_scope_uris(homepage_res) do |uri| - return true if uri.path.match(WORDPRESS_PATTERN) + return true if WORDPRESS_PATTERN.match?(uri.path) || WP_JSON_OEMBED_PATTERN.match?(uri.path) end - homepage_res.html.css('meta[name="generator"]').each do |node| - return true if /wordpress/i.match?(node['content']) + return true if homepage_res.html.css('meta[name="generator"]').any? do |node| + /wordpress/i.match?(node['content']) end return true unless comments_from_page(/wordpress/i, homepage_res).empty? + return true if homepage_res.html.xpath('//script[not(@src)]').any? do |node| + WP_ADMIN_AJAX_PATTERN.match?(node.text) + end + if %i[mixed aggressive].include?(detection_mode) %w[wp-admin/install.php wp-login.php].each do |path| - in_scope_uris(Browser.get_and_follow_location(url(path))).each do |uri| - return true if uri.path.match(WORDPRESS_PATTERN) + return true if in_scope_uris(Browser.get_and_follow_location(url(path))).any? do |uri| + WORDPRESS_PATTERN.match?(uri.path) end end end false end + # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity COOKIE_PATTERNS = { 'vjs' => /createCookie\('vjs','(?\d+)',\d+\);/i diff --git a/spec/fixtures/target/platform/wordpress/detection/wp_admin.html b/spec/fixtures/target/platform/wordpress/detection/wp_admin.html new file mode 100644 index 00000000..26617f59 --- /dev/null +++ b/spec/fixtures/target/platform/wordpress/detection/wp_admin.html @@ -0,0 +1,5 @@ + diff --git a/spec/fixtures/target/platform/wordpress/detection/wp_json_oembed.html b/spec/fixtures/target/platform/wordpress/detection/wp_json_oembed.html new file mode 100644 index 00000000..00bcb28d --- /dev/null +++ b/spec/fixtures/target/platform/wordpress/detection/wp_json_oembed.html @@ -0,0 +1,2 @@ + + diff --git a/spec/shared_examples/target/platform/wordpress.rb b/spec/shared_examples/target/platform/wordpress.rb index 3ba79d5a..646f724a 100644 --- a/spec/shared_examples/target/platform/wordpress.rb +++ b/spec/shared_examples/target/platform/wordpress.rb @@ -15,7 +15,7 @@ shared_examples WPScan::Target::Platform::WordPress do end context 'when pattern/s in the homepage' do - %w[default wp_includes only_scripts meta_generator comments mu_plugins].each do |file| + %w[default wp_includes only_scripts meta_generator comments mu_plugins wp_admin wp_json_oembed].each do |file| context "when a wordpress page (#{file}.html)" do let(:homepage) { file }