Skip to content

Instantly share code, notes, and snippets.

@tarcieri
Created July 12, 2012 01:56
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarcieri/3095168 to your computer and use it in GitHub Desktop.
Save tarcieri/3095168 to your computer and use it in GitHub Desktop.
An chosen plaintext attack on ECB mode allowing recovery of encrypted messages
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
Copy link

tqbf commented Jul 12, 2012

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
Copy link

tqbf commented Jul 12, 2012

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)

@emboss
Copy link

emboss commented Sep 16, 2012

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