2020.10.30   セキュリティ脅威

Reflective DLL Injection で調べる不正コード

01. 概要

不正コードの攻撃者の攻撃方法は日々進化している。より安定的で正確な目標を攻撃するために多様な流布方法を利用し、セキュリティ機器、ソフトウェアの検知を避けるために様々な方法を利用して不正コードを隠している。その中でもファイルレス(Fileless)を利用した不正コードの隠し方は進化している。

今年、発見されたマグニバー(Megniber)ランサムウェアはインターネットエクスプローラーのプロセスにInjectionし(Fileless)、ユーザーのPCに不正コードを残さずにファイルを暗号化する行為をしていたと把握されている。
また、5月の全米北朝鮮委員会(NCNK)の「北朝鮮コロナ19状況インタービュー文書」をなりすましたDOC型の不正コードが発見されたが、これはWindows作業スケジューラを利用したファイルレス型であった。

このようにFileless方法を利用している不正コードが続々登場し、今後使用頻度が上がると想定される。攻撃には主にパワーシェル(Power Shell)スクリプトを難読化して利用したり、Process Hollowing, Reflective DLL Injection 等の方法を利用する。

今年6月22日、韓国の有名コミュニティから視力保護プログラムをなりすました不正コードが流布された。当該の不正コードは実行時、バックグラウンドにペイント(正常ファイル)プログラムを実行してる以外、異常行為は見えないファイルだった。しかし、詳細分析結果、ペイント(正常ファイル)に任意のDLLをReflective DLL Inejctionさせて不正行為の動きが確認できた。バックグラウンドから任意のC2にアクセスするログは残し続けるが、不正行為をするファイルは存在しないFileless不正コードだった。今回は実際に不正コードがどうやってReflective DLL Injection方法を使用しているか確認してみよう。

02. DLL InjectionとReflective DLL Injection

1) DLL Injection

DLL Injectionは実行中の他のプロセスをのスペースに強制にDLLをInjectionする方法を意味する

Reflective DLL Injection


「▲ DLL Injectionの過程 (参照:malwareforensics1.blogspot.com)」

1.OpenProcessを利用して当該のプロセスのハンドルを求める
2.VirtualAllocで当該のプロセスのメモリスペースを確保する
3.WriteProcessMemoryで当該のプロセスのメモリにInejctionするDLLのパスを入力
4.LoadLibary APIアドレスを求める(GetModuleHandle, GetProcAddress)
5.CreateRemoteThreadで当該のプロセスのInjectionされたデータを実行

比較的に簡単な方法でDLLをInjectionすることができるため、不正コードによく使用されていたが、CreateRemoteThreadで当該のプロセスにInjectionされたDLLを実行する際に入るIpStarAddress引数のせいで簡単に検知できるデメリットがある。IpStarAddress引数にはGetProcAddressを通じて取れたLoadLibary(もしくはGetProceAddress)APIのアドレスが入るが、これを検知するとDLL Injectionを防ぐことができる。

2) Reflective DLL Injection

Reflective DLL Injectionは既存のDLL Injection方法とは違って現在実行中のプロセスのメモリに任意のDLL対したデータを挿入後、直接マッピング(Mapping)して実行させる方法で動作する。このような動作方法は実際不正行為をしているDLLはバックグラウンドに存在せず、検知も難しい。このような特徴でファイルレス(Fileless)不正コードでよく使用されていて2017年話題になったSMB脆弱性エターナルブルー(Eternal Blue)とダブルパルサー(Double Pulsar)にも使用された。

1.OpenProcessを利用して当該のプロセスのハンドルを求める
2.VirtualAllocで当該のプロセスのメモリスペースを確保する
3.WriteProcessMemoryで当該のプロセスのメモリにInejctionするDLLのパスを入力
「Reflective Loader」 → メモリ実行権限付与(RWX)
 4.メモリにDLLマッピング(Mapping)
 5.Import Table新規作成
 6.再配置及びマッピングされたDLL動作準備完了
7.CreateRemoteThreadで当該のプロセスのInjectionされたデータを実行
Reflective DLL Injection


「▲ Reflective DLL Injectionの過程 (参照:giac.org)」

3) 違い

2つのInjection方法はDLLをどのような形でプロセスにInjectionするかによって違う。DLL Injectionは実行できるファイル(PE)をそのままプロセスにInjectionし、Reflective DLL Injectionの場合、Injection際、実行できるファイルを現在使用中のメモリに直接Injectionし、メモリからすぐ使用できるようにする作業まで行うことが違う。

区分DLL InjectionReflective DLL Injection
Injection‐方法InjectionしようとするDLLのパスを直接挿入InjectionしようとするDLLのパスを直接挿入後、メモリにマッピング(MAPPING)
Injection-実行スレッド(Thread)スレッド(Thread)
検知方法・レジストリ(Appinlt_DLLs)値チェック ・スレッド件数内部の引数値チェック・正常動作範囲以外のメモリスペースの権限をチェック (メモリにロードするために任意のメモリスペースにRWX権限を付与)

03. 不正コードで調べる Reflective DLL Injection の動作原理

分析に使用された不正コードの6月韓国のコミュニティの掲示板に視力保護プログラムのなりすまして流布された不正コードである。インストーラ(Installer)の形で流布されて実行時、正常に視力保護プログラムをダウンロードするが、バックグラウンドからはペイント(mspaint.exe)プロセスが実行されてC2アドレスにPCの情報を送信する動作をする。ペイントの場合System32内部にある正常プロセスを利用し、攻撃者は当該の攻撃のためにReflective DLL Injection方法を利用した。

1) 不正コードの全体構成 ー どこで使用されたのか

不正コードの全体概要図は下記になる。実行とともに不正DLL(wctE64E.tmp)がドロップされてすぐ削除されるように見える。しかし、バックグラウンドではペイント(mspaint.exe)が動作されてC&Cサーバと通信する。不正行為をしていると想定されるDLLファイルが消えたのが不正行為がプロセスに介して続いてる不思議な現象が確認できる。

区分内容
ファイル名wctE64E.tmp
MD519493F139D74950681354BB881113683
ファイルサイズ286.50KB (293,376 byte)
Reflective DLL Injection


「▲ 不正コードの概要図」

2) Reflective DLL Injection ー どうやって動作されるか

Reflective DLL Injectionは既存のDLL Injection方法とは違って現在実行中のプロセスのメモリに任意のDLL対したデータを挿入後、直接マッピング(Mapping)して実行させる方法で動作する。このような動作方法は実際不正行為をしているDLLはバックグラウンドに存在せず、検知も難しい。このような特徴でファイルレス(Fileless)不正コードでよく使用されていて2017年話題になったSMB脆弱性エターナルブルー(Eternal Blue)とダブルパルサー(Double Pulsar)にも使用された。

・メモリにデータを挿入するための事前作業

当該のプロセスには不正DLLをInjectionする対象としてmspaint.exe(ペイント)を利用した。

Reflective DLL Injection


「▲ mspaint.exeプロセスオープン」

現在実行中の不正DLLファイル(wctE64E.tmp)と同じパスで実行中の不正DLLと同じファイル作成を試すが、CreateFileWのdwShareMode引数が0x0に設定されていてデバッグの状態では正常にファイルが作成できないように設定されている(アンチでバック効果)。それを迂回すると正常にファイルが作成されるところが確認できる。

Reflective DLL Injection


「▲ 現在実行中の不正DLLファイルのハンドル収集」

・dwShareMode = 0が意味すること

dwShareModeの値が0の場合、他のプロセスが削除、読み取り、書き込みアクセスを要請する場合、ファイルまたはデバイスを開けないようにする。従って、不正DLLファイルを分析するために任意のLoaderにInjectionさせる場合、引数によって作成されるファイルのハンドルを正常に持ってくることができないため、それ以降の行為ができない。

正常に作成されたファイル(現在実行中の不正DLL)のサイズを確認後、ヒップ(Heap)を割り当する。正常にヒップを割り当した後、作成されたファイル(現在実行中の不正DLL)のデータを割り当てられたヒップにコピーする。

Reflective DLL Injection


「▲ 不正DLLのデータを使用するための過程①」

Reflective DLL Injection


「▲ メモリロード前(上)とロード後(下)」

mspaint.exeプロセスの内部に本格的に不正DLLをInjectionするために、作成(CreateProcess)していたプロセスをオープンする。

Reflective DLL Injection


「▲ mspaint.exeプロセスオープン」

本格的にReflective DLL Injectionするためにローダー関数であるiAppleCloud関数を呼び出す。当該の関数はImport Tableに宣言されている。関数の内部コードを調べてみよう。

Reflective DLL Injection


「Reflective DLL Injectionローダー関数(iAppleCloud)を呼び出す」

Reflective DLL Injection

| STEP1 ローダーに使用するデータ加工 |
|——————————————————————————————————————————————————————————————————————————————————————————————————————————–|
| Injectionのためにローダー(Loader)の機能が大事である。当該ローダーでは現在実行中の不正DLLが呼び出しているシステムDLL(ntdll.dll, kernel32.dll)の情報が必要とする。ローダーの機能のためにAPいが必要のためである。当該ローダーの関数ではWindows API Hashを利用して必要なシステムDLLとAPIを探してローダーに使用できる形に加工する。 |

Reflective DLL Injection

| STEP2 イメージロード |
|—————————————————————————————————————————————————————————————————-|
| ロードするPEのヘッダーを持ってきた後、不正DLLをメモリにロードするためにメモリを割り当てする。仮想メモリにロードされる際、実行できるImagebaseにローディングできるように再配置(Relocation)作業を行。 |

Reflective DLL Injection

| STEP3 イメージをロードするセクション確認 |
|————————————————————————|
| 任意のセクションにデータをロードするためにセクションエリアを探索する。 |

Reflective DLL Injection

| STEP4 Import Table再作成 |
|—————————————————————|
| ロードされた新しいイメージファイルを参照してIATを再作成する。 |

Reflective DLL Injection

| STEP5 プロセスイメージの再配置 |
|——————————————————————————————–|
| 全ての過程が終わったイメージが競合なく、メモリにロードできるように再配置(Relocation)する。 |

OpenProcessでオープンしたmspaint.exeの内部に0x47AAA(実行中の不正DLLのファイルサイズほど)ほど任意のスペースを割り当てする(割り当てされるスペースのアドレスは実行時異なる)

Reflective DLL Injection


【▲ mspaint.exeの内部に不正DLLをロードするための任意スペースの割り当て】

Reflective DLL Injection


【▲ mspaint.exe – 任意のスペースが割り当てられた】

WriteProcessMemoryを利用して総3回mspaint.exeの内部にデータを挿入する。

NOコピーされるデータ
1Heapスペースにロードされている現在実行中の不正DLL
2現在実行中の不正DLLの絶対パス
3スレッド実行時、初めてスタートする部分
Reflective DLL Injection


【▲ WriteProcessMemoryを利用してデータ挿入】

Reflective DLL Injection


【▲ 最初のWriteProcessMemoryを通じて挿入される内容】

Reflective DLL Injection


【▲ 2回目のWriteProcessMemoryを通じて挿入される内容】

Reflective DLL Injection


【▲ 3回目のWriteProcessMemoryを通じて挿入される内容】

mspaint.exeにReflective DLL Injectionされた不正DLLをCreateRemoteThreadで実行する。

Reflective DLL Injection


【▲ CreateRemoteThreadを利用してInjectionされたDLLのデータが実行される】

04. 参考資料

Reflective DLL Injection

Filelessの事例

Written by CYBERFORTRESS, INC.

サイバーフォートレス CYBERTHREATS TODAY 編集チーム

サイバーフォートレスは、サイバーセキュリティ対策を提供するセキュリティ専門企業です。

セキュリティ対策や、最新のセキュリティ脅威、サイバー攻撃のトレンドなど、当社が研究開発や情報収集した内容をもとに、最新のセキュリティ脅威・セキュリティ対策についてお伝えします。

関連記事

よく読まれている記事