Formatting. q14. q15.

master
Valentin Ochs 2019-09-04 19:22:26 +02:00
parent 62c92eecbb
commit f806cfec45
2 changed files with 156 additions and 23 deletions

View File

@ -58,7 +58,7 @@ impl Aes {
Some(data.clone())
}
pub fn ecb(&self, mut data: Vec<u8>, mode: Mode) -> Option<Vec<u8>> {
pub fn ecb(&self, data: Vec<u8>, mode: Mode) -> Option<Vec<u8>> {
if (!self.pad) && (data.len() % Self::BLOCK_SIZE != 0) {
return None;
}

View File

@ -168,8 +168,8 @@ fn q11() {
let key: Vec<u8> = rng.sample_iter(&dist).take(16).collect();
let iv: Vec<u8> = rng.sample_iter(&dist).take(16).collect();
let aes = crypto::Aes::new(&key, true).unwrap();
let mut start: Vec<u8> = rng.sample_iter(&dist).take(rng.gen_range(5,11)).collect();
let mut end: Vec<u8> = rng.sample_iter(&dist).take(rng.gen_range(5,11)).collect();
let mut start: Vec<u8> = rng.sample_iter(&dist).take(rng.gen_range(5, 11)).collect();
let mut end: Vec<u8> = rng.sample_iter(&dist).take(rng.gen_range(5, 11)).collect();
start.append(&mut data);
start.append(&mut end);
@ -180,21 +180,21 @@ fn q11() {
}
};
let oracle = |data: &Vec<u8>| -> bool {
data[16..32] == data[32..48]
};
let oracle = |data: &Vec<u8>| -> bool { data[16..32] == data[32..48] };
for i in 0..128 {
let data = [0u8;64];
let data = [0u8; 64];
let (ecb, data) = black_box(data.to_vec());
assert!(ecb == oracle(&data));
}
}
fn q12()
{
fn q12() {
println!("Running q12");
let key: Vec<u8> = rand::thread_rng().sample_iter(rand::distributions::Standard).take(16).collect();
let key: Vec<u8> = rand::thread_rng()
.sample_iter(rand::distributions::Standard)
.take(16)
.collect();
let plaintext: Vec<u8> = Bytes::from_base64("Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK").into();
let aes = crate::crypto::Aes::new(&key, true).unwrap();
@ -204,7 +204,10 @@ fn q12()
};
let starting_size = blackbox(Vec::new()).len();
let (first_increment, next_size) = (0..).map(|x:usize| (x, blackbox(std::iter::repeat(0u8).take(x).collect()).len())).find(|(_,x)| *x != starting_size).unwrap();
let (first_increment, next_size) = (0..)
.map(|x: usize| (x, blackbox(std::iter::repeat(0u8).take(x).collect()).len()))
.find(|(_, x)| *x != starting_size)
.unwrap();
let block_size = next_size - starting_size;
println!(" Block size is {}", block_size);
assert!(block_size == 16);
@ -220,15 +223,23 @@ fn q12()
let mut known: Vec<u8> = Vec::with_capacity(data_length);
println!(" Data length: {}", data_length);
for _ in 0..data_length
{
let nulls: Vec<u8> = std::iter::repeat(0u8).take(starting_size - known.len() - 1).collect();
for _ in 0..data_length {
let nulls: Vec<u8> = std::iter::repeat(0u8)
.take(starting_size - known.len() - 1)
.collect();
let target_block = &blackbox(nulls.clone())[0..starting_size];
let mut found = false;
'byteiter: for b in 0u8..=255u8 {
let this_block = &blackbox(nulls.iter().chain(known.iter()).chain(std::iter::once(&b)).cloned().take(starting_size).collect())[0..starting_size];
if this_block == target_block
{
let this_block = &blackbox(
nulls
.iter()
.chain(known.iter())
.chain(std::iter::once(&b))
.cloned()
.take(starting_size)
.collect(),
)[0..starting_size];
if this_block == target_block {
known.push(b);
found = true;
break 'byteiter;
@ -239,10 +250,12 @@ fn q12()
// println!(" {}", String::from_utf8(known).unwrap().replace("\n", "\n "));
}
fn q13()
{
fn q13() {
println!("Running q13");
let key: Vec<u8> = rand::thread_rng().sample_iter(rand::distributions::Standard).take(16).collect();
let key: Vec<u8> = rand::thread_rng()
.sample_iter(rand::distributions::Standard)
.take(16)
.collect();
let parse = |x: &str| -> std::collections::HashMap<String, String> {
let mut out = std::collections::HashMap::new();
@ -251,12 +264,15 @@ fn q13()
if elements.len() == 2 {
out.insert(elements[0].to_owned(), elements[1].to_owned());
}
};
}
out
};
let profile_for = |mail: &str| -> String {
format!("email={}&uid=10&role=user", mail.replace("&","").replace("=",""))
format!(
"email={}&uid=10&role=user",
mail.replace("&", "").replace("=", "")
)
};
let encrypt = |profile: &str| -> Vec<u8> {
@ -278,13 +294,128 @@ fn q13()
let mail2 = " ".repeat(16 - "email=".len());
let mail2 = mail2 + "admin";
let padding_char = (16 - "admin".len()) as u8;
let mail2 = mail2 + &String::from_utf8(vec![padding_char]).unwrap().repeat(padding_char as usize);
let mail2 = mail2
+ &String::from_utf8(vec![padding_char])
.unwrap()
.repeat(padding_char as usize);
let part2: &[u8] = &encrypt(&profile_for(&mail2))[16..32];
let whole: Vec<u8> = part1.iter().chain(part2.iter()).cloned().collect();
assert!(is_admin(whole));
}
fn q14() {
println!("Running q14");
let key: Vec<u8> = rand::thread_rng()
.sample_iter(rand::distributions::Standard)
.take(16)
.collect();
let plaintext: Vec<u8> = Bytes::from_base64("Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK").into();
let aes = crate::crypto::Aes::new(&key, true).unwrap();
let prefix: Vec<u8> = rand::thread_rng()
.sample_iter(rand::distributions::Standard)
.take(rand::thread_rng().gen_range(5, 11))
.collect();
let blackbox = |mut attacker_data: Vec<u8>| -> Vec<u8> {
let mut data: Vec<u8> = prefix.clone();
data.append(&mut attacker_data);
data.append(&mut plaintext.clone());
let rv = aes.ecb(data, Mode::Encrypt).unwrap();
rv
};
let starting_size = blackbox(Vec::new()).len();
let (first_increment, next_size) = (0..)
.map(|x: usize| (x, blackbox(std::iter::repeat(0u8).take(x).collect()).len()))
.find(|(_, x)| *x != starting_size)
.unwrap();
println!(" First size increment at {}", first_increment);
let block_size = next_size - starting_size;
println!(" Block size is {}", block_size);
assert!(block_size == 16);
let long_block = blackbox(std::iter::repeat(0u8).take(1280).collect());
let using_ecb = long_block[480..496] == long_block[496..512];
println!(" Using ECB: {}", using_ecb);
assert!(using_ecb);
let all_zero_ciphertext = blackbox(std::iter::repeat(0u8).take(block_size).collect());
let first_different_block = |x: usize| -> usize {
let data: Vec<u8> = std::iter::repeat(0u8)
.take(x)
.chain(std::iter::once(1u8))
.chain(std::iter::repeat(0u8).take(block_size - 1 - x))
.collect();
let data: Vec<u8> = blackbox(data);
data.chunks_exact(block_size)
.zip(all_zero_ciphertext.chunks_exact(block_size))
.enumerate()
.find(|(_, (a, b))| a != b)
.unwrap()
.0
};
let start_block = first_different_block(0);
let mut prefix_size = start_block * block_size + block_size - 1;
for i in 2..block_size {
let diff_block = first_different_block(i);
if diff_block == start_block {
prefix_size = start_block * block_size + block_size - 1 - i;
}
}
println!(" Prefix length is {}", prefix_size);
assert!(prefix_size == prefix.len());
let data_length = starting_size - first_increment - prefix_size;
let mut known: Vec<u8> = Vec::with_capacity(data_length);
println!(" Data length: {}", data_length);
assert!(data_length == plaintext.len());
let prefix_total = (prefix_size + block_size - 1) / block_size * block_size;
let prefix_nulls = prefix_total - prefix_size;
let starting_size = (prefix_total + data_length + block_size - 1) / block_size * block_size;
for _ in 0..data_length {
let nulls: Vec<u8> = std::iter::repeat(0u8)
.take(starting_size - prefix_size - known.len() - 1)
.collect();
let target_block = &blackbox(nulls.clone())[prefix_total..starting_size];
let mut found = false;
'byteiter: for b in 0u8..=255u8 {
let this_block = &blackbox(
nulls
.iter()
.chain(known.iter())
.chain(std::iter::once(&b))
.cloned()
.take(starting_size)
.collect(),
)[prefix_total..starting_size];
if this_block == target_block {
known.push(b);
found = true;
break 'byteiter;
}
}
assert!(found);
}
assert!(known == plaintext);
}
fn q15() {
println!("Running q15");
let input = b"ICE ICE BABY\x05\x05\x05\x05";
let output = Bytes::from(&input[..]);
let output = output.unpad();
assert!(output == None);
let input = b"ICE ICE BABY\x04\x04\x04\x04";
let output = Bytes::from(&input[..]);
let output = output.unpad().unwrap();
assert!(output.to_string().unwrap() == "ICE ICE BABY");
}
fn main() {
q01();
q02();
@ -299,4 +430,6 @@ fn main() {
q11();
q12();
q13();
q14();
q15();
}