LACTF 2024 Writeups

# LACTF 2024 Writeups
LACTF 2024に参加してきたので、writeup書きます。

# web/terms-and-conditions
画面にあるI Acceptを押すとフラグが表示されるという問題でした。
![a_t_t_a_c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/7c44701c-7390-89d0-c937-77606a7dc492.png)
ただ、このI Acceptボタンを押そうとすると、ボタンが逃げて押せません。
開発者モードからどうにか出来ないかと思いやってみると、開発者モードにした瞬間にhtmlのbodyが書き換えられる仕組みになっていました。
なのでボタンを押すことを諦め、ボタンに紐づけられている関数を見て、フラグを読み取ろうと試みました。
![Screenshot 2024-02-19 114738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/1e281d05-f26a-0e81-8542-2dddffd04261.png)
analytics.jsが怪しいので、このスクリプトを解析します。
難読化が施されていたので、解除して解析します。
![Screenshot 2024-02-19 115135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/a59a8d86-ce73-06f9-2748-bd555e0d20a8.png)
elseの後に続く処理がフラグを表示する処理らしいので、このコードをローカルで実行してフラグを取得して終わりです。
![Screenshot 2024-02-19 115415.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/c55d8d20-7403-b531-e137-8023237f5027.png)

# web/flaglang
このウェブサイトは指定した国の言語でHello, Worldを出力するサイトのようです。
![Screenshot 2024-02-19 123507.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/f2527fcb-b0f2-6fb2-25ea-ebb87110a874.png)
言語とHello, Worldメッセージが格納されたymlファイルがソースコードと一緒に配布されていたので、それを見てみます。
![Screenshot 2024-02-19 120020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/c4e66cf2-ba9e-ecdb-f690-5530b8b93819.png)
すると、Flagistanという国のメッセージがフラグだと分かりました。
ここでソースコードを見ていきます。
![Screenshot 2024-02-19 120853.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/883efc1d-b7f1-f253-c2f1-c20b034f8873.png)
/switchディレクトリに対するGETメソッドでは、toパラメータに国の名前を指定することで、クッキーのiso値に指定した国のiso値を入れています。
ただし、Flagistanの場合はパスワードによる認証処理があり、/switchディレクトリからFlagistanに国を変更するのは出来なさそうです。
さらにこれは署名付きのクッキーなので、クッキーの改ざんは出来なさそうです。
![Screenshot 2024-02-19 120950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/ea5505a2-994f-11f6-258e-5b4e300fccab.png)
/viewディレクトリでは、countryパラメータに国の名前を指定することで、国のメッセージが取得できます。
ただし、こちらはクッキーのiso値がFlagistan以外の値のままFlagistanを指定されないように、フィルタリングが掛けられています。
ただし、このフィルタリングはクッキーの値を用いているので、クッキーを無くせばバイパス出来そうです。
![Screenshot 2024-02-19 121229.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/66554586-3811-6ef0-fa78-d7780650ae71.png)

# rev/shattered-memories
shattered-memoriesという実行形式のファイルが渡されたので、とりあえずstringsコマンドで文字列を全部抜き出してみました。
![Screenshot 2024-02-19 123146.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/ff051c50-dc36-59c0-7f0f-4acd126fa2ab.png)
するとフラグの断片が順不同で出てきました。
これを並び替えればフラグの完成です。
lactf{not_what_forgive_and_forget_means}

# rev/aplet321
aplet321という実行形式のファイルが配布されるので、それを実行してみます。
![Screenshot 2024-02-19 123613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/1548f269-1a92-2ae3-647d-fc2b7e31871c.png)
どうやらflagとだけ出力するとrudeと言われ、pleaseだけだとsorry, i didn't understand what you meanと言われ、flag pleaseやflag please prettyの場合はsorry, i'm not allowed to do thatと言われます。
これだけだと情報が少ないので、idaのpseudo c codeで内容を見てみます。
```c
int __fastcall main(int argc, const char **argv, const char **envp)
{
  char *v3; // rbx
  size_t v4; // rax
  int v5; // ebp
  int v6; // r12d
  char *v7; // r15
  char s[568]; // [rsp+10h] [rbp-238h] BYREF

  v3 = s;
  setbuf(stdout, 0LL);
  puts("hi, i'm aplet321. how can i help?");
  fgets(s, 512, stdin);
  v4 = strlen(s);
  if ( v4 <= 5 )
    goto LABEL_10;
  v5 = 0;
  v6 = 0;
  v7 = &s[(unsigned int)(v4 - 6) + 1];
  do
  {
    v6 += strncmp(v3, "pretty", 6uLL) == 0;
    v5 += strncmp(v3++, "please", 6uLL) == 0;
  }
  while ( v3 != v7 );
  if ( v5 )
  {
    if ( strstr(s, "flag") )
    {
      if ( v6 + v5 == 54 && v6 - v5 == -24 )
      {
        puts("ok here's your flag");
        system("cat flag.txt");
      }
      else
      {
        puts("sorry, i'm not allowed to do that");
      }
    }
    else
    {
      puts("sorry, i didn't understand what you mean");
    }
  }
  else
  {
LABEL_10:
    puts("so rude");
  }
  return 0;
}
```
v6 + v5が54かつv6 - v5が-24の時にフラグを出力するようです。
v6は文字列に含まれるprettyの数、v5は文字列に含まれるpleaseの数です。
後は条件を満たすprettyとpleaseの数を求めるだけです。
するとprettyは15、pleaseは39の時にフラグが出力されると分かりました。
後は実行するだけです。
![Screenshot 2024-02-19 124736.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/93fef34e-3754-3de6-a667-8dda7574744e.png)

# misc/infinite loop
１つのグーグルフォームのURLが配布されたので、まずは見に行ってみます。
![Screenshot 2024-02-19 124906.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/a0c19159-5e96-3646-f803-9843b3566b20.png)
チーム名を入力する欄があったので、入力して次に。
すると1+1の答えを入力する欄が出てきました。
入力して次に進もうとすると、同じページに戻されてしまいました。
![Screenshot 2024-02-19 124941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/956f8e5b-4a1d-a839-8908-15fae86f2ba6.png)
少し調べたところ、ページのソースコードの一番下のscriptタグにフォームのデータが埋め込まれていることが分かりました。
すると、そこにフラグがありました。
![Screenshot 2024-02-19 125430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/6522d43e-3ce6-ca80-4f6d-a1b9a4144230.png)