Practical Malware Analysis (以後、PMA) Lab17-02.dll の詳細解析のメモ。
Lab 17-2 はアンチ・デバッグに焦点が当てられていたが、Lab17-02.dllには他にも多様な機能が実装されており、これらの機能の解析は読者への宿題として詳しくは触れられなかった。
PMAによると以下の機能を擁しているとのこと。
This malware is an extensive backdoor with considerable functionality, including keylogging, capturing audio and video, transferring files, acting as a proxy, retrieving system information, using a reverse command shell, injecting DLLs, and downloading and launching commands.
Lab17-02.dllの詳細な解析を試みてみた。
※自分は本職のマルウェア解析者ではないので、解析内容の正確性については留意されたし。
解析対象のファイルは以下の通り。
ファイル名 | ファイルの種類 | MD5ハッシュ値 |
Lab17-02.dll | 32ビット DLL | D98B63A319AD92B6C3A8347ADE5A351A |
解析に当たり、既知のアンチ・デバッグのコードは予めNOPした。(アンチ・デバッグについては後述する)
サマリ
Lab17-02.dllはXdoorバックドアまたはその亜種と思われる。
ファイルのメタデータにXdoorという文字列が散見された。
ファイルのInternalNameがX-doorc
となっている。
ファイルにxdoors_d
というセクション名が存在している。
解析の結果、以下の機能を有していることが判明した。
- 任意のプロセスへのDLLインジェクション
- インストール先のシステム情報の収集
- 実行中のプロセス情報の収集
- HTTPやFTPを用いてのファイルのダウンロード及び実行
- コマンドシェルの提供
- リモートデスクトップの提供
- スクリーンショットの撮影
- マウスおよびキーボードの操作
- 任意のプロセスの実行
- ファイルシステムの操作
- レジストリの操作
- ビデオの録画
- 音声の録音
- 様々なカスタムDLLのロード及び実行。ロードされるDLLはDDOS攻撃を行うと推測されるもの、プロキシ化のモジュールと推測されるもの、キーロギングを行うと推測されるものなど、多岐に渡る。
Lab17-02.dllはWindowsサービスに自身をサービスDLLとして登録することで永続化を図る。
このマルウェアはバックドア・コマンドや各種メッセージなどが英語で記述されているのだが、文法や綴りの誤りが散見された (自分も人のことは言えないが) ことから、開発者は英語のネイティブ話者ではないことが推測できる。
エクスポート関数の解析
Lab17-02.dllには以下のエクスポート関数が実装されている。
- InstallRT
- InstallSA
- InstallSB
- PSLIST
- ServiceMain
- StartEXS
- UninstallRT
- UninstallSA
- UninstallSB
InstallRT
マルウェア (Lab17-02.dll
) をシステム・ディレクトリにコピーし、任意のプロセス (デフォルトではiexplore.exe
)に対してLab17-02.dll
をインジェクトする。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,InstallRT <target process name>
InstallSA
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost
で定義されているWindowsサービスにマルウェアをサービスDLLとしてインストールすることができる。ただし、使用するWindowsサービスがすでにシステムに存在する場合はインストール出来ない。デフォルトではIrmon
サービスが使用される。サービスの作成が完了すると、サービスの起動時にマルウェアがsvchost.exeに読み込まれることになる。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,InstallSA <service name> <description>
サービス名に加えてdescription (サービスの説明文)を指定することが出来る。
InstallSB
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost
で定義されている既存のWindowsサービス (デフォルトではNtmsSvc
サービス) のサービスDLLをマルウェアに置き換える。乗っ取られたWindowsサービスが起動すると、正規のサービスDLLではなく、マルウェアDLLがsvchost.exeに読み込まれることになる。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,InstallSB <service name>
既存のWindowsサービスを乗っ取るに当たり、正規のサービスDLLのバックアップを作成する。例えば、TermService
を乗っ取る場合、正規のサービスDLL C:\Windows\system32\termsrv.dll
をC:\Windows\system32\termsrv.dll.obak
としてコピーしておく。
続いてマルウェアDLL (Lab17-02.dll)を正規のサービスDLLと置き換える。上記のTermService
の例だと、C:\Windows\system32\termsrv.dll
とC:\Windows\system32\dllcache\termsrv.dll
が(ファイル名はtermsrv.dll
のまま) Lab17-02.dllに差し替えられる。
また、サービス本来のServiceMain関数をServiceMainbak
としてバックアップした上で、ServiceMain関数をマルウェアのものと置き換える。
さらにマルウェアDLL (Lab17-02.dll) のコピーが_ox.dll
としてシステム・ディレクトリに作成される。
サービスの乗っ取りが完了すると、サービスを起動してマルウェアDLLをsvchost.exeに読み込ませる。
加えて、svchost.exeが読み込んでいるモジュールを列挙して_ox.dll
がロードされているか確認し、ロードされていなければ改めてsvchost.exeに_ox.dll
をインジェクトする。
乗っ取り対象のWindowsサービスのHKLM\SYSTEM\CurrentControlSet\Services\<service name>\Parameters
レジストリキーにServiceMainbak
というエントリが存在していたり、_ox.dll
という名前のサービスDLLが存在する場合は、システムはすでに感染済みと判断し、乗っ取りを中断する。
PSLIST
引数に渡されたプロセスのプロセスID、プロセス名、スレッド数をxinstall.dll
に書き込み、さらに結果をサーバーに送信する。引数なしで実行された場合は実行中の全てのプロセスのプロセスID、プロセス名、スレッド数をxinstall.dll
に書き込む。ただし、この場合は結果はサーバーに送信されない。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,PSLIST <process name>
試しにrundll32.exe Lab17-02.dll,PSLIST notepad.exe
というコマンドを実行したところ、以下がxinstall.dll
に書き込まれた。
ServiceMain
この関数はServiceMainに相当する。
StartEXS
引数として受け取ったサーバーのIPアドレスに対してネットワーク通信を行い、サーバーから送られたコマンドを実行する。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。引数にIPアドレスとポート番号を指定する。IPアドレスとポート番号はコロンで区切られていなければならない。
rundll32.exe Lab17-02.dll,StartEXS <IPv4 address>:<port number>
サーバーから受け取るコマンドは以下の通り。
Command in hex | Command in Ascii | Address of subroutine | Description |
0x4F | O | 0x10007BAF | スクリーンショットを撮り、サーバーに送信する。 |
0x50 | P | 0x100078AC | スクリーンショットを撮り、圧縮した後、サーバーに送信する。 |
0x5E | ^ | 0x100076D5 | サーバーからのレスポンスに応じてマウスまたはキーボードの操作を行う。詳細は後述。 |
0x5F | _ | 0x10007D35 | ディスプレイ画面を再描画する。 |
上記のうち、^
コマンドについて、もう少し詳しく解説する。
マルウェアは^
というコマンドをサーバーから受信すると、更なるコマンドをソケットから読み込み、受信したコマンドに応じてマウスやキーボードを操作する。
以下はサーバーからの受信データを元にマルウェアが処理を実行する際のswitch文のコードである。
受信データから0x52減算した時の差が14 (0x0E)以下だった場合、受信したコマンドに応じた処理を行う。
有効なコマンドは以下の通り。
Command in hex | Command in Ascii | Address of event | Description |
0x52 | R | 0x10007711 | マウスの左ボタンを押す。 |
0x53 | S | 0x10007723 | マウスの左ボタンを離す。 |
0x54 | T | 0x10007735 | マウスの右ボタンを押す。 |
0x55 | U | 0x10007747 | マウスの右ボタンを離す。 |
0x56 | V | 0x10007759 | マウスの真ん中のボタンを押す。 |
0x57 | W | 0x1000776B | マウスの真ん中のボタンを離す。 |
0x58 | X | 0x1000777D | マウスの左ボタンを押して離す。 |
0x59 | Y | 0x100077B1 | マウスの右ボタンを押して離す。 |
0x60 | Z | 0x100077E5 | マウスの真ん中のボタンを押して離す。 |
0x5B | [ | 0x10007826 | マウスを移動する。 |
0x5C | \ | 0x10007857 | キーを押す。どのキーを押すのかは不明。 |
0x5D | ] | 0x1000785C | キーを離す。どのキーを離すのかは不明。 |
0x5F | _ | 0x1000783B | Window Stationsを呼び出し元のプロセスに割り当てる。これによりマルウェア・プロセスがデスクトップやクリップボードにアクセスできるようになる。 |
UninstallRT
プロセス・インジェクションの解除を行う。
この関数は引数としてプロセス名を受け取る。指定されたプロセス名にマルウェア (Lab17-02.dll
) がインジェクトされていた場合は、これを解除する。
関数を引数なしで実行した場合は、デフォルトでiexplore.exe
からマルウェアDLLを解除する。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,UninstallRT <target process>
試しに引数なしで関数を実行してみた。
rundll32.exe Lab17-02.dll,UninstallRT
すると、xinstall.log
に以下のログが書き込まれた。
[04/02/22 10:50:18]
The PID Of Process 'iexplore.exe' is '0'
Process 'iexplore.exe' Not Found,Uninject Failed
上記のログより、iexplore.exe
へのDLLインジェクションの解除を試みたものの、iexplore.exe
が実行されていなかったため、失敗したことが伺える。
続いて、引数にsvchost.exe
を指定して関数を実行してみた。
rundll32.exe Lab17-02.dll,UninstallRT svchost.exe
すると、xinstall.log
に以下のログが書き込まれた。
[04/02/22 10:55:31]
The PID Of Process 'svchost.exe' is '568'
Uninject 'Lab17-02.dll' From Process 'svchost.exe' Failed
上記のログより、svchost.exe
(プロセスID: 568)からLab17-02.dll
を排除しようとしたものの、失敗したことが伺える。失敗の理由は、該当のsvchost.exe
はLab17-02.dll
をロードしていなかったため。
UninstallSA
マルウェアDLLの永続化用のWindowsサービスをアンインストールする。
この関数は引数として受け取ったWindowsサービスをアンインストールする。関数を引数なしで実行した場合は、デフォルトでIrmon
というWindowsサービスをアンインストールする。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,UninstallSA <service name>
試しに引数なしで関数を実行してみた。
rundll32.exe Lab17-02.dll,UninstallSA
すると、xinstall.log
に以下のログが書き込まれた。
[04/03/22 09:11:34]
OpenService(Irmon) error 1060
Irmon
というサービスを開こうとしたことが伺える。しかし、該当のサービスがインストールされていなかったため、エラーとなった。
続いて、引数にNtmssvc
というサービス名を指定して実行してみた。(事前にInstallSA関数を実行して該当サービスをインストール済み)
rundll32.exe Lab17-02.dll,UninstallSA Ntmssvc
すると、xinstall.log
に以下のログが書き込まれた。
[04/03/22 09:22:10]
DeleteService(Ntmssvc) SUCCESS.
Ntmssvc
サービスを削除したことが伺える。servicesレジストリキーを確認したところ、確かにNtmssvc
サービスが削除されていた。
UninstallSB
マルウェアDLLによって乗っ取られたWindowsサービスを元に戻す。
この関数は引数として受け取ったWindowsサービスの復元を行う。具体的にはサービスDLLをマルウェアDLLから正規のDLLに戻し、ServiceMain関数もマルウェアのものから正規のものに戻す。関数を引数なしで実行した場合は、デフォルトでNtmsSvc
というWindowsサービスの復元を試みる。
以下はrundll32.exeを使ってエクスポート関数を実行する際のコマンドの例。
rundll32.exe Lab17-02.dll,UninstallSB <service name>
試しに引数なしで関数を実行してみた。
rundll32.exe Lab17-02.dll,UninstallSB
すると、xinstall.log
に以下のログが書き込まれた。
[04/03/22 09:43:00]
MyStopService() -> OpenService() Error.
RegOpenKeyEx(NtmsSvc) KEY_SET_VALUE error 2.
NtmsSvc
というサービスを開こうとしたことが伺える。しかし、該当のサービスがインストールされていなかったため、エラーとなった。
続いて、引数にTermService
というサービス名を指定して実行してみた。(事前にInstallSA関数やInstallSB関数を実行してTermService
サービスにマルウェアDLLをインストールしようとしたが失敗した。)
すると、xinstall.log
に以下のログが書き込まれた。
[04/03/22 09:47:45]
StopService 'TermService' Successfully
StartService 'TermService' Successfully
Service 'TermService' Do Not Need UnInstall.
TermService
サービスを再起動し、TermServiceサービスのアンインストールは不要と判断したことが伺える。これは先述した通り、自分の解析環境ではTermService
サービスの乗っ取りに失敗したため。
もしサービスが乗っ取られていた場合は、サービスDLLをマルウェアDLLから正規のDLLに戻し (正規のDLLは.obakという拡張子を付け足されてバックアップされている)、ServiceMain関数もマルウェアのものから正規のものに戻される (正規の関数はHKLM\SYSTEM\CurrentControlSet\Services\<service name>\Parameters
レジストリキーのServiceMainbak
というエントリーにバックアップされている)。
また、_ox.dll
という名前のサービスDLLを見つけた場合も、正規のサービスDLLに差し替える。
DllEntryPointの解析
DllEntryPoint (0x1001516D)は、このマルウェアDLLのmain関数であり、プロセスがDLLをロードすると自動的に実行される。
サーバーから以下のコマンドを受け取って実行する。
Command | Address of subroutine | Description |
sethostinfo | 0x10004BCD | レジストリキーHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion にHostInfo というエントリを作成する。HostInfo に設定する値はサーバーから送られる。値の型はstring型。 |
delhostinfo | 0x10004C23 | レジストリキーHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion からHostInfo というエントリを削除する。 |
setgroupinfo | 0x10004C66 | レジストリキーHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion にGroupInfo というエントリを作成する。GroupInfo に設定する値はサーバーから送られる。値の型はstring型。 |
delgroupinfo | 0x10004CBC | レジストリキーHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion からGroupInfo というエントリを削除する。 |
exen | 0x10004A03 | 任意のアプリケーション・プロセスを生成する。生成するプロセス名はサーバーから送られる。 |
exeh | 0x10004A03 | 任意のアプリケーション・プロセスを生成する。生成するプロセス名はサーバーから送られる。 |
urln | 0x10004B01 | Internet Explorer (iexplore.exe ) を起動する。この際、サーバーから指定された任意の引数をiexplore.exe に渡すことが出来る。 |
urlh | 0x10004B01 | Internet Explorer (iexplore.exe ) を起動する。この際、サーバーから指定された任意の引数をiexplore.exe に渡すことが出来る。 |
suspendx | 0x1000F6B9 | マルウェアを実行しているスレッドを停止する。 |
uninstall+reboot | 0x1000F6DA, 0x10003B75 | マルウェアの永続化用のサービスをアンインストールし、システムを再起動するものと思われる。詳細は後述。 |
uninstall | 0x1000F6DA | マルウェアの永続化用のサービスをアンインストールする。 |
startxcmd | 0x10010740 | サーバーに対してシェルを提供する。詳細は後述。 |
startxscreen | 0x1000834E | リモートデスクトップ・セッションを開始する。詳細は後述。 |
startxfile | 0x10009933 | ファイルシステムを操作する。詳細は後述。 |
startxreg | 0x1000A318 | レジストリを操作する。詳細は後述。 |
startxvideo | 0x1000ACE6 | ビデオ録画を開始する。フォーマットはMPEG-4またはDivX。 |
startxsound | 0x1000B6D8 | 音声の録音を開始する。 |
startxprocess | 0x10006EE1 | プロセスを操作する。詳細は後述。 |
startxservices | 0x1000C251 | Windowsサービスを操作する。詳細は後述。 |
message | 0x10004738 | システムのシャットダウンや再起動を行うものと思われるが実際の挙動は不明。詳細は後述。 |
fgets | 0x1000399A | HTTPまたはFTPを使用してサーバーから任意のファイルをダウンロードし、実行する。 |
reboot | 0x10003B75 | システムを再起動すると思われるが実際の挙動は不明。詳細は後述。 |
shutdown | 0x10003B75 | システムをシャットダウンすると思われるが実際の挙動は不明。詳細は後述。 |
logoff | 0x10003B75 | システムからログオフすると思われるが実際の挙動は不明。詳細は後述。 |
update | 0x100042DB | 既存のマルウェアDLLを新しいものにアップデートする。 |
plug_sys | 0x10001E88, 0x10001F14 | xsys.dll というDLLをロードしてPlug_Sys_Main という関数を呼び出す。 |
plug_dev | 0x10001EB9, 0x10001F14 | xdev.dll というDLLをロードしてPlug_Dev_Main という関数を呼び出す。 |
plug_acq | 0x10001EEA, 0x10001F14 | xacq.dll というDLLをロードしてPlug_Acq_Main という関数を呼び出す。 |
plug_flood | 0x10001F3E, 0x1000202D | xflood.dll というDLLをロードしてPluG_Flood_Main という関数を呼び出す。DDOS攻撃を行うためのモジュールか? |
plug_stopflood | 0x10001FA0 | Plug_Flood_StopMain という関数を呼び出す。 |
plug_proxy | 0x10001FCC, 0x1000202D | xproxy.dll というDLLをロードしてPlug_Proxy_Main という関数を呼び出す。プロキシ化のためのモジュールか? |
plug_keylog | 0x10002005, 0x1000202D | xkey.dll というDLLをロードしてPlug_KeyLog_Main という関数を呼び出す。キーロガーのモジュールか? |
上記のうち、いくつかのコマンドの詳細を以下に記す。
uninstall+reboot
マルウェアの永続化用のサービスをアンインストールし、システムを再起動するものと思われる。ただし、このコマンドはマルウェア・サービスのアンインストール後にExitWindowsExを呼び出してシステムを操作するのだが、uFlagsの値がMSDNに記載されている値と一致しないため、実際にシステムを再起動するのかは不明。
startxcmd
サーバーに対してシェルを提供する。
以下のコマンドを受け取り実行する。実行結果はサーバーに送信される。
Command | Address of command | Description |
quit | 0x100102C7 | シェルを終了する。 |
exit | 0x100102E5 | シェルを終了する。 |
cd | 0x10010302 | カレント・ディレクトリを変更する。 |
enmagic | 0x10010381 | システムが起動してからの経過時間をHEX形式で送信する。 |
idle | 0x100103DC | システムが最後に操作されてからの経過時間を取得して送信する。 |
uptime | 0x10010404 | システムが起動してからの経過時間を取得して送信する。 |
language | 0x10010428 | システムの言語設定を取得して送信する。 |
robotwork | 0x1001044C | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WorkTime と HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WorkTimes というレジストリ・エントリーの値を読み出して送信する。 |
mbase | 0x10010470 | マルウェアDLLにハードコードされているサーバーのホスト名、ドメイン名 (newsnews.practicalmalwareanalysis.com )、ポート番号 (80番ポート)などの情報をサーバーに送信する。 |
mhost | 0x10010497 | Masthost に関する設定情報をサーバーに送信する。Masthost が何を表しているのかは不明。 |
mmodule | 0x100104BE | カレント・プロセスにロードされているモジュール名を取得して送信する。 |
minstall | 0x100104E5 | マルウェアのインストール形式を取得して送信する。InstallSA、InstallSB、InstallRSB、InstallPE、InstallRTのいずれのインストール形式が利用されたのか判別する。InstallSA、InstallSB、InstallRTの詳細は別項を参照。InstallRSBとInstallPEの詳細は不明。 |
inject | 0x1001050C | iexplore.exe または任意のプロセスに対してプロセス・インジェクションを行う。 |
サーバーからのレスポンスが上記のコマンドのいずれとも一致しなかった場合、サーバーから送られたデータをCreateProcessAで実行しようとする。
startxscreen
リモートデスクトップ・セッションを開始する。またサーバーから以下のコマンドを受け取って実行する。これらのコマンドはStartEXS関数で実行されるコマンドと同一である。
Command in hex | Command in Ascii | Address of subroutine | Description |
0x4F | O | 0x10007BAF | スクリーンショットを撮り、サーバーに送信する。 |
0x50 | P | 0x100078AC | スクリーンショットを撮り、圧縮した後、サーバーに送信する。 |
0x5E | ^ | 0x100076D5 | サーバーからのレスポンスに応じてマウスまたはキーボードの操作を行う。詳細はStartEXSの項を参照。 |
0x5F | _ | 0x10007D35 | ディスプレイ画面を再描画する。 |
startxfile
サーバーから受け取ったコマンドに応じてファイルシステムを操作する。
Command in hex | Address of subroutine | Description |
0x16 | 0x100087A2 | ドライブの種類、ボリュームやファイルシステムの情報、ディスクの空き容量を取得してサーバーに送信する。 |
0x17 | 0x1000894E | サーバーから指定されたファイルやディレクトリを列挙してサーバーに送信する。 |
0x1F, 0x25~0x28, 0x30 | 0x10008FC2 | サーバーから指定されたファイルを実行する。 |
0x19 | 0x10008AEE | サーバーから指定されたファイルに対して書き込みを行う。サーバーから書き込み用のデータが送られなかったり、ファイルの書き込みに失敗した場合はファイルを削除する。 |
0x18 | 0x10008BEF | サーバーから指定されたファイルの属性、タイムスタンプ、サイズなどのメタデータおよびファイルの中身をサーバーに送信する。 |
0x1A | 0x10008F62 | サーバーから指定されたディレクトリを作成する。 |
0x1D | 0x10009309 | サーバーから指定されたファイルまたはディレクトリを削除する。ディレクトリを指定された場合は、該当ディレクトリ以下の全てのファイルとサブディレクトリを削除する。 |
0x20 | 0x100093B6 | サーバーから指定されたファイルをコピーする。 |
0x1E, 0x21 | 0x1000941D | サーバーから指定されたファイルまたはディレクトリを移動する。 |
0x29 | 0x100095CC | ディレクトリを列挙してサーバーに送信する。ディレクトリのみを送信の対象としており、ファイルの情報は送信しない。またSystem Volume Information フォルダは無視する。 |
0x2A | 0x10009668 | 利用可能なドライブの一覧を取得し、各ドライブのファイルやディレクトリの一覧を送信する。 |
0x24 | 0x10008EE8 | ディレクトリを列挙してサーバーに送信する。ディレクトリのみを送信の対象としており、ファイルの情報は送信しない。サブルーチン0x100095CCとは異なり、System Volume Information は無視されない。またディレクトリ情報の送信後、1234567890 という文字列をサーバーに送信する。 |
0x2B | 0x100097A9 | サーバーから指定されたファイルまたはディレクトリを検索する。 |
0x2D | 0x1000981A | サーバーから指定されたファイルのタイムスタンプを取得する。 |
0x2E | 0x100098A9 | サーバーから指定されたファイルにタイムスタンプを設定する。 |
startxreg
サーバーから受け取ったコマンドに応じてレジストリを操作する。
Command in hex | Address of subroutine | Description |
0x0F | 0x10009F73 | サーバーから指定されたレジストリキーを開く、または作成する。 |
0x10 | 0x1000A01F | サーバーから指定されたレジストリキーを削除する。 |
0x11 | 0x1000A18D | サーバーから指定されたレジストリキーに値を設定する。 |
0x12 | 0x1000A0BA | サーバーから指定されたレジストリキーから値を取得する。 |
0x15 | 0x10009B92 | サーバーから指定されたレジストリキーから値を列挙したり取得したりする。 |
0x14 | 0x10009DEA | サーバーから指定されたレジストリキーのサブキーを列挙する。 |
0x13 | 0x1000A268 | サーバーから指定されたレジストリキーから値を削除する。 |
startxprocess
サーバーから受け取ったコマンドに応じてプロセスを操作する。
Command in hex | Address of subroutine | Description |
0xB4 | 0x100062E9 | カレント・プロセスにロードされているモジュール (DLLやEXE)を列挙する。 |
0xB5 | 0x100069E1 | サーバーから指定されたプロセスを終了する。 |
0xB6 | 0x1000692A | サーバーから指定されたプロセスにロードされているモジュールを列挙する。 |
0xBA | 0x10006AB5 | サーバーから指定されたプロセスに対して任意のプライオリティ・クラスを設定する。 |
0xB8 | 0x10006BD5 | サーバーから指定されたプロセスのスレッドを停止する。 |
0xB9 | 0x10006CA7 | サーバーから指定されたプロセスのスレッドを再開する。 |
0xB7 | 0x10006D79 | システムのプロセッサの数、起動時刻や現在時刻、物理メモリ及び仮想メモリの使用状況等を取得する。 |
startxservices
サーバーから受け取ったコマンドに応じてWindowsサービスを操作する。
Command in hex | Address of subroutine | Description |
0xBE | 0x1000B823 | サーバーから指定されたサービスの設定情報を取得する。 |
0xBF | 0x1000BB88 | サーバーから指定されたサービスを開始する。 |
0xC0 | 0x1000BC1B | サーバーから指定されたサービスを終了する。 |
0xC1 | 0x1000BCCD | サーバーから指定されたサービスを停止する。 |
0xC8 | 0x1000BD79 | サーバーから指定されたサービスを再開する。 |
0xC2 | 0x1000BAD5 | サーバーから指定されたサービスを削除する。 |
0xC4 | 0x1000BF52 | サーバーから指定されたサービスの状態及び設定情報を取得する。 |
0xC5 | 0x1000C183 | サーバーから指定されたサービスを作成して起動する。 |
0xC3 | 0x1000BE25 | サーバーから指定されたサービスの起動条件を変更する。 サーバーからの応答データが 1 の場合はサービスの起動条件を自動実行 (システムの起動時に実行)に変更する。サーバーからの応答データが 2 の場合はサービスの起動条件をマニュアル実行に変更する。サーバーからの応答データが 0 の場合はサービスを無効にする。 |
message
サーバーから受けったコマンドに応じてシステムのシャットダウンや再起動を行うものと思われる。ただし、このmessageコマンドはExitWindowsExを呼び出してシステムを操作するのだが、uFlagsの値がMSDNに記載されている値と一致しないため、実際の挙動は不明。
Command | Description |
-reboot | システムを再起動する? |
-shutdown | システムをシャットダウンする? |
-stop | Window station を閉じる。 |
-erro | メッセージボックスを生成した後、デスクトップ・セッションを終了する。 |
-warn | メッセージボックスを生成した後、デスクトップ・セッションを終了する。 |
reboot
システムを再起動するものと思われる。ただし、このコマンドはExitWindowsExを呼び出してシステムを操作するのだが、uFlagsの値がMSDNに記載されている値と一致しないため、実際の挙動は不明。
shutdown
システムをシャットダウンするものと思われる。ただし、このコマンドはExitWindowsExを呼び出してシステムを操作するのだが、uFlagsの値がMSDNに記載されている値と一致しないため、実際の挙動は不明。
logoff
システムからログオフするものと思われる。ただし、このコマンドはExitWindowsExを呼び出してシステムを操作するのだが、uFlagsの値がMSDNに記載されている値と一致しないため、実際の挙動は不明。
アンチ・デバッグ
Lab17-02.dllには解析を阻害するためのアンチ・デバッグのコードが実装されていた。
以下は解析の過程で発見したアンチ・デバッグの解説。
VMの検知
InstallRT、InstallSA、InstallSB、それぞれのエクスポート関数内でサブルーチン0x10006196が呼び出されていた。このサブルーチンはVMwareがホストOS - ゲストOS間の通信に使用する仮想I/Oポートの状態を確認することでVMを検知する。
VMを検知した場合はFound Virtual Machine,Install Cancel.
というメッセージをxinstall.log
に書き込み、vmselfdel.bat
というバッチファイルを作成・実行してLab17-02.dllを削除する。vmselfdel.bat
も実行後に削除される。
rundll32.exe及びrundll64.exeの検知
サブルーチン0x10001000にてrundll32.exe及びrundll64.exeを検知するコードを発見した。このサブルーチンはシステムで実行中のプロセスを列挙し、 rundll32.exeまたはrundll64.exeを発見した場合はEAXに1
という戻り値をセットする。
サブルーチン0x10001000は、Lab17-02.dllがサーバーとのHTTP通信 (サブルーチン0x10001074)、FTP通信 (サブルーチン0x10001365)、Command & Control通信 (サブルーチン0x10001656)を行う際に先んじて呼び出され、システムで実行中のプロセスの中にrundll32.exeまたはrundll64.exeを検知した場合はサーバーとの通信を行わない。
rundll32.exeまたはrundll64.exeによるマルウェアDLLのデバッグ行為を検知することが目的と思われる。
ネットワーク通信の解析
PMAによるとLab17-02.dllはエンコーディングされた通信を生成する模様。
To fully analyze this malware, analyze its export functions and static configuration options before focusing on the backdoor network communication capability. See if you can write a script to decode network traffic generated by this malware.
自分の解析ではStartEXSを引数つきで実行した場合のみ、ネットワーク通信が発生した。
以下はコマンドの例。
Lab17-02.dll,StartEXS 8.8.8.8:80
以下は生成された通信のキャプチャ。
そのほかの通信は生成出来ず、ネットワーク通信の詳細解析には至らなかった。