Flare-On 2015 Challenge 1
I like reverse engineering challenges. For me they are like crossword puzzles or Sudoku (which I also love to do by the way). I think that reverse engineering teaches you so much about computers, so much more then most computer books will teach you.
One of the best known, and most difficult (?), challenges occurs in September of each year. It is Flare-On and is hosted by Fire-Eye. As a contestant you are given a challenge in which you need to find a flag. The flag gives access to the next challenge in which you find another flag. And so on until all challenges are complete. You have 10 weeks to complete all 10 challenges. If you complete all 10 challenges in the time given you will be awarded a challenge coin.
Last year I got to challenge number 7 before time ran out. Inspired by a post on Reddit I decided to work on some challenges before this years event starts. So in this post I will walk through the solution of Challenge 1 of the 2015 edition of Flare-On and work my way through the rest of the challenges in that year.
You can download the previous years from the Flare-On website. For 2015, the first challenge is actually an self extracting zip file in which you first need to agree to the EULA.
It extracts a file called i_am_happy_you_are_to_playing_the_flareon_challenge.exe
which has an md5 sum of 7c0f16de595ae03e2928d3fa6b73b235
. Lets check out what this file is using Detect It Easy, die
.
It seems to be a PE
file, which is a Windows executable. There seems to not be anything particularly special about it, which is to be expected from a starting challenge. Lets open it up in Cutter so we can see the logic of it.
The code is very tiny, so it is doable to view the prolog of the function in a single screenshot. First it sets up some local variables, then prints the “Let’s start out easy…” string. Then it reads the input from the user into a buffer at 0x402158
. This is our input_buffer
.
After the entry function it goes into a loop. First it sets ecx
to 0 by applying a xor
to itself at the end of the prolog. Then the first byte is read from the input buffer into the al
(the lower 8 bits of eax
). The byte is xor
using the value 0x7d
and subsequently compared to the byte at 0x402140
(incremented with the value in ecx
, the counter). If the bytes do not match, it will show a message “You are failure”.
If the bytes match, ecx
is incremented and compared to 0x18
(decimal 24), so the flag will be 24 chars long and will be at 0x402140
. Right click it and lets view in the hex dump.
In the hex dump, at 0x402140
, there should be 24 bytes that will lead to the flag. Select them all and copy them.
There are several ways to go and applying the xor
to these bytes. The first is to use CyberChef. First use the From Hex recipe and then insert a XOR recipe with the key set to 7d
. The result will be the flag.
The other way is to write some code to do it for you. Most of the time people will use Python as a programming language to do these type of things. I am learning Rust currently, so I figured I would use that to do it.
#[macro_use]
extern crate hex_literal;
use std::char;
fn main() {
let data = hex!("1f 08 13 13 04 22 0e 11 4d 0d 18 3d 1b 11 1c 0f 18 50 12 13 53 1e 12 10");
for (_i, elem) in data.iter().enumerate() {
let x = elem ^ 0x7d;
print!("{}", x as char);
}
}
Regardless of the way it is done, the key is bunny_sl0pe@flare-on.com
.