Skip to content

Commit

Permalink
cpa level
Browse files Browse the repository at this point in the history
  • Loading branch information
zardus committed Sep 28, 2024
1 parent 4153f6a commit 989fb70
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
23 changes: 23 additions & 0 deletions cryptography/cpa/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Though the core of the AES crypto algorithm is thought to be secure (not _proven_ to be, though: no one has managed to do that! But no one has managed to significantly break the crypto in the 20+ years of its use, either), this core only encrypts 128-bit (16 byte) blocks at a time.
To actually _use_ AES in practice, one must build a _cryptosystem_ on top of it.

In the previous level, we used the AES-[ECB](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)) cryptosystem: an Electronic Codebook Cipher where every block is indendently encrypted by the same key.
This system is quite simple but, as we will discover here, extremely susceptible to a certain class of attack.

Cryptosystems are held to very high standard of [ciphertext indistinguishability](https://en.wikipedia.org/wiki/Ciphertext_indistinguishability).
That is, an attacker that lacks the key to the cryptosystem should not be able to distinguish between pairs of ciphertext based on the plaintext that was encrypted.
For example, if the attacker looks at ciphertexts `UVSDFGIWEHFBFFCA` and `LKXBFVYASLJDEWEU`, and is able to determine that the latter was produced from the plaintext `EEEEFFFFGGGGHHHH` (or, in fact, figure out _any_ information about the plaintext at all!), the cryptosystem is considered broken.
This property must hold even if the attacker already knows part or all of the plaintext, a setting known as the [Known Plaintext Attack](https://en.wikipedia.org/wiki/Known-plaintext_attack), _or can even control part or all of the plaintext_, a setting known as the [Chosen Plaintext Attack](https://en.wikipedia.org/wiki/Chosen-plaintext_attack)!

ECB is susceptible to both known and chosen plaintext attack.
Because every block is encrypted with the same key, with no other modifications, an attacker can observe identical ciphertext across different blocks that have identical plaintext.
Moreover, if the attacker can choose or learn the plaintext associated with some of these blocks, they can carefully build a mapping from known-plaintext to known-ciphertext, and use that as a lookup table to decrypt other matching ciphertext!

In this level, you will do just this: you will build a codebook mapping from ciphertext to chosen plaintext, then use that to decrypt the flag.
Good luck!

----
**HINT:**
You might find it helpful to automate interactions with this challenge.
You can do so using the `pwntools` Python package.
Check out [this pwntools cheatsheet](https://gist.github.com/anvbis/64907e4f90974c4bdd930baeb705dedf) from a fellow pwn.college student!
27 changes: 27 additions & 0 deletions cryptography/cpa/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/opt/pwn.college/python

from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes

flag = open("/flag", "rb").read()

key = get_random_bytes(16)
cipher = AES.new(key=key, mode=AES.MODE_ECB)

while True:
print("Choose an action?")
print("1. Encrypt chosen plaintext.")
print("2. Encrypt part of the flag.")
if (choice := int(input("Choice? "))) == 1:
pt = input("Data? ").strip().encode()
elif choice == 2:
index = int(input("Index? "))
length = int(input("Length? "))
pt = flag[index:index+length]
else:
break

ct = cipher.encrypt(pad(pt, cipher.block_size))
print(f"Result: {b64encode(ct).decode()}")
2 changes: 1 addition & 1 deletion cryptography/level-4/DESCRIPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ AES _must_ operate on complete blocks.
If the plaintext is _shorter_ than a block (e.g., `AAAABBBB`), it will be _padded_ to the block size, and the padded plaintext will be encrypted.

Different AES "modes" define what to do when the plaintext is longer than one block.
In this challenge, we are using the simplest mode: "[Electronic CodeBook (ECB)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB))".
In this challenge, we are using the simplest mode: "[Electronic Codebook (ECB)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB))".
In ECB, each block is encrypted separately with the same key and simply concatenated together.
So if you are encrypting something like `AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH`, it will be split into two plaintext blocks (`AAAABBBBCCCCDDDD` and `EEEEFFFFGGGGHHHH`), encrypted separately (resulting, let's imagine, in `UVSDFGIWEHFBFFCA` and `LKXBFVYASLJDEWEU`), then concatenated (resulting the ciphertext `UVSDFGIWEHFBFFCALKXBFVYASLJDEWEU`).

Expand Down
2 changes: 2 additions & 0 deletions cryptography/module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ challenges:
name: Many-time Pad
- id: level-4
name: AES
- id: cpa
name: Chosen-plaintext Attack
- id: level-5
name: level5
- id: level-6
Expand Down

0 comments on commit 989fb70

Please sign in to comment.