Formatting. q14. q15.
This commit is contained in:
parent
62c92eecbb
commit
f806cfec45
|
@ -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;
|
||||
}
|
||||
|
|
171
src/main.rs
171
src/main.rs
|
@ -180,9 +180,7 @@ 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];
|
||||
|
@ -191,10 +189,12 @@ fn q11() {
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user