この大会は2024/6/21 21:00(JST)~2024/6/23 21:00(JST)に開催されました。
今回もチームで参戦。結果は3341点で1022チーム中34位でした。
自分で解けた問題をWriteupとして書いておきます。
nc (Pwnable)
10進数で10を入力すれば、win関数をコールし、フラグを表示できる。
$ nc chal-lz56g6.wanictf.org 9003 15+1=0x10 FLAG{th3_b3ginning_0f_th3_r0ad_to_th3_pwn_p1ay3r}
FLAG{th3_b3ginning_0f_th3_r0ad_to_th3_pwn_p1ay3r}
lambda (Reversing)
Pythonコードを整形し、解析する。
(lambda _0: _0(input))( lambda _1: (lambda _2: _2("Enter the flag: "))( lambda _3: (lambda _4: _4(_1(_3)))( lambda _5: (lambda _6: _6("".join))( lambda _7: ( lambda _8: _8(lambda _9: _7((chr(ord(c) + 12) for c in _9)))★各ASCIIコードに+12して文字に変換 )( lambda _10: (lambda _11: _11("".join))( lambda _12: ( lambda _13: _13((chr(ord(c) - 3) for c in _10(_5)))★各ASCIIコードに-3して文字に変換 )( lambda _14: (lambda _15: _15(_12(_14)))( lambda _16: (lambda _17: _17("".join))( lambda _18: ( lambda _19: _19( lambda _20: _18( (chr(123 ^ ord(c)) for c in _20)★各ASCIIコードと123をXORして文字に変換 ) ) )( lambda _21: (lambda _22: _22("".join))( lambda _23: ( lambda _24: _24((_21(c) for c in _16)) )( lambda _25: (lambda _26: _26(_23(_25)))( lambda _27: ( lambda _28: _28( "16_10_13_x_6t_4_1o_9_1j_7_9_1j_1o_3_6_c_1o_6r" ) )( lambda _29: ( lambda _30: _30("".join) )( lambda _31: ( lambda _32: _32( ( chr( int(c, 36)★36進数を10進数に変換し、+10 + 10 ) for c in _29.split(★"16_10_13_x_6t_4_1o_9_1j_7_9_1j_1o_3_6_c_1o_6r"の"_"区切り "_" ) ) ) )( lambda _33: ( lambda _34: _34( _31(_33) ) )( lambda _35: ( lambda _36: _36( lambda _37: lambda _38: _37 == _38 ) )( lambda _39: ( lambda _40: _40( print ) )( lambda _41: ( lambda _42: _42( _39 ) )( lambda _43: ( lambda _44: _44( _27 ) )( lambda _45: ( lambda _46: _46( _43( _45 ) ) )( lambda _47: ( lambda _48: _48( _35 ) )( lambda _49: ( lambda _50: _50( _47( _49 ) ) )( lambda _51: ( lambda _52: _52( "Correct FLAG!" ) )( lambda _53: ( lambda _54: _54( "Incorrect" ) )( lambda _55: ( lambda _56: _56( _41( _53 if _51 else _55 ) ) )( lambda _57: lambda _58: _58 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
入力文字に以下の処理を順にしている。
・各ASCIIコードに+12して文字に変換 ・各ASCIIコードに-3して文字に変換 ・各ASCIIコードと123をXORして文字に変換
"16_10_13_x_6t_4_1o_9_1j_7_9_1j_1o_3_6_c_1o_6r"の"_"区切りの36進数文字列を10進数に変換し、+10したものと比較している。
このことを前提に入力文字列を復号する。
#!/usr/bin/env python3 enc = '16_10_13_x_6t_4_1o_9_1j_7_9_1j_1o_3_6_c_1o_6r' enc = enc.split('_') flag = '' for c in enc: flag += chr(((int(c, 36) + 10) ^ 123) + 3 - 12) print(flag)
FLAG{l4_1a_14mbd4}
home (Reversing)
Ghidraでデコンパイルする。
undefined8 main(void) { char *pcVar1; long lVar2; undefined8 uVar3; long in_FS_OFFSET; char local_418 [1032]; long local_10; local_10 = *(long *)(in_FS_OFFSET + 0x28); pcVar1 = getcwd(local_418,0x400); if (pcVar1 == (char *)0x0) { perror("Error"); uVar3 = 1; } else { pcVar1 = strstr(local_418,"Service"); if (pcVar1 == (char *)0x0) { puts(";)"); } else { puts("Check passed!"); lVar2 = ptrace(PTRACE_TRACEME,0,0,0); if (lVar2 == -1) { puts("Debugger detected!"); uVar3 = 1; goto LAB_00101a3e; } constructFlag(); } uVar3 = 0; } LAB_00101a3e: if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { /* WARNING: Subroutine does not return */ __stack_chk_fail(); } return uVar3; } undefined8 constructFlag(void) { bool bVar1; int local_128; int local_124; int local_120; int local_11c; uint local_118 [44]; char acStack_68 [55]; byte local_31; memcpy(local_118,&DAT_00102010,0xb0); local_11c = 0; local_128 = 0x7c46699a; while( true ) { while( true ) { while( true ) { while( true ) { while( true ) { while( true ) { while( true ) { while( true ) { while( true ) { while( true ) { while (local_128 == -0x5ddba386) { local_124 = local_124 + 1; bVar1 = (x * (x + -1) & 1U) == 0; local_128 = 0x60b926fc; if (bVar1 && y < 10 || bVar1 != y < 10) { local_128 = -0x51fc1498; } } if (local_128 != -0x51fc1498) break; local_128 = 0x19056f3d; } if (local_128 != -0x44e001df) break; local_128 = 0x54525dca; if ((local_31 & 1) != 0) { local_128 = -0x1c311557; } } if (local_128 != -0x34d6a440) break; bVar1 = (x * (x + -1) & 1U) != 0; local_128 = 0x58d9f831; if (bVar1 != 9 < y || !bVar1 && 9 >= y) { local_128 = -0x1d900a39; } } if (local_128 != -0x2d337dcd) break; local_120 = local_120 + 1; local_128 = 0x694bd910; } if (local_128 != -0x2462fe04) break; local_128 = -0x22f9de40; } if (local_128 != -0x22f9de40) break; bVar1 = (x * (x + -1) & 1U) != 0; local_128 = 0x60b926fc; if (bVar1 != 9 < y || !bVar1 && 9 >= y) { local_128 = -0x5ddba386; } } if (local_128 != -0x21c3cf2d) break; local_31 = local_120 < 0x2c; bVar1 = (x * (x + -1) & 1U) == 0; local_128 = 0x34e86ff4; if (bVar1 && y < 10 || bVar1 != y < 10) { local_128 = -0x44e001df; } } if (local_128 != -0x1d900a39) break; acStack_68[local_124] = (char)local_118[local_124] - (char)local_124; bVar1 = (x * (x + -1) & 1U) == 0; local_128 = 0x58d9f831; if (bVar1 != y < 10 || bVar1 && y < 10) { local_128 = -0x2462fe04; } } if (local_128 != -0x1c311557) break; local_118[local_120] = (local_118[local_120] ^ 0xffffffff) & 0x19f | local_118[local_120] & 0xfffffe60; local_128 = -0x2d337dcd; } if (local_128 == 0x19341ee) break; if (local_128 == 0x19056f3d) { local_128 = 0x19341ee; if (local_124 < 0x2c) { local_128 = -0x34d6a440; } } else if (local_128 == 0x25d256eb) { local_118[local_11c] = (int)local_118[local_11c] / 2; local_128 = 0x299ff63b; } else if (local_128 == 0x299ff63b) { local_11c = local_11c + 1; local_128 = 0x7c46699a; } else if (local_128 == 0x33ee2572) { local_120 = 0; local_128 = 0x694bd910; } else if (local_128 == 0x34e86ff4) { local_128 = -0x21c3cf2d; } else if (local_128 == 0x54525dca) { local_124 = 0; local_128 = 0x19056f3d; } else if (local_128 == 0x58d9f831) { acStack_68[local_124] = (char)local_118[local_124] - (char)local_124; local_128 = -0x1d900a39; } else if (local_128 == 0x60b926fc) { local_124 = local_124 + 1; local_128 = -0x5ddba386; } else if (local_128 == 0x694bd910) { bVar1 = (x * (x + -1) & 1U) == 0; local_128 = 0x34e86ff4; if (bVar1 && y < 10 || bVar1 != y < 10) { local_128 = -0x21c3cf2d; } } else if ((local_128 == 0x7c46699a) && (local_128 = 0x33ee2572, local_11c < 0x2c)) { local_128 = 0x25d256eb; } } printf("Processing completed!"); return 0; }
gdbでconstructFlag関数に飛び、その終了時のスタックを確認する。
$ gdb -q ./chal_home Reading symbols from ./chal_home... (No debugging symbols found in ./chal_home) gdb-peda$ start Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated. Use 'set logging enabled off'. Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated. Use 'set logging enabled on'. [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [----------------------------------registers-----------------------------------] RAX: 0x555555555977 (<main>: endbr64) RBX: 0x7fffffffde88 --> 0x7fffffffe218 ("/mnt/hgfs/Shared/chal_home") RCX: 0x7ffff7f9b680 --> 0x7ffff7f9cfc0 --> 0x0 RDX: 0x7fffffffde98 --> 0x7fffffffe233 ("CLUTTER_IM_MODULE=xim") RSI: 0x7fffffffde88 --> 0x7fffffffe218 ("/mnt/hgfs/Shared/chal_home") RDI: 0x1 RBP: 0x7fffffffdd70 --> 0x1 RSP: 0x7fffffffdd70 --> 0x1 RIP: 0x55555555597f (<main+8>: sub rsp,0x410) R8 : 0x555555555ad0 (<__libc_csu_fini>: endbr64) R9 : 0x7ffff7fcfb30 (<_dl_fini>: push rbp) R10: 0x7fffffffdaa0 --> 0x800000 R11: 0x206 R12: 0x0 R13: 0x7fffffffde98 --> 0x7fffffffe233 ("CLUTTER_IM_MODULE=xim") R14: 0x7ffff7ffd000 --> 0x7ffff7ffe2c0 --> 0x555555554000 --> 0x10102464c457f R15: 0x0 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x555555555977 <main>: endbr64 0x55555555597b <main+4>: push rbp 0x55555555597c <main+5>: mov rbp,rsp => 0x55555555597f <main+8>: sub rsp,0x410 0x555555555986 <main+15>: mov rax,QWORD PTR fs:0x28 0x55555555598f <main+24>: mov QWORD PTR [rbp-0x8],rax 0x555555555993 <main+28>: xor eax,eax 0x555555555995 <main+30>: lea rax,[rbp-0x410] [------------------------------------stack-------------------------------------] 0000| 0x7fffffffdd70 --> 0x1 0008| 0x7fffffffdd78 --> 0x7ffff7decc8a (<__libc_start_call_main+122>: mov edi,eax) 0016| 0x7fffffffdd80 --> 0x7fffffffde70 --> 0x7fffffffde78 --> 0x38 ('8') 0024| 0x7fffffffdd88 --> 0x555555555977 (<main>: endbr64) 0032| 0x7fffffffdd90 --> 0x155554040 0040| 0x7fffffffdd98 --> 0x7fffffffde88 --> 0x7fffffffe218 ("/mnt/hgfs/Shared/chal_home") 0048| 0x7fffffffdda0 --> 0x7fffffffde88 --> 0x7fffffffe218 ("/mnt/hgfs/Shared/chal_home") 0056| 0x7fffffffdda8 --> 0x3d1608103f5b73c5 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Temporary breakpoint 1, 0x000055555555597f in main () gdb-peda$ disas constructFlag Dump of assembler code for function constructFlag: 0x00005555555551b0 <+0>: push rbp 0x00005555555551b1 <+1>: mov rbp,rsp 0x00005555555551b4 <+4>: push r15 0x00005555555551b6 <+6>: push r14 0x00005555555551b8 <+8>: push r13 0x00005555555551ba <+10>: push r12 0x00005555555551bc <+12>: push rbx 0x00005555555551bd <+13>: sub rsp,0x158 0x00005555555551c4 <+20>: lea rax,[rip+0xe45] # 0x555555556010 0x00005555555551cb <+27>: mov ecx,0xb0 0x00005555555551d0 <+32>: mov edx,ecx 0x00005555555551d2 <+34>: lea rsi,[rbp-0x110] 0x00005555555551d9 <+41>: mov rdi,rsi 0x00005555555551dc <+44>: mov rsi,rax 0x00005555555551df <+47>: call 0x555555555070 <memcpy@plt> 0x00005555555551e4 <+52>: mov DWORD PTR [rbp-0x114],0x0 0x00005555555551ee <+62>: mov DWORD PTR [rbp-0x120],0x7c46699a 0x00005555555551f8 <+72>: mov eax,DWORD PTR [rbp-0x120] 0x00005555555551fe <+78>: mov ecx,eax 0x0000555555555200 <+80>: sub ecx,0xa2245c7a 0x0000555555555206 <+86>: mov DWORD PTR [rbp-0x124],eax 0x000055555555520c <+92>: mov DWORD PTR [rbp-0x128],ecx 0x0000555555555212 <+98>: je 0x555555555860 <constructFlag+1712> 0x0000555555555218 <+104>: jmp 0x55555555521d <constructFlag+109> 0x000055555555521d <+109>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555223 <+115>: sub eax,0xae03eb68 0x0000555555555228 <+120>: mov DWORD PTR [rbp-0x12c],eax 0x000055555555522e <+126>: je 0x5555555558cf <constructFlag+1823> 0x0000555555555234 <+132>: jmp 0x555555555239 <constructFlag+137> 0x0000555555555239 <+137>: mov eax,DWORD PTR [rbp-0x124] 0x000055555555523f <+143>: sub eax,0xbb1ffe21 0x0000555555555244 <+148>: mov DWORD PTR [rbp-0x130],eax 0x000055555555524a <+154>: je 0x5555555555b4 <constructFlag+1028> 0x0000555555555250 <+160>: jmp 0x555555555255 <constructFlag+165> 0x0000555555555255 <+165>: mov eax,DWORD PTR [rbp-0x124] 0x000055555555525b <+171>: sub eax,0xcb295bc0 0x0000555555555260 <+176>: mov DWORD PTR [rbp-0x134],eax 0x0000555555555266 <+182>: je 0x555555555676 <constructFlag+1222> 0x000055555555526c <+188>: jmp 0x555555555271 <constructFlag+193> 0x0000555555555271 <+193>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555277 <+199>: sub eax,0xd2cc8233 0x000055555555527c <+204>: mov DWORD PTR [rbp-0x138],eax 0x0000555555555282 <+210>: je 0x555555555616 <constructFlag+1126> 0x0000555555555288 <+216>: jmp 0x55555555528d <constructFlag+221> 0x000055555555528d <+221>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555293 <+227>: sub eax,0xdb9d01fc 0x0000555555555298 <+232>: mov DWORD PTR [rbp-0x13c],eax 0x000055555555529e <+238>: je 0x5555555557c0 <constructFlag+1552> 0x00005555555552a4 <+244>: jmp 0x5555555552a9 <constructFlag+249> 0x00005555555552a9 <+249>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555552af <+255>: sub eax,0xdd0621c0 0x00005555555552b4 <+260>: mov DWORD PTR [rbp-0x140],eax 0x00005555555552ba <+266>: je 0x5555555557cf <constructFlag+1567> 0x00005555555552c0 <+272>: jmp 0x5555555552c5 <constructFlag+277> 0x00005555555552c5 <+277>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555552cb <+283>: sub eax,0xde3c30d3 0x00005555555552d0 <+288>: mov DWORD PTR [rbp-0x144],eax 0x00005555555552d6 <+294>: je 0x555555555547 <constructFlag+919> 0x00005555555552dc <+300>: jmp 0x5555555552e1 <constructFlag+305> 0x00005555555552e1 <+305>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555552e7 <+311>: sub eax,0xe26ff5c7 0x00005555555552ec <+316>: mov DWORD PTR [rbp-0x148],eax 0x00005555555552f2 <+322>: je 0x555555555707 <constructFlag+1367> 0x00005555555552f8 <+328>: jmp 0x5555555552fd <constructFlag+333> 0x00005555555552fd <+333>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555303 <+339>: sub eax,0xe3ceeaa9 0x0000555555555308 <+344>: mov DWORD PTR [rbp-0x14c],eax 0x000055555555530e <+350>: je 0x5555555555d2 <constructFlag+1058> 0x0000555555555314 <+356>: jmp 0x555555555319 <constructFlag+361> 0x0000555555555319 <+361>: mov eax,DWORD PTR [rbp-0x124] 0x000055555555531f <+367>: sub eax,0x19341ee 0x0000555555555324 <+372>: mov DWORD PTR [rbp-0x150],eax 0x000055555555532a <+378>: je 0x5555555558de <constructFlag+1838> 0x0000555555555330 <+384>: jmp 0x555555555335 <constructFlag+389> 0x0000555555555335 <+389>: mov eax,DWORD PTR [rbp-0x124] 0x000055555555533b <+395>: sub eax,0x19056f3d 0x0000555555555340 <+400>: mov DWORD PTR [rbp-0x154],eax 0x0000555555555346 <+406>: je 0x555555555657 <constructFlag+1191> 0x000055555555534c <+412>: jmp 0x555555555351 <constructFlag+417> 0x0000555555555351 <+417>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555357 <+423>: sub eax,0x25d256eb 0x000055555555535c <+428>: mov DWORD PTR [rbp-0x158],eax 0x0000555555555362 <+434>: je 0x555555555471 <constructFlag+705> 0x0000555555555368 <+440>: jmp 0x55555555536d <constructFlag+445> 0x000055555555536d <+445>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555373 <+451>: sub eax,0x299ff63b 0x0000555555555378 <+456>: mov DWORD PTR [rbp-0x15c],eax 0x000055555555537e <+462>: je 0x5555555554b2 <constructFlag+770> 0x0000555555555384 <+468>: jmp 0x555555555389 <constructFlag+473> 0x0000555555555389 <+473>: mov eax,DWORD PTR [rbp-0x124] 0x000055555555538f <+479>: sub eax,0x33ee2572 0x0000555555555394 <+484>: mov DWORD PTR [rbp-0x160],eax 0x000055555555539a <+490>: je 0x5555555554da <constructFlag+810> 0x00005555555553a0 <+496>: jmp 0x5555555553a5 <constructFlag+501> 0x00005555555553a5 <+501>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555553ab <+507>: sub eax,0x34e86ff4 0x00005555555553b0 <+512>: mov DWORD PTR [rbp-0x164],eax 0x00005555555553b6 <+518>: je 0x555555555908 <constructFlag+1880> 0x00005555555553bc <+524>: jmp 0x5555555553c1 <constructFlag+529> 0x00005555555553c1 <+529>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555553c7 <+535>: sub eax,0x54525dca 0x00005555555553cc <+540>: mov DWORD PTR [rbp-0x168],eax 0x00005555555553d2 <+546>: je 0x55555555563e <constructFlag+1166> 0x00005555555553d8 <+552>: jmp 0x5555555553dd <constructFlag+557> 0x00005555555553dd <+557>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555553e3 <+563>: sub eax,0x58d9f831 0x00005555555553e8 <+568>: mov DWORD PTR [rbp-0x16c],eax 0x00005555555553ee <+574>: je 0x555555555917 <constructFlag+1895> 0x00005555555553f4 <+580>: jmp 0x5555555553f9 <constructFlag+585> 0x00005555555553f9 <+585>: mov eax,DWORD PTR [rbp-0x124] 0x00005555555553ff <+591>: sub eax,0x60b926fc 0x0000555555555404 <+596>: mov DWORD PTR [rbp-0x170],eax 0x000055555555540a <+602>: je 0x55555555594f <constructFlag+1951> 0x0000555555555410 <+608>: jmp 0x555555555415 <constructFlag+613> 0x0000555555555415 <+613>: mov eax,DWORD PTR [rbp-0x124] 0x000055555555541b <+619>: sub eax,0x694bd910 0x0000555555555420 <+624>: mov DWORD PTR [rbp-0x174],eax 0x0000555555555426 <+630>: je 0x5555555554f3 <constructFlag+835> 0x000055555555542c <+636>: jmp 0x555555555431 <constructFlag+641> 0x0000555555555431 <+641>: mov eax,DWORD PTR [rbp-0x124] 0x0000555555555437 <+647>: sub eax,0x7c46699a 0x000055555555543c <+652>: mov DWORD PTR [rbp-0x178],eax 0x0000555555555442 <+658>: je 0x555555555452 <constructFlag+674> 0x0000555555555448 <+664>: jmp 0x55555555544d <constructFlag+669> 0x000055555555544d <+669>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555452 <+674>: mov eax,0x33ee2572 0x0000555555555457 <+679>: mov ecx,0x25d256eb 0x000055555555545c <+684>: cmp DWORD PTR [rbp-0x114],0x2c 0x0000555555555463 <+691>: cmovl eax,ecx 0x0000555555555466 <+694>: mov DWORD PTR [rbp-0x120],eax 0x000055555555546c <+700>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555471 <+705>: mov eax,0x2 0x0000555555555476 <+710>: movsxd rcx,DWORD PTR [rbp-0x114] 0x000055555555547d <+717>: mov edx,DWORD PTR [rbp+rcx*4-0x110] 0x0000555555555484 <+724>: mov DWORD PTR [rbp-0x17c],eax 0x000055555555548a <+730>: mov eax,edx 0x000055555555548c <+732>: cdq 0x000055555555548d <+733>: mov esi,DWORD PTR [rbp-0x17c] 0x0000555555555493 <+739>: idiv esi 0x0000555555555495 <+741>: movsxd rcx,DWORD PTR [rbp-0x114] 0x000055555555549c <+748>: mov DWORD PTR [rbp+rcx*4-0x110],eax 0x00005555555554a3 <+755>: mov DWORD PTR [rbp-0x120],0x299ff63b 0x00005555555554ad <+765>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555554b2 <+770>: mov eax,DWORD PTR [rbp-0x114] 0x00005555555554b8 <+776>: sub eax,0x8c6ee0f0 0x00005555555554bd <+781>: add eax,0x1 0x00005555555554c0 <+784>: add eax,0x8c6ee0f0 0x00005555555554c5 <+789>: mov DWORD PTR [rbp-0x114],eax 0x00005555555554cb <+795>: mov DWORD PTR [rbp-0x120],0x7c46699a 0x00005555555554d5 <+805>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555554da <+810>: mov DWORD PTR [rbp-0x118],0x0 0x00005555555554e4 <+820>: mov DWORD PTR [rbp-0x120],0x694bd910 0x00005555555554ee <+830>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555554f3 <+835>: mov eax,0x34e86ff4 0x00005555555554f8 <+840>: mov ecx,0xde3c30d3 0x00005555555554fd <+845>: xor edx,edx 0x00005555555554ff <+847>: mov esi,DWORD PTR [rip+0x2b0f] # 0x555555558014 <x> 0x0000555555555505 <+853>: mov edi,DWORD PTR [rip+0x2b0d] # 0x555555558018 <y> 0x000055555555550b <+859>: sub edx,0x1 0x000055555555550e <+862>: mov r8d,esi 0x0000555555555511 <+865>: add r8d,edx 0x0000555555555514 <+868>: imul esi,r8d 0x0000555555555518 <+872>: and esi,0x1 0x000055555555551b <+875>: cmp esi,0x0 0x000055555555551e <+878>: sete r9b 0x0000555555555522 <+882>: cmp edi,0xa 0x0000555555555525 <+885>: setl r10b 0x0000555555555529 <+889>: mov r11b,r9b 0x000055555555552c <+892>: and r11b,r10b 0x000055555555552f <+895>: xor r9b,r10b 0x0000555555555532 <+898>: or r11b,r9b 0x0000555555555535 <+901>: test r11b,0x1 0x0000555555555539 <+905>: cmovne eax,ecx 0x000055555555553c <+908>: mov DWORD PTR [rbp-0x120],eax 0x0000555555555542 <+914>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555547 <+919>: mov eax,0x34e86ff4 0x000055555555554c <+924>: mov ecx,0xbb1ffe21 0x0000555555555551 <+929>: cmp DWORD PTR [rbp-0x118],0x2c 0x0000555555555558 <+936>: setl dl 0x000055555555555b <+939>: and dl,0x1 0x000055555555555e <+942>: mov BYTE PTR [rbp-0x29],dl 0x0000555555555561 <+945>: mov esi,DWORD PTR [rip+0x2aad] # 0x555555558014 <x> 0x0000555555555567 <+951>: mov edi,DWORD PTR [rip+0x2aab] # 0x555555558018 <y> 0x000055555555556d <+957>: mov r8d,esi 0x0000555555555570 <+960>: add r8d,0x7c944e7c 0x0000555555555577 <+967>: sub r8d,0x1 0x000055555555557b <+971>: sub r8d,0x7c944e7c 0x0000555555555582 <+978>: imul esi,r8d 0x0000555555555586 <+982>: and esi,0x1 0x0000555555555589 <+985>: cmp esi,0x0 0x000055555555558c <+988>: sete dl 0x000055555555558f <+991>: cmp edi,0xa 0x0000555555555592 <+994>: setl r9b 0x0000555555555596 <+998>: mov r10b,dl 0x0000555555555599 <+1001>: and r10b,r9b 0x000055555555559c <+1004>: xor dl,r9b 0x000055555555559f <+1007>: or r10b,dl 0x00005555555555a2 <+1010>: test r10b,0x1 0x00005555555555a6 <+1014>: cmovne eax,ecx 0x00005555555555a9 <+1017>: mov DWORD PTR [rbp-0x120],eax 0x00005555555555af <+1023>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555555b4 <+1028>: mov eax,0x54525dca 0x00005555555555b9 <+1033>: mov ecx,0xe3ceeaa9 0x00005555555555be <+1038>: mov dl,BYTE PTR [rbp-0x29] 0x00005555555555c1 <+1041>: test dl,0x1 0x00005555555555c4 <+1044>: cmovne eax,ecx 0x00005555555555c7 <+1047>: mov DWORD PTR [rbp-0x120],eax 0x00005555555555cd <+1053>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555555d2 <+1058>: mov eax,0xffffffff 0x00005555555555d7 <+1063>: movsxd rcx,DWORD PTR [rbp-0x118] 0x00005555555555de <+1070>: mov edx,DWORD PTR [rbp+rcx*4-0x110] 0x00005555555555e5 <+1077>: mov esi,edx 0x00005555555555e7 <+1079>: xor esi,0xffffffff 0x00005555555555ea <+1082>: and esi,0x19f 0x00005555555555f0 <+1088>: xor eax,0x19f 0x00005555555555f5 <+1093>: and edx,eax 0x00005555555555f7 <+1095>: or esi,edx 0x00005555555555f9 <+1097>: movsxd rcx,DWORD PTR [rbp-0x118] 0x0000555555555600 <+1104>: mov DWORD PTR [rbp+rcx*4-0x110],esi 0x0000555555555607 <+1111>: mov DWORD PTR [rbp-0x120],0xd2cc8233 0x0000555555555611 <+1121>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555616 <+1126>: mov eax,DWORD PTR [rbp-0x118] 0x000055555555561c <+1132>: sub eax,0x5dc72bef 0x0000555555555621 <+1137>: add eax,0x1 0x0000555555555624 <+1140>: add eax,0x5dc72bef 0x0000555555555629 <+1145>: mov DWORD PTR [rbp-0x118],eax 0x000055555555562f <+1151>: mov DWORD PTR [rbp-0x120],0x694bd910 0x0000555555555639 <+1161>: jmp 0x555555555972 <constructFlag+1986> 0x000055555555563e <+1166>: mov DWORD PTR [rbp-0x11c],0x0 0x0000555555555648 <+1176>: mov DWORD PTR [rbp-0x120],0x19056f3d 0x0000555555555652 <+1186>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555657 <+1191>: mov eax,0x19341ee 0x000055555555565c <+1196>: mov ecx,0xcb295bc0 0x0000555555555661 <+1201>: cmp DWORD PTR [rbp-0x11c],0x2c 0x0000555555555668 <+1208>: cmovl eax,ecx 0x000055555555566b <+1211>: mov DWORD PTR [rbp-0x120],eax 0x0000555555555671 <+1217>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555676 <+1222>: mov eax,0x58d9f831 0x000055555555567b <+1227>: mov ecx,0xe26ff5c7 0x0000555555555680 <+1232>: mov dl,0x1 0x0000555555555682 <+1234>: mov esi,DWORD PTR [rip+0x298c] # 0x555555558014 <x> 0x0000555555555688 <+1240>: mov edi,DWORD PTR [rip+0x298a] # 0x555555558018 <y> 0x000055555555568e <+1246>: mov r8d,esi 0x0000555555555691 <+1249>: sub r8d,0xb0a79333 0x0000555555555698 <+1256>: sub r8d,0x1 0x000055555555569c <+1260>: add r8d,0xb0a79333 0x00005555555556a3 <+1267>: imul esi,r8d 0x00005555555556a7 <+1271>: and esi,0x1 0x00005555555556aa <+1274>: cmp esi,0x0 0x00005555555556ad <+1277>: sete r9b 0x00005555555556b1 <+1281>: cmp edi,0xa 0x00005555555556b4 <+1284>: setl r10b 0x00005555555556b8 <+1288>: mov r11b,r9b 0x00005555555556bb <+1291>: xor r11b,0xff 0x00005555555556bf <+1295>: mov bl,r10b 0x00005555555556c2 <+1298>: xor bl,0xff 0x00005555555556c5 <+1301>: xor dl,0x1 0x00005555555556c8 <+1304>: mov r14b,r11b 0x00005555555556cb <+1307>: and r14b,0xff 0x00005555555556cf <+1311>: and r9b,dl 0x00005555555556d2 <+1314>: mov r15b,bl 0x00005555555556d5 <+1317>: and r15b,0xff 0x00005555555556d9 <+1321>: and r10b,dl 0x00005555555556dc <+1324>: or r14b,r9b 0x00005555555556df <+1327>: or r15b,r10b 0x00005555555556e2 <+1330>: xor r14b,r15b 0x00005555555556e5 <+1333>: or r11b,bl 0x00005555555556e8 <+1336>: xor r11b,0xff 0x00005555555556ec <+1340>: or dl,0x1 0x00005555555556ef <+1343>: and r11b,dl 0x00005555555556f2 <+1346>: or r14b,r11b 0x00005555555556f5 <+1349>: test r14b,0x1 0x00005555555556f9 <+1353>: cmovne eax,ecx 0x00005555555556fc <+1356>: mov DWORD PTR [rbp-0x120],eax 0x0000555555555702 <+1362>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555707 <+1367>: mov eax,0x58d9f831 0x000055555555570c <+1372>: mov ecx,0xdb9d01fc 0x0000555555555711 <+1377>: mov dl,0x1 0x0000555555555713 <+1379>: xor esi,esi 0x0000555555555715 <+1381>: movsxd rdi,DWORD PTR [rbp-0x11c] 0x000055555555571c <+1388>: mov r8d,DWORD PTR [rbp+rdi*4-0x110] 0x0000555555555724 <+1396>: mov r9d,DWORD PTR [rbp-0x11c] 0x000055555555572b <+1403>: mov r10d,esi 0x000055555555572e <+1406>: sub r10d,r9d 0x0000555555555731 <+1409>: add r8d,r10d 0x0000555555555734 <+1412>: mov r11b,r8b 0x0000555555555737 <+1415>: movsxd rdi,DWORD PTR [rbp-0x11c] 0x000055555555573e <+1422>: mov BYTE PTR [rbp+rdi*1-0x60],r11b 0x0000555555555743 <+1427>: mov r8d,DWORD PTR [rip+0x28ca] # 0x555555558014 <x> 0x000055555555574a <+1434>: mov r9d,DWORD PTR [rip+0x28c7] # 0x555555558018 <y> 0x0000555555555751 <+1441>: sub esi,0x1 0x0000555555555754 <+1444>: mov r10d,r8d 0x0000555555555757 <+1447>: add r10d,esi 0x000055555555575a <+1450>: imul r8d,r10d 0x000055555555575e <+1454>: and r8d,0x1 0x0000555555555762 <+1458>: cmp r8d,0x0 0x0000555555555766 <+1462>: sete r11b 0x000055555555576a <+1466>: cmp r9d,0xa 0x000055555555576e <+1470>: setl bl 0x0000555555555771 <+1473>: mov r14b,r11b 0x0000555555555774 <+1476>: xor r14b,0xff 0x0000555555555778 <+1480>: mov r15b,bl 0x000055555555577b <+1483>: xor r15b,0xff 0x000055555555577f <+1487>: xor dl,0x0 0x0000555555555782 <+1490>: mov r12b,r14b 0x0000555555555785 <+1493>: and r12b,0x0 0x0000555555555789 <+1497>: and r11b,dl 0x000055555555578c <+1500>: mov r13b,r15b 0x000055555555578f <+1503>: and r13b,0x0 0x0000555555555793 <+1507>: and bl,dl 0x0000555555555795 <+1509>: or r12b,r11b 0x0000555555555798 <+1512>: or r13b,bl 0x000055555555579b <+1515>: xor r12b,r13b 0x000055555555579e <+1518>: or r14b,r15b 0x00005555555557a1 <+1521>: xor r14b,0xff 0x00005555555557a5 <+1525>: or dl,0x0 0x00005555555557a8 <+1528>: and r14b,dl 0x00005555555557ab <+1531>: or r12b,r14b 0x00005555555557ae <+1534>: test r12b,0x1 0x00005555555557b2 <+1538>: cmovne eax,ecx 0x00005555555557b5 <+1541>: mov DWORD PTR [rbp-0x120],eax 0x00005555555557bb <+1547>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555557c0 <+1552>: mov DWORD PTR [rbp-0x120],0xdd0621c0 0x00005555555557ca <+1562>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555557cf <+1567>: mov eax,0x60b926fc 0x00005555555557d4 <+1572>: mov ecx,0xa2245c7a 0x00005555555557d9 <+1577>: mov dl,0x1 0x00005555555557db <+1579>: mov esi,DWORD PTR [rip+0x2833] # 0x555555558014 <x> 0x00005555555557e1 <+1585>: mov edi,DWORD PTR [rip+0x2831] # 0x555555558018 <y> 0x00005555555557e7 <+1591>: mov r8d,esi 0x00005555555557ea <+1594>: add r8d,0x19b72d11 0x00005555555557f1 <+1601>: sub r8d,0x1 0x00005555555557f5 <+1605>: sub r8d,0x19b72d11 0x00005555555557fc <+1612>: imul esi,r8d 0x0000555555555800 <+1616>: and esi,0x1 0x0000555555555803 <+1619>: cmp esi,0x0 0x0000555555555806 <+1622>: sete r9b 0x000055555555580a <+1626>: cmp edi,0xa 0x000055555555580d <+1629>: setl r10b 0x0000555555555811 <+1633>: mov r11b,r9b 0x0000555555555814 <+1636>: xor r11b,0xff 0x0000555555555818 <+1640>: mov bl,r10b 0x000055555555581b <+1643>: xor bl,0xff 0x000055555555581e <+1646>: xor dl,0x1 0x0000555555555821 <+1649>: mov r14b,r11b 0x0000555555555824 <+1652>: and r14b,0xff 0x0000555555555828 <+1656>: and r9b,dl 0x000055555555582b <+1659>: mov r15b,bl 0x000055555555582e <+1662>: and r15b,0xff 0x0000555555555832 <+1666>: and r10b,dl 0x0000555555555835 <+1669>: or r14b,r9b 0x0000555555555838 <+1672>: or r15b,r10b 0x000055555555583b <+1675>: xor r14b,r15b 0x000055555555583e <+1678>: or r11b,bl 0x0000555555555841 <+1681>: xor r11b,0xff 0x0000555555555845 <+1685>: or dl,0x1 0x0000555555555848 <+1688>: and r11b,dl 0x000055555555584b <+1691>: or r14b,r11b 0x000055555555584e <+1694>: test r14b,0x1 0x0000555555555852 <+1698>: cmovne eax,ecx 0x0000555555555855 <+1701>: mov DWORD PTR [rbp-0x120],eax 0x000055555555585b <+1707>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555860 <+1712>: mov eax,0x60b926fc 0x0000555555555865 <+1717>: mov ecx,0xae03eb68 0x000055555555586a <+1722>: xor edx,edx 0x000055555555586c <+1724>: mov esi,DWORD PTR [rbp-0x11c] 0x0000555555555872 <+1730>: add esi,0x420bd708 0x0000555555555878 <+1736>: add esi,0x1 0x000055555555587b <+1739>: sub esi,0x420bd708 0x0000555555555881 <+1745>: mov DWORD PTR [rbp-0x11c],esi 0x0000555555555887 <+1751>: mov esi,DWORD PTR [rip+0x2787] # 0x555555558014 <x> 0x000055555555588d <+1757>: mov edi,DWORD PTR [rip+0x2785] # 0x555555558018 <y> 0x0000555555555893 <+1763>: sub edx,0x1 0x0000555555555896 <+1766>: mov r8d,esi 0x0000555555555899 <+1769>: add r8d,edx 0x000055555555589c <+1772>: imul esi,r8d 0x00005555555558a0 <+1776>: and esi,0x1 0x00005555555558a3 <+1779>: cmp esi,0x0 0x00005555555558a6 <+1782>: sete r9b 0x00005555555558aa <+1786>: cmp edi,0xa 0x00005555555558ad <+1789>: setl r10b 0x00005555555558b1 <+1793>: mov r11b,r9b 0x00005555555558b4 <+1796>: and r11b,r10b 0x00005555555558b7 <+1799>: xor r9b,r10b 0x00005555555558ba <+1802>: or r11b,r9b 0x00005555555558bd <+1805>: test r11b,0x1 0x00005555555558c1 <+1809>: cmovne eax,ecx 0x00005555555558c4 <+1812>: mov DWORD PTR [rbp-0x120],eax 0x00005555555558ca <+1818>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555558cf <+1823>: mov DWORD PTR [rbp-0x120],0x19056f3d 0x00005555555558d9 <+1833>: jmp 0x555555555972 <constructFlag+1986> 0x00005555555558de <+1838>: lea rdi,[rip+0x7db] # 0x5555555560c0 0x00005555555558e5 <+1845>: mov al,0x0 0x00005555555558e7 <+1847>: call 0x555555555050 <printf@plt> 0x00005555555558ec <+1852>: xor ecx,ecx 0x00005555555558ee <+1854>: mov DWORD PTR [rbp-0x180],eax 0x00005555555558f4 <+1860>: mov eax,ecx 0x00005555555558f6 <+1862>: add rsp,0x158 0x00005555555558fd <+1869>: pop rbx 0x00005555555558fe <+1870>: pop r12 0x0000555555555900 <+1872>: pop r13 0x0000555555555902 <+1874>: pop r14 0x0000555555555904 <+1876>: pop r15 0x0000555555555906 <+1878>: pop rbp 0x0000555555555907 <+1879>: ret 0x0000555555555908 <+1880>: mov DWORD PTR [rbp-0x120],0xde3c30d3 0x0000555555555912 <+1890>: jmp 0x555555555972 <constructFlag+1986> 0x0000555555555917 <+1895>: xor eax,eax 0x0000555555555919 <+1897>: movsxd rcx,DWORD PTR [rbp-0x11c] 0x0000555555555920 <+1904>: mov edx,DWORD PTR [rbp+rcx*4-0x110] 0x0000555555555927 <+1911>: mov esi,DWORD PTR [rbp-0x11c] 0x000055555555592d <+1917>: sub eax,esi 0x000055555555592f <+1919>: add edx,eax 0x0000555555555931 <+1921>: mov dil,dl 0x0000555555555934 <+1924>: movsxd rcx,DWORD PTR [rbp-0x11c] 0x000055555555593b <+1931>: mov BYTE PTR [rbp+rcx*1-0x60],dil 0x0000555555555940 <+1936>: mov DWORD PTR [rbp-0x120],0xe26ff5c7 0x000055555555594a <+1946>: jmp 0x555555555972 <constructFlag+1986> 0x000055555555594f <+1951>: mov eax,DWORD PTR [rbp-0x11c] 0x0000555555555955 <+1957>: add eax,0x67ac8c74 0x000055555555595a <+1962>: add eax,0x1 0x000055555555595d <+1965>: sub eax,0x67ac8c74 0x0000555555555962 <+1970>: mov DWORD PTR [rbp-0x11c],eax 0x0000555555555968 <+1976>: mov DWORD PTR [rbp-0x120],0xa2245c7a 0x0000555555555972 <+1986>: jmp 0x5555555551f8 <constructFlag+72> End of assembler dump. gdb-peda$ b * 0x00005555555558e7 Breakpoint 2 at 0x5555555558e7 gdb-peda$ jump constructFlag Continuing at 0x5555555551b4. [----------------------------------registers-----------------------------------] RAX: 0x0 RBX: 0x7fffffffdefe --> 0x7fffffffe37c0000 RCX: 0x5f6ee574 RDX: 0xffffffff RSI: 0x0 RDI: 0x5555555560c0 ("Processing completed!") RBP: 0x7fffffffdd70 --> 0x1 RSP: 0x7fffffffdbf0 --> 0x200000038 RIP: 0x5555555558e7 (<constructFlag+1847>: call 0x555555555050 <printf@plt>) R8 : 0xffffffff R9 : 0x0 R10: 0xffffff01 R11: 0x201 R12: 0x1 R13: 0x7fffffffde01 --> 0x7fffffffde R14: 0x7ffff7ffd001 --> 0x400007ffff7ffe2 R15: 0xfe EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x5555555558d9 <constructFlag+1833>: jmp 0x555555555972 <constructFlag+1986> 0x5555555558de <constructFlag+1838>: lea rdi,[rip+0x7db] # 0x5555555560c0 0x5555555558e5 <constructFlag+1845>: mov al,0x0 => 0x5555555558e7 <constructFlag+1847>: call 0x555555555050 <printf@plt> 0x5555555558ec <constructFlag+1852>: xor ecx,ecx 0x5555555558ee <constructFlag+1854>: mov DWORD PTR [rbp-0x180],eax 0x5555555558f4 <constructFlag+1860>: mov eax,ecx 0x5555555558f6 <constructFlag+1862>: add rsp,0x158 Guessed arguments: arg[0]: 0x5555555560c0 ("Processing completed!") [------------------------------------stack-------------------------------------] 0000| 0x7fffffffdbf0 --> 0x200000038 0008| 0x7fffffffdbf8 --> 0x0 0016| 0x7fffffffdc00 --> 0x1071e0df0892b214 0024| 0x7fffffffdc08 --> 0x1f69edd600000000 0032| 0x7fffffffdc10 --> 0x2ab2678f20643858 0040| 0x7fffffffdc18 --> 0x2e8006df 0048| 0x7fffffffdc20 --> 0x1dc4574500000000 0056| 0x7fffffffdc28 --> 0x2357111b1f234c27 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 2, 0x00005555555558e7 in constructFlag () gdb-peda$ x/64gx $rsp 0x7fffffffdbf0: 0x0000000200000038 0x0000000000000000 0x7fffffffdc00: 0x1071e0df0892b214 0x1f69edd600000000 0x7fffffffdc10: 0x2ab2678f20643858 0x000000002e8006df 0x7fffffffdc20: 0x1dc4574500000000 0x2357111b1f234c27 0x7fffffffdc30: 0x25f63ff2248d202e 0x3669e62e2ec6bfbb 0x7fffffffdc40: 0x538f5686467343cd 0x019341ee5f6ee574 0x7fffffffdc50: 0x0000002c019341ee 0x0000002c0000002c 0x7fffffffdc60: 0x0000004d00000046 0x0000004a00000043 0x7fffffffdc70: 0x0000004d0000007f 0x0000007e00000075 0x7fffffffdc80: 0x0000006d00000067 0x0000006f00000073 0x7fffffffdc90: 0x000000860000006b 0x000000840000007d 0x7fffffffdca0: 0x000000780000006f 0x0000008700000077 0x7fffffffdcb0: 0x0000007d00000073 0x000000890000007b 0x7fffffffdcc0: 0x000000780000007d 0x000000710000004e 0x7fffffffdcd0: 0x0000009700000067 0x0000006b00000072 0x7fffffffdce0: 0x0000008300000089 0x0000009000000073 0x7fffffffdcf0: 0x0000008600000074 0x0000008100000068 0x7fffffffdd00: 0x0000005d00000081 0x0000002b000000a7 0x7fffffffdd10: 0x776f487b47414c46 0x756f795f6469645f 0x7fffffffdd20: 0x7265685f7465675f 0x4c547a4b56345f65 0x7fffffffdd30: 0x5a4261506d516269 0x00000000007d3459 0x7fffffffdd40: 0x0000000000000000 0x00007fffffffde88 0x7fffffffdd50: 0x0000000000000000 0x00007fffffffde98 0x7fffffffdd60: 0x00007ffff7ffd000 0x0000000000000000 0x7fffffffdd70: 0x0000000000000001 0x00007ffff7decc8a 0x7fffffffdd80: 0x00007fffffffde70 0x0000555555555977 0x7fffffffdd90: 0x0000000155554040 0x00007fffffffde88 0x7fffffffdda0: 0x00007fffffffde88 0x3d1608103f5b73c5 0x7fffffffddb0: 0x0000000000000000 0x00007fffffffde98 0x7fffffffddc0: 0x00007ffff7ffd000 0x0000000000000000 0x7fffffffddd0: 0xc2e9f7ef845973c5 0xc2e9e7ada7dd73c5 0x7fffffffdde0: 0x0000000000000000 0x0000000000000000
0x7fffffffdd10からフラグ文字列らしきものがある。
gdb-peda$ x/s 0x7fffffffdd10 0x7fffffffdd10: "FLAG{How_did_you_get_here_4VKzTLibQmPaBZY4}"
FLAG{How_did_you_get_here_4VKzTLibQmPaBZY4}
tiny_usb (Forensics)
7-Zip File Managerでisoファイルを開き、FLAG.PNGを取り出す。FLAG.PNGにフラグが書いてあった。
FLAG{hey_i_just_bought_a_usb}
Surveillance_of_sus (Forensics)
バイナリエディタで見ると、先頭が"RDP8bmp"となっている。以下にあるBMC-Toolsを使ってみる。
https://github.com/ANSSI-FR/bmc-tools
$ python3 bmc-tools.py -s Cache_chal.bin -d . [+++] Processing a single file: 'Cache_chal.bin'. [===] 650 tiles successfully extracted in the end. [===] Successfully exported 650 files.
650個のBMP画像がエクスポートでき、フラグらしきものの断片も含まれている。結合して出力してみる。
$ python3 bmc-tools.py -s Cache_chal.bin -d . -b [+++] Processing a single file: 'Cache_chal.bin'. [===] 650 tiles successfully extracted in the end. [===] Successfully exported 650 files. [===] Successfully exported collage file.
画像中にフラグが見つかった。
FLAG{RDP_is_useful_yipeee}
codebreaker (Forensics)
QRコードに大きくバツ印が書いてあり、読み取れない。わかる範囲でExcelを使って、書き起こす。
スマホアプリのクルクルというQRコードリーダで読み取ると、フラグが読み取れた。
FLAG{How_scan-dalous}
beginners_aes (Crypto)
暗号化処理の概要は以下の通り。
・key = b'the_enc_key_is_' ・iv = b'my_great_iv_is_' ・keyにランダム1バイトを結合 ・ivにランダム1バイトを結合 ・flag_hash: FLAGのsha256ダイジェスト(16進数表記) ・msg: FLAGをパディング ・enc: key, ivを使って、msgをAES暗号化したもの ・enc, flag_hashを出力
ivの最後の1バイトは適当にし、keyをブルートフォースし復号する。先頭ブロックの最後をブルートフォースし、ハッシュが合うものを探す。
#!/usr/bin/env python3 from Crypto.Util.Padding import unpad from Crypto.Cipher import AES import hashlib with open('output.txt', 'r') as f: params = f.read().splitlines() enc = eval(params[0].split(' = ')[1]) flag_hash = params[1].split(' = ')[1] key_base = b'the_enc_key_is_' iv_base = b'my_great_iv_is_' iv = iv_base + b'0' for k in range(32, 127): key = key_base + bytes([k]) cipher = AES.new(key, AES.MODE_CBC, iv) try: flag = unpad(cipher.decrypt(enc), 16) except: continue for code in range(32, 127): try_flag = flag[:15] + bytes([code]) + flag[16:] if hashlib.sha256(try_flag).hexdigest() == flag_hash: flag = try_flag.decode() print(flag) break
FLAG{7h3_f1r57_5t3p_t0_Crypt0!!}
beginners_rsa (Crypto)
暗号化処理の概要は以下の通り。
・p, q, r, s, a: 64ビット素数 ・n = p * q * r * s * a ・e = 0x10001 ・m: FLAGを数値化したもの ・enc = pow(m, e, n) ・n, e, encを出力
yafuでnを素因数分解する。
>yafu-x64.exe "factor(317903423385943473062528814030345176720578295695512495346444822768171649361480819163749494400347)" -v -threads 4 06/21/24 21:24:07 v1.34.5 @ RINA-TAKUMI, System/Build Info: Using GMP-ECM 6.3, Powered by GMP 5.1.1 detected Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz detected L1 = 32768 bytes, L2 = 16777216 bytes, CL = 64 bytes measured cpu frequency ~= 2923.479010 using 20 random witnesses for Rabin-Miller PRP checks =============================================================== ======= Welcome to YAFU (Yet Another Factoring Utility) ======= ======= bbuhrow@gmail.com ======= ======= Type help at any time, or quit to quit ======= =============================================================== cached 78498 primes. pmax = 999983 >> fac: factoring 317903423385943473062528814030345176720578295695512495346444822768171649361480819163749494400347 fac: using pretesting plan: normal fac: no tune info: using qs/gnfs crossover of 95 digits div: primes less than 10000 fmt: 1000000 iterations rho: x^2 + 3, starting 1000 iterations on C96 rho: x^2 + 2, starting 1000 iterations on C96 rho: x^2 + 1, starting 1000 iterations on C96 pm1: starting B1 = 150K, B2 = gmp-ecm default on C96 fac: setting target pretesting digits to 29.54 fac: sum of completed work is t0.00 fac: work done at B1=2000: 0 curves, max work = 30 curves fac: 30 more curves at B1=2000 needed to get to t29.54 ecm: 30/30 curves on C96, B1=2K, B2=gmp-ecm default fac: setting target pretesting digits to 29.54 fac: t15: 1.00 fac: t20: 0.04 fac: sum of completed work is t15.18 fac: work done at B1=11000: 0 curves, max work = 74 curves fac: 74 more curves at B1=11000 needed to get to t29.54 ecm: 10/74 curves on C96, B1=11K, B2=gmp-ecm default ecm: found prp20 factor = 12109985960354612149 fac: setting target pretesting digits to 23.69 fac: t15: 1.92 fac: t20: 0.18 fac: sum of completed work is t15.92 fac: work done at B1=11000: 11 curves, max work = 74 curves fac: 63 more curves at B1=11000 needed to get to t23.69 ecm: 4/63 curves on C77, B1=11K, B2=gmp-ecm default ecm: found prp20 factor = 11771834931016130837 fac: setting target pretesting digits to 17.85 fac: t15: 2.33 fac: t20: 0.25 fac: t25: 0.01 fac: sum of completed work is t16.26 fac: work done at B1=11000: 16 curves, max work = 74 curves fac: 41 more curves at B1=11000 needed to get to t17.85 ecm: 0/41 curves on C58, B1=11K, B2=gmp-ecm default ecm: found prp20 factor = 13079524394617385153 fac: setting target pretesting digits to 12.00 fac: t15: 2.42 fac: t20: 0.27 fac: t25: 0.01 fac: sum of completed work is t16.33 starting SIQS on c39: 170496492585767850892341198950965928723 ==== sieve params ==== n = 40 digits, 131 bits factor base: 560 primes (max prime = 9467) single large prime cutoff: 473350 (50 * pmax) using SSE4.1 enabled 32k sieve core sieve interval: 1 blocks of size 32768 polynomial A has ~ 4 factors using multiplier of 11 using SPV correction of 20 bits, starting at offset 32 using SSE2 for x32 sieve scanning using SSE2 for resieving 13-16 bit primes using SSE2 for 8x trial divison to 13 bits using SSE4.1 and inline ASM for small prime sieving using SSE2 for poly updating up to 15 bits using SSE4.1 for medium prime poly updating using SSE4.1 and inline ASM for large prime poly updating trial factoring cutoff at 35 bits ==== sieving in progress ( 4 threads): 624 relations needed ==== ==== Press ctrl-c to abort and save state ==== 756 rels found: 387 full + 369 from 2784 partial, (353.89 rels/sec) sieving required 189 total polynomials trial division touched 23897 sieve locations out of 12386304 QS elapsed time = 10.8159 seconds. ==== post processing stage (msieve-1.38) ==== begin with 3171 relations reduce to 1072 relations in 2 passes attempting to read 1072 relations recovered 1072 relations recovered 189 polynomials freed 7 duplicate relations attempting to build 749 cycles found 749 cycles in 1 passes distribution of cycle lengths: length 1 : 387 length 2 : 362 largest cycle: 2 relations matrix is 560 x 749 (0.1 MB) with weight 13021 (17.38/col) sparse part has weight 13021 (17.38/col) filtering completed in 4 passes matrix is 532 x 596 (0.1 MB) with weight 9564 (16.05/col) sparse part has weight 9564 (16.05/col) commencing Lanczos iteration memory use: 0.1 MB lanczos halted after 10 iterations (dim = 529) recovered 63 nontrivial dependencies Lanczos elapsed time = 1.1600 seconds. Sqrt elapsed time = 0.0000 seconds. SIQS elapsed time = 11.9765 seconds. pretesting / qs ratio was 0.83 Total factoring time = 32.6554 seconds ***factors found*** P20 = 12109985960354612149 P20 = 11771834931016130837 P20 = 13079524394617385153 P19 = 9953162929836910171 P20 = 17129880600534041513 ans = 1
あとは通常通り復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * with open('output.txt', 'r') as f: params = f.read().splitlines() n = int(params[0].split(' = ')[1]) e = int(params[1].split(' = ')[1]) enc = int(params[2].split(' = ')[1]) p = 12109985960354612149 q = 11771834931016130837 r = 13079524394617385153 s = 9953162929836910171 a = 17129880600534041513 phi = (p - 1) * (q - 1) * (r - 1) * (s - 1) * (a - 1) d = inverse(e, phi) m = pow(enc, d, n) flag = long_to_bytes(m).decode() print(flag)
FLAG{S0_3a5y_1254!!}
replacement (Crypto)
1文字ずつブルートフォースして、ASCIIコードのmd5を比較して、メッセージを取得する。
#!/usr/bin/env python3 import hashlib with open('my_diary_11_8_Wednesday.txt', 'r') as f: enc = eval(f.read()) msg = '' for c in enc: for x in range(32, 127): if int(hashlib.md5(str(x).encode()).hexdigest(), 16) == c: msg += chr(x) break print(msg)
結果は以下の通り。
Wednesday, 11/8, clear skies. This morning, I had breakfast at my favorite cafe. Drinking the freshly brewed coffee and savoring the warm buttery toast is the best. Changing the subject, I received an email today with something rather peculiar in it. It contained a mysterious message that said "This is a secret code, so please don't tell anyone. FLAG{13epl4cem3nt}". How strange!Gureisya
文中にフラグが書いてあった。
FLAG{13epl4cem3nt}
Easy calc (Crypto)
暗号化処理の概要は以下の通り。
・p: 1024ビット素数 ・s: 1以上p-1以下のランダム整数 ・A = f(s, p) ・u = 0 ・以下p回繰り返し(i) ・u += p - i ・u *= s ・u %= p ・uを返却 ・ciphertext = encrypt(FLAG, s).hex() ・iv: ランダム16バイト文字列 ・key: sをバイト文字列化したもの ・key: keyのmd5ダイジェスト ・iv + [key, ivを使ってFLAGをAES暗号化したもの]を返却 ・p, A, ciphertextを出力
f関数の計算部分を見てみる。
i = 0: u = p * s % p = 0 i = 1: u = (p - 1) * s % p i = 2: u = ((p - 1) * s + (p - 2)) * s % p = ((p - 1) * s**2 + (p - 2) * s) % p : i = p - 1: u = ((p - 1) * s**(p-1) + (p - 2) * s**(p-2) + ... + 2 * s**2 + s) % p
この結果がAとなる。
両辺に(s - 1)をかけてみる。
A * (s - 1) % p = ((p - 1) * s**p - s**(p-1) - s**(p-2) - ... - s**2 - s) % p = ((p - 1) * s**p - (s**(p-1) + s**(p-2) + ... + s**2 + s)) % p
さらに両辺に(s - 1)をかけてみる。
A * (s - 1)**2 % p = ((p - 1) * s**p * (s - 1) - (s**p - s)) % p = ((1 - s) * s**p - s**p + s) % p = (s - s**(p+1)) % p = (s - s**2) % p = - s * (s - 1) % p
つまり以下が成り立つ。
A * (s - 1) % p == - s % p
sの方程式にすると、以下のように式を変形できる。
(A + 1) * s = A % p s = A * inverse(A + 1, p) % p
あとはこれを使って、AES暗号の鍵を取得し、復号する。
#!/usr/bin/env python3 from hashlib import md5 from Crypto.Cipher import AES from Crypto.Util.number import * with open('output.txt', 'r') as f: params = f.read().splitlines() p = int(params[0].split(' = ')[1]) A = int(params[1].split(' = ')[1]) ciphertext = bytes.fromhex(eval(params[2].split(' = ')[1])) s = A * inverse(A + 1, p) % p key = long_to_bytes(s) key = md5(key).digest() iv = ciphertext[:16] ct = ciphertext[16:] cipher = AES.new(key, AES.MODE_CBC, iv=iv) flag = cipher.decrypt(ct).decode() print(flag)
FLAG{Do_the_math396691ba7d7270a}
dance (Crypto)
暗号化処理の概要は以下の通り。
・isLogged = False ・current_user = '' ・d = {} ・以下繰り返し ・chice: 入力 ・choiceが'1'の場合 ・Register() ・username: 入力 ・dにusernameがある場合はchoiceの入力からやり直し ・dt_now: 現在時刻のオブジェクト ・minutes: dt_nowの分の値 ・sec: dt_nowの秒の値 ・data1 = f'user: {username}, {minutes}:{sec}' ・data2 = f'{username}'+str([0以上10以下のランダム整数]) ・d[username] = make_token(data1, data2) ・right: data1のsha256ダイジェストの16進数表記の先頭20バイト ・left: data1 + data2のsha256ダイジェストの16進数表記の先頭12バイト ・token = left + right ・tokenを返却 ・tokenを表示 ・choiceが'2'の場合 ・Login() ・username: 入力 ・dにusernameがない場合はchoiceの入力からやり直し ・token: 入力 ・d[username]とtokenが一致していない場合、choiceの入力からやり直し ・isLogged = True ・current_user = username ・usernameを表示 ・choiceが'3'の場合 ・Logout() ・isLogged = False ・current_user = '' ・choiceが'4'の場合 ・Encrypt() ・isLoggedがFalseの場合はchoiceの入力からやり直し ・token = d[current_user] ・key: tokenのsha256ダイジェストの16進数表記の先頭32バイト ・nonce: tokenの先頭12バイト ・cipher = MyCipher(key.encode(), nonce.encode()) ・cipher.key = key.encode() ・cipher.nonce = nonce.encode() ・cipher.counter = 1 ・cipher.state = List[F2_32] ・plaintext: 入力 ・ciphertext = cipher.encrypt(plaintext.encode()) ・encrypted_message = b'' ・plaintextの長さを64で割った数だけ以下の処理を実行(i) ・key_stream = cipher.__get_key_stream(cipher.key, cipher.counter + i, cipher.nonce) ・constants: b'expand 32-byte k'をリトルエンディアンで整数4つにし、F2_32の配列にしたもの ・key: keyをリトルエンディアンで整数8つにし、F2_32の配列にしたもの ・counter: cipher.counter + iをF2_32の配列(要素1個)にしたもの ・nonce: nonceをリトルエンディアンで整数3つにし、F2_32の配列にしたもの ・cipher.state = constants + key + counter + nonce ・initial_state = cipher.state[:] ・cipher.__update_state() ・cipher.state = [x + y for x, y in zip(cipher.state, initial_state)] ・cipher.stateの各要素を32ビット整数として、文字列に変換し、連結したものを返却 ・encrypted_messageにplaintext[i*64:(i+1)*64]とkey_streamのXORを結合 ・plaintextの長さを64で割った余りが0でない場合 ・key_stream = cipher.__get_key_stream(cipher.key, cipher.counter + len(plaintext)//64, cipher.nonce) ・encrypted_messageにplaintext[(len(plaintext)//64)*64:]とkey_stream[:len(plaintext) % 64]のXORを結合 ・current_userを表示 ・ciphertextを16進数表記で表示 ・choiceが'5'の場合 ・繰り返し終了
usernameとciphertextだけがわかっている。tokenの生成方法から、60*60*11種類のtokenがあることがわかる。tokenが決まれば、key, nonceは決まる。平文ブロックごとに、key_streamも決まるので、ciphertextとのXORで復号できる。
tokenでブルートフォースして、復号した結果、フラグの先頭が"FLAG{"になるものを探す。
なお、インポートするmycipher.pyの以下の関数名の先頭から"__"を削除し、外部からアクセス可能にしておく。
・__get_key_stream -> get_key_stream ・__xor -> xor
#!/usr/bin/env python3 from mycipher import MyCipher import hashlib def make_token(data1: str, data2: str): sha256 = hashlib.sha256() sha256.update(data1.encode()) right = sha256.hexdigest()[:20] sha256.update(data2.encode()) left = sha256.hexdigest()[:12] token = left + right return token with open('output.txt', 'r') as f: params = f.read().splitlines() username = eval(params[0].split(' = ')[1]) ciphertext = bytes.fromhex(eval(params[1].split(' = ')[1])) len_ct = len(ciphertext) assert len_ct < 64 found = False for minutes in range(60): for sec in range(60): for num in range(11): data1 = f'user: {username}, {minutes}:{sec}' data2 = f'{username}'+str(num) token = make_token(data1, data2) sha256 = hashlib.sha256() sha256.update(token.encode()) key = sha256.hexdigest()[:32].encode() nonce = token[:12].encode() cipher = MyCipher(key, nonce) key_stream = cipher.get_key_stream(key, 1, nonce) flag = cipher.xor(ciphertext, key_stream[:len_ct]) if flag.startswith(b'FLAG{'): found = True flag = flag.decode() print(flag) break if found: break if found: break
FLAG{d4nc3_l0b0t_d4nc3!!}
speedy (Crypto)
暗号化処理の概要は以下の通り。
・s0: ランダム8バイト文字列の数値化したもの ・s1: ランダム8バイト文字列の数値化したもの ・cipher = MyCipher(s0, s1) ・cipher.X = s0 ・cipher.Y = s1 ・cipher.mod = 0xFFFFFFFFFFFFFFFF ・cipher.BLOCK_SIZE = 8 ・secret: "FLAG{*******************}'(25バイト) ・pt: secretを8バイトパディング ・ct = cipher.encrypt(pt) ・ct = b'' ・ptの8バイトの各ブロック(block)ごとに以下の処理を実行 ・ctにcipher.Xのバイト文字列化したものを結合 ・key = cipher.get_key_stream() ・ctにblockとkeyのXORを結合 ・ctを出力
フラグの長さは25バイトなので、4ブロック目の平文と暗号文がわかっている。このため、XOR鍵も算出でき、X, Yがわかる。あとは後ろのブロックからX, Yを逆算していき、XOR鍵を求め、復号していく。
#!/usr/bin/env python3 from Crypto.Util.number import * from Crypto.Util.Padding import * from Crypto.Util.strxor import strxor def rotr(x, y): x &= 0xFFFFFFFFFFFFFFFF return ((x >> y) | (x << (64 - y))) & 0xFFFFFFFFFFFFFFFF mod = 0xFFFFFFFFFFFFFFFF with open('out.txt', 'r') as f: ct = eval(f.read().split(' = ')[1]) assert len(ct) == 64 Xs = [bytes_to_long(ct[i:i+8]) for i in range(0, len(ct), 16)] cts = [ct[i+8:i+16] for i in range(0, len(ct), 16)] pt3 = pad(b'}', 8) ct3 = cts[3] key3 = strxor(pt3, ct3) sum = bytes_to_long(key3[::-1]) X = Xs[3] Y = (sum - X) % (mod + 1) flag = '}' for i in range(3): s1 = rotr(Y, 37) s0 = rotr(X ^ s1 ^ (s1 << 16), 24) assert s0 == Xs[2 - i] s1 ^= s0 sum = (s0 + s1) & mod key = [] for _ in range(8): key.append(sum & 0xFF) sum >>= 8 pt = bytes([cts[2 - i][j] ^ key[j] for j in range(8)]) flag = pt.decode() + flag X = s0 Y = s1 print(flag)
FLAG{x013_ro74te_5hif7!!}