Rating: 5.0

00401000  int64_t _start() __noreturn

00401017      syscall(sys_write {1}, fd: 1, buf: "Give me the flag: That was not t…", count: 0x12)
00401025      int64_t rax = syscall(sys_read {0}, fd: 0, buf: &__return_addr, count: 0x64)
0040102b      if (rax == 0x40)
0040102d          int64_t r12_1 = 0
0040103e          for (int64_t r10_1 = 0; r10_1 s< rax; r10_1 = r10_1 + 1)
0040104d              int64_t r8_2 = rol.q(*((zx.q(*(&__return_addr + r10_1)) << 3) + 0x40203c), 8)
00401051              uint64_t r13_1 = zx.q(r8_2.b)
00401055              int64_t r14_1 = 0
0040105b              while (true)
0040105b                  if (r14_1 s>= r13_1)
0040106b                      r12_1 = r12_1 + 1
0040106b                      break
0040105d                  r8_2 = rol.q(r8_2, 8)
00401064                  if (r8_2.b == r10_1.b)
00401064                      break
00401066                  r14_1 = r14_1 + 1
00401076          if (r12_1 == 0)
00401089              return sub_40109a(0, &data_40202a, 0x12) __tailcall   // win
00401098      return sub_40109a(0, "That was not the flag :(That was…", 0x18) __tailcall

input string of len 0x3f (0x40 with \n), then each char is checked i dont care/know how but:

  • every incorrect flag char increment r12 register
  • at the end, if r12 == 0, it's a win

so we can bruteforce each char using a gdb script:

import gdb
import string

passlen = 0x40
break_addr = 0x00401073

code = ["_"]*passlen
printable = string.printable[:-5]


def gdb_run_with_stdin(pwd):
    with open('_cracking', 'w') as f:
        f.write(pwd)

    gdb.execute('run < _cracking')

def read_reg(reg):
    return gdb.parse_and_eval("${}".format(reg))

def gdb_continue():
    gdb.execute('continue')


gdb.execute('break *{}'.format(break_addr))


errors = -1
for trial in range(passlen):
    for c in range(0x21, 0x7E+1):
        code[trial] = chr(c)

        print("trying: %s"%''.join(code))

        gdb_run_with_stdin(''.join(code))
        res = int(read_reg("r12"))
        if errors == -1:
            errors = res
            continue

        if res > errors:
            errors = res

        if res < errors:
            print('FOUND: %s'%''.join(code))
            errors = res
            break

print(''.join(code))
% gdb switcheroo 
pwndbg>  source lolz.py
//// wait for it
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60az_
Give me the flag: 
Breakpoint 1, 0x0000000000401073 in ?? ()
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a{_
Give me the flag: 
Breakpoint 1, 0x0000000000401073 in ?? ()
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a|_
Give me the flag: 
Breakpoint 1, 0x0000000000401073 in ?? ()
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a}
Give me the flag: 
Breakpoint 1, 0x0000000000401073 in ?? ()
FOUND: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a}_