Lucene search
K

Wordpress Scanner

🗓️ 10 Nov 2013 22:08:59Reported by Christian Mehlmauer <[email protected]>, h00die, shoxxdjType 
metasploit
 metasploit
🔗 www.rapid7.com👁 56 Views

The Metasploit module performs scanning and detection of WordPress versions, themes, plugins, and users. It has the capability to detect exploited plugins and themes for vulnerability assessment

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HTTP::Wordpress
  include Msf::Auxiliary::Scanner
  include Msf::Auxiliary::Report

  def initialize
    super(
      'Name' => 'Wordpress Scanner',
      'Description' => 'Detects Wordpress Versions, Themes, Plugins, and Users',
      'Author' => [
        'Christian Mehlmauer', # original module
        'h00die', # plugins and themes
        'shoxxdj' # users
      ],
      'License' => MSF_LICENSE
    )
    register_options [
      OptBool.new('EXPLOITABLE', [false, 'Only scan plugins and themes which a MSF module exists for', true]),
      OptPath.new('EXPLOITABLE_THEMES', [
        true, 'File containing exploitable by MSF themes',
        File.join(Msf::Config.data_directory, 'wordlists', 'wp-exploitable-themes.txt')
      ]),
      OptPath.new('EXPLOITABLE_PLUGINS', [
        true, 'File containing exploitable by MSF plugins',
        File.join(Msf::Config.data_directory, 'wordlists', 'wp-exploitable-plugins.txt')
      ]),
      OptBool.new('THEMES', [false, 'Detect themes', true]),
      OptBool.new('PLUGINS', [false, 'Detect plugins', true]),
      OptPath.new('THEMES_FILE', [
        true, 'File containing themes to enumerate',
        File.join(Msf::Config.data_directory, 'wordlists', 'wp-themes.txt')
      ]),
      OptPath.new('PLUGINS_FILE', [
        true, 'File containing plugins to enumerate',
        File.join(Msf::Config.data_directory, 'wordlists', 'wp-plugins.txt')
      ]),
      OptInt.new('PROGRESS', [true, 'how often to print progress', 1000]),
      OptBool.new('USERS', [false, 'Detect users with API', true])
    ]
  end

  def print_progress(host, i, total)
    print_status("#{host} - Progress #{i.to_s.rjust(Math.log10(total).ceil + 1)}/#{total} (#{((i.to_f / total) * 100).truncate(2)}%)")
  end

  def run_host(target_host)
    print_status("Trying #{target_host}")
    if wordpress_and_online?
      version = wordpress_version
      version_string = version || '(no version detected)'
      print_good("#{target_host} - Detected Wordpress #{version_string}")
      report_note(
        {
          host: target_host,
          proto: 'tcp',
          sname: (ssl ? 'https' : 'http'),
          port: rport,
          type: "Wordpress #{version_string}",
          data: target_uri.to_s
        }
      )
      if datastore['THEMES']
        print_status("#{target_host} - Enumerating Themes")

        if datastore['EXPLOITABLE']
          f = File.open(datastore['EXPLOITABLE_THEMES'], 'rb')
        else
          f = File.open(datastore['THEMES_FILE'], 'rb')
        end
        total = f.readlines.size
        f.rewind
        f = f.readlines
        f.each_with_index do |theme, i|
          theme = theme.strip
          print_progress(target_host, i, total) if i % datastore['PROGRESS'] == 0
          vprint_status("#{target_host} - Checking theme: #{theme}")
          version = check_theme_version_from_readme(theme)
          next if version == Msf::Exploit::CheckCode::Unknown # aka not found

          print_good("#{target_host} - Detected theme: #{theme} version #{version.details[:version]}")
          report_note(
            {
              host: target_host,
              proto: 'tcp',
              sname: (ssl ? 'https' : 'http'),
              port: rport,
              type: "Wordpress Theme: #{theme} version #{version.details[:version]}"
              # data: target_uri
            }
          )
        end
        print_status("#{target_host} - Finished scanning themes")
      end
      if datastore['PLUGINS']
        print_status("#{target_host} - Enumerating plugins")

        if datastore['EXPLOITABLE']
          f = File.open(datastore['EXPLOITABLE_PLUGINS'], 'rb')
        else
          f = File.open(datastore['PLUGINS_FILE'], 'rb')
        end
        total = f.readlines.size
        f.rewind
        f = f.readlines
        f.each_with_index do |plugin, i|
          plugin = plugin.strip
          print_progress(target_host, i, total) if i % datastore['PROGRESS'] == 0
          vprint_status("#{target_host} - Checking plugin: #{plugin}")
          version = check_plugin_version_from_readme(plugin)
          next if version == Msf::Exploit::CheckCode::Unknown # aka not found

          print_good("#{target_host} - Detected plugin: #{plugin} version #{version.details[:version]}")
          report_note(
            {
              host: target_host,
              proto: 'tcp',
              sname: (ssl ? 'https' : 'http'),
              port: rport,
              type: "Wordpress Plugin: #{plugin} version #{version.details[:version]}"
              # data: target_uri
            }
          )
        end
        print_status("#{target_host} - Finished scanning plugins")
      end

      if datastore['USERS']
        print_status("#{target_host} - Searching Users")
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(wordpress_url_rest_api, 'users')
        })
        if res.nil?
          print_error('Error getting response.')
        elsif res.code == 200
          parsed = res.get_json_document
          if parsed.empty?
            print_error('Response received, but no JSON content was provided.')
          else
            parsed.map do |child|
              name = child['name']
              wp_username = child['slug']
              print_good("#{target_host} - Detected user: #{name} with username: #{wp_username}")
              service_data = {
                address: rhost,
                port: rport,
                service_name: (ssl ? 'https' : 'http'),
                protocol: 'tcp',
                workspace_id: myworkspace_id
              }

              credential_data = {
                origin_type: :service,
                module_fullname: fullname,
                username: wp_username,
                private_data: '',
                private_type: :password
              }.merge(service_data)

              login_data = {
                core: create_credential(credential_data),
                status: Metasploit::Model::Login::Status::UNTRIED,
                proof: nil
              }.merge(service_data)

              create_credential_login(login_data)
            end
            print_status("#{target_host} - Finished scanning users")
          end
        else
          print_status("#{target_host} - Was not able to identify users on site using #{wordpress_url_rest_api}/users")
        end
        print_status("#{target_host} - Finished all scans")
      end
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

07 Jan 2024 20:02Current
7.4High risk
Vulners AI Score7.4
56