Problem

N/A

Solution

We get an ELF 64-bit executable that we should reverse.

Running it gives us a cat-like interface; it echoes back what comes in on stdin.

Looking at the disassembly, I don’t really feel like understanding it - let’s do dynamic RE instead.

Entering a bunch of ‘A’s and stepping, I find interesting things happening:

  1. [-------------------------------------code-------------------------------------]
  2. 0x400e49: lea rsi,[rsp+0x10]
  3. 0x400e4e: mov edi,0x6020e0
  4. 0x400e53: call 0x400d00 <_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@plt>
  5. => 0x400e58: mov rdx,QWORD PTR [rax]
  6. 0x400e5b: mov rdx,QWORD PTR [rdx-0x18]
  7. 0x400e5f: test BYTE PTR [rax+rdx*1+0x20],0x5
  8. 0x400e64: jne 0x400f20
  9. 0x400e6a: lea rsi,[rsp+0x10]
  10. [------------------------------------stack-------------------------------------]
  11. 0000| 0x7fffffffe790 --> 0x601de0 --> 0x4011e0 (cmp QWORD PTR [rip+0x200c18],0x0 # 0x601e00)
  12. 0008| 0x7fffffffe798 --> 0x4010ff (add rsp,0x18)
  13. 0016| 0x7fffffffe7a0 --> 0x615598 ('A' <repeats 44 times>)
  14. 0024| 0x7fffffffe7a8 --> 0xff
  15. 0032| 0x7fffffffe7b0 --> 0x615548 ("DFHLNRTXDFLPRVBHJPTVBFLTXZDFJXBHJTVBHLRXZJLP")
  16. 0040| 0x7fffffffe7b8 --> 0x40171d (add rbx,0x1)
  17. 0048| 0x7fffffffe7c0 --> 0x615608 ("DFHLNRTXDFLPRVBHJPTVBFLTXZDFJXBHJTVBHLRXZJLP")
  18. 0056| 0x7fffffffe7c8 --> 0x0
  19. [------------------------------------------------------------------------------]
  20. Legend: code, data, rodata, value
  21. Breakpoint 1, 0x0000000000400e58 in ?? ()
  22. gdb-peda$

I play around with this and it looks to be a simple rot() based on position. Too lazy, I just use the A-input as key.

Poking around, I find another string that looks like an encrypted flag: FYM-OI}olte_zi_wdqedd_djrzuj_shgmEDFqo{.

  1. _ct = "FYM-OI}olte_zi_wdqedd_djrzuj_shgmEDFqo{"
  2. _key = "DFHLNRTXDFLPRVBHJPTVBFLTXZDFJXBHJTVBHLR"
  3. key = [ord(x) - ord('A') for x in _key]
  4. ct = _ct.upper()
  5. pt = ""
  6. for i in xrange(len(ct)):
  7. if '_{}'.find(ct[i]) >= 0:
  8. pt += ct[i]
  9. continue
  10. x = ord(ct[i]) - ord('A')
  11. x = (x - key[i] + 26) % (26)
  12. x += ord('A')
  13. pt += chr(x)
  14. print pt
  15. # CTFVBR}RIOT_IN_PUBLIC_SQUARE_VGZDLIEJD{
  16. pt="CTF-BR{riot_in_public_square_vgzdLIEjd}"

Adjusting the case and braces returns the flag CTF-BR{riot_in_public_square_vgzdLIEjd}.