ストップランサムウェア:Gunraランサムウェア脅威分析
Detection stack
- AIDR
- Alert
- ETL
- Query
概要
Gunraは、データ暗号化と情報流出を組み合わせた二重強奪モデルを採用するランサムウェア・アズ・ア・サービス (RaaS) のオペレーションです。脅威アクターは重要インフラ、政府組織、そして世界中の多様な商業組織を標的としています。このランサムウェアは流出したContiのソースコードに基づいており、WindowsおよびLinux環境の両方をサポートするように進化しています。
調査
FBIと国際的なパートナーは、Gunraのアクターがインターネットに面した脆弱性を悪用し、盗まれた認証情報を利用して初期アクセスを獲得しているのを観察しました。調査により、横移動にImpacketライブラリを使用し、データ流出には複数のオープンソースツールを使用していることが確認されました。また、Torを利用した交渉ポータルやqToxを使用して被害者とコミュニケーションを取ることに依存しています。
緩和策
組織は、特にVPNゲートウェイやRDPインフラストラクチャにおける既知の悪用されている脆弱性を優先的にパッチ適用する必要があります。無効化できないオフラインバックアップの維持と厳しいネットワーク分割を施行することは、横移動を制限するために重要です。また、すべてのリモートアクセスサービスに多要素認証 (MFA) を有効にする必要があります。
対応
Gunraのアクティビティが検出された場合、侵害されたホストは関連するフォレンジックアーティファクトを保存しながらただちに隔離されるべきです。これには暗号化されたファイルとシステムログが含まれます。脅威ハンティングは侵入の範囲を決定し、特権アカウントのアクティビティを見直すために始めるべきです。その後、組織は正式な追放手続きを行い、環境から敵を完全に封じ込め除去する必要があります。
攻撃フロー
検知
Impacket コマンドラインパターンの可能性 (cmdline経由)
Proof of Value
Powershell、CMD、またはWMIを使用したシャドウコピーの作成または削除 (cmdline経由)
Proof of Value
代替リモートアクセス/管理ソフトウェア (system経由)
Proof of Value
Impacket実行動作の可能性 (audit経由)
Proof of Value
代替リモートアクセス/管理ソフトウェア (audit経由)
Proof of Value
IOCs (HashSha256) 検出用: #StopRansomware: Gunraランサムウェア
Proof of Value
IOCs (SourceIP) 検出用: #StopRansomware: Gunraランサムウェア
Proof of Value
IOCs (DestinationIP) 検出用: #StopRansomware: Gunraランサムウェア
Proof of Value
Gunraランサムウェアアカウント操作と特権昇格検知 [Microsoft Windows Security Event Log]
Proof of Value
FortiOSおよびFortiProxyにおける脆弱性の悪用検知 [ファイアウォール]
Proof of Value
Gunraランサムウェアの横移動と資格情報ダンプの検知 [Windowsプロセス作成]
Proof of Value
Gunraランサムウェアファイルシステム探索APIの検知 [Linuxプロセス作成]
Proof of Value
シミュレーション実行
前提条件: テレメトリー&ベースラインの事前チェックが合格していること。
理由: このセクションは、検出ルールをトリガーするために設計された敵対技術 (TTP) の正確な実行を詳細に述べます。コマンドとナラティブは、TTPsと直接一致し、検出ロジックに期待される正確なテレメトリを生成することを目指す必要があります。抽象的または無関係な例は誤診につながります。
-
攻撃のナラティブ&コマンド: 敵対者の目的はランサムウェアの展開準備です。暗号化が始まる前に、マルウェアはファイルシステムをクロールし、高価値ファイル(文書、データベースなど)のリストを作成する必要があります。Gunraランサムウェアは特に
FindFirstFileWandFindNextFileWAPIを使用してこの大規模な列挙を行います。我々はこれを、DLLインポートを介してこれらのAPIを明示的に呼び出す小さなC#スニペットをコンパイルおよび実行することでシミュレートし、SysmonがAPIの使用をImageLoadedフィールドにログするようにします。 -
回帰テストスクリプト:
# これをTriggerDetection.csとして保存 using System; using System.Runtime.InteropServices; using System.IO; class Program { static void Main() { // これはGunraランサムウェアの探索動作をシミュレートします // これらの特定のAPIのロードを強制することによって。 DirectoryInfo di = new DirectoryInfo(@"C:"); foreach (var file in di.GetFiles()) { // ファイルプロパティへのアクセスは探索APIをトリガーします string name = file.Name; } Console.WriteLine("Traversal complete."); } } # .NET Frameworkに組み込まれているcsc.exeを使用してコンパイルと実行します Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindFirstFileW(string lpFileName, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindNextFileW(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WIN32_FIND_DATA { public uint dwFileAttributes; public uint ftCreationTime; public uint ftLastAccessTime; public uint ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; public uint dwFileIndexHigh; public uint dwFileIndexLow; public uint dwStreamSize; public string cFileName; public string cAlternateDataStream; } } "@ # 特定の関数を明示的に呼び出す小さなC#スクリプトを実行し、ログ内の文字列の存在を確認します $code = @" using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindFirstFileW(string lpFileName, out FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindNextFileW(IntPtr hFindFile, out FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct FIND_DATA { public uint dwFileAttributes; public uint ftCreationTime; public uint ftLastAccessTime; public uint ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; public uint dwFileIndexHigh; public uint dwFileIndexLow; public uint dwStreamSize; public string cFileName; public string cAlternateDataStream; } static void Main() { FIND_DATA data; IntPtr handle = IntPtr.Zero; // これはSysmon ImageLoadedフィールドに特定の文字列をトリガーします if (FindFirstFileW("C:*", out data)) { Console.WriteLine("FindFirstFileWでファイルを見つけました"); FindNextFileW(handle, out data); } } } "@ $code | Out-File -FilePath "$env:TEMPTriggerDetection.cs" & csc.exe "$env:TEMPTriggerDetection.cs" & "$env:TEMPTriggerDetection.exe" -
クリーンアップコマンド:
Remove-Item "$env:TEMPTriggerDetection.cs" -ErrorAction SilentlyContinue Remove-Item "$env:TEMPTriggerDetection.exe" -ErrorAction SilentlyContinue