Windowsカーネルメモリダンプと問題切り分け
Windows 7/8/10、偽装メカニズム、内部解析技術
本稿では、次のような2種類の技術概念に焦点を当て、いくつかの仮説を立てながら、Windows 10に実装されている偽装メカニズムの基本的な解析を行ってまいります。
米Microsoft社は、偽装に関する解説情報を「このページ」から一般公開し、偽装を次のように定義しています。
Impersonation is the ability of a thread to execute using different security information than the process
that owns the thread.
この定義文は次のような解釈を可能とします。
- 偽装はスレッドの機能である
- スレッドは通常所属プロセスのセキュリティー情報を引き継いでいる
- スレッドはプロセスからの引き継ぎ情報と異なるセキュリティー情報で実行(偽装)できる
この高次の偽装定義に加え、次のような4種類の実装上の偽装レベルが定義されています。カッコ内の数値は偽装レベルを示し、数値が大きくなるに従い、偽装内容が高度になります。
- SecurityAnonymous(0): The server cannot impersonate or identify the client.
- SecurityIdentification(1): The server can get the identity and privileges of the client, but cannot impersonate the client.
- SecurityImpersonation(2): The server can impersonate the client's security context on the local system.
- SecurityDelegation(3): The server can impersonate the client's security context on remote systems.
本「IT談話館」の別稿「Windows XP/7/8/10のセッションとプロセス」に含まれる実行結果からは、プロセス、スレッド、セッション、および、トークンの間に次のような関係が存在する、という仮説を立てることができます。
- プロセスオブジェクトとスレッドオブジェクトは「System」(カーネル)プロセスが作成する
- セッションオブジェクトは「SMSS.EXE」(セッションマネージャー)プロセスが作成する
- トークンオブジェクトは「Winlogon.exe」プロセスが作成する
- 偽装とは、主に、ユーザープロセスとシステム/サービスプロセス間のセキュリティーを考慮した通信である
これまでの情報と仮説からは、次のような新たな仮説と条件を実証する解析コードを開発すればよいことになります。
- 偽装スレッドは、所属プロセスと異なる偽装レベル値を持っている
- 偽装スレッドは、「偽装レベル値 == 2」を持っている
- 偽装サーバーのSessionIdは「0」である
- 偽装クライアントのSessionIdは「0」以外の値である
- トークンオブジェクトを解析すれば、セッションオブジェクトも解析できる
(Windows 10サーバー系エディションではなく)Windows 10 Pro環境で採取した「Active Memory Dump」をWinDbgにロードし、本「IT談話館」の独自解析コードを実行いたしますと、たとえば、次のような結果が返されてまいります。
1: kd> vertarget
Windows 10 Kernel Version 14393 MP (2 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 14393.576.amd64fre.rs1_release_inmarket.161208-2252
Machine Name:
Kernel base = 0xfffff803`24481000 PsLoadedModuleList = 0xfffff803`24786060
Debug session time: Thu Dec 29 08:54:19.661 2016 (UTC + 9:00)
System Uptime: 0 days 0:16:20.388
[---]
0xFFFFA183AC794780 svchost.exe
0xFFFFCC847138E060 Token Data
SessionId->0 ImpLevel->0 TokenType->1 SourceName->Advapi
0xFFFFCC846F015D90 Session Data
AccountName->TOYOTA-PC$ AuthorityName->WORKGROUP
+Thread->0xFFFFA183AB17F300
0xFFFFCC8471C72060 Token Data
SessionId->1 ImpLevel->2 TokenType->2 SourceName->User32
0xFFFFCC8470EDBB50 Session Data
AccountName->Toyota AuthorityName->Toyota-PC
[---]
0xFFFFA183AC9CD780 svchost.exe
0xFFFFCC84721D69D0 Token Data
SessionId->0 ImpLevel->0 TokenType->1 SourceName->Advapi
0xFFFFCC846F015D90 Session Data
AccountName->TOYOTA-PC$ AuthorityName->WORKGROUP
+Thread->0xFFFFA183ACE32080
0xFFFFCC8470E9B060 Token Data
SessionId->0 ImpLevel->2 TokenType->2 SourceName->Advapi
0xFFFFCC846F015D90 Session Data
AccountName->TOYOTA-PC$ AuthorityName->WORKGROUP
+Thread->0xFFFFA183ACE30080
0xFFFFCC8470E84060 Token Data
SessionId->0 ImpLevel->2 TokenType->2 SourceName->Advapi
0xFFFFCC846F015D90 Session Data
AccountName->TOYOTA-PC$ AuthorityName->WORKGROUP
+Thread->0xFFFFA183ACE09080
0xFFFFCC8470E969D0 Token Data
SessionId->0 ImpLevel->2 TokenType->2 SourceName->Advapi
0xFFFFCC846F015D90 Session Data
AccountName->TOYOTA-PC$ AuthorityName->WORKGROUP
[---]
この結果は次のようなことを示しています。
- スレッド「0xFFFFA183AB17F300」はユーザー「Toyota」を偽装している
- 偽装サーバーはセッション「0」内で起動されている
- 偽装クライアントはセッション「1」内で起動されている
- 偽装クライアントはセッション「0」内で起動されていることもある
一部の仮説(「偽装クライアントのSessionIdは「0」以外の値である」)は実証されませんでしたが、その他の仮説と条件は予想通りの結果です。 本「IT談話館」は、Windowsカーネルメモリダンプをはじめとする解析作業では、次のようなDKOM(Direct Kernel Object Manipulation)ベースの解析工程を採用しています。
- 「Windowsカーネルアーキテクチャー」知識を基に問題仮説を設定する。
- 上記問題仮説をC/C++とMASMの仕様を継承する「WinDbg内部解析専用言語」で独自解析コードとして実装する。
- 上記解析コードを実行し、設定した問題仮説の真偽を実証する。
- (必要に応じて)上記の工程を繰り返し、直面する問題を解決する。
本「IT談話館」の解析工程は、C++とアセンブラーをベースとし、カーネル空間を直接解析しますから、解析コードが返してくる情報は最新Windowsカーネルの実体を語ってくれます。Windows 10はSaaS(Software As A Service)として提供され、システム内部は黙々と日々更新されている、という認識が必要です。設定した仮説や条件と解析コードの実行結果が今回のように異なることが多々あります。そのような場合、新たな事実を発見したことであり、専門知識の深まりを実感できます。
以上、本稿では基本的な偽装メカニズムの解析例を紹介いたしましたが、実務解析作業では次のような視点からの解析も必要になります。
- 偽装サーバーの実体解明
- 偽装クライアントの実体解明
- 同一セッション内のプロセス間偽装
- 自己偽装の実体解明
実務的な解析コードの開発技術の導入をご予定の場合には、所属チーム内でご協議の上、本「IT談話館」の「オンサイトセミナー」の受講をご検討いただけますと幸いでございます。