commit 44264eeefe86f0d5ffe8088f9a96c2822b9745f9
parent c02b362176501c3b0af17045c93f6aabdd85c66a
Author: Jared Tobin <jared@jtobin.ca>
Date: Thu, 31 Aug 2017 13:23:22 +1200
Updates.
Diffstat:
4 files changed, 96 insertions(+), 4 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,8 +4,9 @@ version = "0.1.0"
authors = ["Jared Tobin <jared@jtobin.ca>"]
[dependencies]
-base64 = "0.6.0"
-clap = "2.26.0"
-hex = "0.2.0"
+base64 = "0.6.0"
+clap = "2.26.0"
+hex = "0.2.0"
openssl = "0.9.11"
+rand = "0.3.16"
diff --git a/docs/s2.md b/docs/s2.md
@@ -64,5 +64,6 @@ and then make the guess:
which is actually the wrong one here.
-But, uh, let's not use bash for this.
+But, uh, let's not use bash for this. Check [the source](../src/s2c11.rs) for
+now.
diff --git a/src/main.rs b/src/main.rs
@@ -5,6 +5,7 @@ mod s1c3;
mod s1c7;
mod s2c10;
+mod s2c11;
fn main() {
println!("s1c1:\n{}\n", s1c1::s1c1());
@@ -12,4 +13,5 @@ fn main() {
println!("s1c3:\n{}\n", s1c3::s1c3());
println!("s1c7:\n{}\n", s1c7::s1c7());
println!("s2c10:\n{}\n", s2c10::s2c10());
+ println!("s2c11:\n{}\n", s2c11::s2c11());
}
diff --git a/src/s2c11.rs b/src/s2c11.rs
@@ -0,0 +1,88 @@
+
+extern crate rand;
+extern crate openssl;
+
+use s1c7::aes_128_ecb_crypt;
+use s2c10::aes_128_cbc_crypt;
+use self::openssl::symm::Mode;
+use self::rand::Rng;
+use self::rand::distributions::{IndependentSample, Range};
+use std::collections::HashSet;
+
+const KEY_SIZE: usize = 16;
+const BLOCK_SIZE: usize = 16;
+
+pub fn gen_bytes(size: usize) -> Vec<u8> {
+ let mut rng = rand::thread_rng();
+ let mut buffer = Vec::with_capacity(size);
+
+ for foo in 0..size {
+ let byte: u8 = rng.gen();
+ buffer.push(byte);
+ }
+
+ buffer
+}
+
+pub fn black_box_encrypter(message: &[u8]) -> Vec<u8> {
+ let mut rng = rand::thread_rng();
+
+ let between = Range::new(5, 11);
+ let prepend_size = between.ind_sample(&mut rng);
+ let append_size = between.ind_sample(&mut rng);
+
+ let prepend = gen_bytes(prepend_size);
+ let append = gen_bytes(append_size);
+
+ let ciphertext_size = prepend_size + message.len() + append_size;
+ let mut ciphertext = Vec::with_capacity(ciphertext_size);
+
+ let key = gen_bytes(KEY_SIZE);
+
+ ciphertext.extend_from_slice(&prepend);
+ ciphertext.extend_from_slice(message);
+ ciphertext.extend_from_slice(&append);
+
+ if rng.gen() {
+ aes_128_ecb_crypt(Mode::Encrypt, &key, &message)
+ } else {
+ let iv = gen_bytes(KEY_SIZE);
+ aes_128_cbc_crypt(Mode::Encrypt, &key, &iv, &message)
+ }
+}
+
+pub fn ecb_detector(ciphertext: &[u8], size: usize) -> bool {
+ let mut blocks = HashSet::new();
+
+ for block in ciphertext.chunks(size) {
+ if blocks.contains(block) {
+ return true;
+ }
+
+ blocks.insert(block);
+ }
+
+ false
+}
+
+pub fn s2c11() -> String {
+ let message = String::from(
+ "Here I'm just gonna try something crazy and type a bunch of words.
+ Like, enough words so that if I actually give decrypting this a shot,
+ it has a reasonable chance of detecting ECB when it actually occurs
+ This is actually more likely than it might initially seem; if the block
+ size is just 16, so two consecutive characters anywhere in the message
+ should encrypt to the same thing. Interesting to see if the oracle
+ will actually be able to bust it on this text. So yeah, anyway, let's
+ see what happens. At the very least there are a bunch of double spaces
+ at the end of sentences.");
+
+ let ciphertext = black_box_encrypter(message.as_bytes());
+
+ if ecb_detector(&ciphertext, BLOCK_SIZE) {
+ String::from("probably ECB.")
+ } else {
+ String::from("probably CBC.")
+ }
+}
+