はじめに
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の呼び出し元
CreateFileInternalの、NtCreateFileの呼び出し付近のデコンパイル結果は以下の通りです。
ここで第 1 引数FileHandleとなっている変数をhandleとします。
NtCreateFile の引数が適切に表示されていない場合、Edit Function Signature から手動で定義することができます。
![]()
NtCreateFileの定義を編集
CreateFileInternalの、return 付近のデコンパイル結果は以下の通りです。
戻り値はhandleであることが分かります。
return 付近のでコンパイル結果が崩れている場合、
__security_check_cookieを Edit Function Signature からインライン展開することで修正できます。
![]()
SecurityCheckCookieをインライン展開
__security_check_cookieは、コンパイラが埋め込んだセキュリティチェック機構です。
コンパイラ セキュリティの徹底調査 | Microsoft Docs
Ghidra のデコンパイラはこの関数を呼び出すことで RAX の値が破壊されるという前提で解析していますが、実際には RAX の値は破壊されません。
インライン展開することでextraout_RAXとなっている戻り値を修正することができます。
![]()
SecurityCheckCookieのインライン展開前
この結果から、CreateFileWとその内部で呼ばれているNtCreateFileについて、実行した際に得られるHANDLEの値は同じと言えます。
しかし、このような静的解析には時間がかかり、研修中は余りの時間だけでは解析を終えることができませんでした。
このように、目的や状況に応じて解析方法を選択する必要があります。
今回の研修を通じて、柔軟な姿勢で解析に取り組む必要があることを実感しました。
おわりに
本記事では、Windows 解析研修の中から 1 問をピックアップして紹介いたしました。
実際の研修ではこのような問題の他に、CTF 形式の問題も出題されました。
どの問題も Windows への興味を強く引き立てるもので、初めて知ることも多くあり、非常に実のある研修でした。
本記事が、FFRIセキュリティの新人研修制度に興味や不安がある方の参考になれば幸いです。
FFRIセキュリティの新人研修にご興味のある方は、こちらの新人研修についての記事一覧もご覧ください。
FFRIセキュリティの新人研修について
FFRIセキュリティでは、毎年 4 月から 4 ヶ月間、新入社員を対象に研修しており、セキュリティに関して事前知識がなくても、研修中に一通りの知識を学べるようになっています。
採用に関しては、採用情報を参照ください。




