Challenge example

Source code

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import json
import os

FLAG = ?
KEY = ?

def encryptFlag():
    data = {"flag": FLAG}

    plaintext = json.dumps(data).encode()
    padded = pad(plaintext, 16)
    iv = os.urandom(16)
    cipher = AES.new(KEY, AES.MODE_CBC, iv)
    try:
        encrypted = iv + cipher.encrypt(padded)
        print(f"Here is your token : {encrypted.hex()}")
    except ValueError as e:
        print({"error": str(e)})
        return

def checkToken():
    token = input("Token : ")
    token = bytes.fromhex(token)
    iv = token[:16]
    token = token[16:]

    cipher = AES.new(KEY, AES.MODE_CBC, iv)
    try:
        plaintext = cipher.decrypt(token)
        unpadded = unpad(plaintext, 16)
        data = json.loads(unpadded)
    except ValueError as e:
        print({"error": str(e)})
        return

    if data["flag"] == FLAG:
        print("Token is valid")


print("Welcome !")
encryptFlag()
checkToken()

The objective is to break the ciphertext to retrieve the flag value.

Exploitation

Vulnerability detection

In order to exploit the padding oracle attack, there are 2 things that need to be checked:

  • We can send as many time as we want a ciphertext to decrypt.

  • The application returns an error in case of padding error.

POC

As explained here, in order to retrieve the last character of the last block, we need to brute force the last character of the penultimate block until the application returns a valid padding.

Then the real plaintext byte will be bruteforce_result ⊕ original_block_byte ⊕ 0x01

here the byte 0x0c was found, it means that there is probably a padding of size 13 on the plain text

Full exploitation

We just have to update the code to make it follow the entire padding oracle algorithm

Using Libraries

Many people have write libraries to automate this attack. Here is an example using this python implementation of padBuster :

Exercice

If you want to try this exploit by yourself, you can pull this docker image :

Deploy the image using the followed command :

The service is available on port 1337

Last updated