Skip to content

Commit

Permalink
padding oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
zardus committed Sep 29, 2024
1 parent f15895c commit 19777b3
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cryptography/aes-cbc-poa/.init
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

dd if=/dev/urandom of=/challenge/.key bs=16 count=1
chmod 600 /challenge/.key
21 changes: 21 additions & 0 deletions cryptography/aes-cbc-poa/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
So you can manipulate the padding...
If you messed up somewhere along the lines of the previous challenge and created an invalid padding, you might have noticed that the worker _crashed_ with an error about the padding being incorrect!

It turns out that this one crash _completely_ breaks the Confidentiality of the AES-CBC cryptosystem.
Let's dig in...

Recall that PKCS7 padding adds N bytes with the value N, so if 11 bytes of padding were added, they have the value `0x0b`.
During unpadding, PKCS7 will read the value N of the last byte, make sure that the last N bytes (including that last byte) have that same value, and remove those bytes.
If the value N is bigger than the block size, or the bytes don't all have the value N, most implementations of PKCS7, including the one provided by PyCryptoDome, will error.

Consider how careful you had to be in the previous level with the padding, and how this required you to know the letter you wanted to remove.
What if you didn't know that letter?
Your random guesses at what to XOR it with would cause an error 255 times out of 256 (as long as you handled the rest of the padding properly, of course), and the one time it did not, by known what the final padding had to be and what your XOR value was, you can recover the letter value!
This is called a [_Padding Oracle Attack_](https://en.wikipedia.org/wiki/Padding_oracle_attack), after the "oracle" (error) that tells you if your padding was correct!

Of course, once you remove (and learn) the last byte of the plaintext, the second-to-last byte becomes the last byte, and you can attack it!
And when you recover the entire last block, you can simply discard it, making the second-to-last block the last block.
You'll need to slightly adjust this attack for the 16th byte of a block, since there is not padding at all, but I trust in your ability to do so!

So, what are you waiting for?
Go recover the flag!
18 changes: 18 additions & 0 deletions cryptography/aes-cbc-poa/dispatcher
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/opt/pwn.college/python

from base64 import b64encode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

import sys

key = open("/challenge/.key", "rb").read()
cipher = AES.new(key=key, mode=AES.MODE_CBC)

if len(sys.argv) > 1 and sys.argv[1] == "flag":
plaintext = open("/flag", "rb").read().strip()
else:
plaintext = b"sleep"

ciphertext = cipher.iv + cipher.encrypt(pad(plaintext, cipher.block_size))
print(f"TASK: {b64encode(ciphertext).decode()}")
28 changes: 28 additions & 0 deletions cryptography/aes-cbc-poa/worker
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/opt/pwn.college/python

from base64 import b64decode
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Random import get_random_bytes

import time
import sys

key = open("/challenge/.key", "rb").read()

while line := sys.stdin.readline():
if not line.startswith("TASK: "):
continue
data = b64decode(line.split()[1])
iv, ciphertext = data[:16], data[16:]

cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
plaintext = unpad(cipher.decrypt(ciphertext), cipher.block_size).decode('latin1')

if plaintext == "sleep":
print("Sleeping!")
time.sleep(1)
elif plaintext == "flag":
print("Not so easy...")
else:
print("Unknown command!")
2 changes: 2 additions & 0 deletions cryptography/module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ challenges:
name: AES-CBC Tampering
- id: aes-cbc-corrupt-resize
name: AES-CBC Resizing
- id: aes-cbc-poa
name: AES-CBC: Padding Oracle Attack
- id: level-6
name: DHKE
- id: level-7
Expand Down

0 comments on commit 19777b3

Please sign in to comment.