From caf6d35b59169036b50419ec147f64ba4a88873d Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Mon, 15 Aug 2022 20:21:40 -0400 Subject: [PATCH] Implement challenge 26 ez katka --- src/main.rs | 3 ++- src/parser.rs | 15 +++++++-------- src/set4.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index d1861cc..f8bbcc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,8 @@ fn main() { set3::challenge24(); set4::challenge25(); set4::challenge26(); + set4::challenge27(); } else { - set4::challenge26(); + set4::challenge27(); } } diff --git a/src/parser.rs b/src/parser.rs index a6de9dd..60f1327 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -40,14 +40,13 @@ fn scan(code: &str, mut ix: usize, mut tokens: Tokens) -> Tokens { let c: char = code[ix..ix + 1].chars().next().unwrap(); if c.is_ascii_alphanumeric() || SPECIAL_CHARS.contains(&c) { return scan_identifier(code, ix, tokens); - } else if c == '&' { - tokens.push(Token::Ampersand); - } else if c == '=' { - tokens.push(Token::Equal); - } else if c == ';' { - tokens.push(Token::Semicolon); - } else { - panic!("Unexpected char '{}' at index {}", c, ix); + } + + match c { + '&' => tokens.push(Token::Ampersand), + '=' => tokens.push(Token::Equal), + ';' => tokens.push(Token::Semicolon), + _ => panic!("Unexpected char '{}' at index {}", c, ix), } ix += 1; scan(code, ix, tokens) diff --git a/src/set4.rs b/src/set4.rs index 820a56f..34e3f77 100644 --- a/src/set4.rs +++ b/src/set4.rs @@ -1,4 +1,4 @@ -use crate::{bytes::Bytes, ctr, utils}; +use crate::{bytes::Bytes, ctr, parser, utils}; pub fn challenge25() { let cipher = utils::read_base64("data/25.txt"); @@ -43,5 +43,42 @@ pub fn challenge25() { } pub fn challenge26() { - println!("[xxxx] Challenge 26: TBD"); + fn encrypt(input: &str, key: &Bytes) -> Bytes { + let mut r = String::new(); + for c in input.chars() { + if c == ';' || c == '=' { + panic!("encrypt: invalid char {}", c); + } + } + r.push_str("comment1=cooking%20MCs;userdata="); + r.push_str(input); + r.push_str(";comment2=%20like%20a%20pound%20of%20bacon"); + let data = Bytes(r.as_bytes().to_vec()); + ctr::encrypt(key, 0, &data) + } + + let key = Bytes::random(16); + + // 0 16 32 48 64 + // 0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f0..34..78..bc..f + // comment1=cooking%20MCs;userdata=aaaaaaaaaaaaaaaa;comment2=%20like%20a%20pound%20of%20bacon + // comment1=cooking%20MCs;userdata=fobar;admin=true;comment2=%20like%20a%20pound%20of%20bacon + let input = "aaaaaaaaaaaaaaaa"; + let cipher = encrypt(&input, &key); + let keystream = utils::xor(&cipher.0[32..48], &Bytes::from_utf8(input).0); + + let input = "fobar;admin=true"; + let mut flipped_cipher = cipher.0[0..32].to_vec(); + flipped_cipher.append(&mut utils::xor(&keystream, &input.as_bytes())); + flipped_cipher.append(&mut cipher.0[48..cipher.len()].to_vec()); + + let cleartext = ctr::decrypt(&key, 0, &Bytes(flipped_cipher)); + let dict = parser::parse_key_value(&cleartext.to_utf8()); + let admin_status = dict.get("admin").unwrap(); + assert_eq!(admin_status, "true"); + println!("[okay] Challenge 26: admin={}", admin_status); +} + +pub fn challenge27() { + println!("[xxxx] Challenge 27: tbd"); }