128 bit AES CBC bit flipping on second block 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.
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