Well, it’s time to post intended way write-up for my own reverse task. It wasn’t very hard and the players told that it was funny :)


Hm, looks like my grand dad used this, when his was young
Damn, can’t log in… Maybe something interesting could be on it…

Put your flag from the file to CTFZone{FLAG}

It is a free dos image with custom MBR(Master Boot Record). After some reversing we find the checks and write our z3 solver for it.

To run image we could use bochs emulator with the following config(it was not necessary, we could use any emulator):

# configuration file generated by Bochs
# config_interface: textconfig
# display_library: x
megs: 32
romimage: file="C:\Program Files\Bochs-2.7/BIOS-bochs-latest"
vgaromimage: file="C:\Program Files\Bochs-2.7/VGABIOS-lgpl-latest"
boot: disk
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, mode=flat, translation=auto, path="magic.img", cylinders=20, heads=16, spt=63, biosdetect=auto, model="Generic 1234"
ata1: enabled=0
ata1-master: type=cdrom, path="/dev/hdc", status=inserted, biosdetect=auto, model="Generic 1234"
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file=""
parport2: enabled=0
com1: enabled=1, mode=null, dev=""
pci: enabled=1, chipset=i440fx
floppy_bootsig_check: disabled=0
vga: extension=vbe, update_freq=15
keyboard: serial_delay=250, paste_delay=100000, type=mf, user_shortcut=none
cpu: ips=15000000
magic_break: enabled=1
mouse: enabled=0
private_colormap: enabled=0
clock: sync=none
# no loader
log: bochsout.txt
logprefix: %t%e%d
debugger_log: -
panic: action=fatal
error: action=report
info: action=report
debug: action=ignore
# no cmosimage

To debug out image we need bochsdbg.exe

With a smile on our face put a breakpoint on 0x7c00 and start reversing :0

After collecting all of the checks we create something like this:

from z3 import *

x0 = Int('x0')
x1 = Int('x1')
x2 = Int('x2')
x3 = Int('x3')
x4 = Int('x4')
x5 = Int('x5')
x6 = Int('x6')
x7 = Int('x7')
x8 = Int('x8')
x9 = Int('x9')
x10 = Int('x10')
x11 = Int('x11')
x12 = Int('x12')
x13 = Int('x13')
x14 = Int('x14')
x15 = Int('x15')

s = Solver()

s.add(x0 >= 0x20, x0 <= 0x7E, x1 * 256 + x0 + x3 * 256 + x2 == 0x8FE2)
s.add(x1 >= 0x20, x1 <= 0x7E)
s.add(x2 >= 0x20, x2 <= 0x7E)
s.add(x3 >= 0x20, x3 <= 0x7E)
s.add(x4 >= 0x20, x4 <= 0x7E, x5 * 256 + x4 + x7 * 256 + x6 == 0xCEA7)
s.add(x5 >= 0x20, x5 <= 0x7E)
s.add(x6 >= 0x20, x6 <= 0x7E)
s.add(x7 >= 0x20, x7 <= 0x7E)
s.add(x8 >= 0x20, x8 <= 0x7E, x9 * 256 + x8 + x11 * 256 + x10 == 0xB3D3)
s.add(x9 >= 0x20, x9 <= 0x7E)
s.add(x10 >= 0x20, x10 <= 0x7E)
s.add(x11 >= 0x20, x11 <= 0x7E)
s.add(x12 >= 0x20, x12 <= 0x7E, x13 * 256 + x12 + x15 * 256 + x14 == 0x9DE0)
s.add(x13 >= 0x20, x13 <= 0x7E)
s.add(x14 >= 0x20, x14 <= 0x7E)
s.add(x15 >= 0x20, x15 <= 0x7E)

s.add(x0 * x2 == 0x31D8)
s.add(x4 * x6 == 0x171C)
s.add(x8 * x10 == 0x2B74)
s.add(x12 * x14 == 0x30F0)

s.add(x15 == x14)
s.add(x1 == 0x30)
s.add(x4 == x2)
s.add(x1 + 3 == x6)
s.add(x5 - 1 == x10)
s.add(x9 != x10)
s.add(x11 + 1 == x12)

while s.check():
    print(chr(s.model()[x0].as_long()), end="")
    print(chr(s.model()[x1].as_long()), end="")
    print(chr(s.model()[x2].as_long()), end="")
    print(chr(s.model()[x3].as_long()), end="")
    print(chr(s.model()[x4].as_long()), end="")
    print(chr(s.model()[x5].as_long()), end="")
    print(chr(s.model()[x6].as_long()), end="")
    print(chr(s.model()[x7].as_long()), end="")
    print(chr(s.model()[x8].as_long()), end="")
    print(chr(s.model()[x9].as_long()), end="")
    print(chr(s.model()[x10].as_long()), end="")
    print(chr(s.model()[x11].as_long()), end="")
    print(chr(s.model()[x12].as_long()), end="")
    print(chr(s.model()[x13].as_long()), end="")
    print(chr(s.model()[x14].as_long()), end="")
    print(chr(s.model()[x15].as_long()), end="")


After entering the right flag we’ll get access to the system (just hit Enter)

But many players didn’t get one thing and asked me, why their solutions didn’t work and they got wrong flags at the end in the file, if they correctly enter the password

The password, that you should enter, decrypts some sector on the disk, so, if you use the wrong pass, bytes will be decrypted, but not correctly)

So after all the tries you found the right flag (the system of equations had many solution, as i remember 5 or 6, but when you see the words, that you got after z3, it’s obvious which solution is the right one), then, if you tried to enter wrongs one earlier, you should start the clear image (that you could download) and that’s it :)

Thanks for participating :)