Module: Msf::Exploit::Remote::HTTP::Drupal

Includes:
Msf::Exploit::Remote::HttpClient
Defined in:
lib/msf/core/exploit/http/drupal.rb

Instance Attribute Summary

Attributes included from Msf::Exploit::Remote::HttpClient

#client

Instance Method Summary collapse

Methods included from Msf::Exploit::Remote::HttpClient

#basic_auth, #cleanup, #configure_http_login_scanner, #connect, #deregister_http_client_options, #disconnect, #download, #full_uri, #handler, #http_fingerprint, #lookup_http_fingerprints, #normalize_uri, #path_from_uri, #peer, #proxies, #reconfig_redirect_opts!, #request_opts_from_url, #request_url, #rhost, #rport, #send_request_cgi, #send_request_cgi!, #send_request_raw, #service_details, #ssl, #ssl_version, #strip_tags, #target_uri, #validate_fingerprint, #vhost

Methods included from Auxiliary::Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Metasploit::Framework::Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Instance Method Details

#drupal_changelog(version) ⇒ String

Return CHANGELOG.txt

Parameters:

  • version (Gem::Version)

    Gem::Version or version string

Returns:

  • (String)

    CHANGELOG.txt as a string


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/msf/core/exploit/http/drupal.rb', line 54

def drupal_changelog(version)
  return unless version && Gem::Version.correct?(version)

  uri = Gem::Version.new(version) < Gem::Version.new('8') ?
        normalize_uri(target_uri.path, 'CHANGELOG.txt') :
        normalize_uri(target_uri.path, 'core/CHANGELOG.txt')

  res = send_request_cgi(
    'method' => 'GET',
    'uri'    => uri
  )

  return unless res && res.code == 200

  res.body
end

#drupal_patch(changelog, patch) ⇒ Boolean?

Check CHANGELOG.txt for patch level

Parameters:

  • changelog (String)

    CHANGELOG.txt to search

  • patch (String)

    Patch to check for (example: SA-CORE-2019-003)

Returns:

  • (Boolean, nil)

    Whether or not the patch was found or unknown


76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/msf/core/exploit/http/drupal.rb', line 76

def drupal_patch(changelog, patch)
  return unless changelog && patch

  # HACK: Patch level removed since undetermined 8.x release
  if changelog.include?('For a full list of fixes in the latest release')
    return nil
  elsif changelog.include?(patch)
    return true
  end

  false
end

#drupal_versionGem::Version

Determine Drupal version

Returns:

  • (Gem::Version)

    Version as Gem::Version


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/msf/core/exploit/http/drupal.rb', line 27

def drupal_version
  res = send_request_cgi(
    'method' => 'GET',
    'uri'    => normalize_uri(target_uri.path)
  )

  return unless res && res.code == 200

  # Check for an X-Generator header
  version = version_match(res.headers['X-Generator'])

  return version if version

  # Check for a <meta> tag
  generator = res.get_html_document.at(
    '//meta[@name = "Generator"]/@content'
  )

  return unless generator

  version_match(generator.value)
end

#initialize(info = {}) ⇒ Object


8
9
10
11
12
13
14
# File 'lib/msf/core/exploit/http/drupal.rb', line 8

def initialize(info = {})
  super

  register_options([
    OptString.new('TARGETURI', [true, 'Path to Drupal install', '/'])
  ])
end

#setupObject


16
17
18
19
20
21
22
# File 'lib/msf/core/exploit/http/drupal.rb', line 16

def setup
  super

  # Ensure we don't hit a redirect (e.g., /drupal -> /drupal/)
  # XXX: Naughty datastore modification instead of send_request_cgi!
  datastore['TARGETURI'] = normalize_uri(datastore['TARGETURI'], '/')
end

#version_match(string) ⇒ Gem::Version

Match a Drupal version

Parameters:

  • string (String)

    String to match against

Returns:

  • (Gem::Version)

    Version as Gem::Version


93
94
95
96
97
98
99
100
101
102
# File 'lib/msf/core/exploit/http/drupal.rb', line 93

def version_match(string)
  return unless string

  # Perl devs love me; Ruby devs hate me
  string =~ /^Drupal ([\d.]+)/

  return unless $1 && Gem::Version.correct?($1)

  Gem::Version.new($1)
end