1/12 の勉強会で WinDBG の使い方なども教えていただいたので忘れないうちにメモしておこう。
とりあえず、VMware 環境に Windows XP Sp2 を用意し、古典的な rootkit ということで Hacker Defender をインストールする。これで INI ファイルに定義されている文字列を持つプロセスやファイルなどは見えない状態になる。次に、win32dd でクラッシュダンプファイルを作成し、これを WinDBG で読み込んで解析開始。
ちなみに、こんなややこしいやり方をしなくても、Hacker Defender は一般的なウイルス対策ソフトでもっと簡単に発見できるはずなのでまぁ演習ということで。
とりあえず現在のプロセスリストを表示してみる。コマンドは「!process 0 0」で実行。!process 0 7 にすると詳細に表示されるがかなり時間がかかるようだ。
以下実行例(一部略)
16.kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** PROCESS 821c2830 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 00b2a000 ObjectTable: e1000cc0 HandleCount: 251. Image: System <省略> PROCESS 8211b620 SessionId: 0 Cid: 0788 Peb: 7ffdf000 ParentCid: 02a0 DirBase: 08300340 ObjectTable: e19f6128 HandleCount: 29. Image: hxdef100.exe PROCESS 82083da0 SessionId: 0 Cid: 07c0 Peb: 7ffdf000 ParentCid: 0194 DirBase: 08300320 ObjectTable: e1d2db10 HandleCount: 137. Image: TrueCrypt.exe PROCESS 81ef2a80 SessionId: 0 Cid: 04fc Peb: 7ffdf000 ParentCid: 0194 DirBase: 08300360 ObjectTable: e1d79520 HandleCount: 31. Image: cmd.exe PROCESS 820a8da0 SessionId: 0 Cid: 00c8 Peb: 7ffda000 ParentCid: 04fc DirBase: 08300380 ObjectTable: e10bd5c8 HandleCount: 22. Image: win32dd.exe
結果を確認すると、タスクマネージャからは見えてないけど、hxdef100.exe がプロセスとして居ることが確認できる。
今は仕込んだのが hxdef100.exe だと知っているのですぐに発見できるわけですが、知らないとすると、タスクマネージャなどで得たプロセスリストと、このリストを比較してみるとかになりますかね(最近のメモリフォレンジック関係の調査ツールでは隠されたプロセスを自動的に報告してくれるのもあるので、手動で比較とかはちょっと面倒そう)。
さて、ここで気になるのはこのhxdef100.exeがどのパス上にファイルとして存在しているのかということですが、WinDBG だとすぐに確認できるのかわかりません。
次に調べたいプロセスに変更する。hxdef100.exe は 8211b620 なので、.process 8211b620 を実行してから .reload コマンドを実行する。
16.kd> .process 8211b620 Implicit process is now 8211b620 16.kd> .reload
hxdef100.exe に関するプロセスの詳細情報だけ取得したいので、!process アドレス 7 を使う。今回は「!process 8211b620 7」を実行してみる。
16.kd> !process 8211b620 7 PROCESS 8211b620 SessionId: 0 Cid: 0788 Peb: 7ffdf000 ParentCid: 02a0 DirBase: 08300340 ObjectTable: e19f6128 HandleCount: 29. Image: hxdef100.exe VadRoot 81b7f718 Vads 46 Clone 0 Private 292. Modified 1. Locked 0. DeviceMap e1004440 Token e17cb580 ElapsedTime 00:01:27.718 UserTime 00:00:00.046 KernelTime 00:00:00.093 QuotaPoolUsage[PagedPool] 28796 QuotaPoolUsage[NonPagedPool] 2200 Working Set Sizes (now,min,max) (623, 50, 345) (2492KB, 200KB, 1380KB) PeakWorkingSetSize 627 VirtualSize 19 Mb PeakVirtualSize 20 Mb PageFaultCount 1526 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 345 THREAD 81b8c658 Cid 0788.078c Teb: 7ffde000 Win32Thread: e1062418 WAIT: (Executive) UserMode Non-Alertable 81b6d47c NotificationEvent IRP List: 81cc0cf0: (0006,0094) Flags: 00000900 Mdl: 00000000 Not impersonating DeviceMap e1004440 Owning Process 8211b620 Image: hxdef100.exe Attached Process N/A Image: N/A Wait Start TickCount 10816 Ticks: 5620 (0:00:01:27.812) Context Switch Count 46 LargeStack UserTime 00:00:00.000 KernelTime 00:00:00.015 *** WARNING: Unable to verify checksum for hxdef100.exe *** ERROR: Module load completed but symbols could not be loaded for hxdef100.exe Win32 Start Address hxdef100 (0x0040ed50) Start Address kernel32!BaseProcessStartThunk (0x7c810867) Stack Init b2900000 Current b28ffc1c Base b2900000 Limit b28fc000 Call 0 Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 0 Kernel stack not resident. ChildEBP RetAddr Args to Child b28ffc34 8050217a 81b8c6c8 81b8c658 804fb9be nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4]) b28ffc40 804fb9be 00000103 00000000 81cc0cf0 nt!KiSwapThread+0x46 (FPO: [0,0,0]) b28ffc68 80575ba8 00000001 00000000 81c60701 nt!KeWaitForSingleObject+0x1c2 (FPO: [5,5,4]) b28ffc90 80572b98 81c60758 00000103 81b6d420 nt!IopSynchronousServiceTail+0xc6 (FPO: [7,0,4]) b28ffd38 8053e808 00000050 00000000 00000000 nt!NtReadFile+0x580 (FPO: [Non-Fpo]) b28ffd38 7c94eb94 00000050 00000000 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ b28ffd64) 0012fc38 7c94e288 7c801875 00000050 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0012fc3c 7c801875 00000050 00000000 00000000 ntdll!NtReadFile+0xc (FPO: [9,0,0]) 0012fca4 77d9b3cb 00000050 0012fd68 00000216 kernel32!ReadFile+0x16c (FPO: [Non-Fpo]) 0012fcd0 77d9b25f 00000050 0012fd68 00000216 advapi32!ScGetPipeInput+0x2a (FPO: [4,1,4]) 0012fd44 77de7dcc 00000050 0012fd68 00000216 advapi32!ScDispatcherLoop+0x3f (FPO: [Non-Fpo]) 0012ff84 0040da70 00490cd0 0040e3fc 0040ee79 advapi32!StartServiceCtrlDispatcherA+0x93 (FPO: [1,136,0]) WARNING: Stack unwind information not available. Following frames may be wrong. 0012ffc0 7c816d4f 00000000 00000000 7ffdf000 hxdef100+0xda70 0012fff0 00000000 0040ed50 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo]) THREAD 81c61350 Cid 0788.0728 Teb: 7ffdd000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable 81ec3e5c NotificationEvent IRP List: 81b92008: (0006,0190) Flags: 00000970 Mdl: 00000000 Not impersonating DeviceMap e1004440 Owning Process 8211b620 Image: hxdef100.exe Attached Process N/A Image: N/A Wait Start TickCount 10871 Ticks: 5565 (0:00:01:26.953) Context Switch Count 300 UserTime 00:00:00.031 KernelTime 00:00:00.546 Win32 Start Address advapi32!ScSvcctrlThreadA (0x77d9b479) Start Address kernel32!BaseThreadStartThunk (0x7c810856) Stack Init b252c000 Current b252bca0 Base b252c000 Limit b2529000 Call 0 Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 0 Kernel stack not resident. ChildEBP RetAddr Args to Child b252bcb8 8050217a 81c613c0 81c61350 804fb9be nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4]) b252bcc4 804fb9be 00000000 00000000 00000000 nt!KiSwapThread+0x46 (FPO: [0,0,0]) b252bcec 805b6a78 00000001 00000006 ffffff01 nt!KeWaitForSingleObject+0x1c2 (FPO: [5,5,4]) b252bd50 8053e808 00000060 00000000 00000000 nt!NtWaitForSingleObject+0x9a (FPO: [Non-Fpo]) b252bd50 7c94eb94 00000060 00000000 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ b252bd64) 00cbfe7c 7c94e9c0 7c801941 00000060 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 00cbfe80 7c801941 00000060 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 00cbfed0 0040e0aa 00000060 00490cbc 0000000d kernel32!ReadFile+0x17c (FPO: [Non-Fpo]) WARNING: Stack unwind information not available. Following frames may be wrong. 00cbff98 0040cf7a 00cbffb4 77d9b48b 00000001 hxdef100+0xe0aa 00cbffa0 77d9b48b 00000001 001490c8 0012e88c hxdef100+0xcf7a 00cbffb4 7c80b50b 001490c0 00000000 0012e88c advapi32!ScSvcctrlThreadA+0x12 (FPO: [1,0,4]) 00cbffec 00000000 77d9b479 001490c0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])
上記の結果中に、ElapsedTime 00:01:27.718 という項目がありますが、これがプロセスが起動してからの経過時間でしょうか。ダンプファイル自体の取得時間は、WinDBG にファイルをロードした時に Debug session time: Mon Jan 12 10:12:35.679 2009 (GMT+9) などと先頭の方に表示されるので、この時間をベースに経過時間を差し引けば何時起動したのかがだいたいわかるんですかねぇ。