この大会は2021/8/14 4:00(JST)~2021/8/17 4:00(JST)に開催されました。
今回もチームで参戦。結果は2300点で602チーム中88位でした。
自分で解けた問題をWriteupとして書いておきます。
Discord (Miscellaneous 50)
Discordに入り、#generalチャネルのトピックを見ると、フラグが書いてあった。
ractf{so_here_we_are_again}
Triangles (OSINT 100)
画像の場所を地図上で指し示す問題。
画像検索すると、"Palazzo Cosentini"であることがわかる。
36.9233815,14.7276226の位置にあるので、Google Mapの位置と見比べながら位置を指定する。赤丸の位置でSubmitしたら、フラグが通った。
Lego Car Generator (Pwn / Reversing 350)
Ghidraでデコンパイルする。
bool main(int param_1,undefined8 *param_2) { undefined8 uVar1; FILE *pFVar2; FILE *pFVar3; size_t __size; void *__ptr; int *piVar4; char *pcVar5; uint uVar6; uint uVar7; size_t sVar8; long in_FS_OFFSET; bool bVar9; undefined local_40 [8]; long local_38; local_38 = *(long *)(in_FS_OFFSET + 0x28); if (param_1 < 3) { bVar9 = false; fprintf(stderr,"usage: %s <in file> <out file>\n",*param_2); } else { pFVar3 = fopen((char *)param_2[1],"rb"); pFVar2 = stderr; if (pFVar3 == (FILE *)0x0) { uVar1 = param_2[1]; piVar4 = __errno_location(); pcVar5 = strerror(*piVar4); fprintf(pFVar2,"failed to open input file %s: %s\n",uVar1,pcVar5); bVar9 = true; } else { fseek(pFVar3,0,2); __size = ftell(pFVar3); rewind(pFVar3); __ptr = malloc(__size); fread(__ptr,1,__size,pFVar3); fclose(pFVar3); uVar7 = rdseed(); rdseedIsValid(); printf("Seed: 0x%08X\n",(ulong)uVar7); uVar7 = rngInit(local_40,uVar7); if (__size != 0) { sVar8 = 0; uVar6 = 0; do { if (uVar6 == 0) { uVar7 = rngNext32(local_40); } uVar6 = uVar6 + 1 & 3; *(byte *)((long)__ptr + sVar8) = *(byte *)((long)__ptr + sVar8) ^ (byte)(uVar7 >> 0x18); sVar8 = sVar8 + 1; uVar7 = uVar7 >> 0x18 | uVar7 << 8; } while (__size != sVar8); } pFVar3 = fopen((char *)param_2[2],"wb"); pFVar2 = stderr; bVar9 = pFVar3 == (FILE *)0x0; if (bVar9) { uVar1 = param_2[2]; piVar4 = __errno_location(); pcVar5 = strerror(*piVar4); fprintf(pFVar2,"failed to open ouput file %s: %s\n",uVar1,pcVar5); } else { fwrite(__ptr,1,__size,pFVar3); fclose(pFVar3); } free(__ptr); } } if (*(long *)(in_FS_OFFSET + 0x28) == local_38) { return bVar9; } /* WARNING: Subroutine does not return */ __stack_chk_fail(); } void rngInit(undefined4 *param_1,undefined4 param_2) { *param_1 = param_2; return; } void rngNext32(int *param_1) { *param_1 = *param_1 * 0x17433a5b + -0x481e7b5d; return; }
4バイトごとにLCGが走る。4バイトの暗号化のkeyは、LCGで生成された数値を8ビットごとにabcdと定義すると以下のように変わる。
1バイト目:abcd→a 2バイト目:bcda→b 3バイト目:cdab→c 4バイト目:dabc→d
フラグがractf{から始まることを前提に復号する。
def rngNext32(r): return (r * 0x17433a5b - 0x481e7b5d) & 0xffffffff with open('secret', 'rb') as f: enc = f.read() pre_flag = 'ractf{' rng = 0 for i in range(4): rng *= 256 rng += ord(enc[i]) ^ ord(pre_flag[i]) flag = '' for i in range(len(enc) / 4 + 1): for j in range(4): if i * 4 + j < len(enc): flag += chr(ord(enc[i*4+j]) ^ ((rng >> (24 - j * 8)) & 0xff)) rng = rngNext32(rng) print flag
復号すると以下の文字列になる。
ractf{CL04K_3NGa6ed}sikeyouthoughttheflagwasthislong
フラグは先頭部分で通った。
ractf{CL04K_3NGa6ed}