Space Jackal – The Proclamation Writeup – CS Adversary Hunt

About CrowdStrike Adversary Hunt CTF and Space Jackal – The Proclamation writeup

This is our CrowdStrike Adversary Hunt 2021 CTF – Space Jackal – The Proclamation writeup (Bootloader Reverse Engineering Debug Challenge). The event took place from 18.01.2021 until 29.01.2021 and contained 3 main modules with 4 challenges each.

Affiliate: Experience limitless no-code automation, streamline your workflows, and effortlessly transfer data between apps with

Space Jackal – The Proclamation Challenge Description

“Space Jackal” module description:

Not to be confused with space flight enthusiasts, SPACE JACKAL have very strict opinions on source code indentation. Brought together by their unbounded hate for ASCII character 9, they will not rest until the last tab stop has been eradicated from the face of the internet.

Note: ASCII character 9 is the [TAB] character. Example: If you press [TAB] in Notepad you will see cursor jumping a several spaces. Notepad will save this as [TAB] character ASCII 9.

“The Proclamation” Challenge description:

A mysterious file appeared on a deep dark web forum. Can you figure out what we can't see right now?
NOTE: Flags will be easily identifiable by following the format CS{some_secret_flag_text}. They must be submitted in full, including the CS{ and } parts.
FILE: proclamation.dat

Space Jackal – The Proclamation Writeup

Launching VM

Opened Kali Linux VM (you can obtain the pre-installed image from official source) with “VMware Workstation Player”. Installed “VMware Tools” and dropped the downloaded “proclamation.dat” into VM.

Determine the File Type

Executed “file” command in Terminal:

file proclamation.dat


DOS/MBR boot sector

This is bootable image. Only 512 bytes, meaning it is only the bootloader.
More information about the image with “fdisk” command:

fdisk -l proclamation.dat

“-l” switch is “listing” the partition table of a device; in our case the device is “proclamation.dat” image.

Disk /proclamation.dat: 512 B, 512 bytes, 1 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x8587ca82

Device                                                    Boot      Start        End    Sectors  Size Id Type
/root/Desktop/AdversryHunt/Proclamation/proclamation.dat1      3939211656 6775681800 2836470145  1.3T 84 OS/2
/root/Desktop/AdversryHunt/Proclamation/proclamation.dat2      3669331162 6720349547 3051018386  1.4T 8e Linu
/root/Desktop/AdversryHunt/Proclamation/proclamation.dat3      2543294681 6652988866 4109694186  1.9T 86 NTFS
/root/Desktop/AdversryHunt/Proclamation/proclamation.dat4      4109694196 8219388391 4109694196  1.9T f4 Spee

Launching the Bootloader Image with QEMU

Installed QEMU to boot the image:

sudo apt-get install qemu-system

In case you will need more components:

sudo apt-get install qemu
sudo apt-get install qemu-utils
sudo apt-get install qemu-user

Loaded the image:

qemu-system-i386 -drive format=raw,file=proclamation.dat

Commands and Switches:
qemu-system-i386: Since the image type is DOS/MBR, this is the type of emulation architecture that we need for QEMU.
-drive format=raw,file=proclamation.dat: “Drive” is the switch that defines new drive.
“Format” is an option of the “drive” switch, since we did not find the exact image type and it is only the bootloader it is set to “raw”.
“File” is the second option of the “drive” switch, which sets the image file path.

QEMU loaded a screen with a message:

Hello. We are looking for highly intelligent
individuals. To find them, we have devised
a test.

There is a message hidden in this bootloader.

Find it, and it will lead you on the road to
finding us. We look forward to meet the
few that will make it all the way through.

Good luck, and remember:
        We love spaces much more than tabs!

Readable Strings

To make sure I am not missing anything obvious – opened this file with “Lister” application [F3] of “Total Commander” on Windows to see any strings. The only thing readable was:

you're on a good way

Like it would be that easy…

Disassembling the Bootloader Image – Space Jackal – The Proclamation Writeup

Back to Linux – using “ndisasm” to see the assembly:

ndisasm -b 16 proclamation.dat

Since it is MBR bootloader used to load on BIOS – we will use the 16-bit mode.

00000000  BC0020            mov sp,0x2000
00000003  B407              mov ah,0x7
00000005  30C0              xor al,al
00000007  31C9              xor cx,cx
00000009  B78A              mov bh,0x8a
0000000B  B661              mov dh,0x61
0000000D  B261              mov dl,0x61
0000000F  CD10              int 0x10
00000011  B402              mov ah,0x2
00000013  31D2              xor dx,dx
00000015  30FF              xor bh,bh
00000017  CD10              int 0x10
00000019  EB46              jmp short 0x61
0000001B  5E                pop si
0000001C  83C614            add si,byte +0x14
0000001F  B209              mov dl,0x9
00000021  6652              push edx
00000023  B300              mov bl,0x0
00000025  B40E              mov ah,0xe
00000027  8A04              mov al,[si]
00000029  83C601            add si,byte +0x1
0000002C  665A              pop edx
0000002E  66C1E202          shl edx,byte 0x2
00000032  6683C242          add edx,byte +0x42
00000036  6681E2FF000000    and edx,0xff
0000003D  6631D0            xor eax,edx
00000040  6652              push edx
00000042  0C00              or al,0x0
00000044  7419              jz 0x5f
00000046  88C2              mov dl,al
00000048  80F20A            xor dl,0xa
0000004B  7404              jz 0x51
0000004D  CD10              int 0x10
0000004F  EBD2              jmp short 0x23
00000051  B403              mov ah,0x3
00000053  CD10              int 0x10
00000055  B402              mov ah,0x2
00000057  FEC6              inc dh
00000059  B200              mov dl,0x0
0000005B  CD10              int 0x10
0000005D  EBC4              jmp short 0x23
0000005F  FA                cli
00000060  F4                hlt
00000061  E8B7FF            call 0x1b
00000064  796F              jns 0xd5
00000066  7527              jnz 0x8f
00000068  7265              jc 0xcf
0000006A  206F6E            and [bx+0x6e],ch
0000006D  206120            and [bx+di+0x20],ah
00000070  676F              a32 outsw
00000072  6F                outsw
00000073  64207761          and [fs:bx+0x61],dh
00000077  792E              jns 0xa7
00000079  BFC686            mov di,0x86c6
0000007C  85C4              test sp,ax
0000007E  CABD8F            retf 0x8fbd
00000081  CA8B98            retf 0x988b
00000084  8F                db 0x8f
00000085  CA8685            retf 0x8586
00000088  85818384          test [bx+di-0x7b7d],ax
0000008C  8D                db 0x8d
0000008D  CA8C85            retf 0x858c
00000090  98                cbw
00000091  CA8283            retf 0x8382
00000094  8D828693          lea ax,[bp+si-0x6c7a]
00000098  CA8384            retf 0x8483
0000009B  9E                sahf
0000009C  8F868683          pop word [bp-0x7c7a]
000000A0  8D8F849E          lea cx,[bx-0x617c]
000000A4  E083              loopne 0x29
000000A6  848E839C          test [bp-0x637d],cl
000000AA  838E9F8B86        or word [bp-0x7461],byte -0x7a
000000AF  99                cwd
000000B0  C4                db 0xc4
000000B1  CABE85            retf 0x85be
000000B4  CA8C83            retf 0x838c
000000B7  848ECA9E          test [bp-0x6136],cl
000000BB  82                db 0x82
000000BC  8F87C6CA          pop word [bx-0x353a]
000000C0  9D                popf
000000C1  8F                db 0x8f
000000C2  CA828B            retf 0x8b82
000000C5  9C                pushf
000000C6  8F                db 0x8f
000000C7  CA8E8F            retf 0x8f8e
000000CA  9C                pushf
000000CB  83998F8EE0        sbb word [bx+di-0x7171],byte -0x20
000000D0  8BCA              mov cx,dx
000000D2  9E                sahf
000000D3  8F                db 0x8f
000000D4  99                cwd
000000D5  9E                sahf
000000D6  C4                db 0xc4
000000D7  E0E0              loopne 0xb9
000000D9  BE828F            mov si,0x8f82
000000DC  98                cbw
000000DD  8F                db 0x8f
000000DE  CA8399            retf 0x9983
000000E1  CA8BCA            retf 0xca8b
000000E4  878F9999          xchg cx,[bx-0x6667]
000000E8  8B8D8FCA          mov cx,[di-0x3571]
000000EC  82                db 0x82
000000ED  838E8E8F84        or word [bp-0x7072],byte -0x7c
000000F2  CA8384            retf 0x8483
000000F5  CA9E82            retf 0x829e
000000F8  8399CA8885        sbb word [bx+di-0x7736],byte -0x7b
000000FD  859E8685          test [bp-0x7a7a],bx
00000101  8B8E8F98          mov cx,[bp-0x6771]
00000105  C4                db 0xc4
00000106  E0E0              loopne 0xe8
00000108  AC                lodsb
00000109  83848ECA83        add word [si-0x3572],byte -0x7d
0000010E  9E                sahf
0000010F  C6                db 0xc6
00000110  CA8B84            retf 0x848b
00000113  8ECA              mov cs,dx
00000115  839ECA9D83        sbb word [bp-0x6236],byte -0x7d
0000011A  8686CA86          xchg al,[bp-0x7936]
0000011E  8F                db 0x8f
0000011F  8B8ECA93          mov cx,[bp-0x6c36]
00000123  859FCA85          test [bx-0x7a36],bx
00000127  84CA              test dl,cl
00000129  9E                sahf
0000012A  82                db 0x82
0000012B  8F                db 0x8f
0000012C  CA9885            retf 0x8598
0000012F  8B8ECA9E          mov cx,[bp-0x6136]
00000133  85E0              test ax,sp
00000135  8C83848E          mov [bp+di-0x717c],es
00000139  83848DCA9F        add word [si-0x3573],byte -0x61
0000013E  99                cwd
0000013F  C4                db 0xc4
00000140  CABD8F            retf 0x8fbd
00000143  CA8685            retf 0x8586
00000146  8581CA8C          test [bx+di-0x7336],ax
0000014A  85989D8B          test [bx+si-0x7463],bx
0000014E  98                cbw
0000014F  8ECA              mov cs,dx
00000151  9E                sahf
00000152  85CA              test dx,cx
00000154  878F8F9E          xchg cx,[bx-0x6171]
00000158  CA9E82            retf 0x829e
0000015B  8F                db 0x8f
0000015C  E08C              loopne 0xea
0000015E  8F                db 0x8f
0000015F  9D                popf
00000160  CA9E82            retf 0x829e
00000163  8B9ECA9D          mov bx,[bp-0x6236]
00000167  838686CA87        add word [bp-0x357a],byte -0x79
0000016C  8B818FCA          mov ax,[bx+di-0x3571]
00000170  839ECA8B86        sbb word [bp-0x7436],byte -0x7a
00000175  86CA              xchg cl,dl
00000177  9E                sahf
00000178  82                db 0x82
00000179  8F                db 0x8f
0000017A  CA9D8B            retf 0x8b9d
0000017D  93                xchg ax,bx
0000017E  CA9E82            retf 0x829e
00000181  98                cbw
00000182  859F8D82          test [bx-0x7d73],bx
00000186  C4                db 0xc4
00000187  E0E0              loopne 0x169
00000189  AD                lodsw
0000018A  85858ECA          test [di-0x3572],ax
0000018E  869F8981          xchg bl,[bx-0x7e77]
00000192  C6                db 0xc6
00000193  CA8B84            retf 0x848b
00000196  8ECA              mov cs,dx
00000198  98                cbw
00000199  8F878F87          pop word [bx-0x7871]
0000019D  888F98D0          mov [bx-0x2f68],cl
000001A1  E0CA              loopne 0x16d
000001A3  CACACA            retf 0xcaca
000001A6  BD8FCA            mov bp,0xca8f
000001A9  86859C8F          xchg al,[di-0x7064]
000001AD  CA999A            retf 0x9a99
000001B0  8B898F99          mov cx,[bx+di-0x6671]
000001B4  CA879F            retf 0x9f87
000001B7  8982CA87          mov [bp+si-0x7836],ax
000001BB  85988FCA          test [bx+si-0x3571],bx
000001BF  9E                sahf
000001C0  82                db 0x82
000001C1  8B84CA9E          mov ax,[si-0x6136]
000001C5  8B8899CB          mov cx,[bx+si-0x3467]
000001C9  EA811911A9        jmp 0xa911:0x1981
000001CE  B991DA            mov cx,0xda91
000001D1  98                cbw
000001D2  8ED9              mov ds,cx
000001D4  98                cbw
000001D5  B5DA              mov ch,0xda
000001D7  8CB5DA92          mov [di-0x6d26],segr6
000001DB  D8DA              fcomp st2
000001DD  B588              mov ch,0x88
000001DF  DADA              fcmovu st2
000001E1  9E                sahf
000001E2  86DA              xchg bl,dl
000001E4  8B8ED998          mov cx,[bp-0x6727]
000001E8  97                xchg ax,di
000001E9  97                xchg ax,di
000001EA  EAF4F4F4F4        jmp 0xf4f4:0xf4f4
000001EF  F4                hlt
000001F0  F4                hlt
000001F1  F4                hlt
000001F2  F4                hlt
000001F3  F4                hlt
000001F4  F4                hlt
000001F5  F4                hlt
000001F6  F4                hlt
000001F7  F4                hlt
000001F8  F4                hlt
000001F9  F4                hlt
000001FA  F4                hlt
000001FB  F4                hlt
000001FC  F4                hlt
000001FD  F4                hlt
000001FE  55                push bp
000001FF  AA                stosb

Will use this as a main map before debugging.

Understanding the Assembly Code and Choosing Main Points

The main points that we see:

0000000F  CD10              int 0x10
00000017  CD10              int 0x10

These are interruption assembly instructions of type 10 hex (0x10 / 10h). This specific type is BIOS Graphical interruption. AH register value specifies the exact type of visualization. In addition, it executes only if the IF (Interruption Flag) bit is set (equals 1) in the EFLAGS register.

You can check the AH value in the code of the first two and see that they are not doing anything special besides setting the initial screen and the first point.

The next main point:

00000019  EB46              jmp short 0x61

This is unconditionally jumping to address 0x61. And at address 0x61 is the following:

00000061  E8B7FF            call 0x1b

This is calling a function in address 0x1b, so we are going back to 0x1b:

0000001B  5E                pop si

After that the code continues to execute, so probably would not call it a function, but rather another unconditional jump.
The next main point is:

00000044  7419              jz 0x5f

The address is 0x44 and it is interesting, since it is conditional jump when ZF (Zero Flag) bit is set (equals 1) in EFLAGS register. If it is set, we will jump to address 0x5f. Probably the ZF will be set because of previous instruction in address 0x42:

00000042  0C00              or al,0x0

Bitwise operators like OR can set the Zero Flag.

And in 0x5f address we have:

0000005F  FA                cli
00000060  F4                hlt

“cli” clears the IF bit in EFLAGS register, so no interruptions will execute. “hlt” instruction is halting the whole program, so it will be stuck at this point. Probably we will need to check whether ZF will be set at the 0x44 address and clear it, so the execution will not jump to 0x5f address to halt the code execution.

We will remember the addresses 0x42 and 0x44, when we will debug the bootloader, since probably it is a clue.
We will continue to follow the code with the main points from address 0x44.
After address 0x44 there are two instructions and after them there is another JZ:

0000004B  7404              jz 0x51

This is another conditional jump if ZF bit is set in the EFLAGS register. The instruction before that:

00000048  80F20A            xor dl,0xa

can set ZF bit of EFLAGS register in case DL register value will be “0xa”.
This is another thing that we need to remember, but probably we will not need to – depends on the debugging process.
First, we will skip a jump in 0x44 and if it will not help, will also set the ZF flag manually in 0x4b to jump into 0x51. So, we will remember this 0x4b address as well.

After address 0x4b the next line is another interruption:

0000004D  CD10              int 0x10

If you were following the code, you will see the AH register value at this point is 0xe, which was set at the address 0x25. This means that this particular interruption will throw ASCII characters to the screen. The ASCII character is set through the hex value of AL register. At this point AL hex value is 0x48, which is “H” in ASCII. If you remember the message on the screen after the regular execution in QEMU, the first word is “Hello”, so this interruption will output characters to the screen in the order that we saw in the message.

After this interruption:

0000004F  EBD2              jmp short 0x23

We jump back to 0x23 address. Probably AL will receive new values each time until it will equal to 0x0 and OR instruction in 0x42 address will set ZF flag in EFLAGS register. This means that at some point ZF will be set and we will jump to address 0x5f and the program will stop, but we will never get to address 0x51, which could probably have the answer.

If we will check what is going on at the address 0x51:

00000051  B403              mov ah,0x3
00000053  CD10              int 0x10
00000055  B402              mov ah,0x2
00000057  FEC6              inc dh
00000059  B200              mov dl,0x0
0000005B  CD10              int 0x10
0000005D  EBC4              jmp short 0x23

There are several BIOS visual interruptions of AH value 0x3 and 0x2, and after that we jump back to address 0x23, that already happened before, to print more ASCII characters.

Note: if you view the rest of the code it is:

0000005F  FA                cli
00000060  F4                hlt
00000061  E8B7FF            call 0x1b

that we already reviewed before. Meaning that after 0x61 is nothing related to the program execution. Could be the string that we saw in the beginning and some random stuff.

Time to initiate debugging.

Debugging the Bootloader in GDB – Space Jackal – The Proclamation Writeup

Open new terminal – install GDB:

sudo apt-get install gdb

Start gdb (the “-q” quiet switch will not show you the GDB opening message):

gdb -q

Open another terminal and start QEMU in debugging mode with following switches:

qemu-system-x86_64 -s -S -m 512 -hda proclamation.dat

The above switches:
-s: same as “-gdb tcp::1234”, meaning open a gdbserver on TCP port 1234.
-S: do not start CPU at startup.
-m 512: sets the virtual RAM size to 512 Megabytes.
– hda proclamation.dat: use file as hard disk 0.

The QEMU will start frozen in initial state.
Return to GDB and connect to QEMU session:

(gdb) target remote localhost:1234

The Bootloader MBR code is starting to execute in the memory at address 0x7c00. So, we will set the first break point there (temporary, since we do not want to hit it each time):

(gdb) tb *0x7c00

tb is equivalent to tbreak command.
Continue the execution of the code until the break point:

(gdb) c

c is equivalent to continue command.
Since we hit the break point at 0x7c00 let us check that we see the code that we found in the output of “ndisasm”:

(gdb) x/50i $pc

Some explanations:
x: shows values of registers, instructions, etc. depending on the switches.
/50i: show 50 instructions of the input address
$pc: is the address of the current instruction that is about to execute.
The whole command means it will show 50 instructions from the next execution address.
Why 50 instructions: The latest address of the code execution should be 0x7c61 as we saw in “ndisasm”. 61 in hex is 97 in decimal. Each instruction has several hex values, it could be one hex value if it is only the instruction itself (like “cli”) or it can be three hex values (like “mov al, 0x3”), basically dividing 97 in 2 should be fine. So, rounding this to 50 should give the approximate number of instructions around address 0x7c61.
The result:

0x7c00:      mov    $0x7b42000,%esp
   0x7c05:      xor    %al,%al
   0x7c07:      xor    %ecx,%ecx
   0x7c09:      mov    $0x8a,%bh
   0x7c0b:      mov    $0x61,%dh
   0x7c0d:      mov    $0x61,%dl
   0x7c0f:      int    $0x10
   0x7c11:      mov    $0x2,%ah
   0x7c13:      xor    %edx,%edx
   0x7c15:      xor    %bh,%bh
   0x7c17:      int    $0x10
   0x7c19:      jmp    0x7c61
   0x7c1b:      pop    %rsi
   0x7c1c:      add    $0x14,%esi
   0x7c1f:      mov    $0x9,%dl
   0x7c21:      push   %dx
   0x7c23:      mov    $0x0,%bl
   0x7c25:      mov    $0xe,%ah
   0x7c27:      mov    (%rbx,%rax,4),%al
   0x7c2a:      movb   $0x66,(%rcx)
   0x7c2d:      pop    %rdx
   0x7c2e:      shl    $0x2,%dx
   0x7c32:      add    $0x42,%dx
   0x7c36:      and    $0xff,%dx
   0x7c3b:      add    %al,(%rax)
   0x7c3d:      xor    %dx,%ax
   0x7c40:      push   %dx
   0x7c42:      or     $0x0,%al
   0x7c44:      je     0x7c5f
   0x7c46:      mov    %al,%dl
   0x7c48:      xor    $0xa,%dl
--Type <RET> for more, q to quit, c to continue without paging--
   0x7c4b:      je     0x7c51
   0x7c4d:      int    $0x10
   0x7c4f:      jmp    0x7c23
   0x7c51:      mov    $0x3,%ah
   0x7c53:      int    $0x10
   0x7c55:      mov    $0x2,%ah
   0x7c57:      inc    %dh
   0x7c59:      mov    $0x0,%dl
   0x7c5b:      int    $0x10
   0x7c5d:      jmp    0x7c23
   0x7c5f:      cli    
   0x7c60:      hlt    
   0x7c61:      call   0x6f7a7c1d
   0x7c66:      jne    0x7c8f
   0x7c68:      jb     0x7ccf
   0x7c6a:      and    %ch,0x6e(%rdi)
   0x7c6d:      and    %ah,0x20(%rcx)
   0x7c70:      outsl  %ds:(%esi),(%dx)
   0x7c72:      outsl  %ds:(%rsi),(%dx)

I was close. You can see that the code is similar. As you remember the address of interest was 0x44. Since we are debugging the bootloader, the address point will be 0x7c44, which is a conditional jump if ZF flag is set.

Now let us check the EFLAGS register to see what flags are set:

(gdb) i r eflags

i r eflags is equivalent to info registers eflags command.
The result:

eflags         0x202               [ IOPL=0 IF ]

This Wikipedia FLAGS Register page will show you all the Flags bits position and its hex value.
Bit 1 of EFLAGS register is always set to 1, so its hex value 0x2 always will be added to the overall hex value of EFLAGS register. IF bit hex value is 0x200. If only IF bit is set – the overall hex value of EFLAGS register will be 0x202.

Now to the main point. We want the execution to stop at address 0x7c44 (when ZF bit of EFLAGS register is already set) before conditional jump to 0x7c5f address. This way we will have the ZF set right before the conditional jump without actually jumping.
Let us check what is the value of EFLAGS register when we are on the first hit of 0x7c44 address.
Set the breakpoint to that location:

(gdb) b *0x7c44

Continue the code execution util that breakpoint:

(gdb) c

Now we hit first time the 0x7c44.
What is the value of eflags:

(gdb) i r eflags


eflags         0x206               [ IOPL=0 IF PF ]

The PF bit was set also, which has the hex value of 0x4. The overall value of EFLAGS is now 0x206 = 0x2 + 0x4 + 0x200 = Default set bit + IF + PF.
If you continue the execution with “c” command, it will stop at this break point the second time. Check the QEMU window and you will see that the first letter “H” will print. If you will continue, you will see the rest of the characters printed. To make this faster we need to set a conditional break point when the ZF bit of EFLAGS will be set, before jumping.
We will delete all the breakpoints (there is only one), so we will not break on it each loop:

(gdb) d

d is equivalent to delete command.
As you remember, ZF is set because of OR operator in address 0x7c42:

0x7c42:      or     $0x0,%al

So, to know when the ZF is set, we need to check whether the AL register has value of zero (0).
We will set a conditional break for that:

(gdb) b *0x7c42 if $al == 0x0

Continue the execution until this condition is true:

(gdb) c

When this condition will occur – you will be at the 0x7c42 address. If you will look at the QEMU screen you will see the exact message that we saw in the beginning.
Check what is the next execution line:

(gdb) x/i $pc


0x7c42:      or     $0x0,%al

This is what we needed. Next – execute exactly 1 line:

(gdb) si

si is equivalent to stepi command.
Executed the OR instruction. Check the EFLAGS register to see if ZF was set:

(gdb) i r eflags


eflags         0x246               [ IOPL=0 IF ZF PF ]

The hex value of ZF bit is 0x40, so = Default Bit + IF + ZF + PF = 0x2 + 0x4 + 0x40 + 0x200 = 0x246
Check again what is the next line to make sure it is the conditional jump:

(gdb) x/i $pc


0x7c44:      je     0x7c5f

if we will continue code execution at this point – the program will simply halt as it happened in the regular QEMU execution.
We want to avoid that, so we will clear the ZF bit:

(gdb) set $eflags = $eflags & ~0x40

Check EFLAGS value again to make sure ZF is not set:

(gdb) i r eflags


eflags         0x206               [ IOPL=0 IF PF ]

Since we know that ZF is no more – we can remove the breakpoints:

(gdb) d

and continue the execution:

(gdb) c

Now look at the QEMU window and collect the flag:


Note: if the flag was not available at this point, we would return to the steps until the last “c” command. Instead of “c” we would “stepi 3” to the address of “0x7c4b” (with second conditional jump) and set the ZF flag with “set $eflags = $eflags ^ 0x40” command and then “c” continue.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.