Blog08: Misc — MCSC v10 Writeups: Part One (Reverse Challenges)

INSEC ENSIAS Club
6 min readMar 6, 2023

--

Hello Folks!
The v10 of our major event, the MCSC, has come to an end and so has its CTF competition. The winners have been crowned, but everyone seemed eager to get the full details of the challenges that were up for the grabs.
For that very reason, we will be bringing to you the official writeups of the challenges that we proposed on this year’s CTF. Starting with the Reverse category.

Stay on the lookout, as more writeups of other categories will be online in the upcoming days.
So let’s get to it, shall we ?

Challenge — selfref

This is an ELF64 which generate dynamically the flag. It is easy to trace it with a good debugger that won’t mind its missing section headers at 4296, like radare2.

[0x00600580]> db sym.main 
[0x00600580]> doo
INFO: File dbg:///home/thamugadi/mcsc/selfref/selfref reopened in read-write mode
[0x00600580]> dc
hit breakpoint at: 0x60064b
[0x0060064b]>
r2

Let’s breakpoint just before strcmp to look at its second argument.

[0x0060064b]> db 0x006006a7 
[0x0060064b]> dc
hit breakpoint at: 0x6006a7
[0x006006a7]> pxq @rsi
0x00a00a48 0x6c6b7b6365736e69 0x7831665f336e3333 insec{kl33n3_f1x
0x00a00a58 0x746e3130705f6433 0x000000000000007d 3d_p01nt}…….
0x00a00a68 0x0000000000000000 0x0000000000000000 …………….

We get the flag: insec{kl33n3_f1x3d_p01nt}

Challenge — pack

pack: ELF 64-bit LSB executable, x86–64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86–64.so.2, stripped
checksec pack
[*] ‘/home/thamugadi/mcsc/pack’
Arch: amd64–64-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

The RWX segments should put us on the correct path: we are facing dynamically generated code.

We are going to follow its execution, using radare2.

The first thing we can notice is that the main function is massively moving bytes into the stack:

We also see that those bytes are being XORed, further. The idea of the binary is to jump to dynamically generated code, that was moved in a ciphered form to the stack during runtime, and XORed to get the real instruction during runtime as well.

Here is the call instruction to the stack region

0x004010ea mov rdx, r10 
0x004010ed call 0x401288
0x004010f2 lea r11, [rbp — 0x304]
0x004010f9 call r11
0x004010fc mov eax, 0
0x00401101 leave
0x00401102 ret

Since radare2 seems to have trouble with executable stacks, let’s just dump the memory @r11, just before the call r11, and let’s copy it on another binary file. This way, we are going to reverse engineer the dynamically generated executable.

dynamically generated executable

It is very simple to reverse: we have a key 0xdeadbeefdeadbeef and five magic values : 0xeaddc58cbbded086, 0xb09cdcb0ba9ed58c, 0xb6ca8f9d81d4ccdb, 0xa3c8ccdcb6d9e19b, 0xfffeedaa9deeebbc that are XORed with it.

The value that we get after doing those operations: insec{p4ck3d_b1n4ry_r1ght_th3re}

Challenge — openfirmware

This challenge consists of an Apple Partition Map image, intended for a Macintosh of the PowerPC era.

After a brief search on the internet, we can learn that the firmware used by these machines is OpenFirmware, and also that it runs a Forth script at startup.

Let’s simply print the raw DISK.APM : we are immediately going to notice the Forth script.

: initmsg .” I just loaded the flag for you! :)” cr ; 
: startmsg .” Find it…” cr ;
: sup — dup abs = ;
: inf dup sup 1 + ;
: diff = if 0 else -1 then ;
: fba frame-buffer-adr ;
: val1 15d74719 ;
: val2 2626cd75 ;
: val3 637b663 ;
: val4 265cd ;
val1 5 * val2 3 
* val3 10 * val4
2bf9 * 80000010 l! 80000014 l! 80000018 l! 8000001c l!
then fba mac99-vram = if mac99-message val1 5
* val2 3 * val3 10 * val4
2bf9 * 81000010 l!
81000014 l! 81000018 l! 8100001c l!
then .” informations stored :” cr variable run -1 run !
fba beige-vram diff fba mac99-vram diff and if hardware-error 0 run ! then
run @ 0 = if 1 0 do 0 +loop then
initmsg
startmsg
boot hd:,\boot\kernel.elf

After researching about it, we can learn that Forth is a stack-based programming language. Everything written is simply pushed in the stack. In addition to that, something like 5 + 3 is expressed as 5 3 +(postfix). Also note that numbers are by default expressed in base 16.

Therefore, those lines:

val1 5 * val2 3 
* val3 10 * val4
2bf9 *

Actually mean:

push 0x5*val1
push 0x3*val2
push 0x10*val3
push 0x2bf9*val4

By replacing the variables, we get on our stack:

0x696e7365
0x637b6630
0x7274685f
0x6d34637d

Which, concatenated, is the flag: insec{f0rth_m4c}

btw, the rest of the disk image is totally irrelevant and just contains one of my toy projects that are booting stuff on a PowerPC-based mac :)

Challenge — famicom

This challenge consists on a Nintendo Entertainment System ROM. In the description, it is suggested to use the FCEUX emulator, which has interesting features such as debugging, memory viewing, disassembly.

Before starting, it should be noted that it is not necessary to have a good understanding of the 6502 assembly (on which the NES CPU is based) to fully understand the part of the code that interests us. In fact, it is sufficient to know that the comparisons are made with the CMP instruction.

We will start the ROM, and dynamically examine the memory (as indicated in a hint).

with LLLLLL.. input
with RRRRRR.. input

We immediately notice something interesting: when we enter a password with the directional arrows, a place in the memory (0x300) fills with bytes 01, 02, 03 or 04. After a few tests, we see that the Left key corresponds to 01, the Right key to 02, the Up key to 03 and the Down key to 04.

Now let’s look at the executed code. We can certainly do this with FCEUX, but I will use radare2 which I find more comfortable.

Let’s go to the address given in the description for the beginning of Main: s 0x90a5

compare

Going down a little, we find ourselves faced with a long chain of conditional branches (BEQ, branch if equal) following comparisons with values ranging from 1 to 4, just like the bytes corresponding to the inputs we identified previously.

By making the correspondence we enunciated before, here is the complete sequence expected by this code:

LUDRLURULRLUDRDU

Let’s try this password, and we get the flag :)

the flag

We hope these writeups answer the questions that you had about the reverse challenges.
And don’t forget! More writeups of other categories are coming up really soon.

Links

Facebook: INSEC Ensias

Instagram: INSEC Ensias

Linkedin: INSEC Ensias

Youtube: INSEC Club

Don’t forget to drop us a follow on social media to stay up to date with everything the club is doing. Looking forward to sharing more knowledge with all the readers and we welcome your feedback at insecblog@gmail.com

Writer: thmgdi

Editors: berradAtay, akna ,F3nn3C

--

--