load3r
100
======= Difficulty level : Easy ========
A basic bootloader challenge. Note: The flag format is inctf{correct_input}
Note: The challenge must be run in qemu-system-i386 version 2.5.0
========== Authors : b3y0nd3r, r00tus3r ==========
They gave us a file named boot sector1
2$ file boot_try.bin
boot_try.bin: DOS/MBR boot sector
So lets first run the binary on an emulator named qemu:
1 | $ qemu-system-i386 -drive format=raw,file=boot_try.bin |
We can see some strings like ENTER THE FLAG and the message NOOOO when we insert an incorrect flag, this strings can help us to localize certain parts of the code while reversing, so first thing I did was to look up for this strings in IDA and search on which zones they are referenced.
At first I was having some trouble with IDA because I was choosing the wrong architecture when opening the binary and IDA wasn’t able to disassemble the code, the only thing that was showing was the strings so make sure you say no to disassemble the binary in 16 bits instead of the 32 bits.
After pressing no, we can already see where is the location of the strings we saw when executing the binary…
So we can start taking some notes from where they start in the binary (note that since the boot sector hasn’t been loaded into memory by the bios, all the addresses are starting from 0 but when we start debugging it everything will start after 0x7c00):
1 | 0x7c16 ENTER THE FLAG\r\n -> calculated with 0x7c00 + 0x16 |
Now we have 2 subroutines to analyse, lets start by the smallest one:
IDA’s comments are very explanatory, this is a function that writes a character into the screen by performing an interruption, so we can just rename this function to print since will be easier to us to identify it when it is called again.
From the image above we can already assume that the flag must have 34 characters if we insert something that doesn’t have that size we go directly to printing the wrong flag message NOOO.
But if we instead give a 34 character string we go through the green flow
The image above is a loop, which iterates all the characters we inserted in the program, after doing the shifts we enter into the final character modification:
We need to reverse this encryption function by doing exactly the opposite:
Example1
2
3
4
5encryption function ->
lr_string = '0'
flag_string = 'T'
for the first character (shift right because the 1st of lr_string is zero):
chr((ord('T') >> 1 ) ^ 5) = /
1 | reverse function -> |
Of course it’s much easier to understand all this assembly while debugging and analysing the code… the way I did it was opening gdb and running this commands inside of it, after the commands bellow is just a matter of putting more breakpoints and reading registers etc etc:
1 | target remote | qemu-system-i386 -S -gdb stdio -m 512 -hda boot_try.bin |
We have now everything to recover the flag it’s trivial to write a python script that recovers the flag for us:
1 | import string |
Running it
1 | $ python final.py |