One man's patch is another man's treasure: A tale of a failed HPE patch

A further analysis of various attack vectors in HPE IMC – Part 2. You can find Part 1 here.

Developers often think code behind an authentication mechanism is safe from attackers and therefore the program inputs are relatively “safe.” This thought often results in sloppy code. Once the attacker finds a hole in the authentication mechanism, a floodgate of post-authentication bugs become available to the attacker to exploit the system.

Many ZDI advisories involving HPE IMC vulnerabilities are post-authentication bugs that require authentication bypass. However, a frequent ZDI contributor submitted an authentication bypass bug (ZDI-18-139) to make these post-auth bugs valuable to attackers. The root cause of this bypass results from an incomplete fix of ZDI-17-161, which was originally discovered by a different researcher and insufficiently patched by HPE in March 2017.

This blog analyzes the patch for ZDI-17-161 to see if we can find this bug ourselves, and examines the submitted authentication bypass bug. Finally, we’ll walk through the esoteric Expression Language injection (ZDI-17-663) vulnerability that relies on this bypass to get RCE as SYSTEM.

Finding the CVE-2017-5791 through patch diffing

As shown in the web.xml, HPE IMC uses the UrlAccessController class as an access control filter to restrict access to protected URLs from unauthenticated users. Filter is a Java servlet feature commonly used by developers to implement authentication and access control.

The following is a snippet of the decompiled patch for the UrlAccessController::doFilter() method from IMC7.3E0504P2, the insufficient fix for ZDI-17-161:

In the patch, a guard function, normalizeSyntax(), is added to sanitize the input prior to the filter logic. This function exits but does nothing if ".." characters are absent from the path. Without further analysis, we can tell normalizeSyntax() attempts to do some “normalization” with paths that contain ".." characters. In fact, that was exactly the bug as previously reported in ZDI-17-161. If the URL path contains /imc/primepush/../<target URI>, the attacker can bypass the filter and access other servlets that are normally blocked from unauthenticated users.

ZDI-18-139: Finding the treasure hidden in the patch

If you take a closer look at the newly added normalizeSyntax(), it is not hard to spot a critical bug in the patch that can be used to bypass authentication. Take a moment and see if you can spot the bug as well.

If you can spot the bug, congratulations! You should consider finding bugs and submitting to our program ☺. The bug in the patch lies in the first few lines of the function. If the attacker URL encodes the ".." characters in the URL, it will trick the function into returning early. In other words, the attacker can simply use /imc/primepush/%2e%2e/<target URI> to bypass the patch!

By URL encoding the path traversal characters, the attacker can bypass the URL access controller only. The attacker may then be able to view certain authentication protected pages. From here, an attacker may use ZDI-18-136 to hijack an admin session, or continue with any of the following Expression Language (EL) injection bugs that exist in this product to gain code execution:

Expression Language (EL) is part of the web application UI framework known as Java Server Faces (JSF). Here is a quick example of how EL works in the JSF framework. The Expression Language injection CWE-917 is a relatively young vulnerability class. Little literature is available for this bug class outside of the initial work done by Stefano Di Paola of Minded Security and Arshan Dabirsiaghi of Aspect Security plus a handful of blog posts.

One of the first EL injection bugs dates back to 2011. CVE-2011-2730 covers a double-evaluation bug in Spring Framework that results in information disclosure. Later in 2012, Dan Amodio demonstrated a new technique of exploiting EL injection bugs in newer JSP/EL 2.2 to achieve code execution in this blog post. This new technique does not require the vulnerable code to evaluate the attacker-controlled expressions twice.

ZDI-17-663: Anatomy of EL injection vulnerability

ZDI-17-663 is a post-auth EL injection vulnerability that allows an attacker to execute arbitrary Expression Language through the beanName parameter passed to ictExpertDownload.xhtml. Let's begin by examining the entry point of the vulnerability -- the view template stored in C:\Program Files\iMC\client\web\apps\imc\ict\export\ictExpertDownload.xhtml:

In the highlight [1] above, the "http://www.huawei-3com.com/jsf/core" namespace is imported, which includes a number of custom tags. One of these is the imcf:beanMethod tag. Whenever this page is requested, the imcf:beanMethod tag seen at [2] invokes the initPage method of the ictTableExportBean. This behavior is documented in the taglib definition located at C:\Program Files\iMC\client\web\apps\imc\WEB-INF\imc-jsf-core.taglib.xml:

Let's take a look at what ictTableExportBean.initPage() does next. This method is defined in the com.h3c.imc.ict.export.view.IctTableExportBean class of imcweb_plat.jar:

The highlight at [4] is not quite where the EL gets evaluated; instead the attacker-controlled data is passed to FacesUtils class, which actually evaluates the expression. Following is the decompiled FaceUtils class:

com.h3c.imc.common.faces.FacesUtils.java:

Here, the attacker-controlled data is parsed into a ValueExpression and ultimately evaluated. Since the web server is running as SYSTEM, the malicious payload will be executed as SYSTEM as well.

Putting it all together: Gaining SYSTEM with EL injection

Today, we are releasing a Metasploit module that utilizes ZDI-18-139 and ZDI-17-663 to exploit IMC. This module has been tested against iMC7.3E0504P2 with the cmd/windows/powershell_reverse payload. The payload of this Metasploit module is taken from the original bug submission, and a detailed explanation of how the payload works can be found here.

Here’s a video of the Metasploit module in action:

Conclusion

The information disclosure and code execution bugs listed here demonstrate why developers should still sanitize program inputs, even if they come from allegedly “safe” spaces. It also shows how post-authentication bugs can still be used by attackers and penetration testers alike. EL injection bugs are rarely discovered partly due to their hard-to-find-by-blackbox-approach nature. It is almost absolutely necessary to have source code access to find these EL injection bugs. Hopefully, this class of bugs will be eradicated as quickly as format string vulnerabilities did once they reach a critical level of popularity in our industry.

Check back on the blog for the conclusion of this series, where I discuss a different exploitation technique for HPE IMC. Until then, you can find me on Twitter @TrendyTofu, and follow the team for the latest in exploit techniques and security patches.