ångstromCTF Reversing One Bite

Reversing

One Bite

Whenever I have friends over, I love to brag about things that I can eat in a single bite. Can you give this program a tasty flag that fits the bill?

/problems/2019/one_bite

Author: SirIan

実行ファイルが与えられる。

radare2でディスアセンブルする。

~/Desktop/ångstromCTF/Reversing/One Bite ᐅ r2 one_bite 
 -- The door is everything ...
[0x004005b0]> aaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Enable constraint types analysis for variables
[0x004005b0]> afl
0x00400510    3 26           sym._init
0x00400540    1 6            sym.imp.puts
0x00400550    1 6            sym.imp.strlen
0x00400560    1 6            sym.imp.__stack_chk_fail
0x00400570    1 6            sym.imp.__libc_start_main
0x00400580    1 6            sym.imp.fgets
0x00400590    1 6            sym.imp.strcmp
0x004005a0    1 6            sym..plt.got
0x004005b0    1 41           entry0
0x004005e0    4 50   -> 41   sym.deregister_tm_clones
0x00400620    4 58   -> 55   sym.register_tm_clones
0x00400660    3 28           entry.fini0
0x00400680    4 38   -> 35   entry.init0
0x004006a6    9 210          main
0x00400780    4 101          sym.__libc_csu_init
0x004007f0    1 2            sym.__libc_csu_fini
0x004007f4    1 9            sym._fini

main関数を見る。

f:id:Yunolay:20190420162442p:plain

[0x004005b0]> s main
[0x004006a6]> pdf
/ (fcn) main 210
|   int main (int argc, char **argv, char **envp);
|           ; var int32_t var_60h @ rbp-0x60
|           ; var int32_t var_54h @ rbp-0x54
|           ; var int32_t var_4ch @ rbp-0x4c
|           ; var int32_t var_48h @ rbp-0x48
|           ; var int32_t var_40h @ rbp-0x40
|           ; var int32_t var_18h @ rbp-0x18
|           ; arg int32_t arg_40h @ rbp+0x40
|           ; arg int argc @ rdi
|           ; arg char **argv @ rsi
|           ; DATA XREF from entry0 (0x4005cd)
|           0x004006a6      55             push rbp
|           0x004006a7      4889e5         mov rbp, rsp
|           0x004006aa      53             push rbx
|           0x004006ab      4883ec58       sub rsp, 0x58               ; 'X'
|           0x004006af      897dac         mov dword [var_54h], edi    ; argc
|           0x004006b2      488975a0       mov qword [var_60h], rsi    ; argv
|           0x004006b6      64488b042528.  mov rax, qword fs:[0x28]    ; [0x28:8]=-1 ; '(' ; 40
|           0x004006bf      488945e8       mov qword [var_18h], rax
|           0x004006c3      31c0           xor eax, eax
|           0x004006c5      bf08084000     mov edi, str.Give_me_a_flag_to_eat: ; 0x400808 ; "Give me a flag to eat: "
|           0x004006ca      e871feffff     call sym.imp.puts           ; int puts(const char *s)
|           0x004006cf      488b158a0920.  mov rdx, qword [obj.stdin]  ; obj.stdin__GLIBC_2.2.5 ; [0x601060:8]=0
|           0x004006d6      488d45c0       lea rax, [var_40h]
|           0x004006da      be22000000     mov esi, 0x22               ; '"' ; 34
|           0x004006df      4889c7         mov rdi, rax
|           0x004006e2      e899feffff     call sym.imp.fgets          ; char *fgets(char *s, int size, FILE *stream)
|           0x004006e7      c745b4000000.  mov dword [var_4ch], 0
|       ,=< 0x004006ee      eb1c           jmp 0x40070c
|       |   ; CODE XREF from main (0x400721)
|      .--> 0x004006f0      8b45b4         mov eax, dword [var_4ch]
|      :|   0x004006f3      4898           cdqe
|      :|   0x004006f5      0fb64405c0     movzx eax, byte [rbp + rax - 0x40]
|      :|   0x004006fa      83f03c         xor eax, 0x3c
|      :|   0x004006fd      89c2           mov edx, eax
|      :|   0x004006ff      8b45b4         mov eax, dword [var_4ch]
|      :|   0x00400702      4898           cdqe
|      :|   0x00400704      885405c0       mov byte [rbp + rax - 0x40], dl
|      :|   0x00400708      8345b401       add dword [var_4ch], 1
|      :|   ; CODE XREF from main (0x4006ee)
|      :`-> 0x0040070c      8b45b4         mov eax, dword [var_4ch]
|      :    0x0040070f      4863d8         movsxd rbx, eax
|      :    0x00400712      488d45c0       lea rax, [var_40h]
|      :    0x00400716      4889c7         mov rdi, rax
|      :    0x00400719      e832feffff     call sym.imp.strlen         ; size_t strlen(const char *s)
|      :    0x0040071e      4839c3         cmp rbx, rax
|      `==< 0x00400721      72cd           jb 0x4006f0
|           0x00400723      48c745b82008.  mov qword [var_48h], str.HZGUcHTURWcUQc_SUR_cHSc_YcOU_WA ; 0x400820 ; "]_HZGUcHTURWcUQc[SUR[cHSc^YcOU_WA"
|           0x0040072b      488b55b8       mov rdx, qword [var_48h]
|           0x0040072f      488d45c0       lea rax, [var_40h]
|           0x00400733      4889d6         mov rsi, rdx
|           0x00400736      4889c7         mov rdi, rax
|           0x00400739      e852feffff     call sym.imp.strcmp         ; int strcmp(const char *s1, const char *s2)
|           0x0040073e      85c0           test eax, eax
|       ,=< 0x00400740      750c           jne 0x40074e
|       |   0x00400742      bf42084000     mov edi, str.Yum__that_was_a_tasty_flag. ; 0x400842 ; "Yum, that was a tasty flag."
|       |   0x00400747      e8f4fdffff     call sym.imp.puts           ; int puts(const char *s)
|      ,==< 0x0040074c      eb0a           jmp 0x400758
|      ||   ; CODE XREF from main (0x400740)
|      |`-> 0x0040074e      bf5e084000     mov edi, str.That_didn_t_taste_so_good_: ; 0x40085e ; "That didn't taste so good :("
|      |    0x00400753      e8e8fdffff     call sym.imp.puts           ; int puts(const char *s)
|      |    ; CODE XREF from main (0x40074c)
|      `--> 0x00400758      b800000000     mov eax, 0
|           0x0040075d      488b4de8       mov rcx, qword [var_18h]
|           0x00400761      6448330c2528.  xor rcx, qword fs:[0x28]
|       ,=< 0x0040076a      7405           je 0x400771
|       |   0x0040076c      e8effdffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
|       |   ; CODE XREF from main (0x40076a)
|       `-> 0x00400771      4883c458       add rsp, 0x58               ; 'X'
|           0x00400775      5b             pop rbx
|           0x00400776      5d             pop rbp
\           0x00400777      c3             ret

以下の部分で"]_HZGUcHTURWcUQc[SUR[cHScYcOU_WA"をrsi、inputをrdiに入れて比較して、正しいときは Yum, that was a tasty flag.を出力している。

|           0x00400723      48c745b82008.  mov qword [var_48h], str.HZGUcHTURWcUQc_SUR_cHSc_YcOU_WA ; 0x400820 ; "]_HZGUcHTURWcUQc[SUR[cHSc^YcOU_WA"
|           0x0040072b      488b55b8       mov rdx, qword [var_48h]
|           0x0040072f      488d45c0       lea rax, [var_40h]
|           0x00400733      4889d6         mov rsi, rdx
|           0x00400736      4889c7         mov rdi, rax
|           0x00400739      e852feffff     call sym.imp.strcmp         ; int strcmp(const char *s1, const char *s2)
|           0x0040073e      85c0           test eax, eax
|       ,=< 0x00400740      750c           jne 0x40074e
|       |   0x00400742      bf42084000     mov edi, str.Yum__that_was_a_tasty_flag. ; 0x400842 ; "Yum, that was a tasty flag."
|       |   0x00400747      e8f4fdffff     call sym.imp.puts           ; int puts(const char *s)
|      ,==< 0x0040074c      eb0a           jmp 0x400758
|      ||   ; CODE XREF from main (0x400740)
|      |`-> 0x0040074e      bf5e084000     mov edi, str.That_didn_t_taste_so_good_: ; 0x40085e ; "That didn't taste so good :("
|      |    0x00400753      e8e8fdffff     call sym.imp.puts           ; int puts(const char *s)

その前の部分で入力値にxor 0x3cしている。

           0x004006e2      e899feffff     call sym.imp.fgets          ; char *fgets(char *s, int size, FILE *stream)
|           0x004006e7      c745b4000000.  mov dword [var_4ch], 0
|       ,=< 0x004006ee      eb1c           jmp 0x40070c
|       |   ; CODE XREF from main (0x400721)
|      .--> 0x004006f0      8b45b4         mov eax, dword [var_4ch]
|      :|   0x004006f3      4898           cdqe
|      :|   0x004006f5      0fb64405c0     movzx eax, byte [rbp + rax - 0x40]
|      :|   0x004006fa      83f03c         xor eax, 0x3c

xorを逆算する。

solve.py

s = ']_HZGUcHTURWcUQc[SUR[cHSc^YcOU_WA'

def xor(msg, key):
    o = ''
    for i in range(len(msg)):
        o += chr(ord(msg[i]) ^ key)
    return o

print xor(s, 0x3c)
~/Desktop/ångstromCTF/Reversing/One Bite ᐅ python solve.py
actf{i_think_im_going_to_be_sick}

FLAG : actf{i_think_im_going_to_be_sick}