Cryptopals - ECB cut-and-paste

16 August 2020

Premises

In challenge 13 of the Cryptopals challenges, a function profile_for() producing valid ciphertexts is provided.

The function profile_for takes an email as its input and encrypts the encoded profile. For instance for the email what@ever.com the encoded profile is

email=what@ever.com&uid=10&role=user

Which corresponds to the JSON role below:

{
  "email": "what@ever.com",
  "uid": 10,
  "role": "user"
}

The goal is to create a profile with the role admin thanks to the profile_for() function. There is a catch though, the function will strip any & or = from the user input.

The code for this challenge is available on my Github repository

Regular encryption

If I use the function with the email foo@bar.com, the profile is encoded to email=foo@bar.com&uid=10&role=user and this encoded string is encrypted with AES-128-ECB.

Regular encryption

My first idea was to compute what the plaintext would have been if the role was "admin". Here the second plaintext block P2P2 is m&uid=10&role=us. If the role was admin that plaintext would have been m&uid=10&rol=ad, and then P3P3 would have been min with the proper PKCS#7 padding.

To make this strategy work I would need the function to encrypt the target plaintext block for me m&uid=10&role=ad, which is impossible since the function strips down = and & characters.

Finding the right size

Nonetheless, the idea is the right one. To make it work I just need to free myself of these special characters. For instance, if I choose the email what@ever.com, the role user will be in its own block:

Initial encryption

This is my initial plaintext, that is why I added a subscript i to the blocks. Thanks to this setup the last block contains the profile role but no special characters.

Target ciphertext

To change the role to admin, I need to replace the last ciphertext block by one that is the result of encrypting admin. In the diagram below I added a subscript t on the blocks since this is my target:

Target encryption

I've got most of the work done for me already since the first two blocks are equal in the initial and target case:

C1i=C1tC2i=C2tC1_i = C1_t \\ C2_i = C2_t

To get an admin role I just have to find a way to compute C3tC3_t

Oracle encryption

The function profile_for() is an oracle that allows me to encrypt arbitrary information. To do so I can craft a special email so that the string admin and its PKCS#7 padding will be in its own block. In the diagram below I use the email what@ever.admin\x11\x11...\x11\x11 (11 times \x11) to compute C3tC3_t:

Computing encryption

Cut and paste

I now have at my disposal:

  • C1tC1_t and C2tC2_t that I computed when I was searching for my target encryption
  • C3tC3_t that I computed with my cleverly crafted email

At this point, I solved the challenge: I just need to concatenate these ciphertext blocks to get the target ciphertext.

You liked this article ? Check out the other posts about the Cryptopals challenges!