reverse-eg-mal-memoのブログ -52ページ目

reverse-eg-mal-memoのブログ

サイバーセキュリティに関して、あれこれとメモするという、チラシの裏的存在。
medium(英語):https://sachiel-archangel.medium.com/

前回、超尻切れトンボになった、特徴のある情報・痕跡の続きです。

感染の判定、マルウェアの通信先の求め方とそれによる追跡のための判定情報、感染予防のアイディアの種になりそうなネタでも展開できればいいなぁと。

 

データがダラダラになりそうなのはご勘弁を!

 

 

マルウェア本体部の特徴のある情報・痕跡の詳細

 

インジェクションしているsvchost.exeのプロセスツリーがおかしい

これは、前回記事でもライブのプロセスツリーで表示したのでそちらを参照していただければOKです。

メモリは、ライブでProcess ExplorerProcess Hackerで参照する方法のほか、メモリのスナップショットが取れるなら、メモリフォレンジックツールを用いて参照できます。

無償で使うなら、コマンドラインベースになりますがVolatility FrameworkやRekallが良いでしょう。

ツールはLinuxやWindowsにインストールして使うほか、SANS SIFTなら無償公開しており、その中にインストールされています(もしプロファイルが古いなら、SANS SIFTのVolatilityの更新記事参照)。

SANS SIFTは、ユーザ登録(無償)すればダウンロードできます。

VMware Playerで使うとスムーズに使えます。

使い方は・・・詳しい解説は、多分誰かがもう書いていると思います(^^;

 

Volatilityを使う場合、以下のコマンドでツリーが見れるはずです。

 

vol.py -f (イメージファイル名) --profile=(プロファイル名) pstree

 

なお、今回はマルウェアのリバースエンジニアリングによって、プロセスツリーがおかしくなる原因となる動作を解析で得ましたが。

そういったノウハウをSANSがポスターにして公開しています。

仮に今回の検体をマルウェア解析していなくても、これに則ってメモリを調査して発見できていたのでは、と思います。

 

SANS DFIR Hunt Evil poster

https://digital-forensics.sans.org/media/DFPS_FOR508_v4.6_4-19.pdf

 

流石のSANSで、解説付きで非常によい出来のポスターです。

詳しく学びたい場合は、トレーニングを受けたいですね(なかなかいい値段のため、個人だと難しいですが)。

 

 

バージョン、サーバのIPアドレスのリストを含むxml

この情報が取れるなら欲しい!という人は多いのではないでしょうか。

特にC&Cサーバのアドレス。これが速やかに分かるのであれば、ブラックリストへの反映による遮断や、通信した痕跡がないかを通信ログからチェックする場合重要な情報になるでしょう。

この情報は、マルウェアの内部データでAES256 CBCモードで暗号化されて格納されていました。

暗号鍵初期化ベクトルは、特定の値をSHA256でハッシュ演算、結合を繰り返すことで計算できるようになっています。

 

 

一応、IPアドレスは一部マスクしました。

いや、とっくにOSINTでブラックリストに出ていそうではあるんだけど。

一方、ちょっと古い検体なので、とっくに解決してもう問題ない状態になっているかもしれないので。

あくまで、私が入手した検体では、以上のようなxml形式でIPアドレスとポート番号が入っていました、というサンプルです。よく見ると、ポート番号449なんてのが混じっています。

 

このxmlからとれる情報は以下のとおり。

  • バージョン番号
    • 1000497
  • gtag(タグ情報?)
    • mor84
  • サーバのIPアドレス
    • 5.182.xxx.xxx:443
    • 5.182.xxx.xxx:443
    • 82.146.xx.xx:443
    • 198.8.xx.xx:443
    • 195.123.xxx.xx:443
    • 51.89.xxx.xxx:443
    • (中略)
    • 190.214.xx.x:449
    • 181.140.xxx.xxx:449
    • (以下略)
  • autorunモジュール名
    • module name="pwgrab"

 

 

xmlを解凍するためのAES256鍵

このサーバ等の情報が入ったAES256の暗号鍵と初期化ベクトルは以下の通り。

居ないとは思うけど、同じ検体で自分で復号してみたい方は以下の鍵でどうぞ。
一時的にしか現れない値なのと、鍵は変えられると思うので、IoCには向かないと思う。
 
AES256 CBCモード暗号鍵
(WindowsのCryptImpotyKeyで利用できるPUBLICKEYSTRUCと鍵本体)
0x000000ED98AAE9D0 08 02 00 00 10 66 00 00 20 00 00 00 D7 82 72 8A 0x000000ED98AAE9E0 AD E1 08 11 2E FE 9E 20 10 F3 D1 E7 E0 70 83 81 0x000000ED98AAE9F0 8D 50 D9 22 19 EA 9B 7F F6 FB EA 01 20 00 00 00
 
AES256 CBCモード初期化ベクトル
0x00000286B894B0E0  13 4D A9 E1 83 5A BD 6E  61 15 84 05 DD 77 86 92
0x00000286B894B0F0  FA 0E 74 09 69 05 F1 F6  F1 10 9C BA 51 59 2E E8
 

 

xmlデータを展開したリストオブジェクト

xmlデータは、分解されて自身のリストに格納されます。

xmlデータはリストに展開後、消去してメモリを解放してしまうので、メモリ上に残るのはこちらの情報となります。

 

 

データとして目立つのは、joaatハッシュ値と展開された要素データのIPアドレスおよびポート番号でしょう。

joaatハッシュ値はxmlの要素名をそのままハッシュ化しているので、「srv」は「0x8289E8C4」とすぐに求めることができます。

この値でメモリを検索すれば、すぐにこのマップを見つけることができるんじゃないでしょうか。

これらのデータは、自分の解析中ではconnect直前ではまだメモリに残存しています。

このため、展開されたxmlデータは、このリストの状態でメモリに残されている可能性が高いと思われます。

 

この解析結果から、展開されたxmlデータを取得する方法を考えると、マルウェアが動作しているメモリをキャプチャし、ツリーで浮いているsvchost.exeを特定してプロセスIDを取得し、Volatilitymemdumpで当該プロセスのデータを抽出し、joaatハッシュ値を検索したり、単純にストリング検索をするだけ(ただし、Unicodeであることだけは注意)でC&CサーバのIPアドレスとポートが抜けるのではないか、ということが分かります。

(ただし、検証まではしていないので、あくまで分析の結果で考えられるというレベルですが。)

そういった手順を見つけるために、マルウェア解析結果を活用できるのではないか、という例です。

 

 

楕円曲線暗号公開鍵

現在の解析段階では一度インポートしてエラーにならないかチェックしているだけですが、この先暗号化で用いるであろう楕円曲線暗号公開鍵を見つけたので以下に示します。

こちらも、通常は暗号化されているのでIoCには向かないと思います。

また、共通鍵の交換のために使うと思われますが、公開鍵で暗号化されたデータは秘密鍵がなければ復号できないので、この鍵情報だけあってもすぐに役に立つことはないかなと。

容疑者を逮捕した際、この公開鍵と対になる秘密鍵をフォレンジック調査などで発見できれば証拠になる!?とかいう妄想くらいですかねー・・・。

他に活用方法がありそうなら、意見が欲しいところ。

 

ECCPUBLICBLOB
0x00000286B8903F70  45 43 53 33 30 00 00 00  F3 20 86 DB 20 4D F0 73
0x00000286B8903F80  37 B5 FB 18 B0 C0 AF 80  BB F3 FB F1 4A C0 3B C6
0x00000286B8903F90  00 1F 23 EF 1C 4C 06 54  A3 8F A6 19 7C 41 57 EB
0x00000286B8903FA0  0B BC 7F 41 A1 58 79 70  0D C3 A1 38 1C 5E E2 7A
0x00000286B8903FB0  D1 29 FB B6 55 41 D5 8E  C7 C7 3E 1E F3 B4 67 63
0x00000286B8903FC0  D3 50 F5 5B 5F D1 C0 56  B8 38 87 DB B5 44 D7 E1
0x00000286B8903FD0  38 79 3E 63 2B 03 2E C8  00 00 00 00 00 00 00 00
 
 

C:\Users\(ユーザ名)\AppData\Roaming\windirectフォルダ

C:\Users\(ユーザ名)\AppData\Roaming\配下にある.txtファイルや.iniファイルから抽出したデータや、マルウェア本体が永続化するためのコピー先がこのフォルダになります。

ただし、私が解析している検体がここである、というだけで、恐らく容易に変更可能だと思われます。

いくつかの検体ではこのフォルダを探すことが有効かもしれませんが、そのナレッジが広まればフォルダを変えてくることが予想されます。

なお、マルウェア本体のコピーをする際、ファイル名を変更する処理を行っています。

 

 

 

タスクスケジューラに登録するためのxml

この検体では、自身の永続化のためにタスクスケジューラを使用しています。

タスクスケジューラに登録する際、XMLデータを用いています。

そのXMLデータは、実行ファイルのパス等の一部のパラメータ以外は暗号化されて格納されています。

データの復号とパラメータの文字列の結合を繰り返し、タスクスケジューラへ登録するXMLを生成していきます。

XMLの生成処理が終わったところでデータを抽出することで、どのようなパラメータでタスクスケジューラを登録するかを知ることができます。

ただし、このパラメータもタスクマネージャ登録時に一時的に作られるだけのため、デバッガによる解析でしか拾うのは困難だと考えられます。

どのようにタスクマネージャに登録されるかを知ることができる一方で、一時的なデータのため、検知用のIoCには向かないパラメータといえます。

 

 

 

タスクスケジューラへ登録しようとするXML文は以下のとおり。

まずは高い権限での登録を試み、それで失敗するとユーザの権限で登録を試みます。

 

 

タスクマネージャ登録(高権限)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Version>1.0.0</Version>
<Author>AuthorName</Author>
<Description>Windows Direct core tools</Description>
</RegistrationInfo>
<Triggers>
<BootTrigger>
<Enabled>true</Enabled>
</BootTrigger>
<TimeTrigger>
<Repetition>
<Interval>PT12M</Interval>
<Duration>P412DT10H30M</Duration>
<StopAtDurationEnd>false</StopAtDurationEnd>
</Repetition>
<StartBoundary>2020-08-29T14:19:10</StartBoundary>
<Enabled>true</Enabled>
</TimeTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<RunLevel>HighestAvailable</RunLevel>
<GroupId>NT AUTHORITY\SYSTEM</GroupId>
<LogonType>InteractiveToken</LogonType>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>true</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>5</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Users\Sachiel\AppData\Roaming\windirect\ckmtct_dd20304b.exe</Command>
</Exec>
</Actions>
</Task>
 

 

タスクマネージャ登録(低権限)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Version>1.0.0</Version>
<Author>AuthorName</Author>
<Description>Windows Direct core tools</Description>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<UserId>DESKTOP-6U1HJNH\Sachiel</UserId></LogonTrigger>
<TimeTrigger>
<Repetition>
<Interval>PT12M</Interval>
<Duration>P412DT10H30M</Duration>
<StopAtDurationEnd>false</StopAtDurationEnd>
</Repetition>
<StartBoundary>2020-08-29T16:51:05</StartBoundary>
<Enabled>true</Enabled>
</TimeTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel><UserId>DESKTOP-6U1HJNH\Sachiel</UserId></Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>true</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>5</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Users\Sachiel\AppData\Roaming\windirect\ckmtct_dd20304b.exe</Command>
</Exec>
</Actions>
</Task>
 

 

 

登録されたタスクスケジュール

実際にタスクスケジューラに登録された画面です。

XMLの値に沿って登録されていることが分かります。

この検体と同じマルウェアが実行されたかどうかの指標にはなると思います。

しかし、名前等のパラメータは変更される可能性が高いため、長期的にはそれだけでIoCにするのは難しいと思われます。

タスクマネージャを新たに登録されているものをチェックする、というのが現実的な検知方法になりそうです。

 

 

 

 

 

 

 

 

 

 

Mutexオブジェクト名

自身の多重起動防止のための排他処理を行うために、Mutexオブジェクトを使用しています。

このMutexオブジェクトの名前ですが、「Global\xxxxxxxxxxxxxxx」(xは再現性のある値)になるようになっています。

xの値ですが、 GetVolumeInformationW で得られた値に少々計算をして作成しています。

計算結果を元に、sprintfで「Global\%08lX%04lX%lu」でパラメータを設定して文字列として出力しています。

このため、端末によってMutexオブジェクト名が変わってしまいます

 

もし仮に、Mutex文字列が固定の文字列だった場合、OS起動時にマルウェアよりも速くその文字列でCreateMutexをしておけば、仮にこのマルウェアに感染したとしても、自身の排他処理によって終了してしまう、というキルスイッチが可能になります。

攻撃者も、それを見越してそう単純ではない値でMutexオブジェクト名を作り、マルウェア感染回避策を自ら作りこむようなことはしない工夫をしている、というわけです。

 

まあ、今回は利用できませんが、解析によってマルウェア自身の機能によって感染抑止をできる方法が見つかるなら、一時的な対処として利用できる可能性もでてくるのではないかと思います。

 

 

 

以上、解析で見つけたパラメータの垂れ流しでした。

セキュリティ対策に利用できたり、解析の役にたったりする情報があれば幸いです。

前にも書きましたが、この本体はロジック自体は特に目立ったヒネリはないので、パッカーを超えることができた人にはただのボーナスステージです。

じゃんじゃん解析して、パラメータの抽出なり弱点探しなりしていければいいんじゃないかと思います。

 

まあ、こまごまと書きましたが、これまだ解析の途中なので、また何か見つかったら追加で書くかもです。

ていうか、中途半端な解析で記事書くなって怒られそうw