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関数を見る。
[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}