Start work on challenge 14.
This commit is contained in:
11
src/main.rs
11
src/main.rs
@@ -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();
|
||||
}
|
||||
|
||||
58
src/set2.rs
58
src/set2.rs
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user