Tags: crypto xor 

Rating:

# Soulcrabber 2

## Overview
Looing at the script, this looks like some simple xor encryption.
The values which the flag is xored with stem from a seeded random number generator.
The seed is the UNIX timestamp, so this sould be easy to crack (at most 2^32 tries ;D).
Although I was able to see how this is unsecure and how to crack it, I had to do some research on how I can do this in rust.

## Research on Rust
First of all, the script doesn't even compile when I did ``rustc main.rs``.
With some help from an ictf friend, I got onto cargo and how to use it.
Nice, but I still need to adapt the script to check if a given seed decrypts the cipher.

## Solve
Some time later, this finally worked with all of rust's type and memory-access(?) checks:
```
use rand::{Rng,SeedableRng};
use rand::rngs::StdRng;
use std::fs;
use std::time::SystemTime;

fn get_rng(i : u64) -> StdRng {
// let seed: u64 = 1618783200; // 18.04.2021 22:00:00
let seed: u64 = 1619222400; // 24.04.2021 00:00:00
return StdRng::seed_from_u64(seed - i);
}

fn xor(input : Vec<u8>, i: u64) -> Vec<u8> {
let mut rng = get_rng(i);
return input
.into_iter()
.map(|c| (c as u8 ^ rng.gen::<u8>()))
.collect::<Vec<u8>>()
}

fn main() -> std::io::Result<()> {
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time is broken")
.as_secs();

println!("{}", timestamp);


let test = [67, 72, 84, 66, 123, 11, 11, 22, 22, 33, 33];
if test[0..5].to_vec() == [67, 72, 84, 66, 123] {
println!("{}", "works ");
}

let cipher_hex = fs::read_to_string("out.txt")?;
let cipher = hex::decode(cipher_hex).expect("Decoding failed");

for x in 0..10000000 {
let xored = xor((*cipher).to_vec(), x);
if xored[0..5].to_vec() == [67, 72, 84, 66, 123] { // == 0x434854427b == CHTB{
println!("{}", std::str::from_utf8(&xored).unwrap());
}

if x % 100000 == 0 {
println!("{}", x);
}
}

Ok(())
}
```
This assumes that if the first 5 bytes decode to ``CHTB{``, the seed is correct and the whole thing gets printed.
For the timestamp I took the current date and just looped back until I found the correct one.
With all the compile errors gone, it's just a simple ``cargo run`` to run the script and eventually getting the flag.