improvisation

プログラム task.py と、その出力 output.txt が与えられた。

task.py は以下の処理をするものだった。

  1. flag.txt を読み込み、先頭が CakeCTF{ であることを確かめる。
  2. flag.txt の内容を数値に変換する。この数値を m とする。
  3. 64ビットのランダムな数を生成する。
  4. c を0に初期化する。
  5. 生成した数を初期値としてビット列を生成し、m の下位ビットから順にXORをし、得られたビットを c の最下位に結合する。
  6. c の値を出力する。

このとき、m の最上位のバイトのうち連続する上位の0のビットについては、結合処理が行われない。
また、出力されるc の値には、最上位に何個0が結合されたかの情報は含まれない。

そこで、まず以下のプログラムを用い、CakeCTF{ を入力した時の出力が与えられたものになるような初期値をZ3で求めた。
m の最上位のバイト (最後のバイト) は改行 (0x0a) であり、結合処理の対象にならない上位の0は4ビットであると仮定すると、適切な初期値が求まった。

A program task.py and its output output.txt were given.

What task.py does was:

  1. Read flag.txt and make sure the prefix of its contents is CakeCTF{.
  2. Convert the contents of flag.txt to an integer m.
  3. Generate a 64-bit random integer.
  4. Initialize a number c to zero.
  5. Generate a sequence of bits using the random integer as aninitial value, perform exclusive-or of the sequence and bytes of m (lower bit first), and append the result bits to the lowest side of c.
  6. Output the value of c.

In this operation, the appendeng doesn't happen for the top consecutive bits with value 0 in the topmost byte of m.
Moremover, the value of c in the output doesn't contain information about how many zeros are concatenated to the highest part.

I used this program to obtain the initial value to make the output to be what is given when the input is CakeCTF{.
I obtained the proper initial value by assuming the hightest byte (the last byte) of m is a newline character (0x0a) and that there are 4 consequtive top bits not for appending.

solve1.py

以下のプログラムに得られた初期値を与えて実行し、出力にCyberChefの From Hex を適用することで、flagが得られた。

I obtained the flag by executing this program with the obtained initial value and applying "From Hex" to the output via CyberChef.

solve2.py

CakeCTF{d0n't_3xp3c7_s3cur17y_2_LSFR}

CakeCTF 2021