【CyberDefenders】$tealer Lab【Walkthrough】

:::note info
これは[脆弱エンジニアの Advent Calendar 2024](https://qiita.com/advent-calendar/2024/full-weak-engineer)の12日目の記事です。
:::

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

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/8f0421cb-cb98-25ba-5aa7-acf33e37ae72.png)

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

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

# Q1
__The provided sample is fully unpacked. How many sections does the sample contain?__

Malwareの基本的な構成や簡易なPacking技術を判断するためにDiEへ食わせます。

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

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/0cd2b577-b950-e449-d335-81ecbc91cb5d.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ca78212e-70e2-a9a1-5040-1f8d004c2a5c.png)
エントロピー高めなので難読化はしっかり入ってそう。この結果からセクション数は判断できます。
`4n4lDetector`にも食わせます。

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

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/b6efe7f0-d421-4e7d-3b17-91f656b3a7e0.png)
追加情報はなさそうですね。

# Q2
__How many imported windows APIs are being used by the sample?__

pestuidoに食わせます。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/3c7f56df-89eb-5e26-e14d-e6b98e5e06d3.png)
これでわかりますね。

# Q3
__The sample is resolving the needed win APIs at run-time using API hashing. Looking at the DllEntryPoint, which function is responsible for resolving the wanted APIs?__

とりあえずどういった難読化をされているかを事前に把握できると楽なので`capa`に食わせます。

https://github.com/mandiant/capa

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/8167c2cc-f9b8-0467-8aa5-3fde94feee07.png)
RC4、XORが気になりますね。Heavens gateもあってアンチデバッグもありそう。
ここで静的解析を行うためBinary Ninjaに食わせます。エントリーポイントから見ていきます。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/38e9c8ee-5e51-eb6a-7cd7-24696ab1d5ec.png)
`sub_6015C0`にハッシュ化されたような文字列を渡しています。数回呼び出されてそうなのでここら辺がAPI Hashの関数なのかなと予測できます。

そのまま[hashdb_automated](https://github.com/Icaro-Cesar/RE_AutomationPythonScripts/blob/main/RE_Automation/HashDB/hashdb_automated.py)で調べてみます。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/17f9d4a6-e7e9-83b3-5a9c-be5f51f9cfcf.png)
別の`0xa8d05acb`の方もダメだったので、この値をそのまま使う感じではなさそう。


# Q4
__Looking inside the function described in question 3, which function is responsible for locating & retrieving the targetted module (DLL)?__

`sub_6015C0`の中身を見てみると`return`付近に以下のようなデコンパイル結果があります。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/e2ac76f9-c0f8-b533-b692-b52dcafa8d0f.png)
`sub_607564`が第一引数をもらってるのでおそらくそれがDLLの復号化、`sub_6067c8`がその結果を受けて第二引数を受けているのでAPIの復号化と予測できます。

`sub_607564`の中身を確認します。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/8524f037-6832-66bf-2675-0a19f2c6675f.png)
予測あってそうですね。

# Q5
__What type of hashing is being used for the API hashing technique?__

`sub_607564`の内部を調べていると`sub_61D620`の関数を見つけます。
中身を見ると以下のデコンパイル結果となります。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/0ac20a54-7166-88dc-af5f-0a71f508510b.png)
ぱっと見以下のような動作はCRC32の動作に似た挙動のように見えます。
```
eax_14 u>> 8 ^ var_420[zx.d(*(arg1 + (ecx_3 << 1)) ^ eax_14.b)]
```

# Q6
__What is the address of the function which performs the hashing?__

Q5を見つけたところですね。

# Q7
__What key is being used for XORing the hashed names?__

`sub_607564`の中に以下が見つかります。
先ほどの`sub_61D620`の結果`eax_7`にXORして第一引数と比較しています。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/1af435fa-dbbb-85ba-4d95-975f4217d17f.png)
この値がXORKeyと予想してAPI Hash解決できなかった`0xa8d05acb`を調べます。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/7f8f7cf0-9b58-d09d-4a5b-f79a40949fd3.png)
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/80cb2fc8-c531-54a7-0967-dbb5693bc43a.png)
あってそうですね！

## Auto Resolve API Hash
このままHashで難読化されたデコンパイル結果を眺めていても解析しにくいので、自動でAPI名を解決してコメントを残すBinary Ninjaのスクリプトを作成します。APIの名前解決は`edx`に`mov`でハッシュを渡しているのでそのオペランドから取ってきます。
```python:add_comment_1.py
import requests ,time, re
from binaryninja import *

def hash_lookup(offset):
    try:
        while True: 
            hunt_url = 'https://hashdb.openanalysis.net/hunt'
            hash_url = 'https://hashdb.openanalysis.net/hash'
            time.sleep(2)
            # Request the user to enter the hashing API values
            hashing_api_input = offset
            hashing_apis = [int(hash_value, 0) for hash_value in hashing_api_input.split(',')]
            for hashing_api in hashing_apis:
                # Create the payload for the hunt request
                hashdb_req = {"hashes": [hashing_api]}
                # Perform the hunt request
                hunt_req = requests.post(hunt_url, json=hashdb_req)
                # Check if there was a hit in the search
                hits = hunt_req.json()['hits']
                if hits:
                    # Extract the algorithm from the hit
                    algorithm = hits[0]['algorithm']
                    # Resolve the hash with the found algorithm
                    hash_resolve = requests.get(f"{hash_url}/{algorithm}/{hashing_api}")
                    # Extract DLL and API information
                    string_info = hash_resolve.json()['hashes'][0]['string']
                    dll_value = string_info['modules'][0]
                    api_value = string_info['api']
                    # Display the desired information
                    print(f"\nHashing Algorithm: {algorithm}")
                    print(f"DLL: {dll_value}")
                    print(f"API: {api_value}\n")
                    return api_value
                else:
                    print(f"\nNo match found for hash {hashing_api}")
                    return None
    except Exception as e: # 例外処理
        print(f"Error occurred: {e}")
        return None

def is_hex(text):
    pattern = r'^0x[0-9a-fA-F]+$'
    return bool(re.match(pattern, text))


def add_comment(bv, address, text):
    try:
        bv.get_functions_containing(address)[0].set_comment_at(address, text)
    except Exception as e:  # 例外処理
        print(f"Error occurred: {e}")
        return

def gather_offsets(bv, xref_address):
    new_address = xref_address
    # 指定されたアドレスが含まれている関数を取得
    functions = bv.get_functions_containing(xref_address)
    if not functions:
        print("Function not found at address:", hex(xref_address))
        return None
    while new_address >= new_address - 0x30: #大体ここくらいまで調べる。
        # 現在のアドレスにおける命令を取得
        instruction_length = bv.get_instruction_length(new_address)
        if instruction_length == 0:
            new_address -= 0x1
            continue
        # 現在の命令を取得（ディスアセンブリ）
        instruction_text = bv.get_disassembly(new_address)
        if "mov" in instruction_text and "edx" in instruction_text:  # "mov","edx"命令を探す
            operands = instruction_text.split()
            if len(operands) > 2:
                print(operands)
                # 3番目のオペランド
                if is_hex(str(operands[2])):
                    return operands[2]
                else:
                    pass
        new_address -= 0x1
    return None

def locate_xrefs(bv, function_address):
    xref_list = []
    func = bv.get_function_at(function_address)
    for xref in bv.get_code_refs(function_address):
        if xref.address not in xref_list:
            xref_list.append(xref.address)
    return xref_list

def main_fuc():
    func_addr = 0x006067c8
    xref_list = locate_xrefs(bv, func_addr) #呼び出し元
    print(xref_list)
    for xref in xref_list:
        offset = gather_offsets(bv, xref) #XOR前のoffset
        if offset and is_hex(str(offset)):
            offset = int(offset, 16)^0x38ba5c7b #XOR key
            print(hex(offset))
            decrypted_string = hash_lookup(str(offset))
            time.sleep(1)
            if decrypted_string:
                add_comment(bv, xref, decrypted_string)
        else:
            pass

main_fuc()
print("Done!")
```
これBinary Ninjaで回していきます。
![15-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/6b29d593-e8a5-7f68-ecd5-bab4972ffdd7.png)
終りました。コメントが残っているか確認します。
![15-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/bda4219b-e893-9d78-98d6-81aea02c3455.png)
イケてそう！このAPIはHeavens gateとかで使われてそう。
※`sub_6067c8`の関数は`APIfunc_Resolve`とか名前を適当につけてます。
※`sub_607564`は`Dll_resolve`とか（命名規則...）

# Q8
__What information is being accessed at the address 0X60769A?__
DllBaseの表記からすぐに判断できると思われる。それに関する名称を入れればいい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/f2ce2c68-5832-9605-27a7-2298131e4e78.png)

# Q9
__Looking inside the function described in question 3, which function is responsible for locating & retrieving the targetted API from the module export table?__
これはすでに予測出来てますね。

# Q10
__Diving inside the function described in question 8, what is being accessed at offset 0X3C within the first passed parameter?__
`0x3C`を見たら`e_lfanew`、`IMAGE_NT_HEADERS`への筋道というのを覚えておいて損はないです。
![スクリーンショット 2024-12-03 214043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/a57a7d6b-dca5-38c9-cff3-454d34511541.png)

# Q11
__Which windows API is being resolved at the address 0X5F9E47 ?__
Q7で見てますね。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/80cb2fc8-c531-54a7-0967-dbb5693bc43a.png)

# Q12
__Looking inside sub_607980, which DLL is being resolved?__
関数を見てみます。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/4209bf1b-99af-7f08-b752-eea3e51b324c.png)
`0x38ba5c7b`とXORした値をhashdb-cliで確認します。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/b7631951-f9e1-baa5-d0ac-acb6cdf393b2.png)

# Q13
__Also Looking inside sub_607980, which API is being resolved?__
先ほど回したScriptでコメントされてます。

# Q14
__What is the appropriate data type of the only argument at function sub_607D40?__
関数を見てみます。
![18-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/466f1225-b9f9-0872-26a6-83afb1da0dd0.png)
argがeaxで各HEX値と比較されてます。この値を調べてみるといいかもですね。
![18-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/bdafdb2c-7389-c830-c9a9-bc17fe2c119e.png)
例外コードっぽい。というわけで修正した結果の関数を以下に記す。
![18-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/6d1184e8-beba-3f1f-cc08-ad9b608cfe86.png)

# Q15
__After reverse-engineering sub_607980 and knowing its purpose, Which assembly instruction is being abused for further anti-analysis complication? (especially when running the sample)__

AntiDebugSeekerを使ってみる。

https://github.com/LAC-Japan/Ghidra_AntiDebugSeeker

![19-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/a1f90f9a-68fe-5666-3162-aa863576bcea.png)
![19-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/ae1ccf6d-8e86-068b-476d-e0095db62862.png)
対象の関数では見つからなかった。
というわけで直接見てみると、その関数から呼び出されてる`sub_607d40`で以下のディスアセンブル結果での命令を見つける。
![19-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/84b8382d-c665-2f2b-acb1-d610bb03dfe1.png)
末尾の`int3`これは有名かなと思う。以下の記事などを参考にしてみてほしい。

https://anti-debug.checkpoint.com/techniques/assembly.html

# Q16
__After reverse-engineering sub_607980 and knowing its purpose, Which assembly instruction is being used for altering the process execution flow? (Also adds anti-disassembly complication)__

見るだけ。

# Q17
__There are important encrypted strings in the .data section. Which encryption algorithm is being used for decryption?__

capaの結果から判断できる。

# Q18
__What is the address of the function that is responsible for strings decryption?__

Binary Ninjaの拡張機能を使う。
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/e5bcc08f-b1eb-9322-4c7c-dd25c07d090b.png)
この関数を確認しにいく。
![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c3b20cbf-02d6-55bc-a6ee-35794218f5bc.png)
とても長ったらしい関数なのですが内部を探っていると、とある関数`sub_61e5d0`が見つかります。
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/826183c8-9d38-476d-a58c-f741e1c8a172.png)
`0x100`ループ...見つけたぞRC4。

# Q19
__What are the two first decrypted words (strings) at 0X629BE8?__

先ほどの関数が呼び出しているXrefを適当に探ります。すると第二引数が`0x28`で安定して渡されており、おそらく鍵の長さ、Offsetであると推測できます。以下に変数名を変更した関数`sub_61e5d0`（RC4）を記します。
![23-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/0df8eee2-9d89-3506-66d3-3c867f294744.png)
問題で言われている箇所の前`0x28`バイト長がKeyと予想できます。完全にGUESSです。この`0x28`バイト以前は`0x00`のバイトで埋められてますしね。
![23-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/d64816c3-d73f-0a0f-2da4-2ec1b0c26209.png)
選択部分がKeyと予想できるので、これで復号を試してみます。
![23-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/4685e6b1-4967-8570-ee43-d5d045e589ea.png)
ダメだった。。。

適当にRC4関数の前の挙動を追っていると、気になる関数が２つ呼ばれているのが分かります。
以下は関数名変更後の表示ですが、大まかに何をやっているかわかるはずです。
![23-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c8587ee2-fdd1-8d3b-ed6f-cad89a02a5b4.png)
中身はこんな感じ。
![23-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/d3ab1762-be13-6e39-39e0-01940b70a6ac.png)
![23-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/161b1279-7730-7cbe-276e-598752f8ade8.png)
というわけで、鍵を反転させて、それで復号してみます。
![23-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/95f6b66a-47ec-83a5-6266-eada2778622b.png)
![23-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/bf0872fd-b585-1a47-e27e-f0220b1c6048.png)
復号出来ました！

# Q20
__What is the key used for decrypting the strings in question 16?__

keyは先ほどの問題が解けていれば解けるはず！

# Q21
__What is the length (in bytes) of the used key in question 16?__

`wininet`辺りのAPI関数が欲しかったのですが、以前回したPythonスクリプトでは全てのAPI関数を復号してコメントを残せているわけではないので、見つかりませんでした。
Wrap関数を用意してAPI復号関数`sub_6067C8`に渡してるパターンもあるからです。
というわけでwrapしてる関数`sub_6015c0`を探して、先ほどと同様にコメントを残すスクリプトを記述します。
```python:add_comment_2.py
import requests ,time, re
from binaryninja import *

def hash_lookup(offset):
    try:
        while True: 
            hunt_url = 'https://hashdb.openanalysis.net/hunt'
            hash_url = 'https://hashdb.openanalysis.net/hash'
            time.sleep(2)
            # Request the user to enter the hashing API values
            hashing_api_input = offset
            hashing_apis = [int(hash_value, 0) for hash_value in hashing_api_input.split(',')]
            for hashing_api in hashing_apis:
                # Create the payload for the hunt request
                hashdb_req = {"hashes": [hashing_api]}
                # Perform the hunt request
                hunt_req = requests.post(hunt_url, json=hashdb_req)
                # Check if there was a hit in the search
                hits = hunt_req.json()['hits']
                if hits:
                    # Extract the algorithm from the hit
                    algorithm = hits[0]['algorithm']
                    # Resolve the hash with the found algorithm
                    hash_resolve = requests.get(f"{hash_url}/{algorithm}/{hashing_api}")
                    # Extract DLL and API information
                    string_info = hash_resolve.json()['hashes'][0]['string']
                    dll_value = string_info['modules'][0]
                    api_value = string_info['api']
                    # Display the desired information
                    print(f"\nHashing Algorithm: {algorithm}")
                    print(f"DLL: {dll_value}")
                    print(f"API: {api_value}\n")
                    return api_value
                else:
                    print(f"\nNo match found for hash {hashing_api}")
                    return None
    except Exception as e: # 例外処理
        print(f"Error occurred: {e}")
        return None

def is_hex(text):
    pattern = r'^0x[0-9a-fA-F]+$'
    return bool(re.match(pattern, text))


def add_comment(bv, address, text):
    try:
        bv.get_functions_containing(address)[0].set_comment_at(address, text)
    except Exception as e:  # 例外処理
        print(f"Error occurred: {e}")
        return

def gather_offsets(bv, xref_address):
    new_address = xref_address
    # 指定されたアドレスが含まれている関数を取得
    functions = bv.get_functions_containing(xref_address)
    if not functions:
        print("Function not found at address:", hex(xref_address))
        return None
    count = 0
    while new_address >= new_address - 0x30: #大体ここまで調べる。
        # 現在のアドレスにおける命令を取得
        instruction_length = bv.get_instruction_length(new_address)
        if instruction_length == 0:
            new_address -= 0x1
            continue  
        # 現在の命令を取得（ディスアセンブリ）
        instruction_text = bv.get_disassembly(new_address)
        if "push" in instruction_text:  # 2つめの"push"命令を探す
            operands = instruction_text.split()
            if len(operands) > 1:
                print(operands)
                if is_hex(str(operands[1])) and count == 1:
                    return operands[1]
                elif is_hex(str(operands[1])) and count == 0:
                    count += 1
                else:
                    pass
        new_address -= 0x1
    return None

def locate_xrefs(bv, function_address):
    xref_list = []
    func = bv.get_function_at(function_address)
    for xref in bv.get_code_refs(function_address):
        if xref.address not in xref_list:
            xref_list.append(xref.address)
    return xref_list

def main_fuc():
    func_addr = 0x006015c0
    xref_list = locate_xrefs(bv, func_addr) #呼び出し元
    print(xref_list)
    for xref in xref_list:
        offset = gather_offsets(bv, xref) #XOR前のoffset
        if offset and is_hex(str(offset)):
            offset = int(offset, 16)^0x38ba5c7b #XOR key
            print(hex(offset))
            decrypted_string = hash_lookup(str(offset))
            time.sleep(1)
            if decrypted_string:
                add_comment(bv, xref, decrypted_string)
        else:
            pass

main_fuc()
print("Done!")
```
APIのハッシュはDLLのハッシュの前にStackにPushされているので、2つ目の`push`命令を探してます。

このスクリプトを回して以下の出力を確認しました。
![24-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/c4fc9c2e-ff20-c623-4a28-2c951a25a39c.png)
おー、使ってそうですね。
![24-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/46db8ceb-8163-6821-21ff-53b5c67e1019.png)
ここらの関数に`wininet`のAPI関数が終結してます。

# Q23
__What is the first C&C IP address in the embedded configuration?__

`InternetConnectW`APIの第二引数辺りを確認すればアドレスが見えるはずです。

https://learn.microsoft.com/ja-jp/windows/win32/api/wininet/nf-wininet-internetconnectw

![25-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/9c21977a-34f8-f151-46f2-a9ea967dd30b.png)
![25-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/3650df1d-c4bf-c382-ae38-6f2026d00b10.png)
このAPIが使われている部分を確認します。
![25-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/d87545e5-1008-8f7a-8c3b-9d87896511ce.png)
色々追っていたのですが以下のdata構造の中にC2アドレスが難読化されてそうです。
と言ってもわけわからな過ぎた。。。
![25-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/31311b1b-47b2-387f-6cf5-223fb0af658f.png)
わけがわからなかったので先人の知恵を借ります。Reversingなので自力で難読化解除したかったのですが、脅威インテル利用します。

HashをVTに投げます。
![25-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/7c845797-eeb0-8d2c-5f2b-1024b29026e9.png)
Dridexマルウェアぽいですね。こいつを調べてみると、以下のブログにヒットします。

https://www.appgate.com/blog/reverse-engineering-dridex-and-automating-ioc-extraction

ここにいいToolの情報が記載されています。

https://github.com/appgate/labs/tree/master/dridex/toolkit

これでDridexマルウェアのコンフィグを抽出します。
![25-8 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/577fd6e2-9000-a5f1-c1d0-9428113515d9.png)
大体見えましたね。ありがとう。

# Q24
__What is the port associated with the first C&C IP address?__

先ほどのToolで見えます。

# Q25
__How many C&C IP addresses are in the sample configuration?__

先ほどのToolで見えます。

# Q26
__What is the address of the function which downloads additional modules to extend the malware functionality?__

`HttpSendRequestW`のAPIを呼び出している以下の関数が怪しいですね。
![25-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2036848/77ca85de-4918-69cd-41ee-2c8358dfaa49.png)

# 最後に
最初動的解析が一切できずに鬼ムズで静的解析に挑んでました。見てみるとアンチデバッグもりもりだったのでそりゃそうかともなりました。
BinaryNinjaのいい練習になったと思います。
Malware解析時間溶ける。16進数がこびり付く。