Created
July 12, 2012 01:56
-
-
Save tarcieri/3095168 to your computer and use it in GitHub Desktop.
An chosen plaintext attack on ECB mode allowing recovery of encrypted messages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'openssl' | |
# Don't use this | |
module Encryption | |
def self.cipher(mode) | |
cipher = OpenSSL::Cipher::Cipher.new("aes-256-ecb") | |
cipher.send mode | |
cipher.key = "ABANDON ALL HOPE YE WHO USE ECB!" | |
cipher.padding = 0 | |
cipher | |
end | |
def self.encrypt(text) | |
return unless text | |
# lolpadding courtesy the fastaes gem | |
block_size = 16 | |
padding_length = block_size - (text.length % block_size) | |
text += "\0" * padding_length | |
aes = cipher(:encrypt) | |
aes.update(text) << aes.final | |
end | |
end | |
# We assume the attacker has access to some kind of encryption oracle somewhere | |
# in the system. An example of this would be an encrypted cookie where the | |
# attacker can control a portion of the plaintext. | |
def oracle(chosen_plaintext) | |
Encryption.encrypt(chosen_plaintext + TARGET_MESSAGE) | |
end | |
PAD = "A" | |
BLOCK_SIZE = 16 | |
TARGET_MESSAGE = "secret message" | |
# LENGTH can be determined automatically but I'm lazy | |
LENGTH = TARGET_MESSAGE.size | |
plaintext = "" | |
LENGTH.times do | |
pad_size = BLOCK_SIZE - plaintext.size - 1 | |
prefix = PAD * pad_size | |
target_ciphertext = oracle(prefix) | |
prefix << plaintext | |
n = -1 | |
begin | |
n += 1 | |
guess = prefix + n.chr | |
encrypted_guess = oracle(guess)[0...BLOCK_SIZE] | |
puts "Guessing: #{guess.inspect}\t(encrypted: #{encrypted_guess.unpack("H*").first[0..8]}, target: #{target_ciphertext[0...BLOCK_SIZE].unpack("H*").first[0..8]})" | |
end until encrypted_guess == target_ciphertext[0...BLOCK_SIZE] | |
plaintext << n.chr | |
puts "LOCK! We now have: #{plaintext}" | |
end |
Also: once you have the code from this, you are very close to having the code for the CBC- with- chained- IV bug that the TLS BEAST attack exploits.
(That's how I learned about this attack: from Thai's frustrated attempts to explain the BEAST attack to me while he was working on it at Matasano)
Sweet! There was a pretty cool assignment in Udacity's CS 387 where you were supposed to perform a BEAST-like attack on CBC. You might enjoy that, too :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Now, make it work if your oracle starts from some arbitrary point in the middle of the ciphertext (that's the common case with cookies).