CBC Bit-Flipping Attack

This blog post is for the discussion of AES CBC Bit-flipping attack. Firstly, get familiar with the CBC mode of encryption before you go through this attack. Please do refer the below blog post to get an idea about CBC mode.

link: CBC mode of encryption

This attack is explained with the help of Cryptopals Challenge16

Bit-Flipping Attack is possible when the format of the message or the message itself are known. We alter the previous ciphertext block, so as to make a predictable change in the plaintext.


In this challenge, we take the input “;admin=true;”. The first function replaces “;” and “=” with “%” and prepends the string with


and again appends it with


Then the entire string is encrypted with the generated random key.

We make a second function that decrypts the ciphertext and searches for “;admin=true;”. It returns true and gives us admin access when it is found, else returns false. So how do we alter the ciphertext to get required plaintext??



Taking a glance at the above figure we understand that change in a byte of ciphertext changes only the corresponding byte of plaintext in the next block. So, for eg by changing Ct1[0] we can only see a change in Pt2[0]. Also we can infer that, for a random byte n

Pt2[n] = Ct1[n] ^ D(Ct2[n])  →(1)

But, D(Ct2[n]) = D(E(Pt2[n] ^ Ct1[n])) i.e E(Pt2[n] ^ Ct1[n])  → (2)

We need to determine the modified Ct1′ to get our required Pt2′ replacing the previous Pt2. On rearranging (1) we get, Ct1′[n] = Pt2′[n] ^ D(Ct2[n]) . Note that Ct2 is the same as before. From (2) we get the final answer as

Ct1′[n] = Pt2′[n] ^ Pt2[n] ^ Ct1[n]

Hence, we can flip the bytes of Ct1 to Ct1′ by XORing the character to be changed with the replaced character along with the previous ciphertext byte. We need not worry what Ct1′ decrypts to.

Explanation to Challenge

Our input is “;admin=true;” but the first function replaces “;” and “=” with “%” and therefore the second function returns false. We have to flip the bytes to bypass the condition. Here the length of the prepended string is 32, so our input is in 3rd block.

Ct[16] = ord(” ; “)  ^ Ct[16] ^ ord(” % “)

Ct[21] = ord( “=” ) ^ Ct[21] ^ ord(” % “)

Ct[31] = ord(” ; “)  ^ Ct[31] ^ ord(” % “)

Now, the modified Ciphertext is sent through the second function for decryption. It decrypts and checks for “;admin=true;”. As it passes the condition we get the admin access.


Thank You!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s