仕様の理解は重要

「Process Ghosting」という新しい手法が確認されています。

通常、アンチマルウェアを実現する機構は、動作環境の機能を使用します。
たとえばWindows環境で動作するアンチマルウェアの場合、PsSetCreateProcessNotifyRoutineExなどのAPIを呼び出すことでこれを実現しようとします。
PsSetCreateProcessNotifyRoutineExは、名前が示す通り、プロセスが生成されたときに知らせてくれることを期待する機能です。
この機能を利用することで、新しいプロセスが生成された際に、そのプロセスが怪しいかそうでないかを判定しよう、という作戦です。
これまではこれはうまくいきました。
でも、このAPIの仕様を詳しく理解すると、必ずしもその効能がいつでも得られるとは限らないことがわかりました。
このAPIの動作は、厳密にいうとこうなります。

  • PsSetCreateProcessNotifyRoutineExは、プロセス内の最初のスレッドの作成時に呼び出される

なんとなくしっくりこない感じがします。
ここが重要なポイントでした。

もう一つ、深くかかわるものがあります。
ファイルの削除機能です。
OSにはファイルの削除機能が搭載されます。
ファイルの削除を行うと、ファイルは削除されます。
ですが、ここでも例外があります。
削除される予定のファイルを参照しようとすると参照が失敗します。

これらを組み合わせると、OS作成の側が想定できなかった使い方ができるようになります。
「Process Ghosting」です。

  1. ファイルを作成する
  2. NtSetInformationFile(FileDispositionInformation)を使用して、ファイルを削除保留状態にする
  3. ペイロード実行可能ファイルをファイルに書き込みます。ファイルはすでに削除保留中であるため、コンテンツは永続化されない
    通常はファイルは書き換えられるとOSにキャッシュされますが、削除保留中のものは対象外となるため、こっそり内容だけを変更できる
  4. ファイルのimageセクションを作成する
  5. 削除保留ハンドルを閉じて、ファイルを削除する
  6. imageセクションを使用してプロセスを作成する
  7. プロセス引数と環境変数を割り当てる
  8. プロセスで実行するスレッドを作成する

そうです。
プロセスのスレッドが作成されたときには、すでにそのファイルはありません。
削除される前にファイルを開こうにも、削除保留状態に設定されているため、参照できません。
つまり、内容を誰にも検査されていないコードを誰にも検査されない状態で、実行できることになります。

実装上の問題(実装バグ)は、修正が困難でない場合が多いです。
しかし、設計上の問題(仕様バグ)は、表面的な対策で対応することは容易ではありません。

Windows環境におけるアンチマルウェアということの実現が怪しくなってしまう問題と言えそうです。

試合開始のゴングは鳴らされました。
さて、この問題に早く対応できるのは、攻撃側と防御側のどちらなのでしょうか。

参考記事(外部リンク):What you need to know about Process Ghosting, a new
executable image tampering attack

www.elastic.co/jp/blog/process-ghosting-a-new-executable-image-tampering-attack