Last November, the SEC Consult Cryptography Competence Center came across a rather interesting cryptographic format used by the Oracle Access Manager (OAM).

In this blog post we will demonstrate how minor peculiarities of the cryptographic implementation had a real-life impact on the security of the product. By exploiting this vulnerability we were able to fabricate arbitrary authentication tokens, allowing us to impersonate any user and effectively break the main functionality of OAM.

The Oracle Access Manager (OAM) is the component of the Oracle Fusion Middleware that handles authentication for all sorts of web applications. In typical scenarios, the web server that provides access to the application is equipped with an authentication component (the Oracle WebGate). When a user requests a protected resource from the web server, it redirects her to an authentication endpoint of the OAM. The OAM then authenticates the user (e.g. with username and password) and redirects her back to the web application. Since all the authentication is handled by a central application, a user only has to authenticate once to access any application protected by the OAM (Single Sign-On).

During a research project, we found that a cryptographic format used by the OAM exhibits a serious flaw. By exploiting this vulnerability, we were able to craft a session token. When a WebGate is presented with this token, it would accept it as a legitimate form of authentication and allow us to access protected resources. What’s more, the session cookie crafting process lets us create a session cookie for an arbitrary username, thus allowing us to impersonate any user known to the OAM.

Who was affected?

Both currently supported versions, 11g and 12c were affected by this vulnerability – the scenario described here was only verified with version 12c. A simple Google Dork to find OAM installations yields about 11.800 results, some pointing to high-profile organizations (including Oracle itself). Those are only the installations reachable on the Internet.

We responsibly disclosed this vulnerability to Oracle immediately after we identified it in November 2017. Oracle was very responsive and provided a fix with the latest Critical Patch Update (CPU) in April 2018. As this patch was provided in Oracle’s regular update schedule, we expect OAM administrators to have applied the patch by now. If this is not the case for your organization, it’s high time to do so now!1

Moreover, it is advisable to analyze historic logs for the distinct pattern that this attack leaves behind: A successful attack causes a large number of decryption failures resulting from bad padding (javax.crypto.BadPaddingException).

Our security advisory contains further information regarding affected versions, vendor timeline etc.

The technical details

This section will elaborate on the technical details of the vulnerability. If you are not interested in those, you can skip to the bottom of this article where we provide a demo video showing the attack.

On a more technical level, the following happens during an authentication:

The user accesses a protected resource. The Oracle Webgate component inside the web server answers this request with a redirect to the OAM. An encrypted message (“encquery”) is passed in a URL parameter. The user authenticates against the OAM (e.g. with username and password). The OAM redirects the user back to the web server. Information about the successful login is passed in the parameter “encreply”. The web server redirects the user to the resource that was initially requested. An encrypted authentication token is stored in a cookie (“OAMAuthnCookie”). The authentication token in the cookie is used from now on to authenticate the user.

The values in encquery, encreply and the OAMAuthnCookie are (supposed to be) cryptographically protected against modification. This way, when one of these values is received by the OAM or a WebGate, the contents are (supposed to be) assured to be unmodified, even if they come from a user. The OAM uses a single cryptographic format for all these messages. The secret key used for all of these messages is shared between the OAM and the WebGate.

The Cryptographic Format

As already hinted before, the flaw lies in the implementation of the cryptographic format. The algorithm that creates the protected messages processes inputs of key-value pairs and, using a shared secret, produces a base64-encoded output string. The main objective of this format is to provide integrity and authenticity. This is how the algorithm works:

The input is formatted in this way:

salt=<salt> <key>=<value> [...] validate=<base64 hash>

where the salt is a randomly generated value and the parameter validate is a hash over fixed parts of the message (MD5). This string is then encrypted using a block cipher in CBC mode.

The Flaw

The very first thing that comes to mind when analyzing this format is, that none of the cryptographic algorithms used (i.e. the hash and the CBC block cipher) are intended to provide the main objective – authenticity. One could assume that, although it might not exactly be by the book, attacks are impossible since the attacker does not know the shared secret.

As people with a cryptography background may have noticed, one thing that particularly stands out is the CBC mode. When used incorrectly, it can be broken using a padding oracle attack. A classical padding oracle attack requires an encrypted input and a padding oracle. A padding oracle is a component that discloses whether a provided encrypted string, when it is decrypted has a valid padding. An oracle that discloses this information might not seem useful at first – but it, in fact, allows us to decrypt and encrypt arbitrary messages.

Simply put, a padding is required for block ciphers to be able to encrypt messages with arbitrary lengths. Block ciphers can only deal with blocks of a fixed size (e.g.16 bytes). If we want to e.g. encrypt a message that is 25 bytes long, we would encrypt the first 16 bytes and are then left with 9 bytes. As the block cipher cannot deal with a 9 byte input, we need to append 7 padding bytes. The typical approach to this is to add padding bytes where each byte contains the number of padding bytes (as defined in PKCS#7). E.g. in this case 7 bytes, each containing the value 7 are appended. When no padding would be required, a full padding block is appended (16 bytes, each containing the value 16).

An explanation of the padding oracle attack is beyond the scope of this post – for now, it is sufficient to understand that we need to find a way to figure out if an encrypted string, when decrypted, has proper padding.