Skip to content

Instantly share code, notes, and snippets.

@cookie-s
Last active July 22, 2023 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cookie-s/ed097f7a3c657e1aedead178b1c5b102 to your computer and use it in GitHub Desktop.
Save cookie-s/ed097f7a3c657e1aedead178b1c5b102 to your computer and use it in GitHub Desktop.
require 'socket'
require 'expect'
require 'openssl'
rust = IO.popen('./rust', "r+")
# s = TCPSocket.new('localhost', 4567)
s = TCPSocket.new('crypto.ctf.zer0pts.com', 10929)
begin
pt1 = '00'*16
s.expect('> ')
s.puts 1
s.expect('(hex): ')
s.puts pt1
s.expect(': ')
iv1, iv2, ct = s.gets.chomp.split(?:)
s.expect('> ')
s.puts 2
s.expect(': ')
iv1x= [iv1].pack("H*").tap{|x| x[0] = (x[0].ord ^ 1).chr}.unpack1("H*")
s.puts [iv1x, iv2, ct]*?:
s.expect('(hex): ')
pt2 = s.gets.chomp
rust.puts pt1
rust.puts pt2
key0 = rust.gets.chomp
puts key0
end
begin
s.expect('> ')
s.puts 2
s.expect(': ')
ctx = [ct].pack("H*").tap{|x| x[0] = (x[0].ord ^ 1).chr}.unpack1("H*")
s.puts [iv1, iv2, ctx]*?:
s.expect('(hex): ')
pt2 = s.gets.chomp
rust.puts pt1
rust.puts pt2
rust.puts iv1
key1 = rust.gets.chomp
puts key1
end
begin
rust.puts iv1
rust.puts iv2
rust.puts pt1
rust.puts ct
key2 = rust.gets.chomp
puts key2
end
begin
s.expect('> ')
s.puts 3
s.expect(': ')
iv1, iv2, ct = s.gets.chomp.split(?:)
rust.puts iv1
rust.puts iv2
rust.puts ct
begin
ct = [ct].pack("H*")
d = OpenSSL::Cipher::AES.new(128, :CFB).tap{|c| c.decrypt; c.key = [key2].pack("H*"); c.iv = [iv2].pack("H*")}
ct = d.update(ct) + d.final
d = OpenSSL::Cipher::AES.new(128, :CBC).tap{|c| c.decrypt; c.key = [key1].pack("H*"); c.iv = [iv1].pack("H*")}
ct = d.update(ct) + d.final
d = OpenSSL::Cipher::AES.new(128, :ECB).tap{|c| c.decrypt; c.key = [key0].pack("H*")}
ct = d.update(ct) + d.final
puts ct
puts ct.unpack1("H*")
rescue => e
puts e
end
puts rust.gets.chomp
end
[package]
name = "aes"
version = "0.1.0"
authors = ["cookie-s <kcz@kcz.sh>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
hex = "0.4.3"
md5 = "0.7.0"
openssl = "0.10.32"
use openssl::symm::{decrypt, encrypt, Cipher, Crypter, Mode};
use std::io;
fn main() {
let k0 = (|| -> Option<[u8; 16]> {
let stdin = io::stdin();
let cipher = Cipher::aes_128_ecb();
let pt1 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(pt1.len(), 16);
let pt2 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(pt2.len(), 16);
for r0 in 0..=255u8 {
for r1 in 0..=255u8 {
for r2 in 0..=255u8 {
let key: [u8; 16] = md5::compute([r0, r1, r2]).into();
let mut ct1 = encrypt(cipher, &key, None, &pt1).unwrap();
ct1[0] ^= 1;
let pt = decrypt(cipher, &key, None, &ct1).unwrap();
if pt == pt2 {
return Some(key);
}
}
}
}
None
})()
.unwrap();
println!("{}", hex::encode(&k0));
let k1 = (|| -> Option<[u8; 16]> {
let stdin = io::stdin();
let cipher = Cipher::aes_128_cbc();
let pt1: &[u8] = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
let cipher = Cipher::aes_128_ecb();
let pt = hex::decode(&buf[..32]).unwrap();
&encrypt(cipher, &k0, None, &pt).unwrap()[..16]
};
assert_eq!(pt1.len(), 16);
let pt2: &[u8] = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
let cipher = Cipher::aes_128_ecb();
let pt = hex::decode(&buf[..32]).unwrap();
&encrypt(cipher, &k0, None, &pt).unwrap()[..16]
};
assert_eq!(pt2.len(), 16);
let iv1 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(iv1.len(), 16);
for r0 in 0..=255u8 {
for r1 in 0..=255u8 {
for r2 in 0..=255u8 {
let key: [u8; 16] = md5::compute([r0, r1, r2]).into();
let mut ct1 = encrypt(cipher, &key, Some(&iv1), &pt1).unwrap();
ct1[0] ^= 1;
let mut dec = Crypter::new(cipher, Mode::Decrypt, &key, Some(&iv1)).unwrap();
dec.pad(false);
let mut buf = [0u8; 64];
dec.update(&ct1, &mut buf).unwrap();
if buf[..16] == pt2[..] {
return Some(key);
}
}
}
}
None
})()
.unwrap();
println!("{}", hex::encode(&k1));
let k2 = (|| -> Option<[u8; 16]> {
let stdin = io::stdin();
let cipher = Cipher::aes_128_cfb128();
let iv1 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(iv1.len(), 16);
let iv2 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(iv2.len(), 16);
let pt1: &[u8] = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
let pt = hex::decode(&buf[..32]).unwrap();
let cipher = Cipher::aes_128_ecb();
let pt = &encrypt(cipher, &k0, None, &pt).unwrap()[..16];
let cipher = Cipher::aes_128_cbc();
&encrypt(cipher, &k1, Some(&iv1), &pt).unwrap()[..16]
};
assert_eq!(pt1.len(), 16);
let ct = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(ct.len(), 16);
for r0 in 0..=255u8 {
for r1 in 0..=255u8 {
for r2 in 0..=255u8 {
let key: [u8; 16] = md5::compute([r0, r1, r2]).into();
let ct1 = encrypt(cipher, &key, Some(&iv2), &pt1).unwrap();
if ct == ct1 {
return Some(key);
}
}
}
}
None
})()
.unwrap();
println!("{}", hex::encode(&k2));
let res = (|| {
let stdin = io::stdin();
let iv1 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(iv1.len(), 16);
let iv2 = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
hex::decode(&buf[..32]).unwrap()
};
assert_eq!(iv2.len(), 16);
let ct = {
let mut buf = String::new();
stdin.read_line(&mut buf).unwrap();
let buf = &buf[..buf.len() - 1];
hex::decode(&buf).unwrap()
};
let pt = ct;
let cipher = Cipher::aes_128_cfb128();
let pt = decrypt(cipher, &k2, Some(&iv2), &pt).unwrap();
let pt = {
let mut buf = vec![0u8; 1024];
let cipher = Cipher::aes_128_cbc();
let mut dec = Crypter::new(cipher, Mode::Decrypt, &k1, Some(&iv1)).unwrap();
dec.pad(false);
let mut cnt = dec.update(&pt, &mut buf).unwrap();
cnt += dec.finalize(&mut buf).unwrap();
buf.truncate(cnt);
buf
};
let pt = {
let mut buf = vec![0u8; 1024];
let cipher = Cipher::aes_128_ecb();
let mut dec = Crypter::new(cipher, Mode::Decrypt, &k0, None).unwrap();
dec.pad(false);
let mut cnt = dec.update(&pt, &mut buf).unwrap();
cnt += dec.finalize(&mut buf).unwrap();
buf.truncate(cnt);
buf
};
pt
})();
println!("{}", String::from_utf8(res.to_vec()).unwrap());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment