0
$\begingroup$

I have a 128 bit AES cipher in CBC Mode with the IV prepended to the message. I am aware of the security issues here, but that is exactly the point of my example. I would like to change the plain text message via bit-flipping, which I have partially implemented in the example below:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes


key = b'WOAH, SO SECRET!'
block_size = 16 # in bytes (128 bit)


def encrypt_data(data):
    iv = get_random_bytes(block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    enc = cipher.encrypt(pad(data, block_size, style='pkcs7'))
    return iv + enc


def decrypt_data(data):
    iv = data[:block_size]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_params = cipher.decrypt(data[block_size:])
    return unpad(padded_params, block_size, style='pkcs7')


# 128 bit blocks for better visualization
plain = b'Hello everybody!' \
        b' This is a very ' \
        b'cool message,wow'

wanted = b'THIS CAN CHANGE!' \
         b' This is a very ' \
         b'cool message,wow'


cipher_text = bytearray(encrypt_data(plain))

for block in range(len(plain)//block_size):
        for i in range(block_size):
                block_idx = (block*block_size)+i
                xor_byte = plain[block_idx] ^ wanted[block_idx]

                cipher_text[block_idx] ^= xor_byte

result = decrypt_data(bytes(cipher_text))
print(result)

Above code outputs:

b'THIS CAN CHANGE! This is a very cool message,wow'

Which is exactly what I want!

However, I only ever managed to change the first block sucessfully, by changing the preceding block of the cipher message (in this case IV, which does not affect the rest of the message). If I modify my example with a wanted message like that:

wanted = b'Hello everybody!' \
         b'THIS CAN CHANGE ' \
         b'cool message,wow'

My code outputs:

b'g\x114\xb4\xc4\xd6\xd6\x16\xcf\x88\x87\x99\xea@\xe4\x11THIS CAN CHANGE cool message,wow'

I understand, that this happens due to the fact of using CBC mode and the impact of blocks on each other as described here. But what exactly am I missing here? How can I change my message to the desired output after decryption?

b'Hello everybody!THIS CAN CHANGE cool message,wow'

I'd appreciate any push in the right direction.

$\endgroup$
1
$\begingroup$

There is only one way I see how to avoid having this block of garbage in you plaintext after CBC bit flipping attack, but it requires to be able to see the result of the decryption and to know the whole plaintext you are attacking, which may not be the case in most practical scenarios.

Say you want to alter the third block of plaintext, P3:

  • Do your CBC bit flipping attack on P3 by modifying C2, the normal way
  • get the modified plaintext. P2 should be garbage
  • now modify C1 in order to “repair” P2, that is, C1 = (the garbage you got) XOR (the original P2)
  • this is going to mess up P1, so you now you modify the IV to “repair” P1
| improve this answer | |
$\endgroup$
  • $\begingroup$ I'll give it a try and share an update soon $\endgroup$ – NotFound404 Dec 6 '19 at 13:37
  • $\begingroup$ Thank you so much for your help! Your solution worked! $\endgroup$ – NotFound404 Dec 6 '19 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.