Last year you've enjoyed pwning a binary from the MS-DOS era.
This year, we challenge you to reverse engineer one such binary.
Attachment is a DOS program that verifies flag from the command line argument. It does:
0x279[0x258[i]] == 0x37e[i]
To recover the data in memory before the check, we installed Borland C++ 3.0 in DosBox.
Installation steps:
disk01.img
to disk08.img
to ~/borlandcpp
, mkdir -p ~/borlandcpp/disk ~/borlandcpp/installer
, launch DosBox~/borlandcpp/INSTALL.BAT
:mount -u a
mount -u c
mount -u f
mount f ~/borlandcpp/installer
imgmount a ~/borlandcpp/disk01.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk02.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk03.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk04.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk05.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk06.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk07.img -t floppy
copy a:\*.* f:\
mount -u a
imgmount a ~/borlandcpp/disk08.img -t floppy
copy a:\*.* f:\
mount -u a
mount a ~/borlandcpp/installer
mount c ~/borlandcpp/system
a:
.\INSTALL.exe
Run the following commands in DosBox:
mount d ~/borlandcpp
d:
.\INSTALL.BAT
Follow the instructions to install Borland C++ to C:\
. Use default options. Then, copy CHALL.COM
in the attachment to ~/borlandcpp
, and launch the debugger using C:\BORLANDC\BIN\TD.EXE D:\CHALL.COM
.
First, we can discover that the flag must have 31 characters between FortID{
and }
, so we setup the argument using dummy flag:
Then, we make a breakpoint at cs:0135, which is right before the flag validation loop:
The validation loop does:
So it requires 0x279[0x258[i]] == 0x37e[i]
. We can find the memory content in the debugger and find the flag body:
# data in 0x279
data = b"\x5d\x13\x8f\xcc\x33\x53\x98\xb5\xd5\x97\x4c\x07\x3d\xd2\x19\x42\xa9\x4d\x1a\xb9\xd9\x1c\x7c\xe1\x3f\x93\xcb\x90\x39\x48\x7d\x9e\xfb\x59\x5e\x00\x2a\xf7\xeb\xc9\x66\x8b\xd7\x44\x61\x94\xca\x69\x51\xd6\xff\x1d\x0b\x0c\x9d\xf0\x09\x7f\x92\xea\x14\x03\x45\x83\xab\x20\xf8\xa2\xe0\xc1\x70\x43\xf9\xb7\x32\x81\xc8\x35\x4e\x6f\x8e\x80\x3c\x87\x68\x95\xf2\x4b\x5a\xf3\x3b\x5f\xdc\x2d\xba\x75\x01\xe5\x8c\xaa\xd3\x5b\xd0\x99\x86\xf6\x06\x3e\x0e\xbd\x65\x15\x29\xb6\x49\xbe\xec\x37\x73\xcd\x2f\x36\x4f\xb3\xa8\xa4\x6e\x2e\x54\x18\xf4\x52\x6a\xa6\xc3"
# target in 0x37e
target = b"\x4e\x51\xcd\x75\x87\x0b\x73\x1d\x75\x87\x1d\xec\xf0\xd6\x65\x99\x0c\x75\x0b\x65\xd3\x75\xc8\x0b\x37\x65\xaa\x86\x75\xe0\x51\x51\x35"
# data[flag[i]] == target[i]
print("FortID{", end="")
for i in target:
print(chr(data.index(i)), end="")
print("}")
Flag: FortID{N0w_S4v3_S3t71ng5_4nd_L4unch_D00M}
.