Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

An chosen plaintext attack on ECB mode allowing recovery of encrypted messages

View ecb_is_bad.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
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
tqbf commented

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).

tqbf commented

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
Something went wrong with that request. Please try again.