Padding Oracle Attack


This kind of attack exists because of the cryptographic padding that takes place on the message length. Since, Plaintext can be of varying length, however block ciphers require that all messages need to be exact number of blocks. To satisfy this requirement we use padding, to get the exact number of blocks.

Detecting POA Vulnerability:


  1. The application needs to use CBC mode of operation while encrypting.

  2. The application uses only encryption, but no authentication. i.e, application should not generate MAC for the ciphertext.


Applications in order to maintain the state of the user use cookies or sessions, usually they are encrypted, so that no other party can view the parameters and impersonate legitimate users. When an application is passed an encrypted value, it responds in one of the following cases:

  1. The encrypted value is valid with correct padding, the applications sends 200 OK response.

  2. The encrypted value is invalid with incorrect padding, the application sends 500 Internal Server Error.

  3. The encrypted value is invalid with correct padding, the application sends custom error message (200 OK).

In Practice

Look for long and random looking strings, probably in the form of base64- or URL-encoded.

For eg., 7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6

Using some Proxy, like Burp try to change the values of last byte or last couple of bytes, duplicating last couple of blocks and see how the application responds, usually in one of the above cases.

Request : http://sampleapp/home.jsp?UID=0000000000000000F851D6CC68FC9537
Response: 500 - Internal Server Error

Things to look out for

  1. Timing: processing encrypted data takes usually longer.

  2. New cookie might be created on invalid data, but usually you get an error when padding is bad.

  3. Look out for any Exceptions generated during 500 error

Stacktrace with padding-exception (Java, Ruby).
         Given final block not properly padded
         OpenSSL::Cipher::CipherError in ApplicationController:bad decrypt

Exploit Tool:

PadBuster is an excellent automation tool released by GDS which does the dirty work, once you figured out that application is vulnerable to Padding. _Note: The tool requires Perl to be installed in order to run. _The tool takes 3 mandatory arguments :

  1. URL : the url of the server you want to exploit, in cryptography terms server is called as Oracle, including Query string if needed. You can also supply, Post data using (-post) switch or cookie using (-cookie) switch.

  2. Encrypted Sample : This is the encrypted sample that will be tested, it should also be present in any one of them URL query string, post or cookie.

  3. Block Size : The block size should be mentioned in either 8 or 16.

  4. Encoding : (optional) It is used to specify how the encrypted text is encoded, by default it takes base64. Using the switch (-encoding) you specify the type :

* 0: base64 encoding

* 1: Lowercase HEX ASCII

* 2: Uppercase HEX ASCII http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
8 -encoding 2

In the next step,i.e. when the tool starts processing the first block, it asks the User to which response code it should test (200 or 500), the padbuster is intelligent enough to suggest the user on which response it should continue testing, it highlights by presenting (**) by the side of options it provides us.

ID#    Freq    Status    Length    Location 
1       1       200        89         N/A
2**     255     500       3643        N/A

Once we select this, the rest of the blocks are decrypted, and the plaintext is shown.

What else can we do – Encryption?

One important thing, that we get from the above process besides Plaintext is the Intermediate value for each block, which is vital in CBC operation. Since, we can deduce the intermediate values, we can use this information to encrypt new arbitrary values. One mandatory switch that needs to be passed with the above arguments is:

  1. -plaintext [string] : The plaintext that you want to encrypt. http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
8 -encoding 2 -plaintext "ENCRYPT TEST"

There are two optional switches that you can provide to speed up the process, they are -ciphertext [Bytes], -intermediary [Bytes]. If you know them, you can send these values to speed up the brute-force, but anyhow since we are lazy we can neglect these switches, as the Padbuster itself gets them, from the encrypted sample you have provided.


The only solution for this is to append a MAC to the encrypted text, so that data cannot be tampered, and be used for repeated querying.

External Links: