
Process Herpaderping の概念実証、ツール、および技術的な詳細。Process Herpaderping はプロセスの意図を隠蔽することでセキュリティ製品を回避します。
[
][png.HerpaderpIcon]
Process Herpaderping は、イメージがマッピングされた後にディスク上のコンテンツを変更することで、プロセスの意図を隠蔽する手法です。これにより、セキュリティ製品やOS自体に興味深い動作が発生します。
![][png.mimioogle]
![][gif.SurivDemo]
一般的に、セキュリティ製品はWindowsカーネルでコールバックを登録することで([PsSetCreateProcessNotifyRoutineEx][msdn.PsSetCreateProcessNotifyRoutineEx])、プロセス作成時にアクションを実行します。この時点で、セキュリティ製品は実行可能ファイルのマッピングに使用されたファイルを検査し、このプロセスの実行を許可するかどうかを判断する場合があります。このカーネルコールバックは、プロセスオブジェクトが作成されたときではなく、最初のスレッドが挿入されたときに呼び出されます。
このため、攻撃者はプロセスを作成してマッピングし、ファイルの内容を変更してから最初のスレッドを作成することができます。作成コールバックで検査を行う製品は、変更されたコンテンツを確認することになります。さらに、一部の製品はファイル書き込みを監視するオンライトスキャンアプローチを使用しています。ここでよく知られた最適化手法は、ファイルが書き込まれたことを記録し、[IRP_MJ_CLEANUP][msdn.IRP_MJ_CLEANUP](ファイルハンドルが閉じられるなど)が発生するまで実際の検査を延期することです。したがって、write -> map -> modify -> execute -> close ワークフローを使用する攻撃者は、[IRP_MJ_CLEANUP][msdn.IRP_MJ_CLEANUP]での検査のみに依存するオンライトスキャンを回避できます。
この慣行を悪用するには、まずバイナリをディスク上のターゲットファイルに書き込みます。次に、ターゲットファイルのイメージをマッピングし、プロセス作成に使用するためにOSに提供します。OSは親切にも元のバイナリをマッピングしてくれます。既存のファイルハンドルを使用し、最初のスレッドを作成する前に、ターゲットファイルのコンテンツを変更してイメージをバックアップするファイルを隠蔽または偽装します。しばらくして、最初のスレッドを作成して元のバイナリの実行を開始します。最後に、ターゲットファイルハンドルを閉じます。これをステップごとに見ていきましょう:
NtCreateProcessEx)。NtCreateThreadEx)。
![][svg.StateDiagram]
@startuml
hide empty description
[*] --> CreateFile
CreateFile --> FileHandle
FileHandle --> Write
FileHandle --> NtCreateSection
Write -[hidden]-> NtCreateSection
NtCreateSection --> SectionHandle
SectionHandle --> NtCreateProcessEx
FileHandle --> Modify
NtCreateProcessEx -[hidden]-> Modify
NtCreateProcessEx --> NtCreateThreadEx
Modify -[hidden]-> NtCreateThreadEx
NtCreateThreadEx --> [*]
FileHandle --> CloseFile
NtCreateThreadEx -[hidden]-> CloseFile
NtCreateThreadEx --> PspCallProcessNotifyRoutines
PspCallProcessNotifyRoutines -[hidden]-> [*]
CloseFile --> IRP_MJ_CLEANUP
IRP_MJ_CLEANUP -[hidden]-> [*]
PspCallProcessNotifyRoutines --> Inspect
PspCallProcessNotifyRoutines -[hidden]-> CloseFile
IRP_MJ_CLEANUP --> Inspect
Inspect -[hidden]-> [*]
CreateFile : Create target file, keep handle open.
Write : Write source payload into target file.
Modify : Obscure the file on disk.
NtCreateSection : Create section using file handle.
NtCreateProcessEx : Image section for process is mapped and cached in file object.
NtCreateThreadEx : The cached section is used.
NtCreateThreadEx : Process notify routines fire in kernel.
Inspect : The contents on disk do not match what was executed.
Inspect : Inspection of the file at this point will result in incorrect attribution.
@enduml
以下のデモでわかるように、実行ターゲットとして CMD.exe が使用されています。最初の実行では、ディスク上のバイトがパターンで上書きされます。2回目の実行では、CMD.exe が ProcessHacker.exe で上書きされます。Herpaderping ツールは、元の署名を保持しながら、バイナリを可能な限り ProcessHacker.exe に近い形に修正します。同じバイナリの複数回の実行と、ユーザーに表示されるプロセスとディスク上のファイルとの比較に注目してください。
![][gif.ProcessHerpaderp]
![][png.procmon]
上記の動作を観察しましたが、一部は驚くべき内容かもしれません。この動作を説明してみましょう。
[技術的な詳細解説][md.DivingDeeper]
Windowsプラットフォームをセキュリティで保護するための製品を設計する際、この分野の多くのエンジニア(私も含めて)は、OSがデータをどのように扱うかについて先入観を持ってしまうことがよくあります。このシナリオでは、プロセスが作成されたときにディスク上のファイルが「ロック」されたままになると期待する人もいるかもしれません。ファイルを削除することはできません。書き込むこともできません。しかし、名前を変更することはできます。ここで示されているように、適切な条件下では、実際にファイルに書き込むことができます。自身の前提に常に警戒し、疑問を持ち、調査を行うことが重要です。
この研究の動機は、ファイルが書き込まれたときの分析方法を発見することにありました。プロセスハローイングやドッペルギャンギングに関する以前の研究を踏まえ、これが可能かもしれないと理論化しました。目標は、より優れたセキュリティを提供することです。古い錠前の壊し方を理解せずして、より良い錠前を作ることはできません。
Herpaderping はハローイングやドッペルギャンギングに似ていますが、いくつかの重要な違いがあります。
プロセスハローイングでは、実行開始前にマッピングされたセクションを変更します。抽象化すると、map -> modify section -> execute のようになります。このワークフローにより、ハローイングされたプロセスの意図した実行フローが、意図しないコードへと分岐することになります。ドッペルギャンギングはハローイングの一種と見なされるかもしれません。しかし、私の意見では、ハローイングは既にマッピングされたコードへの明示的な書き込みを伴うという点で、インジェクションに近いものです。これは、セクションが変更されない Herpaderping とは異なります。
プロセスドッペルギャンギングは Herpaderping に近いです。ドッペルギャンギングはトランザクション化されたファイル操作を悪用し、一般的に以下の手順を含みます:
transact -> write -> map -> rollback -> execute。
このワークフローでは、OSはイメージセクションを作成し、トランザクションを考慮するため、キャッシュされたイメージセクションはトランザクションに書き込んだものになります。OSはこの手法に対するパッチを適用しました。正確には、それが引き起こすクラッシュをパッチしました。彼らはこれをトランザクションの「合法的な」使用と見なしているかもしれません。ありがたいことに、Windows Defenderはドッペルギャンギング手法を検出します。ドッペルギャンギングは Herpaderping とは異なり、トランザクション化されたファイル操作に依存しません。また、Defenderは Herpaderping を検出しません。
参考までに、一般化された手法を示します:
| タイプ | 手法 |
|---|---|
| ハローイング | map -> modify section -> execute |
| ドッペルギャンギング | transact -> write -> map -> rollback -> execute |
| Herpaderping | write -> map -> modify -> execute -> close |
ここに違いが明確に示されています。Herpaderpingはドッペルギャンギングよりもノイズが多く、悪意のあるビットがディスクに書き込まれるという点で議論の余地がありますが、セキュリティ製品は依然として Herpaderping を検出できないことが確認されています。
ここには明確な修正方法はありません。ファイルへの書き込みアクセス権がある場合にイメージセクションがマッピング/キャッシュされるのを防ぐことが、この穴を塞ぐ合理的な方法であると思われます。しかし、それが実用的な解決策であるかどうかは別問題です。
別の選択肢としては、まだプロセスにマッピングされていない場合、ファイルへの変更をキャッシュされたイメージセクションにフラッシュすることも考えられます。しかし、新しいプロセスへのマッピングは NtCreateProcess で行われるため、これはおそらく実行可能な解決策ではありません。
検出の観点からは、実際にマッピングされたビットを特定する優れた方法はありません。[IRP_MJ_CLEANUP][msdn.IRP_MJ_CLEANUP] での検査や、[PsSetCreateProcessNotifyRoutineEx][msdn.PsSetCreateProcessNotifyRoutineEx] で登録されたコールバックでは、ディスク上のビットが変更されているため、誤った属性判定につながります。作成されたセクションからファイルを再構築する必要があります。ここで指摘しておく価値があるのは、Windows 10 で登録可能な新しいコールバック [PsSetCreateProcessNotifyRoutineEx2][msdn.PsSetCreateProcessNotifyRoutineEx2] ですが、これも以前のコールバックと同じ問題を抱えており、プロセスオブジェクトが作成されたときではなく、最初のスレッドが実行されたときに呼び出されます。Microsoft は [PsSetCreateThreadNotifyRoutineEx][msdn.PsSetCreateThreadNotifyRoutineEx] を追加しました。これは、[PsCreateThreadNotifyNonSystem][msdn.PSCREATETHREADNOTIFYTYPE] で登録した場合、実行開始直前ではなく、最初のスレッドが挿入されたときに呼び出されます。[PSCREATEPROCESSNOTIFYTYPE][msdn.PSCREATEPROCESSNOTIFYTYPE] を拡張してプロセスオブジェクトが作成されたときに呼び出すようにしても役に立ちません。詳細な解説セクションで見たように、イメージセクションオブジェクトは NtCreateProcess ではなく [NtCreateSection][msdn.NtCreateSection] 呼び出しでキャッシュされるからです。
何が実行されたかを簡単に特定することはできません。残された手段は、攻撃者による悪質な動作を検出することです。動作指標の発見は読者への課題とします。
以下は、2020年8月31日時点でテストされた製品とWindows OSのリストです。テストは既知の悪意のあるバイナリを使用して実施されました。
| オペレーティングシステム | バージョン | 脆弱性あり |
|---|---|---|
| Windows 7 Enterprise x86 | 6.1.7601 | はい |
| Windows 10 Pro x64 | 10.0.18363.900 | はい |
| Windows 10 Pro Insider Preview x64 | 10.0.20170.1000 | はい |
| Windows 10 Pro Insider Preview x64 | 10.0.20201.1000 | はい |