I set out to create a brutal Reverse Engineering challenge for this CTF using Deepseek. It delivered… a little too well. Now there’s so much randomness in the code that even I can’t reverse it to recover the flag. 💀
The Capa information will be used when crafting a Rust application, which we will use to generate a signature.
Deepseek
The challenge description mentioned Deepseek, so I used Deepseek R1 to generate a Rust application with the same library versions and Flare-Capa information. Two or three examples were used while trying to utilize all possible methods. (You can use the Solver code to be used as example).
Build the example And Make Signature
cargo build
Load the demo binary in IDA and create Sig file.
Applying the signature
Load the signature to identify functions
Solution
After recognizing all the functions used by the program's main function, use Deepseek again to find a solution to retrieve the flag by sending the decompiled code to Deepseek.
// Found flag with timestamp 1738793904: BITSCTF{i_guess_t3xt_f1les_h3v3_m3tad4ta_as_W3ll_451a587f}
use std::fs::File;
use std::io::Read;
use aes::Aes256;
use cipher::{BlockDecrypt, KeyInit};
use generic_array::GenericArray;
// from rand 0.8+
use rand::rngs::StdRng;
use rand_core::{RngCore, SeedableRng};
fn main() {
// Read encrypted file
let mut ciphertext = Vec::new();
let mut file = File::open("flag.txt").expect("File open failed");
file.read_to_end(&mut ciphertext).expect("Read failed");
// If the puzzle code uses a 64-bit seed (u64) for `StdRng`, do the same:
// exiftool flag.txt # File Modification Date/Time : 2025:02:06 03:48:24+05:30
// date --date="2025-02-06 03:48:24 +0530" +"%s" # 1738793904
let release_time: u64 = 1738793904;
// Adjust if you want
let window = 0;
for secs in (release_time.saturating_sub(window))..=(release_time.saturating_add(window)) {
// 1) Initialize "standard RNG" from the puzzle's timestamp
let mut rng = StdRng::seed_from_u64(secs);
// 2) Derive AES-256 key
let mut key = [0u8; 32];
rng.fill_bytes(&mut key);
// Debug
// println!("Trying timestamp {:X} with AES key = {:02X?}", secs, key);
// 3) Decrypt using AES-256 ECB
let mut data = ciphertext.clone();
let cipher = Aes256::new(GenericArray::from_slice(&key));
for chunk in data.chunks_mut(16) {
cipher.decrypt_block(GenericArray::from_mut_slice(chunk));
}
// 4) Check for a "BITSCTF{...}" pattern
if let Some(end) = data.iter().position(|&b| b == b'}') {
if data.starts_with(b"BITSCTF{") {
let flag = &data[..=end];
if let Ok(flag_str) = std::str::from_utf8(flag) {
println!("Found flag with timestamp {}: {}", secs, flag_str);
return;
}
}
}
}
println!("Flag not found in time window");
}