Hazmat Symmetric Key - Bitflipping Ciphertext (CBC)Some AES modes are vulnerable to bit flipping attacks. In this case, we will use AES CTR mode, and flip the bits of the nth character in the ciphertext, and where we specify the character to target and the bit value to flip. |
Theory
Don’t you just love making money? Well, if we use the wrong type of encryption, we could end up with the wrong amount of money being allocated to someone.
So, let’s see if we can double Bob’s money. In this case, Bob will give Alice one dollar, and then she will send a ciphertext message to Trent to pay Bob back. But Eve modifies the encrypted ciphertext so that Bob gets two dollars each time. Eve never knows the encryption key that Alice and Trent are using.
And, so, Alice encrypts “Pay Bob 1 Dollar”, with a secret key and a random salt value, and gets a cipher of “39dda42138cc4be3b62161f61ff4fe5ef89dbfd6a2e6c8af7884902558ab4cf0”, and sends this to Trent for payment to Bob.
Eve then sneaks in - she's an Eve-in-the-middle - and changes only one part of the ciphertext to “39dda42138cc4be3b52161f61ff4fe5ef89dbfd6a2e6c8af7884902558ab4cf0”. When Trent decrypts the ciphertext, he gets “Pay Bob 2 Dollar”, and pays Bob two dollars. Bob is very happy and keeps giving Alice more dollars, and to keep sending these transactions to Trent. Bob soon becomes a millionaire and shares his earnings with Eve, but Alice has to sell everything — she’s lost everything!
Bit-flipping
You need to beware of bit flipping in certain modes of AES, including with ECB, CBC and CTR. In the following, we flip the bits of a specific ciphertext, and reveal that we have changed the plaintext.
Message: b'Pay Bob 1 Dollar' Key: b'c6823af982e238374ad8f43e36a8fa500092cd4866fb607d3c97816eaec1ef45' IV: b'1faca392225803f7f3b5eae4da1a69bb' Flipping bits in character 0 with value of 1 Before bitflip: b'1faca392225803f7f3b5eae4da1a69bbcea45ddcfede9d87bfe136ee2c129490117513ef9478c7dd9c600412948d8024' After bitflip: b'1eaca392225803f7f3b5eae4da1a69bbcea45ddcfede9d87bfe136ee2c129490117513ef9478c7dd9c600412948d8024' Decrypted: Qay Bob 1 Dollar
The code is:
from base64 import b64decode from base64 import b64encode import os from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad, unpad import binascii import sys def encrypt(key,data,iv): cipher = AES.new(key, AES.MODE_CBC, iv) return b64encode(iv +cipher.encrypt(pad(data, AES.block_size))) def decrypt(key, data): raw = b64decode(data) cipher = AES.new(key, AES.MODE_CBC, raw[:AES.block_size]) return unpad(cipher.decrypt(raw[AES.block_size:]), AES.block_size) def bitFlip( pos, bit, data): raw = b64decode(data) list1 = list(raw) list1[pos] = list1[pos] ^ bit raw = bytes(list1) return b64encode(bytes(raw)) key = os.urandom(32) iv = get_random_bytes(AES.block_size) msg = b"Pay Bob 1 Dollar" chartoflip=0 charflip=1 if (len(sys.argv)>1): msg=str(sys.argv[1]).encode() if (len(sys.argv)>2): chartoflip=int(sys.argv[2]) if (len(sys.argv)>3): charflip=int(sys.argv[3]) print ("Message:\t",msg) print ("Key:\t",binascii.b2a_hex(key)) print ("IV:\t",binascii.b2a_hex(iv)) ctx = encrypt(key,msg,iv).decode('utf-8') print(f"Flipping bits in character {chartoflip} with value of {charflip}") print(f"\nBefore bitflip: { binascii.b2a_hex(b64decode(ctx))}") ctx = bitFlip(chartoflip,charflip,ctx) print(f"\nAfter bitflip: { binascii.b2a_hex(b64decode(ctx))}") print(f"Decrypted: {decrypt(key,ctx).decode('utf-8')}")