掲載日:2023/09/14

あなたは多言語を話せますか?マルウェアは話します

※ 本ブログは、2023年8月10日にHP WOLF SECURITY BLOGにポストされた Do You Speak Multiple Languages? Malware Does. の日本語訳です。

 

ここ数カ月間、金融をテーマにした悪質なスパムキャンペーンが急増しており、バッチスクリプト(.bat)を通じてマルウェアを拡散しています。このキャンペーンでは、バッチスクリプト、PowerShell、Go、シェルコードから.NETまで、感染チェーンの中の異なる目的を達成するために多種多様なプログラミング言語が使用されています。感染はPowerShellを使用してWebから第2段階のマルウェアをダウンロードする単純なバッチスクリプトから始まります。このマルウェアは、メモリ内でシェルコードを復号化して実行するShellGoと呼ばれるGo暗号化ツールによるものを含み、検知を回避するために2回パックされています。このシェルコードは、Windowsの2つのセキュリティ機能を回避し、ペイロードを復号化しメモリ内で実行します。私たちが以下で分析したキャンペーンのペイロードは、.NETで開発されたよく知られたリモートアクセス型トロイの木馬(RAT)であるAsyncRATでした。注目すべきは、マルウェアの作成者が、複雑な関数呼び出しのシーケンスを通じてRATをメモリ内で実行する巧妙なテクニックを使用している点です。これらのキャンペーンは、脅威アクターがツールを組み合わせることで、少ないリソースでも分析防止や検知防止のような広範囲の機能を実現することが容易にできることを示しています。HP Sure Clickは、この種の攻撃からユーザーを保護し、その封じ込めベースのアプローチにより、マルウェアの実行トレースをキャプチャすることができます。このブログでは、この攻撃に関するHPの分析を要約し、保護されていない組織に対して可能な緩和策を提案します。

 

それはバッチスクリプトから始まる

HP Sure Clickが特定した脅威 図1 - HP Sure Clickが特定した脅威

 

バッチスクリプトのファイル名は、請求書や支払確認書などに似せて作られており、典型的なフィッシングの手口です。場合によっては、".pdf.bat"のような二重拡張子を使用して、ユーザーを騙してスクリプトを実行させることもありました。Windowsのファイルエクスプローラーでは、デフォルトでファイル拡張子が非表示に設定されているため、この単純な手法で、ユーザはファイルの末尾が ”.pdf”であると認識し、スクリプトをドキュメントと勘違いする可能性があります。

送信者アドレスを偽装するEメールヘッダ 図2 - 送信者アドレスを偽装するEメールヘッダ

 

脅威アクターは、送信者アドレスを偽装することで、あたかも正当な送信者から送信されたかのようにEメールを細工していました。多くのEメールクライアントは、この送信者アドレスを精査することなく表示するため、受信者は添付ファイルを開いてしまう可能性があります。

ユーザーがこのスクリプトを開くと、ペイロードがダウンロード、解凍、実行されます。図3 は、我々の脅威封じ込めソリューションである HP Sure Click の脅威のふるまい分析におけるダウンロードコマンドを示しています。このケースでは、ペイロードのダウンロードをする PowerShell の実行でフィルターしています。

マイクロ仮想マシン内の脅威に対するHP Sure Clickのふるまい分析 図3 - マイクロ仮想マシン内の脅威に対するHP Sure Clickのふるまい分析

 

緩和の機会

 

  • スクリプトファイルのようなリスクがあるファイルタイプが、Eメールの添付ファイルとしてユーザに送信されないようにブロックする。さらに、アーカイブ内の圧縮されたリスクのあるファイルタイプをブロックする。
  • EメールのヘッダーにあるSender Policy Framework (SPF)の結果を確認し、受信したメールが認証されたEメールサーバーから送信されたものであるかどうかを確認する。
  • スクリプトファイルのデフォルトのファイルタイプハンドラーをメモ帳に変更する。ユーザーがスクリプトファイルをダブルクリックすると、実行されずにメモ帳で開く。

 

肥大化したバイナリ

このスクリプトはZIPアーカイブをダウンロードし、それを解凍して、内部に格納されている実行ファイル(.exe)を実行します。バイナリーパディングを使用することで、この脅威アクターはファイルを人為的に2GB近くまで膨れ上がらせています。この方法は、一部のオンアクセス型のマルウェアスキャナーを回避します。

パディングされた実行ファイルを含むアーカイブファイル 図4 - パディングされた実行ファイルを含むアーカイブファイル

 

実行ファイル(PE形式)のセクションは元の状態のままなので、実行ファイルの正しいサイズを計算し、復元することができます。これは、ダイナミックサンドボックスやデバッガ、逆アセンブラでファイルを解析しやすくするためです。実行ファイルの正しいサイズは、すべてのセクションの実サイズとヘッダーサイズの合計です。

 

In [1]: headers = 0x600
In [2]: sections = [0x64c00, 0x72c00, 0x18600, 0x600, 0x1a00, 0x200]
In [3]: headers + sum(sections)
Out[3]: 992768

元のファイルサイズを復元するためのセクションヘッダー 図5 - 元のファイルサイズを復元するためのセクションヘッダー

 

実行ファイルのエントロピーが高いことは、脅威アクターがファイルをパックした可能性を示しています。パックすることは、静的シグネチャに基づく検知を回避する一般的な方法です。マルウェアのペイロードはバイナリ内に暗号化されて保存され、バイナリ実行時に復号化されてロードされます。

 

SHELLGOというクリプター

プログラムの静的解析から、このプログラムの一部はGoで書かれていることがわかりました。ほとんどのGoプログラムは静的にリンクされるため、すべての依存関係を含み、動的にリンクされる場合よりも大きなバイナリが生成されます。そのため、このようなマルウェアの解析やリバースエンジニアリングはより複雑になります。しかしながら、このマルウェアでは、脅威アクターはマルウェアの最初の部分だけをGo(GellGoという名前のクリプター)で書いています。

Goのモジュール情報から抽出された文字列 図 6 - Goのモジュール情報から抽出された文字列

 

デバッガーを使ってマルウェアを解析すると、Main関数に到達する前に多くのライブラリーコードを実行しなければならないため、時間がかかることがあります。解析をスピードアップするには、静的解析ツールを使ってMain関数を特定します。このケースでは、GoReSymを使用しました。GoReSymは、有用なプログラムのメタデータを抽出するGo用のシンボルパーサーです。このようにして、ユーザーコードのアドレスとMain関数を特定します。図7はユーザー関数のアドレスと名前を示しています。

GoReSymを使って抽出されたユーザー関数情報 図7 - GoReSymを使って抽出されたユーザー関数情報

 

開始アドレスは、10進数形式の仮想アドレス(VA)に対応します。デバッガでロードされたバイナリ内の”Main”関数の正しいアドレスを見つけるには相対仮想アドレス(RVA)を計算する必要があります。ロードされたイメージのベースアドレスに、これを加算して”Main”関数のアドレスを得ます。ユーザーコードに直接ジャンプするには、このアドレスにブレークポイントを設定し、 プログラムをこのポイントまで実行させます。

Main関数に設定されたブレークポイン 図8 - Main関数に設定されたブレークポイン

 

Goプログラムがパッカーであると仮定しているので、VirtualAllocRtlMoveMemoryなど、マルウェアがよく使うメモリー関連のWindows API関数に、さらにいくつかのブレークポイントを設定しました。

ShellGoはこれら2つの関数を使って、暗号化されたデータを".data "セクションから新しく割り当てられたメモリ領域にコピーします。その後、単純なadd命令によるループでこのデータをデコードします。この手順の結果が実行シェルコードです。

デバッガで復号化されたシェルコード 図9 - デバッガで復号化されたシェルコード

 

シェルコードは、さまざまなWindows API関数を使い実行することができます。多くの場合、コールバック関数のアドレスを引数として取る関数が選択されます。このケースでは、ShellGoはEnumPageFilesW関数を使用し、コールバック関数としてシェルコードのアドレスを渡します。コールバック関数がトリガーされると、シェルコードが実行されます。

 

シェルコードパッカー

今日、シェルコードはさまざまなWindowsダイナミックリンクライブラリ(DLL)をロードし、目的のAPI関数を解決します。このマルウェアでは、よく知られた解析防止テクニック Windows API hashing を使用して解析をより困難にしています。目的のAPI関数は、マルウェアに保存されたハッシュに基づいて解決されます。さらに、検知を回避するために、このシェルコードはAnti-malware Scan Interface(AMSI)Windows Lockdown Policy(WLDP)といったWindowsのセキュリティ機構を無効にします。

最初のステップで、シェルコードは AMSI DLL をロードします。次に、シェルコードは関数 AmsiScanBufferAsmiScanString を解決し、VirtualProtect を使用してページ保護を Read-Write-Execute に変更し、シェルコードのコードで関数を上書きします。最後に、シェルコードはページ保護をRead-Executeに戻します。この方法により、マルウェアは、多くのアンチウィルスプログラムが使用するインターフェースであるAMSIを使用して、バッファと文字列がマルウェアとしてスキャンされるのを防ぎます。このシェルコードは、WLDP DLLを無効にするために同じ方法を使用します。この場合、WldpQueryDynamicCodeTrust関数とWldpIsClassInApprovedList関数が上書きされ無効化されます。

これらのセキュリティ機能が迂回されると、シェルコードはさらに暗号化されたデータを復号します。その中に、マルウェアのペイロードであるPEファイルがあります。

 メモリ内の PE ペイロード 図 10 - メモリ内の PE ペイロード

 

ペイロードは.NETバイナリであるため、.NETの依存関係によらずにメモリ内で直接実行することはできません。マルウェアの作者は、mscoreei.dllとclr.dllへの複雑な関数呼び出しのシーケンスを通じてペイロードを巧みに実行することで、この課題を克服しています。マルウェアはメモリ内で実行され、ディスクに保存されないため、攻撃による「ノイズ」が少なくなり、検知に依存するセキュリティツールに検知されない可能性が高まります。以下は、マルウェアがメモリ内で.NETペイロードを実行するために使用する一連の関数呼び出しの解説です:

NETペイロードをメモリ上で実行する関数のシーケンス 図11 - .NETペイロードをメモリ上で実行する関数のシーケンス

 

 

.NETペイロード

マルウェアのペイロードは実質的に難読化されていません。おそらく脅威アクターは、2つのパッカーがあれば検知を回避できると考えたのでしょう。次に、さらなる解析のためにPEファイルをメモリから抽出し、ディスクに保存します。.NETは中間言語であるため、公開されている逆コンパイラを使用すれば、何らかの形でコードの復元が可能です。

AsyncRATペイロードの逆コンパイルされたメイン関数 図12 - AsyncRATペイロードの逆コンパイルされたメイン関数

 

このケースでは、脅威アクターはキーロギングおよびスティーラー機能を持つ人気の高いオープンソースのリモートアクセス型トロイの木馬であるAsyncRATを設定していました。マルウェアが実行されると、このサンプルの設定がロードされます。逆コンパイラが見事にコードを復元したため、私たちは簡単にコードをデバッグし、ブレークポイントを設定し、マルウェアの最も重要な設定変数を抽出することができました。興味深いことに、コマンド&コントロール(C2)サーバーとして設定されたIPアドレス(45.81.243[.]217)は、脅威アクターが悪意のあるEメールを送信するために使用したアドレスと一致しています。

AsyncRATから抽出された設定 図13 - AsyncRATから抽出された設定

 

 

結論

これらのキャンペーンでは、感染チェーンのさまざまな段階で使用されるプログラミング言語の興味深い相互作用が見られます。感染は、PowerShellを使用してWeb上から追加のマルウェアをダウンロードする単純なバッチスクリプトから始まります。このマルウェアは、検知を回避するために2回パックされます。パッカーの1つであるShellGoはGoで書かれており、メモリ内でシェルコードを復号して実行します。シェルコードはWindowsのAMSIとWLDPセキュリティ機能を無効化し、AsyncRATペイロードを復号化し、メモリ内で実行します。

無償で利用できる RAT を使用し、スパム送信用と C2 用に 1 台のサーバを使用するという脅威アクターのツールと構成の選択に基づき、この脅威アクターの能力とリソースは低レベルと考えられます。脅威アクターが検知を回避するために使用した2つのパッカーなどのコンポーネントは、おそらくサイバーアンダーグラウンドで入手可能なコモディティツールです。にもかかわらず、このキャンペーンは、攻撃者がいかにツールを簡単に組み合わせて、アンチ解析やアンチ検知のようなかなりの範囲の機能を実現できるかを示しています。感染チェーンで使用されるプログラミング言語が多様であるため、分析者は各言語の動作を理解するか、この知識を習得するために時間を費やす必要があり、分析はさらに複雑になります。幸いなことに、セキュリティコミュニティはネットワーク防御者にとって優れたリソースであり、公開レポート、トラストグループ内での共有、オープンソースの解析ツールの公開などを通じてサポートを提供しています。

 

Author : Patrick Schläpfer

監訳:日本HP