サービスとして登録されタイムアウトしたマルウェアは動作するか?(その1)の検証の続きです。
今回は、サービスに登録する処理をCreateProcessにし、実際にプロセスを起動するか検証してみました。
さらに、イベントログの設定を変えて、それらのプロセスの起動を追えるか確認してみました。
サービスにCreateProcessだけするプログラムを設定
今回は、前回の記事で作った「TestWriteFile.exe」を起動するだけのプログラムを作成し、これをサービス登録します。
正常に動作すれば、「TestWriteFile.exe」を実行します。
「TestWriteFile.exe」はループ処理を続けるので、プロセスが残る、というわけです。
プロセスを起動するプログラムのソースは以下のとおりです。
TestCreateProcess.cpp
うーん、雑なソース。
まあ、実験目的なので(汗)
これを、前回同様「test」というサービスで動作するように設定します。
レジストリを以下のように設定します。
サービスの設定状況を確認すると、「TestCreateProcess.exe」を自動実行するようになっているのが確認できます。
実行されるファイルが、「C:\tmp」にあることも確認します。
準備ができたことを確認したら、再起動によりサービスを開始してみます。
サービスとして登録したプログラムのCreateProcessの結果
CreateProcessで「TestWriteFile.exe」を起動する「TestCreateProcess.exe」をサービスで起動するように設定したら、再起動します。
これが正しく動けば、再起動時に自動的に「TestCreateProcess.exe」が実行され、「TestCreateProcess.exe」が「TestWriteFile.exe」を実行し、「test.txt」ファイルが出力されるはずです。
また、「TestCreateProcess.exe」はすぐ終了しますが、サービス終了のログが出るかもしれません。
再起動してイベントログを確認したところ、以下のようなログが残されていました。
これは、前回記事同様、サービスでないプログラムがサービスの登録、ステータス設定をしなかった場合、エラーとして出力されている、ということです。
このことから、サービスとして登録された「TestCreateProcess.exe」が実行されたことは確認できました。
では、この実行プログラムは「TestWriteFile.exe」を起動し、このプログラムは「test.txt」を出力できたのでしょうか?
確認した結果は以下のとおりです。
無事、「TestWriteFile.exe」は起動され、プロセスが残っています。
(「TestWriteFile.exe」は、内部でタイマー付き永久ループのため、プロセスは終了しません。)
また、「TestWriteFile.exe」が作成する「test.txt」も出力されています。
以上から、サービスとして起動された通常のプログラムは、タイムアウトまでに別プロセスを実行させることができることを確認できました。
実行された「TestWriteFile.exe」プロセスをよく見ると、ツリーとして親プロセスがありません。
起動した「TestCreateProcess.exe」が終了しているので当然といえば当然なのですが、「TestCreateProcess.exe」を起動した「service.exe」の子になることはない、ということです。
これをサイバー攻撃に例えれば、「マルウェアを起動するプログラム」と「常駐するマルウェア」を用意し、「マルウェアを起動するプログラム」を自動起動サービスとして登録することで、「常駐するマルウェア」を起動することは技術的に可能ということになります。
確かに、最初からサービスとして動作する「常駐するマルウェア」を作ったほうが、技術的にはスマートかもしれません。
しかし、そこまで作りこむかどうかは攻撃者の都合や考え方次第ですし、むしろ調査員の目をごまかすためにあえて二段構えにする可能性も捨てきれません。
実際、この検証は、私がフォレンジック調査をしている際に、その可能性がある兆候を見つけたからやっているんです。
(こういった検証は仕事のスコープ外なんですが、フォレンジック屋さんとして技術的に納得いくように確認したかっただけなので、プライベートの趣味でやってます。)
以上の検証結果とサイバー攻撃の可能性を考慮してまとめると、以下の着眼点があると思います。
- 通常のプログラムをサービスとして登録しても、タイムアウトまでは正常に動作する。
- そのプログラムが他の通常プログラムを起動した場合、そのプロセスはサービスではないためタイムアウトしない。
- 起動元のサービスがタイムアウトしたプロセスは、親プロセスが無い状態で実行されている。
フォレンジック調査の観点でいえば、不審なプログラムがサービスとして起動していた場合、タイムアウトになっていても安心はできず、他のプロセス起動等何らかの挙動をしていないか疑うべき、その不審なプログラムが新たに実行した可能性があるプロセスが、メモリ上に親プロセス不明で動作していたら、今回の検証の状況から十分疑う根拠となる、ということです。
おじさん、これを確認したかったのですよ!!
この動作をより確実に検証できるようにする方法はないか?
以上の分析では、イベントログとしては「TestCreateProcess.exe」のタイムアウトくらいしか残っていません。
「TestWriteFile.exe」プロセスはプロセスリストを直接確認していますし、「test.txt」の確認もタネが分かっているからできるだけです。
これをフォレンジックでやるとなると、メモリ情報をダンプしてメモリフォレンジックする、プロセスの起動をレジストリのシムキャッシュやプリフェッチを分析する、マルウェアを特定して分析し、ファイルの出力を見つける、といったことをする必要があります。
また、これらも、直接的なつながりではなく、動作の傾向からの推定となります。
これを、もう少し省力化したり、確実な記録にできないか?というと、実は記録を残すように設定することは可能なのです。
以前、「Windowsのイベントログ、足りてますか?」という記事を書きましたが、その時に指摘したデフォルトでOFFになっているログの記録を取るように変更することで、より確実な記録が取れる、というわけです。
今回も、その記事で挙げているバッチファイルを利用して有効化しました。
バッチファイルは、以下のGithubにアップロードしてあります。
ただし、このバッチのままだと、レジストリへのアクセスで一気にセキュリティログが埋まってしまい、ログサイズを200MBにしても起動時のログが流れてしまいました。
このため、このバッチの実行後、レジストリのアクセスの記録を手動でOFFにしました。
(あまりにログが出すぎて他のログが流れてしまって意味がなくなってしまうので、このバッチを後日修正するかもしれません。)
もし、上記のバッチを使うのであれば、当面は「レジストリのアクセス記録を有効化しない」ように修正したほうが良いと思います。
また、有効化した際は、ログの出力状況を確認し、ログサイズの調整や、ログが大きすぎる場合は不要なログを絞るといったチューニングも考慮してください(現状のバッチは割とファットな設定です)。
2021/2/24 追記:
バッチのうち、レジストリの監査は変更しないよう修正しました。
以上のとおりログの取得方法を変更した上で、再起動して動作結果を検証してみました。
イベントログの取得を増やして検証した結果
動作はこの記事の最初の検証と同じく、再起動時に自動的に「TestCreateProcess.exe」が実行され、「TestCreateProcess.exe」が「TestWriteFile.exe」を実行し、「test.txt」ファイルが出力する、といったものです。
では、どのように記録が残ったか見てみましょう。
サービスの設定等は変更していないため省略し、再起動を実行したところから見ていきます。
まず、「TestCreateProcess.exe」が実行されたサービスのエラーログを確認します。
システムに、「TestCreateProcess.exe」が実行されるように登録された「test」サービスがタイムアウトしたことが記録されています。
これは、先の検証と変わりません。
今度は、「セキュリティ」のイベントログを参照します。
同じ時刻の12:53:46の記録を参照してみると、「Process Creation」 (ID:4688) が記録されていました。
これらの情報の詳細を確認すると、以下のような情報が記録されていました。
一番目のプロパティでは、サービスのプロセス(service.exe)が「TestCreateProcess.exe」のプロセスを生成したことが記録されています。
二番目のプロパティでは、「TestCreateProcess.exe」が「TestWriteFile.exe」のプロセスを生成したことが記録されています。
三番目のプロパティでは、「TestWriteFile.exe」が「test.txt」にアクセスしたことが記録されています。
これらのパラメータを確認すれば、サービスが「TestCreateProcess.exe」を実行し、さらに「TestWriteFile.exe」を実行していることが確認できるということです。
このように、ログに記録する内容を増やすことで、インシデントの調査の正確性も上がり、かつ時間も短縮できる可能性がある、ということです。
このログが出力された例でフォレンジック調査したとすると、以下のように確認できるわけです。
- 自動起動を調査していると、不審なサービスの起動設定を発見。
- サービス設定のレジストリ情報から、サービス名が「test」、実行されるプロセスが「TestCreateProcess.exe」であることが分かる。
- イベントログのシステムログを調べると、「TestCreateProcess.exe」はエラーで終了している。
- イベントログのセキュリティログを「TestCreateProcess.exe」で検索すると、PC起動時にサービス(service.exe)が「TestCreateProcess.exe」を起動していることを確認できる。
- さらに「TestCreateProcess.exe」を検索すると、このプロセスが「TestWriteFile.exe」を起動していることを発見する。
- 「TestWriteFile.exe」で検索すると、このプロセスが「test.txt」にアクセスしている(=関係するファイルである)ことを発見する。
- 「test.txt」を調査することで、「TestWriteFile.exe」の挙動の一部を知ることができる
このように、イベントログが残されていれば、流れるように、かつ根拠のある調査ができるわけです。
私の大したことないような記事でも、ここまで読み進めた方々なら、その効果の大きさを理解できるのではないでしょうか。
(え?ここまでできるなら、もう調査依頼必要ない?ソレはチョット困るな(汗))
昨今、エンドポイントのセキュリティの強化でEDRが期待されているのは、EDRは振る舞いからすぐに検知するだけでなく、こういった振る舞いを記録しておくことで、後から調査をすることが可能になることもメリットとなるためです。
「EDRをすぐに導入するのは難しい」と考えている組織でも、それぞれのPCのHDDやSSDにある程度余裕があるのであれば、ログ出力設定の変更とログ容量の増加をすることで、万一の時や疑わしいときに調査できるようにしておくことができるのではないでしょうか。
フォレンジック調査では、「残っていない記録」は調査できません。
そのため、以前の記事でも「ログを残すための工夫」について触れました。
実際に、フォレンジック調査を模擬してみると、このような効果があることがハッキリすると思い、この検証記事としました。
こういった内容が、専門家だけでなく、システムの管理者にも伝わってくれればと思います。
そのため、なるべくフォレンジックツールのような専門的なものは用いず、フリーでダウンロードできるプロセスモニタやOSに付いている機能で確認できるような内容にしてみました。
セキュリティの向上に、少しでも寄与できれば幸いです。