Introduction
Ivanti Endpoint Manager (EPM) is an enterprise endpoint management solution that allows for centralized management of devices within an organization. On May 24, 2024, ZDI and Ivanti released an advisory describing a SQL injection resulting in remote code execution with a CVSS score of 9.8. In this post we will detail the internal workings of this vulnerability. Our POC can be found here.
RecordGoodApp
Luckily for us, the ZDI advisory told us exactly where to look for the SQL injection. A function named RecordGoodApp. After installation, we find most of the application binaries in C:\Program Files\LANDesk. Searching for RecordGoodApp we find its present in a file named PatchBiz.dll.
We can use JetBrains dotPeek tool to disassemble the PatchBiz.dll C# binary. From there we can search for the RecordGoodApp method.
We can readily see that the first SQL statement in the function is potentially vulnerable to an SQL injection. They use string.Format to insert the value of goodApp.md5 into the SQL query. Assuming we can find a way to influence the value of goodApp.md5 we should be able to trigger the SQL injection.
Finding a Path to the Vulnerable Function
Next, we would like to see if there are any obvious paths to the RecordGoodApp function that we can use to trigger the vulnerability. Luckily we can use dotPeek again to search for any references to RecordGoodApp. However, to make sure we don’t miss anything, we first want to make sure that we have all potential application binaries loaded into dotPeek. If we don’t, we run the risk of missing a reference to the vulnerable function. We find that RecordGoodApp is first called from AppMonitorAction.RecordPatchIssue.
Continuing, we find the AppMonitorAction.RecordPatchIsssue is called by Patch.UpdateActionHistory
We find that UpdateActionHistory is called from three different locations.
This most interesting of these usages is StatusEvents.EventHandler.UpdateStatusEvents. We find that it is annotated with [WebMethod] in the EventHandler class. EventHandler inherits from System.Web.Services.WebService. This strongly indicates that we should be able to hit UpdateStatusEvents over HTTP.
Triggering the Vulnerable Function
Now that we have found a viable path to the vulnerable function, our attention turns to triggering the vulnerable function. First, using IIS Manager, we notice that EventHandler.cs is hosted on the /WSStatusEvents endpoint.
Navigating to the endpoint in a browser, we are led to a page that shows up some example requests and responses.
Now, we can copy these example requests into Burp Suite and begin modifying them to see if we can trigger the exploit. Using dyspy, we attach to the IIS process hosting the vulnerable endpoint and start sending requests. After a little bit more reversing, we come up with a fairly trivial request using xp_cmdshell to gain RCE.
Finally, we see notepad.exe running under sqlservr.exe proving that our exploit worked!
Indicators of Compromise
The MS SQL logs can be examined for evidence of xp_cmdshell being utilized to obtain command execution. Note that this is likely not the only method for gaining RCE, but it is a popular one.
NodeZero
Horizon3.ai clients and free-trial users alike can run a NodeZero operation to determine the exposure and exploitability of this issue.
Sign up for a free trial and quickly verify you’re not exploitable.
