
OffsetInspect v3.3.0
PowerShellツールキット。AMSI/Defender検出境界の解析と静的マルウェアトリアージのためのもので、バイトオフセットを検出トリガーにマッピングし、さらにYARA、エントロピー、文字列、PE/imphash解析を提供します。OffsetScanのコンパニオンツールです。
OffsetInspect
バイトオフセット検査、ソース相関、バイナリ比較、防御的検知境界分析のための、メモリ使用量を制限したPowerShellツールキット。
OffsetInspectは、アナリストの実践的な問いに答えます:
このバイトオフセットにはどのようなコンテンツが存在し、その周囲にはどのようなソースまたはバイナリコンテキストがあるのか?
また、ThreatCheckが扱うのと同じアナリストの問題に着想を得た、OffsetInspectネイティブの検知境界ワークフローを提供します(ThreatCheckのソースやバイナリは同梱しません)。AMSIまたはMicrosoft Defenderがまだ検知する最も早いコンテンツプレフィックスを特定し、その境界を繰り返し検証し、得られたオフセットをそのままコンテキストインスペクタに渡します。その中核に加えて、レッドチーム分析と静的トリアージスイートを追加します。複数領域の発見、コーパススキャン、検知差分、検知トリガー相関、ドリフトジャーナリング、エンゲージメントレポート、エントロピー解析、文字列抽出、PE/imphash解析など、すべて読み取り専用です。さらに、承認された利用に限った署名ロバストネステスターも備え、サンプルをメモリ内でのみ改変し、エンドポイント保護を無効化または再構成することは一切ありません。
関連ツール
PowerShellのオーバーヘッドなしでコーパス規模の静的トリアージ(PE解析、エントロピー、文字列、IOC)を行うには、OffsetScan を参照してください。同じJSON出力スキーマを持つネイティブRustバイナリです。OffsetInspect 3.1.0以降は、-IocJsonPath を使用してOffsetScanのIOC JSONを直接取り込めます。
ハイライト
- 一意の各検査ファイルを安定した読み取りハンドルで開き、要求されたすべてのオフセットをまとめて処理します。
- オフセットごとにファイル全体を再読み取りする代わりに、メモリ使用量を制限したストリーミングパスを使用して行マッピングを行います。
- 16進出力と比較のために、要求されたバイトウィンドウのみを読み取ります。
- UTF-8およびUTF-16のバイトオフセットをソース行と文字位置にマッピングします。
-ContextLinesによる前後のソースコンテキストを実装します。- 人間可読、オブジェクト、JSON、CSV、CSVファイルの出力契約をサポートします。
- 一対多、多対一、ペア形式のファイル/オフセット計画をサポートします。
- 2番目のファイルを繰り返し読み込むことなく、対象バイトをそのファイルと比較します。
- 独立に実装されたAMSIおよびMicrosoft Defenderプロバイダーレイヤーを追加し、エラー、タイムアウト、ブロック、不確定の各状態を明示します。
- プロバイダー呼び出しの種類ごとにプローブ単位の監査証跡(
ProbeLog/ProbeCount)を記録し、-Verboseにライブでストリーミングして、スキャンの実際のプロバイダーコストをレポートに使える形で記録します。 - インメモリAMSIスキャンにより、1つのファイル内で独立に検知可能な複数の領域を発見し(検知されたものはディスクに書き込まれません)、各境界を絶対オフセットにマッピングします。
- コーパスをスキャンして統合検知マトリックスを生成し、2つのスキャン間の検知差分を取ります。さらにMarkdown/HTMLのエンゲージメントレポートをエクスポートします(コーパス規模のIOCパネルには、オプションでネイティブOffsetScanエンジンのJSONを利用できます)。
- 検知境界を、それを生み出したコンテンツと関連付けます。PEセクション、境界までのランのエントロピー、境界で終わる/またがる文字列を候補シグネチャコンテンツとして関連付けます。
- 検知を経時的にジャーナリングします(ファイルハッシュ および ローカルのDefenderシグネチャバージョン)。これにより、検知可能性の変化を、ファイル自体、シグネチャデータベースの更新、または非決定的なプロバイダー結果のいずれかに帰属させることができます。
- 承認されたエンゲージメントのために、検知されたサンプルをメモリ内で改変(大文字小文字、連結、コメント、空白)し、どの変換クラスが回避するかを報告することで、署名のロバストネスをテストします。変異体がディスクに書き込まれることは決してありません。
- スキャンを、それが生成するWindowsテレメトリ(
-CaptureTelemetry)と関連付けます:Microsoft Defenderのアラートが発生したかどうか、どのようなコンテキストで発生したか、どのテレメトリソースが盲点だったか。「可視性を仮定し、それを検証する」という原則を具現化します。読み取り専用、非管理者、Windowsのみ。 - 静的マルウェアトリアージヘルパーを追加します:ウィンドウ単位のエントロピー(パック/暗号化領域)、オフセット付きのASCII/UTF-16LE文字列抽出、imphashとオーバーレイ検出を含むPEヘッダー/セクション/インポート解析。
- Authenticodeの来歴を検証します(
Get-OffsetSignature):プラットフォームの実際の信頼検証を使用して、ファイルが有効に署名され信頼されているか、誰が署名したか、埋め込み署名とカタログ署名のどちらであるかを報告します。imphashおよびビルドツールチェーンのフィンガープリント(インポート vs ツールチェーン vs 署名者)を補完する署名者シグナルです。Windowsのみ。 - Defenderの除外設定、リアルタイム保護、またはシステムのセキュリティ構成を変更することは決してありません。
- 外部ランタイム依存関係のない自己完結型のPowerShell Galleryパッケージとして提供されます。YARAおよびClamAVスキャンのみがオプションの例外で、それぞれ独自の外部エンジンが必要です。
コマンド
| コマンド | 目的 | プラットフォーム |
|---|---|---|
Invoke-OffsetInspect | バイトオフセットをソース/バイナリコンテキスト、16進、比較にマッピング | クロスプラットフォーム |
Invoke-OffsetThreatScan | 1つのファイルに対するAMSI/Defender検知境界検索 | Windows |
Invoke-OffsetThreatScanBatch | ファイルのコーパスをスキャン;-Summary は検知マトリックスを返す | Windows |
Invoke-OffsetThreatScanRegion | インメモリAMSIによる複数領域の発見(ディスク書き込みなし) | Windows |
Invoke-OffsetMutationTest | 署名ロバストネステスト:検知されたサンプルをメモリ内で改変し、どの変換が回避するかを報告(承認された利用のみ) | Windows |
Compare-OffsetThreatResult | 2つのスキャン結果の差分を取る(例:シグネチャ定義の更新前後) | クロスプラットフォーム |
Get-OffsetDetectionTrigger | 検知境界を、それを最も引き起こした可能性が高いコンテンツと関連付ける | クロスプラットフォーム |
Add-OffsetDriftEntry | 検知スナップショット(ファイルハッシュ + Defenderシグネチャバージョン)をジャーナルに記録 | クロスプラットフォーム² |
Get-OffsetDrift | ファイルの検知可能性がどのように変化したかを説明:ファイル変更 vs シグネチャ更新 vs 非決定的 | クロスプラットフォーム |
Export-OffsetThreatReport | スキャン結果をMarkdown/HTMLエンゲージメントレポートに変換 | クロスプラットフォーム |
Invoke-OffsetYaraScan | ファイルをYARAルールと照合し、バイトオフセット付きのヒットを返す | クロスプラットフォーム¹ |
Invoke-OffsetClamScan | ClamAVエンジンでファイルをスキャン;正規化された検知結果を返す | クロスプラットフォーム¹ |
Get-OffsetEntropy | パック/暗号化領域を特定するためのウィンドウ単位のシャノンエントロピー | クロスプラットフォーム |
Get-OffsetString | バイトオフセット付きでASCII/UTF-16LE文字列を抽出 | クロスプラットフォーム |
Get-OffsetPEInfo | PEヘッダー、セクション、インポート/imphash、オーバーレイ、オフセット→セクション | クロスプラットフォーム |
Get-OffsetIOC | 統合インジケーターパネル:ハッシュ、エントロピー、PE/imphash、文字列 | クロスプラットフォーム |
Get-OffsetSignature | Authenticode署名:有効に署名され信頼されているか、誰によるものか、埋め込み署名とカタログ署名のどちらか | Windows |
¹ これら2つのコマンドにはオプションの外部依存関係があります:Invoke-OffsetYaraScan はYARAエンジン(winget install VirusTotal.YARA)が必要で、Invoke-OffsetClamScan はシグネチャデータベースを持つClamAV(winget install Cisco.ClamAV、続けて freshclam)が必要です。他のすべてのコマンドは自己完結型です。ここでのClamAVは単一ファイル検出器であり、境界検索エンジンではありません。clamscan は呼び出しのたびに全データベースを読み込むため、二分探索には clamd デーモンが必要です。
² Add-OffsetDriftEntry はクロスプラットフォームでジャーナリングしますが、Defenderのシグネチャ/エンジンバージョン欄はWindows(Get-MpComputerStatus 経由)でのみ設定されます。それ以外の環境ではnullとして記録され、スナップショットの残りは引き続き書き込まれます。
オフセット検査の中核とすべての静的トリアージヘルパーはクロスプラットフォーム(Windows、Linux、macOS)です。AMSI/Defender脅威プロバイダーはWindowsのみです。
インストール
PowerShellギャラリー```powershell
Install-Module OffsetInspect -Scope CurrentUser Import-Module OffsetInspect
### リポジトリのチェックアウト```powershell
git clone https://github.com/warpedatom/OffsetInspect.git
cd OffsetInspect
Import-Module ./module/OffsetInspect/OffsetInspect.psd1 -Force
このリポジトリには、軽量なCLIラッパーも含まれています:```powershell ./OffsetInspect.ps1 ./OffsetThreatScan.ps1 -Engine AMSI
## オフセット検査
### 人間可読出力```powershell
Invoke-OffsetInspect ./sample.bin 0x200
はじめに
前提条件
- このデモリポジトリのすべての手順は、Ubuntu 22.04上で
KinD version v0.20.0 go1.20.4 linux/amd64を使用してテストされました。このデモはまた、2023 MacBook Pro M2 Max上でUTMを介してUbuntu 22.04 ARM64 VMを実行することによっても検証されています。 - CockroachDB ServerlessまたはCockroachDB Dedicatedの無料トライアルデータベースのいずれか。https://cockroachlabs.cloud/signup で登録してください。注:これらのデモはCDC webhookクエリに依存しており、すべてのCRDBバージョンで利用可能です。```powershell $inspectParameters = @{ FilePaths = './script.ps1' OffsetInputs = 128, 256, 512 ByteWindow = 64 ContextLines = 4 } Invoke-OffsetInspect @inspectParameters
### 構造化オブジェクト```powershell
$inspectParameters = @{
FilePaths = './script.ps1'
OffsetInputs = 0x80, 0x100
PassThru = $true
}
$results = Invoke-OffsetInspect @inspectParameters
$results | Where-Object BytesDiffer
JSONとCSV```powershell
Invoke-OffsetInspect ./sample.bin 0x200 -Json Invoke-OffsetInspect ./sample.bin 0x200 -Csv Invoke-OffsetInspect ./sample.bin 0x200 -CsvPath ./artifacts/offsets.csv
JSON モードは常に配列を出力します。単一の結果の場合も同様です。
### バイナリ比較```powershell
$compareParameters = @{
FilePaths = './before.bin'
OffsetInputs = 0x200
CompareFile = './after.bin'
PassThru = $true
}
Invoke-OffsetInspect @compareParameters
Offset formats
| Input | Interpretation |
|---|---|
512 | 10進数 512 |
0x200 または 0X200 | 16進数 0x200 |
200h | 16進数 0x200 |
E1AB1 | A-F を含むためプレフィックスなしの16進数 |
プレフィックスやサフィックスがない数値のみの値は、意図的に10進数として扱われます。
Encoding modes
| Mode | Behavior |
|---|---|
Auto | UTF-8/UTF-16 の BOM を検出します。それ以外の場合は UTF-8 を使用します |
Default | ホストオペレーティングシステムのデフォルトエンコーディングを使用します |
UTF8 | UTF-8 ソースマッピング |
UTF16LE | リトルエンディアン UTF-16 ソースマッピング |
UTF16BE | ビッグエンディアン UTF-16 ソースマッピング |
ASCII | ASCII ソースマッピング |
出力には BytePositionInLine と CharacterPosition の両方が報告されます。この違いは、ソースファイルにマルチバイト文字が含まれている場合に重要です。
Threat boundary analysis
脅威プロバイダ分析は Windows 専用です。通常のオフセット検査コマンドは、クロスプラットフォームのままです。
AMSI text scan```powershell
$scanParameters = @{ FilePath = './script.ps1' Engine = 'AMSI' ScanMode = 'Text' RepeatCount = 3 PassThru = $true } $result = Invoke-OffsetThreatScan @scanParameters
テキストモードは `AmsiScanString` を使用し、サロゲートペアを分割せずにUnicodeスカラー接頭辞を検索し、検出された接頭辞を検証済みのソースエンコーディングにマッピングして、Unicodeスカラー、UTF-16コードユニット、およびソースファイルのバイトインデックスを返します。埋め込まれたNUL文字はテキストモードでは拒否されます。そのようなファイルにはraw-byteモードを使用してください。
### AMSI raw-byte スキャン```powershell
Invoke-OffsetThreatScan ./content.bin -Engine AMSI -ScanMode RawBytes
Microsoft Defender スキャン```powershell
$scanParameters = @{ FilePath = './sample.bin' Engine = 'Defender' RepeatCount = 3 TimeoutSeconds = 45 } Invoke-OffsetThreatScan @scanParameters
The Defender provider:
- インストールされている最新の `MpCmdRun.exe` プラットフォームパスを解決します。
- プレフィックスを一意のユーザー一時ディレクトリに書き込みます。
- `-DisableRemediation` を使用したカスタムスキャンを実施します。
- タイムアウト、プロバイダーエラー、ローカライズ済み/不明な出力、あいまいなマーカーは非決定的なものとして扱います。
- スキャン完了時に一時ワークスペースを削除します。
### 境界セマンティクス
`DetectionPrefixLength = 841` のような結果は、次のことを意味します:
- プレフィックス長840はクリーン/未検出として分類されました。
- プレフィックス長841は検出/ブロックとして分類されました。
- 繰り返しチェックを行うことで、その遷移が安定しているかどうかを判断します。
これは、バイト840が完全なシグネチャ、唯一の寄与バイト、または悪意のある範囲全体であることを**証明するものではありません**。アンチウイルスの判定は、トークン化、周囲のコンテキスト、ファイルタイプ、プロバイダーの状態、シグネチャ更新に依存する場合があります。
### 実際の例: 2つのエンジン、1つのファイル
同じサンプル(PowerUp.ps1、公開されたレッドチーム用スクリプト、445,954バイト)を両方のプロバイダーでスキャンすると、境界が何であるか、そして2つのエンジンがどの程度まで一致すると信頼できるかがわかります。テキストモードのAMSI:```text
Threat boundary scan: C:\Ops\Samples\PowerUp.ps1
SHA-256: 7abc87d9620aef493617a4fc1f823850f32fb26ca9ae0f3befeadb04971e0246
Engine: AMSI
Scan mode: Text
Initial status: Detected
Scans performed: 25
Provider probes: 25 (see -Verbose or the ProbeLog property for the full audit trail)
Duration: 22771.419 ms
Known clean prefix: 445953
Detected prefix: 445954
Boundary offset: 445953 (0x6CE01)
Unicode scalar index: 445953
UTF-16 code-unit idx: 445953
Stable: True
Confidence: High
Line number: 4586
Byte in line: 46
Target byte: 0A (10)
--- Source Context ---
4585 | Set-Alias Get-CurrentUserTokenGroupSid Get-ProcessTokenGroup
4586 | Set-Alias Invoke-AllChecks Invoke-PrivescAudit
^
raw-byte モードの Microsoft Defender、同じファイル:```text Engine: Defender Scan mode: RawBytes Initial status: Detected Scans performed: 25 Duration: 15370.562 ms Known clean prefix: 445951 Detected prefix: 445952 Boundary offset: 445951 (0x6CDFF) Stable: True Confidence: High Signature: Trojan:Win32/Kepavll!rfn
Line number: 4586 Byte in line: 44 Target byte: 69 (105)
--- Hex Dump --- 0006CDBF 74 2D 50 72 6F 63 65 73 73 54 6F 6B 65 6E 47 72 t-ProcessTokenGr 0006CDCF 6F 75 70 0A 53 65 74 2D 41 6C 69 61 73 20 49 6E oup.Set-Alias In 0006CDDF 76 6F 6B 65 2D 41 6C 6C 43 68 65 63 6B 73 20 49 voke-AllChecks I 0006CDEF 6E 76 6F 6B 65 2D 50 72 69 76 65 73 63 41 75 64 nvoke-PrivescAud 0006CDFF 69 74 0A it.
両エンジンは**4586行目**で収束します。Defenderの境界は`Invoke-PrivescAudit`の末尾の`it`の内側に位置し、AMSIの境界は同じ行を終了する改行文字上にあり、2バイト後になります。どちらのオフセットも「シグネチャそのもの」ではなく、各プロバイダーが依然としてフラグを立てる最も早いプレフィックスであり、2バイトの不一致はまさに前述のトークン化/コンテキスト効果です。Defenderはさらに、一致した対象の名前を報告します(`Trojan:Win32/Kepavll!rfn`)。AMSIはシグネチャ名を報告しないため、AMSIヒットを特徴付けるために`Invoke-OffsetThreatScanRegion`と`Get-OffsetDetectionTrigger`が存在します。
両スキャンとも約436 KiBのファイルに対して25回のプロバイダープローブを消費します。二分探索はファイルサイズに対して対数的であり、すべてのプローブは`ProbeLog`に記録されます。
プロバイダー契約と解釈の指針については[脅威スキャン設計](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/THREAT-SCANNING.md)、スキャナー契約と検索コアを変更せずにプロバイダーを追加する方法については[プロバイダーインターフェース](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/PROVIDER-INTERFACE.md)、実装の境界と帰属については[脅威スキャンの来歴](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/PROVENANCE.md)、バージョン管理されたオブジェクト契約については[出力スキーマ](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/OUTPUT-SCHEMA.md)を参照してください。
### 検出境界レポート
`Export-OffsetThreatReport`は、1つ以上のスキャン結果を自己完結型のMarkdownまたはHTMLレポート(ファイルごとのサマリー、プロバイダー/シグネチャ/エンジンのメタデータ、完全な`ProbeLog`監査証跡、警告を含む)に変換し、エンゲージメントの報告書に添付できるようにします。結果のみを読み取り、再スキャンは行わないため、クロスプラットフォームで実行できます。`-IncludeIoc`を追加すると、ハッシュ/エントロピー/PEインジケーターパネル(`Get-OffsetIOC`と同じデータ)が各レポートエントリに組み込まれ、`-IncludeTrigger`を追加すると、境界を持つすべての結果に検出トリガー分析(下記参照)が追加されます。```powershell
Invoke-OffsetThreatScan ./sample.ps1 -Engine AMSI -ScanMode Text -PassThru |
Export-OffsetThreatReport -Path ./report.html -Format Html
# Aggregate many scans into one report, with an indicators panel and trigger analysis per file:
$results | Export-OffsetThreatReport -Path ./engagement.md -IncludeIoc -IncludeTrigger
コーパス規模のレポートでは、-IncludeIoc はPowerShell内のすべてのファイルを再スキャンするため、遅くなります。同梱のネイティブエンジン OffsetScan は、スキーマが同一のIOC JSONをはるかに高速に出力します。レポートで -IocJsonPath を指定すると、各パネルはそのJSONからデータを取得します(そこに含まれないファイルについてのみ、ライブの Get-OffsetIOC にフォールバックします):```powershell
offsetscan ioc ./corpus --recurse > ./ioc.json
$results | Export-OffsetThreatReport -Path ./engagement.md -IocJsonPath ./ioc.json
### バッチ / コーパススキャン
`Invoke-OffsetThreatScanBatch` は、ファイル、ディレクトリ、ワイルドカードをファイルリストに展開し、各ファイルをスキャンして(ファイルごとの失敗があっても続行し)、ファイルごとに1つの結果を返します。`-Summary` はフラット化された検出マトリックスを返します。完全な結果はレポートジェネレーターに直接パイプされます。プロバイダースキャンはWindows専用です。```powershell
Invoke-OffsetThreatScanBatch ./payloads -Recurse -Engine AMSI |
Export-OffsetThreatReport -Path ./engagement.html -Format Html
Invoke-OffsetThreatScanBatch ./samples -Summary |
Format-Table File, DetectionPrefixLength, Confidence, ProbeCount
検出差分 / リグレッション
Compare-OffsetThreatResult は、2つのスキャン結果 - 例えば、シグネチャ定義の更新前と更新後の同じファイル - を差分比較し、その変化を(NewlyDetected、NoLongerDetected、BoundaryEarlier、BoundaryLater、BoundaryUnchanged、BothClean)として分類し、境界デルタと変更されたフィールドを報告します。```powershell
$before = Invoke-OffsetThreatScan ./sample.ps1 -Engine Defender -PassThru
... update Defender signature definitions ...
$after = Invoke-OffsetThreatScan ./sample.ps1 -Engine Defender -PassThru Compare-OffsetThreatResult -Reference $before -Difference $after
### マルチリージョン検出
プレフィックス検索は*最初の*検出境界を見つけます。`Invoke-OffsetThreatScanRegion` は、ファイルをセグメントに分割し、各セグメントをAMSI経由で**完全にメモリ内で**個別にスキャンすることで、*複数の*独立して検出可能な領域を見つけます。検出されたものはディスクに書き込まれないため、Defenderのリアルタイム保護がトリガーされたり再設定されたりすることはありません。各ヒットはセグメント内で二分され、正確なトリガー境界を絶対ファイルオフセットにマッピングします。```powershell
Invoke-OffsetThreatScanRegion ./payload.bin -SegmentCount 16 |
Select-Object -ExpandProperty DetectedRegions |
Format-Table SegmentIndex, StartOffset, EndOffset, AbsoluteBoundaryOffset, SignatureName
これは、単独でトリガーする領域を報告します。ファイル全体のコンテキストでのみ発火するシグネチャや、セグメント境界をまたぐシグネチャを見逃す可能性があるため、領域はあくまで手がかりとして扱い、Invoke-OffsetThreatScan と手動検証で確認してください。ここでサポートされているエンジンは AMSI(インメモリ)のみです。Defender のファイルスキャンは、検出されたコンテンツをディスクに書き込む必要があります。
検出トリガーの相関
境界は、検出が反転する場所を示します。Get-OffsetDetectionTrigger は、そこに何があるかを示します。プレフィックス境界は、最も早く検出されたプレフィックスの最後のバイトであるため、トリガーコンテンツはそのオフセットで終わるランレングスです。このコマンドは、境界が該当する PE セクション、そこまでのランのエントロピー(プレーンテキスト vs パック/エンコード)、およびそのオフセットで終わる、またはまたぐ抽出された文字列を近接度順にランク付けして報告します(候補シグネチャコンテンツ)と、1行の解釈を報告します。バイトのみを読み取り、再スキャンは行わないため、保存された結果に対してクロスプラットフォームで実行できます。```powershell
Invoke-OffsetThreatScan ./flagged.ps1 -Engine AMSI -PassThru | Get-OffsetDetectionTrigger
Or point it at a file and a known boundary directly:
Get-OffsetDetectionTrigger -FilePath ./sample.bin -BoundaryOffset 0x4A1 | Select-Object Interpretation, Section, PreBoundaryEntropy -ExpandProperty CandidateStrings
### Detection-drift journal
「以前は検出されたのに、今は検出されない」には、ファイルが変更された、シグネチャが変更された、プロバイダーが非決定的である、という3つのまったく異なる原因があります。`Add-OffsetDriftEntry` は追記専用のNDJSONスナップショット(ファイルのSHA-256、ステータス、境界、シグネチャ名、ローカルのDefenderシグネチャ/エンジンバージョン)を記録し、`Get-OffsetDrift` はその履歴を読み取って、各変更を正しい原因に帰属させます。```powershell
# Record a snapshot over time (from a scan result, or directly):
Invoke-OffsetThreatScan ./sample.ps1 -Engine AMSI -PassThru | Add-OffsetDriftEntry
Add-OffsetDriftEntry -FilePath ./sample.ps1 -Status Detected -Engine AMSI -SignatureName 'Trojan:PowerShell/X'
# Later, explain what changed:
Get-OffsetDrift -FilePath ./sample.ps1 | Select-Object -ExpandProperty Transitions
各遷移にはラベルが付けられています。SHA-256 の変更は ファイル変更 として読み取られ、ファイルは変更されずに Defender シグネチャのバージョンが変わった状態の変化は シグネチャのドリフト として読み取られ、どちらでもない状態の変化は 非決定的 なプロバイダ結果として読み取られます。ジャーナルの既定値は %LOCALAPPDATA%\OffsetInspect\drift.ndjson です。-JournalPath で上書きします。
シグネチャ堅牢性テスト(許可された使用のみ)
Invoke-OffsetMutationTest は、検出エンジニアリングの問いに答えます。シグネチャはもろい完全リテラル一致なのか、それとも一般的な難読化に対して堅牢なのか? AMSI が現在検出するサンプルが与えられた場合、標準的な摂動(大文字小文字の反転、文字列リテラルの連結、コメント挿入、空白の注入)を適用し、各バリアントを再スキャンして、どのクラスが検出を無効化するかを報告します。すべてはメモリ内で AMSI のプロセス内インターフェイスを介して行われ、どのバリアントもディスクに書き込まれないため、回避アーティファクトは生成されず、Defender のリアルタイム保護も関与しません。このコマンドは -AuthorizedEngagement なしでは実行を拒否し、テストを許可されたサンプルにのみ使用することを意図しています。```powershell
Invoke-OffsetMutationTest -FilePath ./flagged.ps1 -AuthorizedEngagement |
Select-Object RobustnessSummary -ExpandProperty Results
たとえば、"brittle: neutralized by StringConcatenation, CommentInsertion" という結果は、ディフェンダーに対して、シグネチャが連続したリテラルにキーイングされており、拡張すべきであることを伝えます。また、権限を持つオペレーターには、コントロールのカバレッジについて同じことを伝えます。
### テレメトリ相関
境界の検出は、*エンジン*が何を見ているかを示します。`-CaptureTelemetry` は、*ディフェンダー*が何を見ているかを示します。これは、スキャン前にアクセス可能な各 Windows テレメトリログのハイウォーターマークをスナップショットし、そのアクションがアラートを発生させたかどうか、どのようなコンテキストで発生したか、どのソースがブラインドであったかを報告します - 「可視性を想定し、それを検証する」という問いに、証拠をもって答えるものです。```powershell
$r = Invoke-OffsetThreatScan ./flagged.ps1 -Engine AMSI -CaptureTelemetry -PassThru
$r.Telemetry | Format-List AlertGenerated, CorrelationConfidence, Findings
$r.Telemetry.Alert | Format-List ThreatName, SeverityName, SourceName, ProcessName, DetectionUser
Telemetry プロパティ(OffsetInspect.TelemetryCorrelation)が報告する内容:
AlertGenerated/Alert- スキャンに対して Microsoft Defender の検出(イベント 1116/1117)が記録されたかどうか、およびそのコンテキスト(脅威名、重大度、検出ソース、プロセス、ユーザー)。CorrelationConfidence- 検出のソースがプロバイダーと一致し、かつそのプロセスがスキャン実行ホストと一致する場合にのみ High となります。偶然の同時検出が主張されることはありません。ソースのみの一致は Medium、どちらも一致しない場合は Low です。SourcesAccessible/SourcesUnavailable- 読み取り可能だったテレメトリログと、参照できなかったテレメトリログ(Sysmon が存在しない、Security ログが管理者権限を必要とするなど)。可視性のギャップ自体が1つの所見です。Findings- 平易な言葉による結論: 完全なコンテキストを伴うアラート、脅威名を欠いたアラート、テレメトリがまったくない場合、またはソースが欠落している場合。
主要なソースは Microsoft Defender Operational ログであり、管理者権限なしで読み取れます。相関付けはイベント RecordId(単調増加でタイムゾーンに依存しない)によって行われます。Windows のみで、-CaptureTelemetry が渡されない限り動作しません。
静的トリアージヘルパー
3つのクロスプラットフォーム静的解析コマンドは、マルウェアのトリアージをサポートし、オフセットコアと組み合わせて使用できます:
Get-OffsetEntropy- パック済みまたは暗号化された領域を特定するためのウィンドウ単位のシャノンエントロピー(bits/byte)。フラグが付いたウィンドウをInvoke-OffsetThreatScanRegionの検出結果と照合します。Get-OffsetString- バイトオフセット付きの印刷可能な ASCII および UTF-16LE 文字列。オフセットをInvoke-OffsetInspectにパイプしてコンテキストを取得します。Get-OffsetPEInfo- PE の machine/ビット数、エントリポイント、セクションテーブル、インポートと imphash、末尾に追加されたオーバーレイの検出、リソースサイズ。-Offsetはバイトオフセットをそのセクション(.text、.rsrc、...)に対応付けます。Imphash は標準のlibrary.functionMD5 を使用し、pefile/VirusTotal とバイトレベルで同一であることを検証済みです。特殊ライブラリの序数解決も含まれるため、ws2_32/wsock32/oleaut32からインポートされた序数は実際の関数名に解決されます。それ以外の序数インポートは、pefile とまったく同じくordNNNとして表示されます。Get-OffsetIOC- 上記を組み合わせたワンショットのインジケーターパネル: MD5/SHA-1/SHA-256(シングルパス)、全体エントロピー、印刷可能文字列の数、そして該当する場合は PE machine/imphash/overlay。```powershell Get-OffsetEntropy ./sample.bin -HighOnly | Select-Object -ExpandProperty Windows Get-OffsetString ./sample.bin -MinimumLength 6 | Where-Object Value -match 'http|.dll' Get-OffsetPEInfo ./sample.exe | Select-Object Machine, EntryPointHex, ImpHash, ImportedDllCount, HasOverlay, OverlaySize Get-OffsetIOC ./sample.exe | Format-List
### YARA スキャン
`Invoke-OffsetYaraScan` は、アナリストが作成した YARA ルールを実行し、各マッチをバイトオフセットとともに返します。これは、AMSI/Defender の検出境界ビューを、自身で制御するシグネチャで補完し、ウイルス対策ソフトのインストールも不要です(YARA エンジンのみ必要。例: `winget install VirusTotal.YARA`)。オフセットはそのままインスペクタに渡されます。```powershell
Invoke-OffsetYaraScan ./sample.bin -RulePath ./rules/malware.yar |
ForEach-Object { Invoke-OffsetInspect $_.File $_.Offset -ContextLines 2 }
ClamAV スキャン
Invoke-OffsetClamScan は、ClamAV のオンデマンドエンジンでファイルをスキャンし、正規化された結果(Clean / Detected / Error、およびシグネチャ名)を返します。clamscan は呼び出しのたびに完全なシグネチャデータベースを読み込むため、これは単一ファイル検出器であり、境界検索エンジンではありません(境界検索には clamd デーモンが必要です)。ClamAV がインストールされていることと、そのシグネチャデータベースがダウンロードされていることが必要です - freshclam は、設定ファイルが存在するまで実行されません:```powershell
One-time setup: create the freshclam config (remove the sample's "Example" line), then fetch databases.
Copy-Item "$env:ProgramFiles\ClamAV\conf_examples\freshclam.conf.sample" "$env:ProgramFiles\ClamAV\freshclam.conf" (Get-Content "$env:ProgramFiles\ClamAV\freshclam.conf") -notmatch '^\sExample\s$' | Set-Content "$env:ProgramFiles\ClamAV\freshclam.conf" # requires admin to write under Program Files & "$env:ProgramFiles\ClamAV\freshclam.exe"
Invoke-OffsetClamScan ./sample.bin
`-DatabasePath` を使用して、書き込み可能な(管理者権限のない)場所にある署名ディレクトリを指定し、`clamscan` が `PATH` にない場合は `-ClamScanPath` を使用します。
## 結果オブジェクト
`Invoke-OffsetInspect -PassThru` は、以下を含む `OffsetInspect.Result` オブジェクトを返します。
- 正規化されたファイルパス、ファイルサイズ、10進数および16進数のオフセット。
- 要求されたエンコーディングと検出されたエンコーディング。
- 行番号、ソースプレビュー、コンテキスト行、バイト位置、文字位置。
- 対象バイトと境界付き16進ダンプ。
- オプションの比較バイトと差分状態。
- 警告、所要時間、成功状態、エラーメッセージ。
`Invoke-OffsetThreatScan -PassThru` は、以下を含む `OffsetInspect.ThreatScanResult` オブジェクトを返します。
- ファイルSHA-256、UTCスキャンタイムスタンプ、エンジン、スキャンモード、初期プロバイダーステータス、プロバイダーメタデータ。
- 既知クリーンおよび既知検出のプレフィックス長。
- バイト境界とオプションの文字境界。
- 安定性、信頼度、スキャン回数、繰り返し境界ステータス、および利用可能な場合はシグネチャ名。
- すべての個別プロバイダープローブの `ProbeLog` 監査証跡(CSV出力では `ProbeCount` として表示され、`-ProbeLogPath` でJSONトランスクリプトにエクスポート可能)。[出力スキーマ](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/OUTPUT-SCHEMA.md) を参照してください。
- マッピングされた境界におけるネストされた `OffsetInspect.Result` コンテキスト。
## パフォーマンスモデル
v1 スタイルの実装では、オフセットごとにファイル全体を再読み取りしてデコードしていました。バージョン 2 では、ファイルごとに処理をグループ化しています。```text
Previous approach: approximately O(file size × offset count)
Version 2: approximately O(file bytes scanned once + requested windows)
ソースマッピングはストリーミングステートマシンを使用し、要求されたオフセットに必要な前後の行記述子のみを保持します。非常に長い個々の行は、-MaxLineBytes によって制御される境界付きプレビューで表示されます。
リポジトリ構成```text
OffsetInspect.ps1 Thin offset-inspection CLI wrapper OffsetThreatScan.ps1 Thin threat-scan CLI wrapper module/OffsetInspect/ Complete Gallery package OffsetInspect.psd1 OffsetInspect.psm1 OffsetInspect.Format.ps1xml Public/ Private/ tests/ Pester tests benchmarks/ Reproducible performance harness build/ Validation, packaging, signing, publishing .github/workflows/ CI, dependency review, release publishing docs/ Architecture, schemas, provider design, release checklist
## 開発
固定された検証ツールをインストールします:```powershell
Install-Module Pester -RequiredVersion 5.7.1 -Scope CurrentUser
Install-Module PSScriptAnalyzer -RequiredVersion 1.25.0 -Scope CurrentUser
完全なローカルゲートを実行してください:```powershell ./build/Test-Module.ps1
決定論的ベンチマークハーネスを実行します:```powershell
./benchmarks/Measure-OffsetInspect.ps1 -FileSizeMiB 64 -OffsetCount 5000
ベンチマーク結果は、ストレージ、ホストの負荷、PowerShell エディション、ファイルの形状によって異なります。コミットを比較する際は、これらの入力を記録してください。
決定論的なリリースアーカイブと SHA-256 ファイルを構築する:```powershell ./build/New-ReleasePackage.ps1
CIは、WindowsとLinux上のPowerShell 7、Windows PowerShell 5.1、PSScriptAnalyzer、分離モジュールのパッケージング、およびリリースアーカイブを検証します。リリースメンテナーは、[リリースチェックリスト](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/RELEASE-CHECKLIST.md)にも従う必要があります。
## セキュリティと責任ある利用
OffsetInspectは、許可された防御的研究、検知エンジニアリング、リバースエンジニアリング、マルウェア解析、およびセキュリティテストを目的としています。脅威プロバイダー機能はコンテンツを分析しますが、エンドポイント保護を無効化、回避、または再構成することはありません。
`Invoke-OffsetMutationTest`は、シグネチャ堅牢性の評価のための検知回避バリアントを生成します。これは完全にメモリ上で動作し(バリアントはディスクに書き込まれません)、明示的な`-AuthorizedEngagement`の確認なしでは実行を拒否します。テストする権限のあるサンプルとコントロールに対してのみ使用してください。
脆弱性を報告する前に[SECURITY.md](https://github.com/warpedatom/offsetinspect/blob/HEAD/SECURITY.md)を確認してください。機密性の高いサンプルを公開のGitHub issuesに提出しないでください。
## ライセンス
OffsetInspectは[MITライセンス](https://github.com/warpedatom/offsetinspect/blob/HEAD/LICENSE)の下でリリースされています。