@port139 Blog

基本的にはデジタル・フォレンジックの技術について取り扱っていますが、記載内容には高確率で誤りが含まれる可能性があります。

WinDBG と rootkit

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) などと先頭の方に表示されるので、この時間をベースに経過時間を差し引けば何時起動したのかがだいたいわかるんですかねぇ。

怪しいから取り出してみる

さて、メモリ上で hxdef100.exe という怪しいプロセスを発見したとして、このプロセスというかを取り出してみたいと思ったのですが、残念ながら WinDBG だと簡単ではないんでしょうかね?
ということで、Volatility framework には procdump(Dump a process to an executable sample)があるぞと ukky3 さんに教えていただいたので、それで抽出してみる。*1

C:\>Volatility-1.3_Beta\volatility procdump -p 1928 -f c:\case\Evidence\w32ddRAM.bin
c:\Volatility-1.3_Beta\forensics\win32\crashdump.py:31
: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
************************************************************************
Dumping hxdef100.exe, pid: 1928   output: executable.1928.exe
Memory Not Accessible: Virtual Address: 0x491000 File Offset: 0x91000 Size: 0x1000
Memory Not Accessible: Virtual Address: 0x496000 File Offset: 0x96000 Size: 0x1000

さて、このコマンドで抽出された executable.1928.exe(サイズ608KB)を Virustotal に突っ込んでみると以下に結果が得られ、ちゃんとHacker Defender と識別されてますね。

アンチウイルス バージョン 更新日 結果
a-squared 4.0.0.73 2009.01.14 Backdoor.Win32.HacDef.fh!IK
AhnLab-V3 2009.1.13.3 2009.01.14 Win-Trojan/HackDef.70656.N
AntiVir 7.9.0.54 2009.01.13 BDS/Hacdef.073.Z
Authentium 5.1.0.4 2009.01.13 W32/Hackdef.J
Avast 4.8.1281.0 2009.01.13 Win32:HacDef-LB
AVG 8.0.0.229 2009.01.13 BackDoor.Hacdef.C
BitDefender 7.2 2009.01.14 Generic.Hacdef.3156715F
CAT-QuickHeal 10.00 2009.01.14 Backdoor.HacDef.ky
ClamAV 0.94.1 2009.01.14 Trojan.HacDef.073.B
Comodo 927 2009.01.13 Backdoor.Win32.HacDef
DrWeb 4.44.0.09170 2009.01.13 BackDoor.HackDef.272
eSafe 7.0.17.0 2009.01.13 -
eTrust-Vet 31.6.6306 2009.01.13 Win32/HacDef.E
F-Prot 4.4.4.56 2009.01.13 W32/Hackdef.J
F-Secure 8.0.14470.0 2009.01.14 Backdoor.Win32.HacDef.ky
Fortinet 3.117.0.0 2009.01.14 -
GData 19 2009.01.14 Generic.Hacdef.3156715F
Ikarus T3.1.1.45.0 2009.01.14 Backdoor.Win32.HacDef.fh
K7AntiVirus 7.10.584 2009.01.09 -
Kaspersky 7.0.0.125 2009.01.14 Backdoor.Win32.HacDef.ky
McAfee 5494 2009.01.13 HackerDefender.gen.c
McAfee+Artemis 5494 2009.01.13 HackerDefender.gen.c
Microsoft 1.4205 2009.01.14 Backdoor:Win32/Hackdef.BJ
NOD32 3763 2009.01.13 Win32/HacDef
Norman 5.93.01 2009.01.13 -
Panda 9.5.1.2 2009.01.13 Bck/Hacdef.gen
PCTools 4.4.2.0 2009.01.13 Backdoor.HacDef.MF
Prevx1 V2 2009.01.14 System Back Door
Rising 21.12.21.00 2009.01.14 Backdoor.HacDef.br
SecureWeb-Gateway 6.7.6 2009.01.13 Rootkit.Hacdef.100.A
Sophos 4.37.0 2009.01.14 Troj/HacDef-T
Sunbelt 3.2.1831.2 2009.01.09 -
Symantec 10 2009.01.14 Backdoor.HackDefender
TheHacker 6.3.1.4.219 2009.01.14 Trojan/hackdef.d3
TrendMicro 8.700.0.1004 2009.01.14 BKDR_HACDEF.GEN
VBA32 3.12.8.10 2009.01.13 suspected of Embedded.Backdoor.HacDef.073.b
ViRobot 2009.1.14.1558 2009.01.14 Backdoor.Win32.HacDef.622592.B
VirusBuster 4.5.11.0 2009.01.13 Backdoor.HacDef.MF

ということで、サンプルで試してみましたが、クラッシュダンプファイルだけでなく、ハイバネーションファイルでも同じことができるので、ハイバネーションファイルが残っていて不審なプロセスとかあれば、それを取り出してウイルスチェックしてみるとか色々できそうですね。

*1:というか、プロセスリストもみれますけど、それはそれとして

ひーぷとかすたっくとか

なぜか手元でこの hxdef100.exe のプロセスの heap とか表示しようとしてもうまくいってないのですが、それは手順が悪いのか、win32dd で取得したからなのか・・・orz
hxdef100.exe の持っているデータ内容を調べることで、どんなファイルを隠そうとしていたのか(INIファイルの内容)が調べられないのかなぁとちょっと考えてますが、どなんでしょね?