ペンギン技術 blog

CTFのWriteupなどを記載していこうと思います

setodaNoteCTF Writeup[Rev]

Rev

Helloworld

50

気が付くと椅子に座っていた。簡単なテストから始めよう。ガラスを隔てて真正面に白衣の女が立っている。
君が優秀であることを示してくれ。声は天井のスピーカーから聞こえてくるようだ。
心配はいらない。そばにある端末が起動する。どちらにしてもすぐに済む。

添付されたファイルを解析してフラグを得てください。
ファイルは「infected」というパスワード付き ZIP になっています。

ZIPをパスワードinfectedで解凍
VirusTotalで若干検知ありなので、仮想マシンで実行してみる

メッセージに従って引数を渡したり試したらクリア

>~\helloworld.exe
Nice try, please set some word when you run me.

>~\helloworld.exe a
Good job, but please set 'flag' when you run me.

>~\helloworld.exe flag
flag{xxxxx}`

ELF

80

監獄というより研究室のような施設だった。見る角度が大切なんだ。ガラスで隔てたられた部屋を
白衣の男が歩いている。すべてを疑ってみることから始める。そばにある端末の電源が入る。
手を動かして検証するというのは実に大事なことだ。

添付されたファイルを解析してフラグを入手してください。

ファイルコマンドで見ると、dataとなっていて、詳細不明

$ file elf
elf: data

stringsでみてみる

$ strings elf
XXXX
/lib64/ld-linux-x86-64.so.2
puts
__cxa_finalize
__libc_start_main
libc.so.6
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
NDIOSZ]FH
wEICAJIUH
[]A\A]A^A_
;*3$"
GCC: (Debian 10.2.1-6) 10.2.1 20210110
:

フラグっぽいものはない
ファイル名がelfであり、stringsコマンドの結果にgcc、libc.so.6などがあるので、elfファイルっぽい
XXXXがやや気になる

ファイルをバイナリエディタでみると、先頭が不自然に以下になっている
このせいでファイルタイプが不明なのでは?
gccやghidraもうまく読み込めず)

58 58 58 58 XXXX

ELFファイルという前提で、以下に書き換える

7F 45 4C 46 .ELF

ghidraで開けるようになった
権限をつけ、実行してみる

$ chmod 755 elf

$ ./elf
flag{xxxxx}

(参考)odコマンドで先頭64バイト表示(ビックエンディアン指定)
(バイトオーダーしていないとリトルエンディアンになるっぽい)

$ od -Ax -tx --endian=big -N 64 elf
000000 7f454c46 02010100 00000000 00000000
000010 03003e00 01000000 50100000 00000000
000020 40000000 00000000 50310000 00000000
000030 00000000 40003800 0b004000 1c001b00
000040

Passcode

ひとまず、stringsコマンドで見てみる

$ strings passcode
:
Invalid passcode.
Invalid passcode. Too short.
Invalid passcode. Too long.
20150109
The passcode has been verified.
:

日付のような文字列が怪しいので試す

$ ./passcode
Enter the passcode: 20150109
The passcode has been verified.

Flag is : flag{xxxxx}

Passcode2

150

予想以上の結果だった。今日もガラス越しに対象が目を覚ます。ここまでうまくいったことはかつてない。
端末に今日のデータを送信する。今度こそうまくいくかもしれない。

添付されたファイルを解析してフラグを得てください。

ghidraで開く

以下のコードが関係ありそう
パスコードは11桁
パスコードがそのままフラグ

undefined8 FUN_00101175(void)

{
  int iVar1;
  undefined8 uVar2;
  size_t sVar3;
  byte local_124 [4];
  undefined local_120;
  undefined local_11f;
  undefined local_11e;
  undefined local_11d;
  undefined local_11c;
  undefined local_11b;
  undefined local_11a;
  undefined local_119;
  undefined8 local_118;
  undefined8 local_110;
  undefined8 local_108;
  undefined8 local_100;
  undefined8 local_f8;
  undefined8 local_f0;
  undefined8 local_e8;
  undefined8 local_e0;
  undefined8 local_d8;
  undefined8 local_d0;
  undefined8 local_c8;
  undefined8 local_c0;
  undefined8 local_b8;
  undefined8 local_b0;
  undefined8 local_a8;
  undefined8 local_a0;
  undefined8 local_98;
  undefined8 local_90;
  undefined8 local_88;
  undefined8 local_80;
  undefined8 local_78;
  undefined8 local_70;
  undefined8 local_68;
  undefined8 local_60;
  undefined8 local_58;
  undefined8 local_50;
  undefined8 local_48;
  undefined8 local_40;
  undefined8 local_38;
  undefined8 local_30;
  undefined8 local_28;
  undefined8 local_20;
  ulong local_10;
  
  local_118 = 0;
  local_110 = 0;
  local_108 = 0;
  local_100 = 0;
  local_f8 = 0;
  local_f0 = 0;
  local_e8 = 0;
  local_e0 = 0;
  local_d8 = 0;
  local_d0 = 0;
  local_c8 = 0;
  local_c0 = 0;
  local_b8 = 0;
  local_b0 = 0;
  local_a8 = 0;
  local_a0 = 0;
  local_98 = 0;
  local_90 = 0;
  local_88 = 0;
  local_80 = 0;
  local_78 = 0;
  local_70 = 0;
  local_68 = 0;
  local_60 = 0;
  local_58 = 0;
  local_50 = 0;
  local_48 = 0;
  local_40 = 0;
  local_38 = 0;
  local_30 = 0;
  local_28 = 0;
  local_20 = 0;
  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: ");
  iVar1 = __isoc99_scanf("%255[^\n]%*[^\n]",&local_118);
  if (iVar1 == -1) {
    uVar2 = 1;
  }
  else {
    __isoc99_scanf(&DAT_0010202c);
    if ((char)local_118 == '\0') {
      printf("Invalid passcode.");
    }
    else {
      sVar3 = strlen((char *)&local_118);
      if (sVar3 < 0xb) {
        printf("Invalid passcode. Too short.");
      }
      else {
        sVar3 = strlen((char *)&local_118);
        if (sVar3 < 0xc) {
          sVar3 = strlen((char *)&local_118);
          if (sVar3 == 0xb) {
            local_10 = 0;
            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);  ★mdファイル変換でエラーとなるので\%としている
            }
            else {
              printf("Invalid passcode. Nice try.");
            }
          }
          else {
            printf("Invalid passcode.");
          }
        }
        else {
          printf("Invalid passcode. Too long.");
        }
      }
    }
    putchar(10);
    uVar2 = 0;
  }
  return uVar2;
}

特に以下がポイントで、これを満たすパスコードを探す

          if (sVar3 == 0xb) {
            local_10 = 0;
            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");

Excelで計算したが、local_124[local_10] ^ 0x2aは10進数で以下のように変化するハズ

XOR(DEC) XOR(bin)
50  110010
53  110101
46  101110
83  1010011

11桁だとオーバーフローさせる?(難しい)
ブレークポイントをどこに設定するかがわかれば)gdbデバッグしながら試してみるというのはできそう

$ echo 12345678901 | ./passcode2
Enter the passcode: Invalid passcode. Nice try.

総当たりも考えたが、11桁だと難しそう
(ここまで) (解けていない)

(追記)ASCIIに直すとフラグがでてくるとのこと
https://muchipopo.com/ctf/setoda-writeup/#toc4

もう少しだったと思う反面、local_124[3]より後ろのlocal_120からがghidraでは
別変数に見えていたのでやっぱり気づかなかったかな・・・

  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;
  :

to_analyze

200

あの施設はなんだったのだろう。ふとした瞬間に思い出す。「秘密情報が含まれているファイルを入手した。
特定の環境で実行した場合のみ情報が表示される仕組みのようだが条件が特定できない。
解析してみてくれないか。」同僚から連絡が入る。端末を開き受信データを確認する。
今日の解析対象が画面に表示される。

添付されたファイルを解析してフラグを入手してください。
ファイルは「infected」というパスワード付き ZIP になっています。

思つくのは(マルウェアとかで聞いたことがあるのは)
タイムゾーン設定
・OS言語設定
・特定のフォルダに特定のファイルがある
とか?
ghidraにて見たが、わからず
(解けていない)

(追記).NETで作られているので、デコンパイラILSPYなどで解析できるとのこと
https://muchipopo.com/ctf/setoda-writeup/#toc4