NCS 2021 Writeup

My writeup for the National Cyber Scholarship Competition 2021


Project maintained by codekrafter Hosted on GitHub Pages — Theme by mattgraham

go back home

BM02

Briefing

Download the file and find a way to get the flag.

Contents: program

Walkthrough

This is another binary program, which when ran prints ā€œI’m not going to make it that easy for you.ā€ and exits:

My next step was to load it into gdb (the standard GNU debugger), and place a breakpoint on main with b main. I then started the program with r and waited for the program to load and break at main. I then disassembled the instructions with disas, which gave me the following:

Breakpoint 1, 0x00005555555547e7 in main ()
(gdb) disas
Dump of assembler code for function main:
   0x00005555555547e3 <+0>:     push   %rbp
   0x00005555555547e4 <+1>:     mov    %rsp,%rbp
=> 0x00005555555547e7 <+4>:     sub    $0x10,%rsp
   0x00005555555547eb <+8>:     movl   $0x1,-0x4(%rbp)
   0x00005555555547f2 <+15>:    cmpl   $0x539,-0x4(%rbp)
   0x00005555555547f9 <+22>:    jne    0x555555554807 <main+36>
   0x00005555555547fb <+24>:    mov    -0x4(%rbp),%eax
   0x00005555555547fe <+27>:    mov    %eax,%edi
   0x0000555555554800 <+29>:    call   0x5555555546aa <printFlag>
   0x0000555555554805 <+34>:    jmp    0x555555554813 <main+48>
   0x0000555555554807 <+36>:    lea    0x9a(%rip),%rdi        # 0x5555555548a8
   0x000055555555480e <+43>:    call   0x555555554570 <puts@plt>
   0x0000555555554813 <+48>:    mov    $0x0,%eax
   0x0000555555554818 <+53>:    leave  
   0x0000555555554819 <+54>:    ret    
End of assembler dump.

I am far from an assembly expert, but from my basic knowledge I can see it does some operations on the stack, does a compare and then a jne (which jumps if the operands to the last compare call were not equal) to the end of the main function at +36, which appears to call puts and exit, which is probably what the program does by default. It completely skips over a call to the printFlag function. I planned on fixing it so I would get the program into the printFlag function so I set a breakpoint there with b printFlag. In order to get into that function I stepped over the stack manipulation with nexti a few times until I got to +22, when I jumped to the next instruction by calling jump *0x00005555555547fb.

It successfully enters the printFlag function, which appears to also have a early jump that skips most of the function (most of the disassembly has been omitted as it is a long function):

Dump of assembler code for function printFlag:
=> 0x00005555555546aa <+0>:     push   %rbp
   0x00005555555546ab <+1>:     mov    %rsp,%rbp
   0x00005555555546ae <+4>:     sub    $0x40,%rsp
   0x00005555555546b2 <+8>:     mov    %edi,-0x34(%rbp)
   0x00005555555546b5 <+11>:    mov    %fs:0x28,%rax
   0x00005555555546be <+20>:    mov    %rax,-0x8(%rbp)
   0x00005555555546c2 <+24>:    xor    %eax,%eax
   0x00005555555546c4 <+26>:    cmpl   $0x539,-0x34(%rbp)
   0x00005555555546cb <+33>:    jne    0x5555555547cc <printFlag+290>
   0x00005555555546d1 <+39>:    movb   $0x15,-0x20(%rbp)
   0x00005555555546d5 <+43>:    movb   $0x70,-0x1f(%rbp)
   0x00005555555546d9 <+47>:    movb   $0xe5,-0x1e(%rbp)
   0x00005555555546dd <+51>:    movb   $0x64,-0x1d(%rbp)
   0x00005555555546e1 <+55>:    movb   $0x7a,-0x1c(%rbp)
   ...

I used nexti to execute each instruction until I got to +33, where the jen instruction is. I wanted to override this so it would not jump and would print the flag. To do it slightly different I know that jen jumps if the ZF flag is not set (This wikibook is a great assembly resource). I printed out the flag register with print $eflags and saw that it was not set, so I executed the following gdb script to set it, making the jne not jump:

set $eflags |= (1 << 6)

the ZF flag is at index 6, so I simply perform a bitwise operation to make sure it is on. I then ran c to continue the program, which printed the following providing the flag:

(gdb) c
Continuing.
Flag: patchItFixIt