This write-up serves as a personal reference and a tool for me to practice FlareOn. It includes information and solutions collected from various sources.
Challenge
Challenge 2.zip : Challenge 2.zip
1
2
# file very_success
very_success: PE32 executable (console) Intel 80386, for MS Windows
Password: flare
Walkthrough & Solution
When we run the program, it prompts us to enter a password. However, if we enter the incorrect password, the program outputs the message ‘You are failure’. This challenge is almost the same as the first challenge.
1
2
3
4
PS > .\very_success.exe
You crushed that last one! Let's up the game.
Enter the password> password
You are failure
Looking at the code for FUN_00401000
, I noticed that it is similar to the previous challenge, but there is no straightforward XOR operation. Instead, our input is used by FUN_00401084
to perform some operation and return a boolean value.
1
iVar1 = FUN_00401084(unaff_retaddr,&DAT_00402159,local_4)
This line will accept 3 arguments:
- First argument = data located at return address
- Second argument = our input
- Third argument = Length of our input
The jl
instruction at loc_401096
checks whether the value at [ebp+arg_8]
(our inputs) is less than 0x25
. If it is, the function jumps to loc_4010D7
. Otherwise, it continues execution.
This means our input must be more than 37 (0x25)
1
Input: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (37)
The code above loads the values of [ebp+arg_4]
and [ebp+arg_0]
into the esi
and edi
registers, respectively. It then calculates the address of the last character of the string and stores it in edi
. Some similar codes can also be found in Ghidra.
I tried to set breakpoint at the EDI and jump to the hex view. We found these values.
1
AF AA AD EB AE AA EC A4 BA AF AE AA 8A C0 A7 B0 BC 9A BA A5 A5 BA AF B8 9D B8 F9 AE 9D AB B4 BC B6 B3 90 9A A8
Some operation involve inside loc_4010A2
such as AND
, XOR
and ROL
.
Python script (Reverse):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Function ROL
def rol(byte, count):
byte = (byte << count | byte >> (8 - count)) & 0xFF
# byte = (byte >> count | byte << (8 - count)) & 0xFF (ROR)
return byte
# Enc Flags
data = "".join(map(chr, bytes.fromhex('AF AA AD EB AE AA EC A4 BA AF AE AA 8A C0 A7 B0 BC 9A BA A5 A5 BA AF B8 9D B8 F9 AE 9D AB B4 BC B6 B3 90 9A A8')))[::-1]
# Initialize Registers
AH = AL = AX = BX = DX = 0
flags = ""
# Loop each Enc Flags
for i in range(0,len(data)):
AH = rol(1, DX)
AL = (ord(data[i]) - AH -1) ^ 0xC7
BX = BX + ord(data[i])
DX = BX & 3
flags += chr(AL)
print(flags)
Flag : a_Little_b1t_harder_plez@flare-on.com
References
- https://github.com/fareedfauzi/Flare-On-Challenges/blob/master/Write-ups/2015/2015solution2.pdf
- https://www.tophertimzen.com/blog/flareOn/
- https://www.ghettoforensics.com/2015/09/solving-2015-flare-on-challenges.html
- https://github.com/angr/angr-doc/blob/master/examples/flareon2015_2/solve.py
- https://secwriteups.blogspot.com/2016/08/flare-on-2015-challenge-2.html
- https://buildfunthings.com/posts/flare-on-2015-challenge-2/
- http://0x0atang.github.io/reversing/2015/09/17/flareon2-concolic.html
- https://www.aldeid.com/wiki/The-FLARE-On-Challenge-2015/Challenge-2
- https://rstforums.com/forum/topic/106101-flare-on-2015-level-2-very_successexe/
- https://www.redblue.team/2015/11/solving-2015-flare-on-re-contest.html
- https://unhere.com/2015/09/09/flare-on-challenge-2015-2/