Formatting. q14. q15.
This commit is contained in:
parent
62c92eecbb
commit
f806cfec45
|
@ -58,7 +58,7 @@ impl Aes {
|
||||||
Some(data.clone())
|
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) {
|
if (!self.pad) && (data.len() % Self::BLOCK_SIZE != 0) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
177
src/main.rs
177
src/main.rs
|
@ -168,8 +168,8 @@ fn q11() {
|
||||||
let key: Vec<u8> = rng.sample_iter(&dist).take(16).collect();
|
let key: Vec<u8> = rng.sample_iter(&dist).take(16).collect();
|
||||||
let iv: 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 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 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 end: Vec<u8> = rng.sample_iter(&dist).take(rng.gen_range(5, 11)).collect();
|
||||||
|
|
||||||
start.append(&mut data);
|
start.append(&mut data);
|
||||||
start.append(&mut end);
|
start.append(&mut end);
|
||||||
|
@ -180,21 +180,21 @@ fn q11() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let oracle = |data: &Vec<u8>| -> bool {
|
let oracle = |data: &Vec<u8>| -> bool { data[16..32] == data[32..48] };
|
||||||
data[16..32] == data[32..48]
|
|
||||||
};
|
|
||||||
|
|
||||||
for i in 0..128 {
|
for i in 0..128 {
|
||||||
let data = [0u8;64];
|
let data = [0u8; 64];
|
||||||
let (ecb, data) = black_box(data.to_vec());
|
let (ecb, data) = black_box(data.to_vec());
|
||||||
assert!(ecb == oracle(&data));
|
assert!(ecb == oracle(&data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn q12()
|
fn q12() {
|
||||||
{
|
|
||||||
println!("Running 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 plaintext: Vec<u8> = Bytes::from_base64("Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK").into();
|
||||||
let aes = crate::crypto::Aes::new(&key, true).unwrap();
|
let aes = crate::crypto::Aes::new(&key, true).unwrap();
|
||||||
|
|
||||||
|
@ -204,7 +204,10 @@ fn q12()
|
||||||
};
|
};
|
||||||
|
|
||||||
let starting_size = blackbox(Vec::new()).len();
|
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;
|
let block_size = next_size - starting_size;
|
||||||
println!(" Block size is {}", block_size);
|
println!(" Block size is {}", block_size);
|
||||||
assert!(block_size == 16);
|
assert!(block_size == 16);
|
||||||
|
@ -220,15 +223,23 @@ fn q12()
|
||||||
let mut known: Vec<u8> = Vec::with_capacity(data_length);
|
let mut known: Vec<u8> = Vec::with_capacity(data_length);
|
||||||
println!(" Data length: {}", data_length);
|
println!(" Data length: {}", data_length);
|
||||||
|
|
||||||
for _ in 0..data_length
|
for _ in 0..data_length {
|
||||||
{
|
let nulls: Vec<u8> = std::iter::repeat(0u8)
|
||||||
let nulls: Vec<u8> = std::iter::repeat(0u8).take(starting_size - known.len() - 1).collect();
|
.take(starting_size - known.len() - 1)
|
||||||
|
.collect();
|
||||||
let target_block = &blackbox(nulls.clone())[0..starting_size];
|
let target_block = &blackbox(nulls.clone())[0..starting_size];
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
'byteiter: for b in 0u8..=255u8 {
|
'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];
|
let this_block = &blackbox(
|
||||||
if this_block == target_block
|
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);
|
known.push(b);
|
||||||
found = true;
|
found = true;
|
||||||
break 'byteiter;
|
break 'byteiter;
|
||||||
|
@ -239,10 +250,12 @@ fn q12()
|
||||||
// println!(" {}", String::from_utf8(known).unwrap().replace("\n", "\n "));
|
// println!(" {}", String::from_utf8(known).unwrap().replace("\n", "\n "));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn q13()
|
fn q13() {
|
||||||
{
|
|
||||||
println!("Running 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 parse = |x: &str| -> std::collections::HashMap<String, String> {
|
||||||
let mut out = std::collections::HashMap::new();
|
let mut out = std::collections::HashMap::new();
|
||||||
|
@ -251,12 +264,15 @@ fn q13()
|
||||||
if elements.len() == 2 {
|
if elements.len() == 2 {
|
||||||
out.insert(elements[0].to_owned(), elements[1].to_owned());
|
out.insert(elements[0].to_owned(), elements[1].to_owned());
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
out
|
out
|
||||||
};
|
};
|
||||||
|
|
||||||
let profile_for = |mail: &str| -> String {
|
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> {
|
let encrypt = |profile: &str| -> Vec<u8> {
|
||||||
|
@ -278,13 +294,128 @@ fn q13()
|
||||||
let mail2 = " ".repeat(16 - "email=".len());
|
let mail2 = " ".repeat(16 - "email=".len());
|
||||||
let mail2 = mail2 + "admin";
|
let mail2 = mail2 + "admin";
|
||||||
let padding_char = (16 - "admin".len()) as u8;
|
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 part2: &[u8] = &encrypt(&profile_for(&mail2))[16..32];
|
||||||
let whole: Vec<u8> = part1.iter().chain(part2.iter()).cloned().collect();
|
let whole: Vec<u8> = part1.iter().chain(part2.iter()).cloned().collect();
|
||||||
|
|
||||||
assert!(is_admin(whole));
|
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() {
|
fn main() {
|
||||||
q01();
|
q01();
|
||||||
q02();
|
q02();
|
||||||
|
@ -299,4 +430,6 @@ fn main() {
|
||||||
q11();
|
q11();
|
||||||
q12();
|
q12();
|
||||||
q13();
|
q13();
|
||||||
|
q14();
|
||||||
|
q15();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user