これは、2021/8/21~2021/9/4の期間で開催された、setodaNote CTFの Rev 分野のwriteupです。全体writeupはこちら
Helloworld (50)
気が付くと椅子に座っていた。簡単なテストから始めよう。ガラスを隔てて真正面に白衣の女が立っている。君が優秀であることを示してくれ。声は天井のスピーカーから聞こえてくるようだ。心配はいらない。そばにある端末が起動する。どちらにしてもすぐに済む。
添付されたファイルを解析してフラグを得てください。 ファイルは「infected」というパスワード付き ZIP になっています。
配布されたファイルを解凍すると、helloworld.exe
ファイルが出現。
windows機があれば、実行時にflag
を引数にとって実行するだけでflagが出そう。だけど無いのでghidraに食わせて処理を見てみます。
local_c = 0x2b2d2f3e; uStack40 = 0x2b3c2835; uStack36 = 0x2f28112b; uStack32 = 0x2f113c27; local_8 = 0x33; uVar3 = 0; local_1c = 0x3d112a20; uStack24 = 0x3c3b2d2b; uStack20 = 0x372d112b; uStack16 = 0x3d3c2b2c; FUN_00401010(&DAT_004021a8,(&stack0xffffffd4)[uVar3] ^ 0x4e)
こんな処理を発見。ここに書かれた16進を組み合わせて xor 0x4e
してもうまく行かなかったので、DAT_004021a8
の領域を覗いてみて、近辺の怪しい値を xor 0x4e
したらflagが出てきました。
ELF (80)
監獄というより研究室のような施設だった。見る角度が大切なんだ。ガラスで隔てたられた部屋を白衣の男が歩いている。すべてを疑ってみることから始める。そばにある端末の電源が入る。手を動かして検証するというのは実に大事なことだ。
添付されたファイルを解析してフラグを入手してください。
添付ファイルにはelf
というファイルが入っているけど、実行できない。dataファイルとして認識されている。バイナリエディタで見てみると、シグネチャ部分がXXXX
になってしまっている。elfのシグネチャは7F 45 4C 46
なので、これに書き換えて実行してみる。
$ ./elf flag{run_makiba}
Passcode (120)
その部屋はまぶしいほどの明かりで照らされていた。ここからが本番だ。白衣の人物が書類に目を落としながらつぶやくように話している。結果がすべてという訳ではないが。そばにある端末が起動する。いい結果を期待している。
添付されたファイルを解析してフラグを得てください。
passcode
というELFファイルが配布されます。
ghidraで開いてみると、passcodeは20150109
で、flagはこれをflagフォーマットで囲ったものでした。この辺参照。
if (sVar3 < 9) { iVar1 = strcmp((char *)&local_108,"20150109"); if (iVar1 == 0) { puts("The passcode has been verified.\n"); printf("Flag is : flag{%s}",&local_108);
Passcode2 (150)
予想以上の結果だった。今日もガラス越しに対象が目を覚ます。ここまでうまくいったことはかつてない。端末に今日のデータを送信する。今度こそうまくいくかもしれない。
添付されたファイルを解析してフラグを得てください。
こちらもELFファイルが配布されているので、ghidraに突っ込んで解析してもらいます。decompile結果のentry
関数より抜粋
undefined8 FUN_00101175(void) { ~(中略)~ local_124[0] = 0x18; local_124[1] = 0x1f; local_124[2] = 4; local_124[3] = 0x79; local_120 = 0x4f; local_11f = 0x5a; local_11e = 4; local_11d = 0x18; local_11c = 0x1a; local_11b = 0x1b; local_11a = 0x1e; local_119 = 0; printf("Enter the passcode: "); ~(中略)~ while ((sVar3 = strlen((char *)local_124), local_10 < sVar3 && (*(byte *)((long)&local_118 + local_10) == (local_124[local_10] ^ 0x2a)))) { local_10 = local_10 + 1; } sVar3 = strlen((char *)local_124); if (local_10 == sVar3) { puts("The passcode has been verified.\n"); printf("Flag is : flag{%s}",&local_118); } ~(中略)~} return uVar2; }
ということで、local_124
の16進を xor 0x2a
したものがPasscode。
これをflagフォーマットで囲めばflagになる。