oracle – Padding oracle attacks

This module provides a functions that, given an oracle function that returns True when a message is properly padded and False otherwise, will decrypt or encrypt a given message assuming that the underlying cipher operates in CBC mode.

pwnypack.oracle.padding_oracle_decrypt(oracle, ciphertext, known_prefix=b'', known_suffix=b'', block_size=128, alphabet=None, pool=None, block_pool=None, progress=None)[source]

Decrypt ciphertext using an oracle function that returns True if the provided ciphertext is correctly PKCS#7 padded after decryption. The cipher needs to operate in CBC mode.

Parameters:
  • oracle (callable) – The oracle function. Will be called repeatedly with a chunk of ciphertext.
  • ciphertext (bytes) – The data to decrypt. Should include the IV at the start.
  • known_prefix (bytes) – If the start of the plaintext is known, it can be provided to skip decrypting the known prefix.
  • known_suffix (bytes) – If the end of the plaintext is known, it can be provided to skip decrypting the known suffix. Should include padding.
  • block_size (int) – The cipher’s block size in bits.
  • alphabet (bytes) – Optimize decryption if you know which characters the plaintext will consist of.
  • pool (multiprocessing.Pool) – A multiprocessing pool to use to parallelize the decryption. This pool is used to call the oracle function. Fairly heavy due to the required inter-process state synchronization. If None (the default), no multiprocessing will be used.
  • block_pool (multiprocessing.Pool) – A multiprocessing pool to use to parallelize the decryption. This pool is used to decrypt entire blocks in parallel. When decrypting ciphertext consisting of multiple blocks, it is usually more efficient than using the pool argument. If None (the default), no multiprocessing will be used.
  • progress (callable) – A callable that will be called each time a new byte is decrypted. Is called with the positition of the character in the plaintext result and the character itself.
Returns:

The decrypted data with its PKCS#7 padding stripped.

Return type:

bytes

Raises:

RuntimeError – Raised if the oracle behaves unpredictable.

Example

>>> from pwny import *
>>> with multiprocessing.Pool(5) as pool:
>>>     print(padding_oracle_decrypt(oracle_function, encrypted_data, pool=pool))
b'decrypted data'
pwnypack.oracle.padding_oracle_encrypt(oracle, plaintext, block_size=128, pool=None)[source]

Encrypt plaintext using an oracle function that returns True if the provided ciphertext is correctly PKCS#7 padded after decryption. The cipher needs to operate in CBC mode.

Parameters:
  • oracle (callable) – The oracle function. Will be called repeatedly with a chunk of ciphertext.
  • plaintext (bytes) – The plaintext data to encrypt.
  • block_size (int) – The cipher’s block size in bits.
  • pool (multiprocessing.Pool) – A multiprocessing pool to use to parallelize the encryption. This pool is used to call the oracle function. Fairly heavy due to the required inter-process state synchronization. If None (the default), no multiprocessing will be used.
Returns:

The encrypted data.

Return type:

bytes

Raises:

RuntimeError – Raised if the oracle behaves unpredictable.