本「
IT談話館」一般公開記事は、10年以上の実務経験を持つ上級Windowsエンジニアを想定しています。
本館は、Windowsカーネル深層を解析し、クラッシュ原因をはじめとするシステム内の「異様な動き」を検出・分析する
超高度な技術と実績を保有しています。
WinDbgとWindows XP/7/8/10のハンドルテーブル解析
本「IT談話館」の「一般公開記事」は、「Active Memory Dump とカーネルメモリダンプ」の解析結果を基に起草されています。「本館」主筆の「豊田孝」はDKOM(Direct Kernel Object Manipulation)ベースの解析手法の第一人者であり、Windowsカーネル空間の解析分野では世界の先頭を走っています。
現在、セキュリティー問題を無視することはできません。Microsoft社側の負担だけではなく、同社製品の利用者側の負担も増しています。困ったことではありますが、当面避けられません。セキュリティーの視点から「Windows10ソフトウェアセンサー」を見た場合、本「IT談話館」の確認範囲では、「カーネル層保護ロジック」に加え、次のような保護メカニズム階層が考案・実装されています。下記リンクはすべて本館記事を指しています。
- Silo/Server Silo
- Job
- Session
- Protected Process
- Mandatory Integrity Control(MIC)
- Windows API(+CPU)
- CPU
本稿ではハンドルテーブルを取り上げます。ハンドルテーブルは、ハンドル値とカーネルオブジェクトを対応付ける重要なWindowsカーネル内部システムテーブルの一つです。このテーブルの不正な改ざんを防止するには、テーブルへのアクセスロジックを工夫する必要があります。
ハンドルテーブルは、XPから10までのバージョンアップ過程で継続的に再設計されてきました。2015年7月末にWindows 10がリリースされた時、本「IT談話館」はいち早くカーネルメモリダンプを採取し、ハンドルテーブルの解析にとりかかりました。予想した通り、Windows 8.1時代の解析コードは動作しなくなりました。Windows 7からWindows 8へのバージョンアップの過程で導入されたハンドルテーブル保護ロジックは貧弱であり、そこに気付いたMS社内の開発担当チームはWindows 10の開発段階で修正してきました。次の情報をご覧ください。
2: kd> vertarget
Windows 8.1 Kernel Version 9600 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS Personal
Built by: 9600.17238.amd64fre.winblue_gdr.140723-2018
Machine Name:
Kernel base = 0xfffff801`6868c000 PsLoadedModuleList = 0xfffff801`68956350
Debug session time: Thu Oct 9 00:34:44.270 2014 (UTC + 9:00)
System Uptime: 0 days 13:38:52.140
2: kd> u nt!ObGetObjectType l0n20
nt!ObGetObjectType:
fffff801`68b318c4 0fb641e8 movzx eax,byte ptr [rcx-18h]
fffff801`68b318c8 488d0d51dee0ff lea rcx,[nt!ObTypeIndexTable (fffff801`6893f720)]
fffff801`68b318cf 488b04c1 mov rax,qword ptr [rcx+rax*8]
fffff801`68b318d3 c3 ret
この情報は、次のようなことを示しています。
- このメモリダンプはWindows 8.1環境で採取されている
- このカーネルルーチンは受け取ったインデックス(バイト)値をそのまま使用し、インデックステーブル経由でカーネルオブジェクト情報を取得・返している
この実装ロジックはきわめて単純であり、バイト値を与えればインデックステーブルへのアクセスが可能であることを示しています。本館が確認している範囲では、Windows 8.1以前のバージョンのWindowsシステムもすべてこのリスキーなロジックを採用しています。セキュリティーを確保する視点からは、きわめて危険なロジック、といえるでしょう。このロジックは、Windows 8.1カーネルの資産を継承するWindows 10では次のように変更されています。
0: kd> vertarget
Windows 10 Kernel Version 10586 MP (2 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 10586.17.amd64fre.th2_release.151121-2308
Machine Name:
Kernel base = 0xfffff802`02411000 PsLoadedModuleList = 0xfffff802`026efc70
Debug session time: Tue Jan 12 15:08:49.559 2016 (UTC + 9:00)
System Uptime: 1 days 3:41:20.157
0: kd> u nt!ObGetObjectType l0n20
nt!ObGetObjectType:
fffff802`02897bfc 488d41d0 lea rax,[rcx-30h]
fffff802`02897c00 0fb649e8 movzx ecx,byte ptr [rcx-18h]
fffff802`02897c04 48c1e808 shr rax,8
fffff802`02897c08 0fb6c0 movzx eax,al
fffff802`02897c0b 4833c1 xor rax,rcx
fffff802`02897c0e 0fb60d5f88efff movzx ecx,byte ptr [nt!ObHeaderCookie (fffff802`02790474)]
fffff802`02897c15 4833c1 xor rax,rcx
fffff802`02897c18 488d0dc18cefff lea rcx,[nt!ObTypeIndexTable (fffff802`027908e0)]
fffff802`02897c1f 488b04c1 mov rax,qword ptr [rcx+rax*8]
fffff802`02897c23 c3 ret
この情報からは、次のような技術者事情と時代背景を知ることができます。
- このメモリダンプはWindows 10環境で採取されている
- インデックステーブルにアクセスする過程で演算が行われている
- 演算にはクッキーが使用されている
- パフォーマンスとセキュリティーを同時に向上させようとする意図が見える
- セキュリティー向上は米Microsoft社側とユーザー側の双方にコストを強いる
本「IT談話館」は、先の逆アセンブルコードを次のような内部情報を返す独自解析コードに移植・実行してみました。
0: kd> vertarget
Windows 10 Kernel Version 10586 MP (2 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 10586.17.amd64fre.th2_release.151121-2308
Machine Name:
Kernel base = 0xfffff802`02411000 PsLoadedModuleList = 0xfffff802`026efc70
Debug session time: Tue Jan 12 15:08:49.559 2016 (UTC + 9:00)
System Uptime: 1 days 3:41:20.157
HandleCount(1248) explorer.exe ffffe001f6a69840
No.001 Object->0xFFFFC000C748A340 ObjectType->0xFFFFE001F4CDBDE0 Name->Key
Index->0x027 Handle->0x004
No.002 Object->0xFFFFC000C65AAD40 ObjectType->0xFFFFE001F4CDBDE0 Name->Key
Index->0x027 Handle->0x008
No.003 Object->0xFFFFC000C335D150 ObjectType->0xFFFFE001F4C291D0 Name->Directory
Index->0x003 Handle->0x00c
No.004 Object->0xFFFFE001F6F88980 ObjectType->0xFFFFE001F4C99DD0 Name->Event
Index->0x00c Handle->0x010
No.005 Object->0xFFFFE001F7950BD0 ObjectType->0xFFFFE001F4C99DD0 Name->Event
Index->0x00c Handle->0x014
No.006 Object->0xFFFFE001F7981F20 ObjectType->0xFFFFE001F4C24DC0 Name->File
Index->0x01f Handle->0x018
No.007 Object->0xFFFFE001F7857560 ObjectType->0xFFFFE001F4C99DD0 Name->Event
Index->0x00c Handle->0x01c
No.008 Object->0xFFFFE001F7AE4F90 ObjectType->0xFFFFE001F4C24F20 Name->WaitCompletionPacket
Index->0x01e Handle->0x020
No.009 Object->0xFFFFE001F785ADA0 ObjectType->0xFFFFE001F4CD7CF0 Name->ALPC Port
Index->0x028 Handle->0x024
No.010 Object->0xFFFFE001F786ED40 ObjectType->0xFFFFE001F4C1FDC0 Name->IoCompletion
Index->0x01d Handle->0x028
[---]
0: kd> !handle 24 3 ffffe001f6a69840
PROCESS ffffe001f6a69840
SessionId: 1 Cid: 0fd8 Peb: 0021f000 ParentCid: 0fac
DirBase: 0cc94000 ObjectTable: ffffc000c747bf00 HandleCount:
Image: explorer.exe
Handle Error reading handle count.
0024: Object: ffffe001f785ada0 GrantedAccess: 001f0001 (Protected) (Inherit) (Audit) Entry: ffffc000c748d090
Object: ffffe001f785ada0 Type: (ffffe001f4cd7cf0) ALPC Port
ObjectHeader: ffffe001f785ad70 (new version)
HandleCount: 1 PointerCount: 32441
0: kd> !trueref ffffe001f785ada0
ffffe001f785ada0: HandleCount: 1 PointerCount: 32441 RealPointerCount: 3
0: kd> !handle 28 3 ffffe001f6a69840
PROCESS ffffe001f6a69840
SessionId: 1 Cid: 0fd8 Peb: 0021f000 ParentCid: 0fac
DirBase: 0cc94000 ObjectTable: ffffc000c747bf00 HandleCount:
Image: explorer.exe
Handle Error reading handle count.
0028: Object: ffffe001f786ed40 GrantedAccess: 001f0003 (Protected) Entry: ffffc000c748d0a0
Object: ffffe001f786ed40 Type: (ffffe001f4c1fdc0) IoCompletion
ObjectHeader: ffffe001f786ed10 (new version)
HandleCount: 1 PointerCount: 25319
0: kd> !trueref ffffe001f786ed40
ffffe001f786ed40: HandleCount: 1 PointerCount: 25319 RealPointerCount: 95
本「IT談話館」の独自解析コードをいろいろなプロセスのハンドルテーブルの解析に適応してみると、それぞれのプロセスの内部で使用されているカーネルオブジェクトが列挙され、解析対象プロセスの特性が一目で分かります。