On Padding Oracle Attacks

John Stickle, Security Consultant, Coalfire

Poodle is a vulnerability found in late 2014, and it is still occasionally seen during penetration tests. The vulnerability allows an attacker with a man-in-the-middle position to downgrade a secure connection between a client and a server to the vulnerable SSLv3. After the connection is downgraded, the attacker can proceed to perform the padding oracle attack, recover known plaintext, and decrypt the ciphertext.

To begin the exploitation process, the attacker utilizes a man-in-the-middle position as a starting point. When the initial connection between client and server is created, the two first agree on which encryption protocol they would like to communicate over. The client will begin by asking the server if communication can be established utilizing TLS 1.2. Rather than the server responding to the request, the attacker speaks on its behalf from the man-in-the-middle position, and replies with a simple “No.” Next, the client will ask if communication in TLS 1.1 is acceptable, and again the response is a “No.” The process repeats itself with TLS 1.0; then, once all other encryption protocols are denied, SSLv3 is reached. When the client asks if communication in SSLv3 is acceptable, the attacker responds on the server’s behalf with a “Yes,” as SSLv3 is vulnerable.

Once a connection utilizing SSLv3 is established, the attacker can proceed to intercept the traffic and perform the padding oracle attack. In order to understand how these attacks work, we must first understand how padding works.

Padding is a large part of CBC mode encryption. If you use a stream cipher to encrypt 1 byte of data, you will get 1 byte of encrypted data out. If you want to encrypt 2 bytes of data, you will get two bytes of encrypted data out. CBC however works in blocks. If you want to encrypt 1 byte of data, you will get 16 bytes of output. 2 bytes of data will still correspond to 16 bytes of output. This repeats itself until you reach 16 bytes of output.

The PCKS7 states that the padding value will equal the number of pads left to fill within the block. So, back to our earlier example, if you encrypt 1 byte of data, and you get 16 bytes out, the rest of those pads will have the value of 15, since there are 15 more pads left in the 16-byte block. If you encrypt 2 bytes of data, the padding values in the block will each have the value of 14, since there are 14 more pads left in the block.

/Users/john/Desktop/Talk/Screen Shot 2017-09-12 at 10.19.32 AM.png

If the value of the pads within the encrypted message are discovered, then you have known plaintext. With known plaintext, an attacker can decrypt the rest of the message.

To begin, the attacker needs to discover what the padding value is within the ciphertext. This can be achieved by performing a simple brute-force attack and watching if the server responds with a padding error. The server will tell an attacker whether they have the correct value or not. If a padding error is returned, then the guessed value is incorrect. If there is no error returned, then the guessed value is correct. In order to start guessing the correct padding values, the attacker begins by incrementing the least significant byte within the initialization vector, one by one. This will increase the padding value accordingly. Once a padding error is not returned within the incrementation process, the attacker knows they have the correct padding value.

Once they do have the correct padding value, they can simply XOR that value with the modified initialization vector value. So, if the attacker had to change a byte in the initialization vector from a 1 to a 4 to get the right padding value, then they XOR the padding value with the 4. After that, the result is a byte from the keystream.

Once they have the byte from the keystream, the attacker can just XOR that with the original IV value that they changed, which in this case is a 1. The result is plaintext. They go ahead and rinse and repeat this process to decrypt the whole message.

To reiterate the attack in a simple manner, the attacker begins guessing padding values by incrementing the initialization vector until they don’t receive an error. Then, they XOR the padding value with the modified value, and then XOR that result with the original IV value. The result is a byte of plaintext.

As shown, when a server acts as an oracle and discloses information related to the integrity of a message, this leaves an open door for brute-force attacks. This behavior is the cornerstone of numerous vulnerabilities, with POODLE being arguably the most prevalent. To aid in preventing these sorts of attacks, it is a best practice to never disclose the integrity of the padding to the end user in this manner.

The POODLE vulnerability was largely remediated by most TLS implementers upon public release of the vulnerability, however new variants are still arising. Along with ensuring the server does not disclose information directly related to the integrity of the message, it is also a best practice to ensure that legacy technology is left in the past. It is a common occurrence for software developers to maintain support of legacy technology in order to provide for a more seamless user experience. However, when the legacy technology is vulnerable, trading security for usability is never wise.

John Stickle


John Stickle — Security Consultant, Coalfire

Recent Posts

Post Topics