Black Hat MEA 2023 CTF Final Round Writeups — Reverse

0xRobin
4 min readDec 25, 2023
Black Hat MEA 2023 CTF Final Round

Challenge Name : Ground Hog Day (DAY 3 Challenge)

A zip file is provided and from that we got a binary file called “main”. lets do some basic checks first.

file command on the binary.
strings command on the binary
checksec command on the binary.
running the file

So, we have some information now — NX is enabled so stored data/input on the stacks cannot be executed and ASLR is on. If we try to run the binary it prints a part of the flag but it doesn’t continue or gets stuck.

Open the binary with GDB/Ghidra and lets see whats going on —

listing the functions in gdb

There are two functions called ‘why’ and ‘main’.

In the Ghidra we can easily understand the what the functions are doing and here is the main func

main function

so, basically there are 8 variables with some kind of hardcoded value(we will discuss these later.) and in the for loop these things are happening as far as i understand :

  1. loop is running for 52 times
  2. &local48 pointing to a memory address where local48 is stored and taking that value, adding it to local4c, then storing it in bvar1.
  3. lvar2 is storing the returned value from the ‘why’ function.

this is the why function :

why function

I think its pretty self explanatory what the ‘why’ func is doing.

4. Then doing an xor(bvar1^lvar2) , and printing the ascii/char value using putchar of the xored result.

this is overall the functionality of the binary as per my understanding, and the current output we are getting is the ‘BHFlagY{’ this part.

So, we thought why not change the value of local48 and see what happens , because its only using that only one value and rest of the variable are currently not in use.

So, we can do this using GDB. I am using GDB-pwndbg.

disassembled main function and the second variable(local40)

this is the value of local40, now we need to figure out where is the local48 value is set and replace it with this value using a function called , you guessed it ‘set’.

So, I added a breakpoint in main using b main` and hit run.

local48 stored here

using `ni` command we can go one step and reach the rax value. Lets go one step again and replace the local48 value with the local40 value.

replacing rax value and getting different results.

So, Awesome, a different output. Now doing it with the rest of value reveals this :

so, we thought why not write a code to simplify this operation and get the flag faster.

So, here is the code and the output flag:

python code for better view
the flag

[Note: From GDB output when manually replacing rax values and after this python code, we can understand that # and E are junk values. So I replaced them in the code. ]

And the flag is : BHFlagY{r1ng_ar0nd_th3__________________h4_g0t_you}

I hope you learned something new. It will be helpful if you comment and also let me know if there is any different faster way to write this code.

Have a nice day!

--

--

0xRobin

Security Researcher | CTF Player | Penetration Tester