diff options
author | Jesse Luehrs <doy@tozt.net> | 2015-03-28 03:28:25 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2015-03-28 03:28:25 -0400 |
commit | 1505a949589b17837319a292a07e1c15ed9296e4 (patch) | |
tree | 551764e450e4a8f0b9e367dc331c1bd1b87aab62 /src | |
parent | cf487bb3c09d4e0532bd452ad3aa5eb292b176ba (diff) | |
download | matasano-1505a949589b17837319a292a07e1c15ed9296e4.tar.gz matasano-1505a949589b17837319a292a07e1c15ed9296e4.zip |
problem 17
Diffstat (limited to 'src')
-rw-r--r-- | src/aes.rs | 33 | ||||
-rw-r--r-- | src/lib.rs | 1 |
2 files changed, 34 insertions, 0 deletions
@@ -255,6 +255,39 @@ pub fn crack_cbc_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8> return ciphertext; } +pub fn crack_cbc_padding_oracle<F> (iv: &[u8], ciphertext: &[u8], f: &F) -> Vec<u8> where F: Fn(&[u8], &[u8]) -> bool { + let mut prev = iv; + let mut plaintext = vec![]; + for block in ciphertext.chunks(16) { + let mut plaintext_block = vec![]; + 'BYTE: for byte in 0..16u8 { + for c_int in 0..256 { + let c = (255 - c_int) as u8; + let offset = (16 - byte - 1) as usize; + let mut iv: Vec<u8> = prev + .iter() + .take(offset) + .map(|x| *x) + .collect(); + iv.push(prev[offset] ^ c ^ (byte + 1)); + for i in 0..(byte as usize) { + iv.push(prev[offset + i + 1] ^ plaintext_block[i] ^ (byte + 1)); + } + if f(&iv[..], block) { + plaintext_block.insert(0, c); + continue 'BYTE; + } + } + panic!("no byte found! ({})", byte); + } + for c in plaintext_block { + plaintext.push(c); + } + prev = block; + } + return unpad_pkcs7(&plaintext[..]).unwrap().to_vec(); +} + fn count_duplicate_blocks (input: &[u8], block_size: usize) -> usize { let mut set = HashSet::new(); let mut dups = 0; @@ -19,6 +19,7 @@ pub use aes::crack_padded_aes_128_ecb; pub use aes::crack_padded_aes_128_ecb_with_prefix; pub use aes::crack_querystring_aes_128_ecb; pub use aes::crack_cbc_bitflipping; +pub use aes::crack_cbc_padding_oracle; pub use base64::to_base64; pub use http::parse_query_string; pub use http::create_query_string; |