【CyberDefenders】UnPackMe Lab【Walkthrough】

# はじめに
本記事は ___CyberDefenders___（以下リンク参考）の「__UnPackMe Lab__」にチャレンジした際のWalkthroughになります

https://cyberdefenders.org/blueteam-ctf-challenges/unpackme/

※本チャレンジについてはRed側のペネトレというよりはBlue側の分析力を問われるものになります。
※今回のチャレンジはMalware解析メインでしたね。

# チャレンジ開始前
## 問題について
以下の画像の「__Download Lab Files__」に問題ファイルのリンクがあります。
アーカイブファイルで圧縮されているので仮想環境で解凍してください。
※ホストで解凍しないでください。中には本物のマルウェアが入ってたりします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ed5c1bd0-3196-73f8-68aa-aa1fa42a3f61.png)

## 環境
この ___CyberDefenders___ を解く際には仮想環境でマルウェア解析やメモリフォレンジックを行う環境を用意する必要があります。
今回は以下のような環境を用意しました。
+ [remnux](https://remnux.org/)
+ Windows 10

今回はWindows 10の環境を利用しました。
主に`x64dbg`, `BinaryNinja`を利用しました。

# Q1
__Upon initiating your analysis of 'ShadowSteal,' understanding its obfuscation techniques is critical. One tell-tale sign is the file's entropy. Can you determine its value, which hints at whether the malware is packed?__
Malwareの基本的な構成や簡易なPacking技術を判断するためにDiEへ食わせます。

https://github.com/horsicq/Detect-It-Easy

![die.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/31b7a3bf-cbb2-5cad-d863-4a5008c45b34.png)
エントロピー高めなので難読化はしっかり入ってそう。
`4n4lDetector`にも食わせます。

https://github.com/4n0nym0us/4n4lDetector

![1-4N4L.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/a10c2156-1e03-c2c7-9fd8-80876c67d65a.png)
エントロピーはこれでわかります。pestudioとかでもわかるのでそっちでもいいですね。

## Unpacking
実際に難読化されてる内容を見に行きます。
バイナリをBinaryNinjaに食わせます。
![upack-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/1c209416-f784-495d-bc39-b9d5668fe781.png)
`.rsrc`セクションに難読化されてそうな文字列が見えます。packing技術は先ほどのToolではわかりませんでした。一応パッキングでRC4などを利用してるケースも考えて簡易的に`capa`も回します。

https://github.com/mandiant/capa

![capa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/85a24d01-095d-faa2-90af-34d8f3cf6079.png)
特段そういったこともなさそうですね。

もう動的に動かしてunpackします。とりあえず直ぐにreversingしたいならこういった手法が有効ですね。
`x64dbg`を起動します。とりあえず以下のBreakpointを打ちます。
![upack-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/6f2e4235-36c8-1e0e-d11a-cbb7a75663ae.png)

+ VirtualAlloc
+ VirtualProtect
+ WriteProcessMemory 

この辺りはmalwareが難読化解除したPayloadをメモリ上に展開するときよく利用するwinapiなので打っておいて損はないです。

+ CreateProcess
+ CreateProcessInternal

EvasionのためにPayloadをインジェクトするときによく使います。RemoteThreadに注入する際にはそのProcessに対してデバッカをアタッチしたいのでその前にBPで止めるようにします。

+ IsDebuggerPresent

アンチデバックのために使われるwinapiです。この関数の結果を改ざんするためにBP打っておきます。`ScyllaHide`とか入れておけばここら辺は省略してもいいかもですね。

https://github.com/x64dbg/ScyllaHide

それでは起動します。
![upack-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/71d4da79-4a75-09c3-fc17-677df96a7394.png)
VirtualAllocに引っかかりました。returnまで回します。
![upack-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/d6893979-3490-b2e9-a3c1-9669acaae4a5.png)
returnで帰ってきた(eaxレジスタ)のアドレスをfollow dumpしておきます。
![upack-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/5c0f7c11-0b5e-0521-034a-915b858b81f3.png)
メモリ確保しただけなのでnullですね。回してみます。
![upack-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/3b3a51f5-777c-91b5-ecbf-03113e6f84ea.png)
おそらくShellcodeでしょう。このタイミングで止まっているAdressはBPを打ったVirtualAllocなので再度returnで確保したメモリのアドレスを拾います。
![upack-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/0254c40c-d8b5-cd50-99bc-be6c163cc073.png)
Follow Dumpします。
![upack-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/25ea5f72-b0f7-5a9e-6f5c-70fd513878c5.png)
まぁ先ほどと同様ですね。回します。
![upack-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/80ad547a-97e3-f2a1-2e11-46165068fb60.png)
`4D 5A`が見えるのでPEファイルぽいことが確認できます。これが難読化解除後のMalware本体でしょう。
`021F0000`のアドレス領域をProcess Hackerからダンプします。まずは起動します。
![upack-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/37203c93-e830-ad96-35cd-c8684d10295f.png)
メモリを確認します。
![upack-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/d54175d0-d782-ccf8-508b-da2aae2e37df.png)
`RW`で書き込み可能なことが分かります。ここから`VirtualProtect`とかで実行可能にするんでしょうね。
この`021F0000`のメモリ領域をダンプしました。これでUnpacking成功です。

# Q2
__Before 'ShadowSteal' begins its data theft, it cleverly checks for a mutex to avoid duplicative data collection. This mutex includes a unique string combined with the computer's name. What is the hardcoded string that 'ShadowSteal' uses for this purpose?__
先ほどUnpackingしたバイナリをBinaryNinjaに食わせます。そうすればMutexをいじるwinapiを利用しているFunctionを確認できます。
![2-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/a47c1ecc-8b59-2ff8-3a1b-936699985e67.png)
感染していた端末かどうかの確認でよく使われますね。
`CreateMutexA`のapiを確認します。

https://learn.microsoft.com/ja-jp/windows/win32/api/synchapi/nf-synchapi-createmutexa

```c
HANDLE CreateMutexA(
  [in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
  [in]           BOOL                  bInitialOwner,
  [in, optional] LPCSTR                lpName
);
```
第3引数を求めるための`sub_4324c4`を解析出来れば答えが分かりそうです。
と言ってもこの関数の中身の解読は静的解析ではきつかったので動的解析を実施します。

適当に以下のようにBreakPointを打ちます。
![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/1b8dd13a-b6a1-3849-5b2e-8f29f3ecd31a.png)
`24c4`の関数実行直後まで回します。
![2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/53b874e0-e479-69fe-b761-465ca8806d71.png)
returnで帰ってきてますね。

ここら辺の関数のチェックが終わったので後々の解析のしやすさのために名前を適当につけておきます。
![2-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/9d4efd1e-d2f4-b21c-a64d-97eb917b580a.png)
この関数を呼び出している関数がMainぽかったのでそこも変更しておきます。
![2-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/d8a2efae-1d3e-1273-fd7c-1035dcb02123.png)

# Q3
__'ShadowSteal' employs base64 and RC4 algorithms to safeguard the stolen data and its communication with the control server. Dive into its code to find the RC4 encryption key. What is it?__
とりあえずBinary NinjaでCryptscan回しておきます。
![cryptscan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/4cc6816c-9664-4729-3a07-cef4b8f0b7fc.png)
なるほど、capaも回しておきます。
![capa2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/337f2e9e-69c5-0292-a5b6-0bdea87dd187.png)
難読化てんこ盛りぽい。難読化解除するときはここら辺のアルゴリズムを意識して読んでいくとサクサク読めることがあります。

Main関数を見ていると以下の不審な文字列が見えます。
![3-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/29de0ce9-ba85-b062-2582-72dd9dd33e8a.png)
まず初めの`\x11\xca\xb4\xdc\x9d\x8e\x9a\x8b\x80\xb2\xae\x8c\xab\xd7\x98\x94\xbc\x00`を解読する。
最初のビットを反転させ、そのバイトと各バイトをXORしているようにみえます。
まぁ、実際に動かしてみてどんな結果になるか確認してみる。適当に近場のAddressにBPを仕込んで`x64dbg`を起動する。
![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/79ef23c9-fece-b73d-f22f-4635f7ed8f63.png)
Follow Dumpした部分にそれっぽい文字列が出てきている。

こいつの復号化のコードも作成してみた。
```python
encrypted_data = bytearray(b"\x11\xca\xb4\xdc\x9d\x8e\x9a\x8b\x80\xb2\xae\x8c\xab\xd7\x98\x94\xbc\x00")
print(len(encrypted_data))

# 最初のバイトをビット反転
not_b0 = ~encrypted_data[0] & 0xFF  
print(hex(not_b0))

# 最初のバイトのビット反転結果で各バイトをXOR
decrypted_data = bytearray()
for byte in encrypted_data[:17]: 
    decrypted_data.append(byte ^ not_b0)


key = bytes(decrypted_data)
print("decrypt:", key)
```
回したら同じ文字列を確認できる。これが答えのKeyっぽい。
実際にこのKeyを使ってその下のBase64文字列をどう復号しているのか確認してみた。

___※この問題の解答欄はブラウザ経由だと正解を受けつけてくれないのでHTTPリクエストベースでBurpなど使い、インターセプトした後に解答を修正する必要があります。___

## C2 address
`47fc`辺りのアドレスの関数を回した後に復号結果が確認できる。ここら辺にRC4の関数があるようだ（再帰呼び出し多すぎて探るの面倒ｗ）
![3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/76473e8f-5b89-776f-bd70-19ce64b0cbd1.png)
ここへアクセスするようだ。この復号化の後に`WinHttp`周りのwinapiが呼び出されてるので飛ばしてみた。
![3-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/cd0f5fea-ac49-0492-529f-d31f64266336.png)
まぁもう応答しないですよね

# Q4
__In its data collection phase, 'ShadowSteal' compiles a report which, among other things, reveals its version to the attacker. This detail is crucial for our threat intelligence. What version of 'ShadowSteal' are you analyzing?__
Mutexの特徴的な単語で調べると以下の解析ブログが見つかります。

https://blogs.blackberry.com/ja/jp/2021/11/threat-thursday-raccoon-infostealer

ここにバージョンが載ってます。

# Q5
__Part of ShadowSteal's reconnaissance involves scanning for installed software, a task it accomplishes by querying a specific registry key. Identify the registry key it uses for this purpose.__
Binary Ninjaでそれっぽいレジストリが引っかかるようにString検索かけます。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/a9194966-5685-7dba-1136-e97560a9d678.png)
ありますね。

# Q6
__'ShadowSteal' captures a screenshot of the current operating window as part of its information-gathering process. Which function address is responsible for this action?__
それっぽい単語を先ほど同様にString検索かけます。
![6-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/1036d9fb-b34a-c5d3-af4d-fd5a8dfca527.png)
このデータを参照している関数を調べます。
![6-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c06a6fa3-0f93-d921-1f73-af3e4629ba7f.png)
これが正解ではないので、この関数の参照を調べます。
![6-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ee977531-d247-4009-d4e5-a7e35d3b9e99.png)
`GetDesktopWindow`や`SelectObject`があるのでこれっぽいですね。

# Q7
__Once 'ShadowSteal' has fulfilled its mission, it removes all traces of its existence from the infected system. What command does it execute to delete itself?__
`floss`を回すとそれっぽい値が出てきます。

https://github.com/mandiant/flare-floss

![floss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c6efcc26-da77-9489-9e51-8a31f993340a.png)

# Q8
__For a comprehensive threat analysis, knowing where 'ShadowSteal' originates from is key. This includes the full path to its build folder on the attacker's computer. Can you provide this path?__
適当にBinary Ninja眺めてると出てきます。
![8-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/34e3ed1b-e1fd-7420-f7ab-4f2f526c919b.png)
![8-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/52175df5-9fd7-08d1-4431-88e9c4456c47.png)
これっぽいですね。

# 最後に
`x64dbg`と`Binary Ninja`の動的解析と静的解析を行き来する、いいMalware解析問題でした。
本当はここからもっと詰めて解析していく形になるのですが、ここまでで問題は終了です。（この検体の関数多すぎ。）
Malware解析時間溶ける。