RICERCA CTF 2023 writeup [welcome, crackme, Revolving letters]

picoCTF、RitsecCTFに続き、今回はRicercaCTFに参加しました。
解けた問題は、「welcome」、「crackme」、「Revolving Letters」、、、以上!

1問に1時間くらいかかりました。そもそも、gzファイル展開したらtarファイルが出てくることもわかってなかった。
もうちょっとctfの実力を上げてから、writeup書いていこうかなぁなんて思ってましたが、今回のctfはwriteupを書くといいことあるかもってことが分かったので、たった3問でも書きます。

目次 【 開閉 】

1,welcome

2,crackme

3,Revolving Letters

4,今後、、、

数字がふってあるところだけを見れば、分かるようになってます。

welcome

問題文

Ricerca CTF 2023へようこそ! この問題のフラグを見つけるには
まず、ルールを読みましょう。
次に、Discordの#announcementチャンネルに投稿されたフラグを探しましょう。

解き方

  1. ルール」のリンク先に飛ぶ。
  2. 「Official Discord」をクリックしてDiscoredに参加。
  3. 「#announcement」をクリック。
  4. flagゲット。(写真中央)

crackme

問題文

パスワードをクラックできますか。

解き方

  1. 添付のファイルをダウンロード。
  2. ファイルの名前が長かったため、「password.gz」に名前変更。
  3. linuxで、次のコマンドを打つ。
  4. 1
    $ gzip -d password.gz

    「password」というファイルができたので、調べてみると、tarファイルということがわかった。

  5. 次の2つのコマンドを打つ。
  6. 1
    $ cp password password.tar
    1
    $ tar -xvf password.tar
  7. 「crackme」というフォルダができたので、cdで移動。
  8. 1
    $ cd crackme

    移動した先に、「crackme」というファイルがあったので、とりあえず実行すると、passwordが必要だと分かった。

  9. catコマンドで、「crackme」の中身を確認。
  10. 1
    $ cat crackme

    だいぶ文字化けしてるが、読めるところを探すと、ヒントが、、、!

  11. 次のコマンドを実行し、パスワードを入力
  12. 1
    $ ./crackme
  13. flagゲット。(写真下部)

Revolving Letters

問題文

文字を回すの、だーぁれ?

解き方

  1. 添付ファイルをダウンロード。
  2. ファイルの名前を「attach.gz」に変更。
  3. 前の問題と同じ要領で、linuxコマンドを実行する。
  4. 1
    $ gzip -d attach.gz
    1
    $ cp attach attach.tar
    1
    $ tar -xvf attach.tar
    1
    $ cd revolving-letters
  5. 「output.txt」と「chall.py」が入っていた。
  6. shall.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz"

    def encrypt(secret, key):
    assert len(secret) <= len(key)

    result = ""
    for i in range(len(secret)):
    if secret[i] not in LOWER_ALPHABET: # Don't encode symbols and capital letters (e.g. "A", " ", "_", "!", "{", "}")
    result += secret[i]
    else:
    result += LOWER_ALPHABET[(LOWER_ALPHABET.index(secret[i]) + LOWER_ALPHABET.index(key[i])) % 26]

    return result

    flag = input()
    key = "thequickbrownfoxjumpsoverthelazydog"
    example = "lorem ipsum dolor sit amet"
    example_encrypted = encrypt(example, key)
    flag_encrypted = encrypt(flag, key)

    print(f"{key=}")
    print(f"{example=}")
    print(f"encrypt(example, key): {example_encrypted}")
    print(f"encrypt(flag, key): {flag_encrypted}")

    output.txt

    1
    2
    3
    4
    key='thequickbrownfoxjumpsoverthelazydog'
    example='lorem ipsum dolor sit amet'
    encrypt(example, key): evvug kztla qtzla exl vqvm
    encrypt(flag, key): RpgSyk{qsvop_dcr_wmc_rj_rgfxsime!}

    「shall.py」は、ざっくりいうと次のようなことを行うプログラムになっていた。

    1. 入力されたテキストの文字がアルファベットの小文字以外の場合、そのまま出力する。
    2. 入力されたテキストの文字がアルファベットの小文字の場合、
    3. アルファベット順で見た時の、その文字の位置と、key文字列の位置を足す。
    4. 出た値を26で割った余りを出す。
    5. 出た値の場所にあるLOWER_ALPHABETを暗号化された値としてresultに追加する。


    例(入力されたテキストの3番目に「c」がある場合)

    LOWER_ALPHABETで「c」は3番目にあるから、(LOWER_ALPHABET.index(secret[i])の値は2。
    また、key文字列の3番目は「e」だから、LOWER_ALPHABET.index(key[i])の値は4。
    これらを足して26で割ると6余る。
    LOWER_ALPHABET[6]は「g」を表すから、暗号化された値は「g」となる。

    output.txtにあったRpgSyk{qsvop_dcr_wmc_rj_rgfxsime!}は、フラグをこのpythonファイルで暗号化させたもの。

  7. 次のpythonプログラムを実行することで、フラグを出すことができた。
  8. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz"

    def encrypt(secret, key):
    assert len(secret) <= len(key)

    result = ""
    for i in range(len(secret)):
    if secret[i] not in LOWER_ALPHABET: # Don't encode symbols and capital letters (e.g. "A", " ", "_", "!", "{", "}")
    result += secret[i]
    else:
    result += LOWER_ALPHABET[(LOWER_ALPHABET.index(secret[i]) - LOWER_ALPHABET.index(key[i])) % 26] #chall.pyでは、「+」になっていたところを「-」に変更

    return result

    flag = "RpgSyk{qsvop_dcr_wmc_rj_rgfxsime!}" #output.txtに書かれていたフラグになりそうなテキスト
    key = "thequickbrownfoxjumpsoverthelazydog"
    flag_encrypted = encrypt(flag, key)


    print(f"encrypt(flag, key): {flag_encrypted}")

今後、、、

writeupをもっとうまく書けるようになりたい。