Testing for Padding Oracle (OTG-CRYPST-002)

Brief Summary
A padding oracle is a function of an application which decrypts encrypted data provided by the client, e.g. internal session state stored on the client, and leaks the state of the validity of the padding after decryption. The existence of a padding oracle allows an attacker to decrypt encrypted data and encrypt arbitrary data without knowledge of the key used for these cryptographic operations. This can lead to leakage of sensible data or to privilege escalation vulnerabilities, if integrity of the encrypted data is assumed by the application.

Description of the Issue
Block ciphers encrypt data only in blocks of certain sizes. Block sizes used by common ciphers are 8 and 16 bytes. Data where the size doesn't matches a multiple of the block size of the used cipher has to be padded in a manner, that the decryptor is able to strip the padding. A commonly used padding scheme is PKCS#7. It fills the remaining bytes with the value of the padding length.

Example: if the padding has the length of 5 bytes, the byte value 0x05 is repeated five times after the plain text.

An error condition is present, if the padding doesn't matches the syntax of the used padding scheme. A padding oracle is present, if an application leaks this specific padding error condition for encrypted data provided by the client. This can happen by exposing exceptions (e.g. BadPaddingException in Java) directly, by subtle differences in the responses sent to the client or by another side-channel like timing behavior.

Certain modes of operation of cryptography allow bit-flipping attacks, where flipping of a bit in the cipher text causes that the bit is also flipped in the plain text. Flipping a bit in the n-th block of CBC encrypted data causes that the same bit in the (n+1)-th block is flipped in the decrypted data. The n-th block of the decrypted cipher text is garbaged by this manipulation.

The padding oracle attack enables an attacker to decrypt encrypted data without knowledge of the encryption key and used cipher by adaptively sending skillful manipulated cipher texts to the padding oracle and observing of the results returned by it. This causes loss of confidentiality of the encrypted data. E.g. in the case of session data stored on the client side the attacker can gain information about the internal state and structure of the application. A padding oracle attack also enables an attacker to encrypt arbitrary plain texts without knowledge of the used key and cipher. If the application assumes that integrity and authenticity of the decrypted data is given, an attacker could be able to manipulate internal session state and possibly gain higher privileges.

Black Box testing and example
Testing for padding oracle vulnerabilities: First, possible input points for padding oracles must be identified. Generally the following conditions must be met:


 * 1) The data is encrypted. Good candidates are values which appear to be random.
 * 2) A block cipher is used. The length of the decoded (Base64 is used often) cipher text is a multiple of common cipher block sizes like 8 or 16 bytes. Different cipher texts (e.g. gathered by different sessions or manipulation of session state) share a common divisor in the length.

If such an input value candidate is identified, the behavior of the application to bit-wise tampering of the encrypted value should be verified. For this purpose, multiple requests should be issued, where one bit of the base value is flipped. At least the last two blocks should be tampered. The bit flipping must be performed on the decoded cipher text, while the tampered cipher text must be encoded as expected by the application. This tests and the base value should at least cause three different states while and after decryption:


 * Cipher text gets decrypted, resulting data is correct.
 * Cipher text gets decrypted, resulting data is garbled and causes some exception or error handling in the application logic.
 * Cipher text decryption fails due to padding errors.

Compare the responses carefully. Search especially for exceptions and messages which state that something is wrong with the padding. If such messages appear, the application contains a padding oracle. If the three different states described above are observable implicitly (different error messages, timing side-channels), there is a high probability, that there is a padding oracle present at this point. Try to perform the padding oracle attack to ensure this.

Examples: Result Expected: A secure implementation will check for integrity and cause only two responses: ok and failed. There are no side channels which can be used to determine internal error states.
 * ASP.NET throws "System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed." if padding of a decrypted cipher text is broken.
 * In Java a javax.crypto.BadPaddingException is thrown in this case.
 * Decryption errors or similar can be possible padding oracles.

White Box testing and example
Testing for padding oracle vulnerabilities: Verify all places where encrypted data from the client, that should only be known by the server, is decrypted. The following conditions should be met by such code:


 * 1) The integrity of the cipher text should be verified by a secure mechanism which uses a different secret than the encryption and decryption of the cipher text.
 * 2) All error states while decryption and further processing are handled uniformly.