Start work on challenge 14.

This commit is contained in:
2022-06-23 09:46:31 -04:00
parent 6f739b6781
commit 52222e90e9
2 changed files with 61 additions and 8 deletions

View File

@@ -15,9 +15,10 @@ fn main() {
// set1::challenge6();
// set1::challenge7();
// set1::challenge8();
set2::challenge9();
set2::challenge10();
set2::challenge11();
set2::challenge12();
set2::challenge13();
// set2::challenge9();
// set2::challenge10();
// set2::challenge11();
// set2::challenge12();
// set2::challenge13();
set2::challenge14();
}

View File

@@ -221,7 +221,7 @@ pub fn challenge13() {
// "valid" ciphertexts) and the ciphertexts themselves, make a
// role=admin profile.
// (FelixM) I assume ECB and block_size = 16; we could figure
// it out easily my adding enough 'a' to the email
// it out easily by adding enough 'a' to the email
let mut r = vec![];
// ________________________________
@@ -250,9 +250,61 @@ pub fn challenge13() {
let dict = decrypt(&key, &profile);
let role = dict.get("role").unwrap();
assert_eq!(role, "admin");
println!("[done] Challenge 13: role={}", role);
println!("[okay] Challenge 13: role={}", role);
}
pub fn challenge14() {
println!("[xxxx] Challenge 14:");
fn read(path: &str) -> Bytes {
let s = std::fs::read_to_string(path).unwrap();
BytesBase64::from_base64(&s).to_bytes()
}
fn encryption_oracle(
Bytes(random_prefix): &Bytes,
random_key: &Bytes,
Bytes(attacker_controlled): &Bytes,
) -> Bytes {
// AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key)
// Thoughts: If I generate a random prefix for every encryption, then I don't
// know how to decode it because I cannot really run experiments. If I generate
// a single random prefix it becomes rather trivial. I just have to find out how
// long it is and then adjust the decoding routine.
let mut plaintext = random_prefix.to_vec();
plaintext.append(&mut attacker_controlled.to_vec());
let mut target_bytes = read("data/12.txt").0;
plaintext.append(&mut target_bytes);
let cipher = ecb::encrypt(&random_key, &Bytes(plaintext));
cipher
}
fn get_block_size(prefix: &Bytes, key: &Bytes) -> usize {
// Detect cipher block size this approach also confirms that it is ECB
let v = vec![b'a'; 256];
let cipher = encryption_oracle(prefix, key, &Bytes(v));
for i in 1..10 {
let block_size = i * 16;
let chunks: Vec<&[u8]> = cipher.0.chunks(block_size).collect();
for i in 0..chunks.len() {
for j in (i + 1)..chunks.len() {
if chunks[i] == chunks[j] {
return block_size;
}
}
}
}
0
}
let prefix = Bytes::random_range(0, 200);
let key = Bytes::random(16); // consistent but unknown key
assert_eq!(get_block_size(&prefix, &key), 16);
let _clear_text = read("data/12.txt");
// AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key)
// rrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaathe real text
// 0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f
// 0 1 2 4 5
println!("[xxxx] Challenge 14: {}", get_block_size(&prefix, &key));
}