Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

My attempt of explanation with a (hopefully) relatable example: imagine that you store all your backup files encrypted, then restore the backup on your machine. The backup is stored on untrusted NAS but it's OK since it's encrypted, right?

With OFB (and CTR, and any other unauthenticated cipher basically), no. Ciphers guarantee confidentiality, but nothing else. This means that the attacker can alter one of your encrypted backed-up files. It's not a hypothetical attack. For example your backed up /bin/ls file likely starts with something like (hexencoded):

    7f454c4602010100000000000000000002003e000100 .ELF..............>...
Let's assume attacker wants to trick you into running "echo hacked" on your system. They may achieve this by altering your backed up /bin/ls such that it decrypts to something like this:

    23212f62696e2f73680a6563686f206861636b65640a  #!/bin/sh\necho hacked\n
And it's really easy! Stream ciphers work by XORing input plaintext with keystream:

    ciphertext = plaintext ^ generate_keystream(key)
    plaintext = ciphertext ^ generate_keystream(key)
If you look closely at the equations, it's apparent that one can flip a byte in decrypted plaintext by flipping a byte in the ciphertext. To drive the point home, a small demonstration in Python (I'll use CTR instead of OFB but it's the same):

    >>> from Crypto.Cipher import AES
    >>> def xor(a, b): return bytes([ac ^ bc for ac, bc in zip(a, b)])
    >>> aes_enc = AES.new(b"mysupersecretkey", AES.MODE_CTR)
    >>> plaintext = open("/bin/ls", "rb").read(32)
    >>> ciphertext = aes_enc.encrypt(plaintext)
    >>> known_plaintext = bytes.fromhex("7f454c4602010100000000000000000002003e000100")
    >>> wanted_plaintext =bytes.fromhex("23212f62696e2f73680a6563686f206861636b65640a")
    >>> flip = xor(known_plaintext, wanted_plaintext)
    >>> flipped_ciphertext = xor(flip, ciphertext)
    >>> aes_dec = AES.new(b"mysupersecretkey", AES.MODE_CTR, nonce=aes_enc.nonce)
    >>> aes_dec.decrypt(flipped_ciphertext)
    b'#!/bin/sh\necho hacked\n\\d\xc3\xd9\*o.sh\n'
In this example attacker can change the first 22 bytes of file to arbitrary payload by abusing the predictable header of the ELF file. No knowledge of the key is necessary.


Thank you!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: