はじめに
2021 年度に新卒入社した H です。
FFRIセキュリティでは、入社後から 4 ヶ月間に渡って新人研修が行われます。
本記事では、今回実施された研修の中から、5 日間に渡って行われた「Windows 解析研修」について紹介します。
Windows 解析研修
Windows 解析研修では、Windows に関する解析を中心とした問題がいくつか用意されています。
本年度ではその内の 1 問として、CreateFileW
とその内部で呼ばれているNtCreateFile
について、実行した際に得られるHANDLE
の値は同じであるかを検証する問題が出題されました。
ここでは、この問題にクローズアップして、具体的な検証方法や考慮するべきことについて紹介していきます。
調査
まず、各関数についてHANDLE
として比較する値の見当をつけるため、Microsoft Docs を参照して定義を確認します。
CreateFileW
はファイルなどのオブジェクトを開くまたは作成する関数であり、Win32 API の 1 つとしてユーザーに提供されています。
CreateFileW
は以下のように定義されており、戻り値としてHANDLE
が返されます。
CreateFileW function (fileapi.h) - Win32 apps | Microsoft Docs
HANDLE CreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
NtCreateFile
もファイルなどのオブジェクトを開くまたは作成する関数であり、ユーザーモードからカーネルモードへのインターフェイスの役割を担います。
NtCreateFile
は以下のように定義されており、第 1 引数FileHandle
にHANDLE
を指すポインターが格納されます。
NtCreateFile function (winternl.h) - Win32 apps | Microsoft Docs
__kernel_entry NTSTATUS NtCreateFile( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength );
したがって、CreateFileW
の戻り値とNtCreateFile
の第 1 引数のポインターが指す値を検証すれば良いということになります。
実行するごとにこの値は変化します。
検証
次に、CreateFileW
とNtCreateFile
の呼び出しの様子の解析方法を検討します。
解析には動的解析と静的解析の 2 つがあり、それぞれの利点と欠点を以下に示します。
動的解析 | 静的解析 | |
---|---|---|
利点 | 解析にかかるコストが比較的低い | 詳細なロジックを把握しやすい |
欠点 | 詳細なロジックを把握しづらい | 解析にかかるコストが比較的高い |
本研修の進め方は受講者に任せられており、各課題の時間配分についても自身で考える必要がありました。
そこで、一先ず動的解析の結果を元にレポートを作成し、余りの時間で静的解析に取り組みました。
動的解析
動的解析では、API Monitor を用いて Windows API が呼び出される様子を確認します。
検証にあたって、以下のようなCreateFileW
を呼び出すプログラムを作成します。
#include <Windows.h> int main() { HANDLE hFile = CreateFileW( L"test.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile == INVALID_HANDLE_VALUE) { return 1; } CloseHandle(hFile); return 0; }
作成したプログラムを実行し、CreateFileW
及びNtCreateFile
が呼び出される様子を API Monitor で確認します。
CreateFileW
の呼び出しで得られたHANDLE
は、0x00000000000000e0
であることが分かります。
また、NtCreateFile
の呼び出しで得られたHANDLE
も、0x00000000000000e0
であることが分かります。
この結果から、CreateFileW
とその内部で呼ばれているNtCreateFile
について、実行した際に得られるHANDLE
の値は同じであると言えそうです。
しかし、引数や環境などの条件を変えて呼び出した場合でも、同じ結果になるという確証はありません。
このような動的解析からは、検証時に実行されなかったコードの挙動は分からないことを考慮しておかなければなりません。
したがって、より精細な結果が求められる場合は静的解析をする必要があります。
静的解析
静的解析では、Ghidra を用いてデコンパイル結果を解析します。
API Monitor で確認できた Call Stack の内容から、NtCreateFile
はKERNELBASE.dll
に定義されたCreateFileW
から呼び出されていることが分かります。
そこで、KERNELBASE.dll
を解析し、CreateFileW
の内部でNtCreateFile
がどのように呼び出されているのかを確認していきます。
KERNELBASE.dll
のパスは以下のコマンドで調べることが出来ます。
KERNELBASE.dll
を Ghidra で開いたら、Data Type Manager からwindows_vs12_64
を適用します。
CreateFileW
のデコンパイル結果は以下の通りです。
ここで呼び出されている関数をCreateFileInternal
とします。
CreateFileW
はCreateFileInternal
のラッパー関数となっていることが分かります。
余談ですが、
CreateFileInternal
はCreateFileW
だけでなくCreateFileA
からも同様に呼び出されています。
つまり、W版であるCreateFileW
とA版であるCreateFileA
の内部実装は共通しているということになります。
CreateFileInternal
の、NtCreateFile
の呼び出し付近のデコンパイル結果は以下の通りです。
ここで第 1 引数FileHandle
となっている変数をhandle
とします。
NtCreateFile の引数が適切に表示されていない場合、Edit Function Signature から手動で定義することができます。
CreateFileInternal
の、return 付近のデコンパイル結果は以下の通りです。
戻り値はhandle
であることが分かります。
return 付近のでコンパイル結果が崩れている場合、
__security_check_cookie
を Edit Function Signature からインライン展開することで修正できます。
__security_check_cookie
は、コンパイラが埋め込んだセキュリティチェック機構です。
コンパイラ セキュリティの徹底調査 | Microsoft Docs
Ghidra のデコンパイラはこの関数を呼び出すことで RAX の値が破壊されるという前提で解析していますが、実際には RAX の値は破壊されません。
インライン展開することでextraout_RAX
となっている戻り値を修正することができます。
この結果から、CreateFileW
とその内部で呼ばれているNtCreateFile
について、実行した際に得られるHANDLE
の値は同じと言えます。
しかし、このような静的解析には時間がかかり、研修中は余りの時間だけでは解析を終えることができませんでした。
このように、目的や状況に応じて解析方法を選択する必要があります。
今回の研修を通じて、柔軟な姿勢で解析に取り組む必要があることを実感しました。
おわりに
本記事では、Windows 解析研修の中から 1 問をピックアップして紹介いたしました。
実際の研修ではこのような問題の他に、CTF 形式の問題も出題されました。
どの問題も Windows への興味を強く引き立てるもので、初めて知ることも多くあり、非常に実のある研修でした。
本記事が、FFRIセキュリティの新人研修制度に興味や不安がある方の参考になれば幸いです。
FFRIセキュリティの新人研修にご興味のある方は、こちらの新人研修についての記事一覧もご覧ください。
FFRIセキュリティの新人研修について
FFRIセキュリティでは、毎年 4 月から 4 ヶ月間、新入社員を対象に研修しており、セキュリティに関して事前知識がなくても、研修中に一通りの知識を学べるようになっています。
採用に関しては、採用情報を参照ください。