-
-
Save cookie-s/ed097f7a3c657e1aedead178b1c5b102 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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