diff options
author | Jesse Luehrs <doy@tozt.net> | 2015-04-07 01:18:04 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2015-04-07 01:18:04 -0400 |
commit | a16eee14a18d4c345d6485593d3543e342c86af3 (patch) | |
tree | e0b0215eb1b7ea2de66803ec9ea5b70e69878db4 | |
parent | 4213d57bdf70b6339bc4affdc751c296f9aa14f0 (diff) | |
download | matasano-a16eee14a18d4c345d6485593d3543e342c86af3.tar.gz matasano-a16eee14a18d4c345d6485593d3543e342c86af3.zip |
problem 26
-rw-r--r-- | src/crack.rs | 12 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | tests/set4.rs | 38 |
3 files changed, 51 insertions, 0 deletions
diff --git a/src/crack.rs b/src/crack.rs index abfd84a..b5ff9ff 100644 --- a/src/crack.rs +++ b/src/crack.rs @@ -435,6 +435,18 @@ pub fn crack_aes_128_ctr_random_access<F> (ciphertext: &[u8], edit: F) -> Vec<u8 return fixed_xor(&keystream[..], ciphertext); } +pub fn crack_ctr_bitflipping<F> (f: &F) -> Vec<u8> where F: Fn(&str) -> Vec<u8> { + let ciphertext = f("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); + let replacement = fixed_xor(&ciphertext[32..44], b";admin=true;"); + return ciphertext[..32] + .iter() + .chain(replacement.iter()) + .chain(ciphertext[44..].iter()) + .map(|x| *x) + .collect(); +} + + fn crack_single_byte_xor_with_confidence (input: &[u8]) -> (u8, f64) { let mut min_diff = 100.0; let mut best_key = 0; @@ -43,3 +43,4 @@ pub use crack::clone_mersenne_twister_from_output; pub use crack::recover_16_bit_mt19937_key; pub use crack::recover_mt19937_key_from_time; pub use crack::crack_aes_128_ctr_random_access; +pub use crack::crack_ctr_bitflipping; diff --git a/tests/set4.rs b/tests/set4.rs index 3967f85..35c3edf 100644 --- a/tests/set4.rs +++ b/tests/set4.rs @@ -48,3 +48,41 @@ fn problem_25 () { let got = matasano::crack_aes_128_ctr_random_access(&ciphertext[..], edit); assert_eq!(&got[..], &plaintext[..]); } + +#[test] +fn problem_26 () { + let key = util::random_aes_128_key(); + let nonce = rand::thread_rng().gen(); + let prefix = "comment1=cooking%20MCs;userdata="; + let suffix = ";comment2=%20like%20a%20pound%20of%20bacon"; + let admin = ";admin=true;"; + + let escape = |input: &str| { + input.replace("%", "%25").replace(";", "%3B").replace("=", "%3D") + }; + + let encode = |input: &str| -> Vec<u8> { + let plaintext: Vec<u8> = prefix + .as_bytes() + .iter() + .chain(escape(input).as_bytes().iter()) + .chain(suffix.as_bytes().iter()) + .map(|x| *x) + .collect(); + return matasano::aes_128_ctr(&plaintext[..], &key[..], nonce); + }; + + let verify = |ciphertext: &[u8]| -> bool { + let plaintext = matasano::aes_128_ctr(ciphertext, &key[..], nonce); + return (0..(plaintext.len() - admin.len())).any(|i| { + plaintext + .iter() + .skip(i) + .zip(admin.as_bytes().iter()) + .all(|(&c1, &c2)| c1 == c2) + }); + }; + + let ciphertext = matasano::crack_ctr_bitflipping(&encode); + assert!(verify(&ciphertext[..])); +} |