EmoEmotet

ファイル emoemotet.doc が与えられた。

LibreOffice 7.1.6.2 で開こうとしたところ、破損しているとみなされて開けなかった。
テキストとしてファイルの中身を確認すると、Base64エンコードされているような文字列や、スクリプトのような文字列が見られた。

そこで、問題文にヒントとして示されていたページを参考に、Pythonのvirtualenvを用意して pip install oletools を実行した。
そして、olevba コマンドを用い、ファイルからスクリプトを抽出した。

抽出されたスクリプトを見ると、unxor 関数の呼び出しが並んでいた。
これは、Base64エンコードされた key の指定したオフセット以降のデータと指定した配列のデータをxorする関数であることが読み取れた。
そこで、CyberChef を用い、まずはここで使っているBase64のデータをデコードした。

A file emoemotet.doc was given.

I tried to open the file with LibreOffice 7.1.6.2, but it considered the file as broken and failed to open the file.
Seeing the contents of the file as text, I found strings that looks like Base64-encoded and strings that looks like a part of a script.

Referring the page specified as a hint in the challenge descryption, I set up Python virtualenv and executed a command pip install oletools.
Then, I extracted a script from the file using olevba command.

Reading the extracted script, I found many calls of a function unxor.
This function performs exclusive-or of the input array and Base64-encoded key from the specified offset.
Seeing this, firstly I decoded the Base64 data used here using CyberChef.

From Base64, To Hex - CyberChef

次に、以下の手順により、unxor 関数の処理を再現した。

  1. 鍵を1行目に、再現する unxor 関数の呼び出しを2行目以降に入力する。
  2. 1行目の鍵をRegisterに入れ、入力から消す。
  3. 関数呼び出しの情報からデータとオフセットを取得する。
  4. 入力を鍵にし、オフセットを考慮してRegisterに入れる。
  5. 入力を関数呼び出しで用いるデータにし、XORを実行する。

以下のRecipeは、CreateObject().Run に挟まれている部分のデコードを行う。

Then, I simulated what the function unxor does in these steps:

  1. Put the key as the first line and calls of the function unxor to simulate from the second line of the input.
  2. Put the key in the first line to "Register", and remove that from the input.
  3. Obtain the data and offset from the function calls.
  4. Change the input to the key, and put the key to "Register" with caring the offset.
  5. Change the input to the data used in the function call, and apply "XOR".

This Recipe decodes the part between CreateObject( and ).Run.

Register, 9 more - CyberChef

結果は WScript.Shell となった。

行末のゴミを取り除く処理を追加した以下のRecipeは、Run の後の部分のデコードを行う。

The result was WScript.Shell.

This Recipe with a step to remove extra things in the end of lines added decoded the part after Run.

Register, 10 more - CyberChef

得られた結果にはBase64エンコードされているっぽい部分があったので、デコードを行った。
その結果は文字と . が交互になっていたので、UTF-16であると推測した。

The result had a part that looks like Base64-encoded, so I decoded that.
The result had . between each characters, so I guessed that the result is UTF-16.

From Base64, Decode text - CyberChef

結果はBase64エンコードされた文字列をデコードして解凍しているようだったので、同様の処理を行った。

The result looked like decoding a Base64-encoded string and expanding that, so I followed the process.

From Base64, Raw Inflate - CyberChef

この結果にflagが含まれていた。

The result contained the flag.

FLAG{w0w_7h3_3mb3dd3d_vb4_1n_w0rd_4u70m471c4lly_3x3cu73d_7h3_p0w3r5h3ll_5cr1p7}

WaniCTF 2021