サービスとして登録されタイムアウトしたマルウェアは動作するか?(その1) | reverse-eg-mal-memoのブログ

reverse-eg-mal-memoのブログ

サイバーセキュリティに関して、あれこれとメモするという、チラシの裏的存在。
medium(英語):https://sachiel-archangel.medium.com/

マルウェアは、永続的に動作するようにするため、自動起動するように設定することがあります。

Windowsの場合、スタートアップの登録、レジストリの自動起動登録、タスクスケジューラへの登録、サービスの登録などがよく見られます。

フォレンジック調査では、マルウェア感染調査ではこれらを調べ、永続化されているかを確認します。

それにより、マルウェアが実行された後電源がOFFになるまでの影響だったか、マルウェアが発見され除去、もしくはPCが除去されるまで影響していたかが変わるため、調査範囲が変わります。

 

今回は、「マルウェアが感染し、サービスとして自動起動するようになっていたが、サービスがタイムアウトエラーになっていた場合、このマルウェアは動作していたか?」ということを検証した記事になります。

こんなことを調べた理由は簡単で、そういうケースがあったからですw

何事も、想像ではなく、ちゃんと検証して、理論的な根拠をもって報告しないと、一人前のフォレンジッカーとは言えませんからね!

 

 

サービスがタイムアウトしたマルウェアは動作したか?

結論から書いておきます。

忙しいフォレンジッカーは、この結論が欲しいでしょう。

 

  • 自動起動するサービスとして登録されたマルウェアは起動する
  • ただし、サービスとしての登録処理が無い場合は一定時間でOSにタイムアウトされる
  • この結果、そのプロセスは常駐はしないが、タイムアウトまでの間に実行された処理は有効

 

このため、サービスとして起動したが、タイムアウトしたというエラーログが残っているマルウェアであっても、タイムアウトまでの間は動作していた、ということになります。

 

 

通常のプログラムとサービスプログラムの違い

サービスがタイムアウトする理由として考えられるのは、バグや必要なファイルが無いといったシステム的な問題、起動処理が重すぎてタイムアウトまでに起動が終わらない、サービスプログラムではない、といった理由です。

 

サービスプログラムも、いわゆる「.exe」形式の実行形式ファイルだったりします。

では、通常のプログラムと違いがあるのかというと、実は違いがあります

サービスとして利用されるプログラムは、「RegisterServiceCtrlHandlerEx」や「SetServiceStatus」といったAPIを呼び、サービスの登録やステータス設定処理を行う必要があります。

OSは、これらの処理が一定時間内に行われないと、処理が失敗したとみなして終了させてしまう、というわけです。

 

もちろん、マルウェアがこれらの処理をきっちり書いていれば、タイムアウトエラーにならず、そのままサービスとして動作します。

そんなマルウェアがあるか?というと、私は一つ見たことがあります。

 

WannaCryですよ。

 

あいつ、通常起動すると暗号化処理が走り、引数付で起動するとサービス処理として動くように書かれてますよ?

ちなみに、サービスとして動作するのは、WannaCryの悪名を上げた、EtarnalBlueとDoublePulserを利用したワーム機能です。

おっちゃん、GIAC GoldをWannaCryの解析とSnortルールのレポートで取ってるから、実はその辺はちゃんと解析してるんだぜ?(ドヤァ)

 

このため、サービス登録やステータス処理が書かれていない通常のプログラムは、サービスとして長時間動作することはできず、既定のタイムアウト時間でタイムアウトしてしまう、ということです。

 

 

試しにサービス登録してみる

では、実際に実行プログラムをサービス登録して、動作を確認してみましょう。

今回は、ファイルを作成し、その後スリープの永久ループに入る、という単純なプログラムで動作を確認してみます。

 

TestWriteFile.cpp

#include "pch.h"
#include <Windows.h>

#define OUTFILEPATH L"C:\\tmp\\test.txt"
#define OUTPUTSTRING "This is test\r\n"

int main()
{
    HANDLE hFile = 0;
    DWORD dwWritten = 0;

    hFile = CreateFile(
        OUTFILEPATH,
        (GENERIC_READ | GENERIC_WRITE),
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hFile == INVALID_HANDLE_VALUE)
        return -1;

    WriteFile(
        hFile,
        OUTPUTSTRING,
        strlen(OUTPUTSTRING),
        &dwWritten,
        NULL
    );

    CloseHandle(hFile);

    for (;;) {
        Sleep(10000);
    }

    return 0;
}

 

・・・いやもうね、Githubに上げる価値もないくらい単純なプログラムなので、ここに掲載するのみにします。

固定のパスでファイルを作成し、固定の文字列をいれてファイルを閉じ、あとは永久ループで待ちにはいっているだけです。

一応、Sleepを入れることで、CPU回りっぱなしを回避しています。

これを実行すると、「C:\tmp」フォルダに「test.txt」ファイルが作られ、中身の文字列に「This is test」が書かれるという、極めて単純なプログラムです。

 

さて、これをサービスとして登録しましょう。

サービスとして登録するには、以下のレジストリに設定します。

 

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\(サービス毎のキー)

 

ここに、いくつかのパラメータを設定することでサービスが登録されます。

フォレンジック調査でマルウェアがサービスとして登録されていないか調査するなら、ここは絶対見ることになります。

 

今回は、「test」というキーを新たに作成し、パラメータを設定しました。

パラメータについては、Microsoftのドキュメントなりを調べてください。

 

 

ポイントは、自動起動であること、実行されるプログラムが「C:\tmp\TestWriteFile.exe」であることです。

 

実際のサービスの登録状況は、以下のように確認できます。

 

 

 

 

 

これで、サービスとしてTestWriteFile.exeが起動できるようになりました。

 

 

PCの再起動でサービスを起動

PCを再起動して、サービスとして起動するかどうかを試してみます。

マルウェアが永続化する場合なら、再起動したときに起動しなければ意味が無いので、その検証も兼ねています。

 

・・・といっても、再起動で色々バタバタ動いていて重いときに、当該プロセスが立ち上がっているかを素早く確認するのはちょっとキビシイです。

 

 

 

今回はタイムアウトエラーになることが分かっているので、イベントログを確認します。

タイムアウトエラーは、イベントログビューアの「システム」で確認することができます。

 

 

タイムアウトの場合、システムのログにイベントID7009でタイムアウトとして記録されます。

マルウェアがサービスとして登録された場合、このようにイベントログに情報が記録されている場合があります。

そういった着眼点をもってイベントログを調査することも重要になります。

実際に、サービスとして登録されたマルウェアの動作を追っていて、このエラーが出ていることを発見したことが、今回の検証の原因となりました。

(まあ、自宅でプライベートタイムにやってるんですけどねー。)

 

さて、タイムアウトが記録されているので、起動はしたと思いますが、実際サービスとしての処理が入っていないプログラムがどの程度動いたか、ということです。

先ほどのプログラムは、「C:\tmp」フォルダに「test.txt」ファイルを作成したあと、永久ループに入る、というものでした。

では、「test.txt」ファイルは作成されたのでしょうか?

 

 

 

「C:¥tmp」に「test.txt」が作られていました。

タイムスタンプを見ても、タイムアウトで停止したのが 23:57:16 なので、そのタイムアウト直前に作成されたことが分かります。

つまり、サービスプログラムでなくても、タイムアウトまでの間はそのプログラムは正常に動作する、ということです。

 

 

マルウェアの調査で留意すべきことは?

この検証で、サービスプログラムでなくても、サービスとして登録されたプログラムがタイムアウトまでの間は動作することが確認できました。

これは、実行されたマルウェアがサービスプログラムではない場合、それ自身は永続化はできないものの、タイムアウトまでの間は動作する、ということです。

 

つまり、「タイムアウトまでに必要な処理を終わらせることができるマルウェアなら、タイムアウトは問題ない」ということになります。

具体的には、「タイムアウトまでに別の悪意あるプロセスを起動させる」、「タイムアウトまでの時間を長めにし、マルウェアが必要な処理をやりきってしまう」、「サービスがエラー停止した場合、定期的に再起動する設定にすることで、半常駐のような状態にする」といった手口が予想されます。


このため、マルウェアがサービスとして登録されていた場合、今回のようにタイムアウトエラーになっていたとしても、タイムアウトまでの間の挙動やサービスの動作の設定に注目する必要がある、ということです。

そこに注視して調査することで、さらなるマルウェアの起動やコマンドの実行、不審なファイルアクセスの痕跡を見つけることができるかもしれません。

 

逆に、「タイムアウトエラーになったから、動作していなかったのだろう」と判断してしまうと、落とし穴にはまり、痕跡を見落としてしまう可能性があるかもしれません。

今回は、それを懸念したため、動作を検証した次第です。

 

フォレンジック調査では、残された痕跡について、その理由を正しく判断できることが求められます。

そのためには、OSの仕組みや動作のリアクションがいかなるものかについて、可能な限り正しく、かつ深い知識が必要になります。

知っている人にはくだらない検証かもしれませんが、こういうことを積んでいかないと、フォレンジッカーとしては成長できないんだろうなぁ、と思った次第です。

 

 

さて、気になることがあるので、もちっと検証してみようと思い、「その1」としました。

できれば、「その2」も検証して書いてみたいところです。

(できなかったら、しれっと「その1」を消します・・・)