翟繼強(qiáng), 孫宏泰, 趙洛平, 楊海陸
(哈爾濱理工大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院, 黑龍江 哈爾濱 150080)
計(jì)算機(jī)取證是網(wǎng)絡(luò)安全應(yīng)急響應(yīng)的基本步驟,主要包括磁盤取證[1]、實(shí)時(shí)分析[2]和內(nèi)存取證[3]。惡意軟件在計(jì)算機(jī)系統(tǒng)中執(zhí)行的異常或未授權(quán)操作,可通過分析系統(tǒng)的磁盤驅(qū)動(dòng)器或內(nèi)存進(jìn)行檢測。近年來,一些惡意軟件不會(huì)將關(guān)鍵的數(shù)據(jù)寫入磁盤,這使得磁盤取證無法取得有效的數(shù)字證據(jù),而內(nèi)存取證技術(shù)針對(duì)易失性存儲(chǔ)器進(jìn)行分析,彌補(bǔ)了磁盤取證的不足,逐漸在數(shù)字取證領(lǐng)域中發(fā)揮出不可替代的作用[4]。
以往的內(nèi)存取證研究專注于內(nèi)存內(nèi)核地址空間的結(jié)構(gòu)和內(nèi)容,對(duì)用戶地址空間的結(jié)構(gòu)和內(nèi)容研究較少[5-6]。內(nèi)存注入攻擊是一種針對(duì)進(jìn)程用戶地址空間注入惡意代碼的攻擊技術(shù),如Shellcode注入[7]、DLL注入[8]、Atom Bombing注入和Hollowing注入等,通常對(duì)目標(biāo)進(jìn)程用戶地址空間的堆棧緩沖區(qū)、動(dòng)態(tài)鏈接庫、共享內(nèi)存和其他內(nèi)存區(qū)域注入并執(zhí)行惡意代碼。Windows 10 64位系統(tǒng)作為目前主流的操作系統(tǒng),是網(wǎng)絡(luò)攻擊者的主要目標(biāo)。對(duì)于64位操作系統(tǒng),在高達(dá)128 TB的地址空間中檢測惡意代碼加重了取證分析人員的工作量,增加了安全事件響應(yīng)所需的時(shí)間。在保證不流失有效數(shù)字證據(jù)的前提下篩選出可訪問的內(nèi)存區(qū)域,并明確其詳細(xì)信息,能夠減少取證分析人員檢測、定位和提取惡意代碼的工作量,減少安全事件響應(yīng)所需的時(shí)間。
Gavitt[9]最早從內(nèi)存取證的角度分析內(nèi)存VAD樹,并明確了用戶地址空間中映射文件和共享內(nèi)存的遍歷方法,但是只適用于舊版本的Windows XP 32位系統(tǒng),Windows 10 64位系統(tǒng)的VAD樹結(jié)構(gòu)與舊版本的不同,這使得映射文件、共享內(nèi)存的遍歷方法也不同。White等[10]提出了一種用戶地址空間遍歷方法,并通過Volatility插件實(shí)現(xiàn)了該方法,但是只適用于Windows XP和Windows 7的32位操作系統(tǒng)。與Windows 10之前的版本相比,用于描述用戶地址空間的元數(shù)據(jù)變動(dòng)較大,這使得針對(duì)舊版本系統(tǒng)的用戶地址空間遍歷方法不再適用于Windows 10系統(tǒng)。 翟繼強(qiáng)等[11]詳細(xì)地闡述了Windows 10系統(tǒng)中段堆的結(jié)構(gòu)和工作原理,但是涉及的數(shù)據(jù)結(jié)構(gòu)只適用于低版本的Windows 10系統(tǒng),并且方法尚未應(yīng)用到內(nèi)存取證領(lǐng)域。Otsuki等[12]提出了一種Windows 64位系統(tǒng)的棧追蹤方法,方法中明確64位系統(tǒng)運(yùn)行的WOW64(Windows on Windows 64)進(jìn)程分為WOW64層和32位應(yīng)用層,每個(gè)線程維護(hù)2個(gè)棧,但沒有明確WOW64棧的遍歷方法。
針對(duì)以上用戶地址空間遍歷方法中完整度低和不兼容Windows 10 64位系統(tǒng)的問題,提出了一種基于VAD樹遍歷Windows 10 64位系統(tǒng)用戶地址空間的方法。經(jīng)測試,本文方法能夠完整地展示W(wǎng)indows 10 64位系統(tǒng)進(jìn)程的用戶地址空間布局,相比于傳統(tǒng)的遍歷方法,提高了遍歷的完整度,并適用于目前所有版本的Windows 10 64位系統(tǒng)。
Windows系統(tǒng)每個(gè)進(jìn)程都擁有自己的虛擬地址空間,根據(jù)地址高地,可將虛擬地址空間劃分為內(nèi)核和用戶地址空間兩部分。對(duì)于32位進(jìn)程,用戶地址空間為低于0x80000000地址部分,64位進(jìn)程用戶地址空間為低于0x800000000000地址部分。Windows系統(tǒng)以連續(xù)的虛擬地址范圍管理用戶地址空間,這些連續(xù)的地址范圍稱為用戶分配。在每個(gè)進(jìn)程的內(nèi)核空間中維護(hù)著1個(gè)自平衡二叉樹,稱之為VAD樹,樹中每一個(gè)節(jié)點(diǎn)存儲(chǔ)1個(gè)用戶分配的基本信息(如起始地址、結(jié)束地址、分配保護(hù)和內(nèi)存類型等),但是VAD節(jié)點(diǎn)并不存儲(chǔ)詳細(xì)的描述信息。通過解析相關(guān)元數(shù)據(jù)能夠補(bǔ)充用戶分配的描述信息,彌補(bǔ)VAD樹中描述信息不足的缺陷。
本文中所有涉及的相關(guān)元數(shù)據(jù)是基于WinDbg[13]調(diào)試Windows 10 64位各個(gè)版本的操作系統(tǒng)所確定的。表1中列出了現(xiàn)存用戶分配研究與本文的不同側(cè)重點(diǎn)。

表1 現(xiàn)存研究與本文研究的側(cè)重點(diǎn)
VAD樹的每個(gè)節(jié)點(diǎn)由_MMVAD結(jié)構(gòu)維護(hù),在Windows 10 64位系統(tǒng)下使用WinDbg調(diào)試其結(jié)構(gòu)如圖1所示。結(jié)構(gòu)中Core成員是-MMVAD-SHORT結(jié)構(gòu),它的StartingVpn成員和EndingVpn成員記錄了每個(gè)用戶分配的起止虛擬地址;u成員記錄了內(nèi)存分配的權(quán)限。
lkd>dt-MMVAD
nt!-MMVAD
+0x000 Core :-MMVAD-SHORT
+0x000 NextVad :Ptr64-MMVAD-SHORT
+0x008 ExtraCreateInfo :Ptr64 Void
+0x000 VadNode :-RTL-BALANCED-NODE
+0x018 StartingVpn :Uint4B
+0x01c EndingVpn :Uint4B
?
+0x030u:
?
+0x040 u2 :
+0x048 Subsection :Ptr64-SUBSECTION
?
+0x080 FileObject : Ptr64-FILE-OBJECT
圖1-MMVAD結(jié)構(gòu)
定義用戶分配算法的偽代碼如算法1所示,由于VAD樹是自平衡二叉樹,通過遞歸所有左子樹和右子樹的方法即可遍歷全部節(jié)點(diǎn)。分配的起始地址和終止地址來源于VAD節(jié)點(diǎn)的StartingVpn和EndingVpn成員。結(jié)構(gòu)體的u成員以索引值的形式標(biāo)記每個(gè)用戶分配的保護(hù),每個(gè)索引值對(duì)應(yīng)不同的分配保護(hù),這些在WinNT.h中定義。當(dāng)VAD樹節(jié)點(diǎn)的ControlArea字段為有效指針時(shí),對(duì)應(yīng)分配的內(nèi)存類型為共享類型,其余為私有類型。
算法1定義用戶分配算法
輸入:EPROCESS進(jìn)程對(duì)象E;
輸出:初始化的用戶分配集合U.
1:V← TraverseVadTree(E.VadRoot);/*從VAD樹根節(jié)點(diǎn)遍歷全部節(jié)點(diǎn)*/
2:U←?;
3: forv∈Vdo
4:u.vad←v;/*用戶分配對(duì)應(yīng)的VAD節(jié)點(diǎn)*/
5:u.start←v.StartingVpn;/*定義起始地址*/
6:u.end←v.EndingVpn;/*定義終止地址*/
7:u.permission← Transform(v.u);/*根據(jù)索引值確定保護(hù)*/
8:u.type← ‘private’;/*確定內(nèi)存類型*/
9: ifv.Subsection.ControlArea≠None then
10:u.type← ‘shared’;
11: end if
12: end for
傳統(tǒng)的遍歷映射文件方法采用解析進(jìn)程句柄表的方式獲取內(nèi)核文件對(duì)象,但是這種方法很容易受到Rootkit隱遁攻擊的影響[5],使得方法無法獲取被隱藏的文件對(duì)象。本文通過解析VAD樹發(fā)現(xiàn),VAD樹節(jié)點(diǎn)的FileObject成員同樣指向了文件對(duì)象結(jié)構(gòu)體,通過遍歷全部VAD節(jié)點(diǎn)能夠獲取進(jìn)程維護(hù)的全部文件對(duì)象。此外,進(jìn)程VAD樹結(jié)構(gòu)在系統(tǒng)中很不穩(wěn)定,如果惡意軟件企圖通過非法方式訪問或修改VAD樹中的數(shù)據(jù),很容易造成系統(tǒng)崩潰,因此VAD樹中的數(shù)據(jù)具有可靠性。
每個(gè)進(jìn)程對(duì)象結(jié)構(gòu)都包含1個(gè)指向其進(jìn)程句柄表的指針,句柄表包含進(jìn)程正在使用的句柄。通過解析句柄表可獲取維護(hù)共享內(nèi)存的-SECTION結(jié)構(gòu)。通過WinDbg調(diào)試Windows 10 64位系統(tǒng)內(nèi)存數(shù)據(jù)結(jié)構(gòu)發(fā)現(xiàn),當(dāng)-SECTION結(jié)構(gòu)的ControlArea成員與部分VAD節(jié)點(diǎn)中的ControlArea成員指向相同的地址,說明VAD樹與-SECTION結(jié)構(gòu)描述的是同一用戶分配,結(jié)構(gòu)之間具體關(guān)系示意圖如圖2所示。

圖2 共享內(nèi)存結(jié)構(gòu)示意圖
遍歷映射文件和共享內(nèi)存的算法偽代碼如算法2所示。首先從-MMVAD結(jié)構(gòu)中獲取文件對(duì)象結(jié)構(gòu),將FlieName成員作為映射文件的描述信息。通過解析進(jìn)程句柄表獲取-SECTION對(duì)象,當(dāng)VAD節(jié)點(diǎn)的ControlArea成員與-SECTION對(duì)象的ControlArea成員指向相同的地址時(shí),以-SECTION對(duì)象中存儲(chǔ)的信息描述用戶分配,當(dāng)-SECTION對(duì)象中的信息為空字符串或不可打印的字符串時(shí),則以共享內(nèi)存描述該區(qū)域。
算法2遍歷映射文件和共享內(nèi)存算法
輸入:用戶分配集合U;
輸出:包含映射文件與共享內(nèi)存信息的用戶分配集合U.
1: forv∈Vdo
2: ifv.FileObject≠None then /*判斷該VAD節(jié)點(diǎn)描述的區(qū)域是否包含映射文件*/
3:u.description←v.FileObject.FileName;
4: end if
5:S← Handle(); /*通過進(jìn)程句柄表獲取section對(duì)象集合*/
6: fors∈Sdo
7: ifv.Subsection.ControlArea=
s.ControlArea then
8:u.description←s.Name or ‘Shared’;/*描述共享內(nèi)存*/
9: end if
10: end for
11: addutoU;
12: end for
13: returnU
從Windows 10系統(tǒng)開始,在原有NT堆的基礎(chǔ)上新增了段堆機(jī)制, White等[10]詳細(xì)地闡述了NT堆的遍歷方法,本文重點(diǎn)研究段堆的遍歷方法。
本文通過調(diào)試Windows 10 64位系統(tǒng)進(jìn)程堆相關(guān)的元數(shù)據(jù)時(shí)發(fā)現(xiàn),段堆堆塊的起始地址與部分VAD樹節(jié)點(diǎn)中記錄的起始地址相同,這說明段堆堆塊也分布在用戶地址空間中。遍歷段堆算法偽代碼如算法3所示。首先通過進(jìn)程環(huán)境塊(process environment block,PEB)的ProcessHeaps成員獲取全部指向進(jìn)程堆結(jié)構(gòu)的指針。解析進(jìn)程堆首先要根據(jù)堆簽名將這些進(jìn)程堆分為NT堆和段堆,堆簽名為0xffeeffee表示NT堆,堆簽名為0xddeeddee表示段堆。在遍歷段堆的后端分配前需要對(duì)Windows 10系統(tǒng)版本進(jìn)行判斷,當(dāng)系統(tǒng)內(nèi)部版本號(hào)低于或等于15063時(shí),通過SegmentListHead成員遍歷鏈表,能夠獲取所有后端分配的基址;當(dāng)內(nèi)部版本號(hào)高于15063時(shí),將SegContext成員解析為2個(gè)指向-HEAP-SEG-CONTEXT結(jié)構(gòu)的指針,通過這個(gè)結(jié)構(gòu)的SegmentListHead成員遍歷鏈表,獲取所有后端分配的基址。對(duì)于大塊分配,則從根節(jié)點(diǎn)遍歷所有-HEAP-LARGE-ALLOC-DATA結(jié)構(gòu),當(dāng)用戶分配的起始地址與段堆分配的起始地址相匹配時(shí)將段堆分配信息寫入用戶分配的描述中。
算法3遍歷段堆算法
輸入:用戶分配集合U;
輸出:包含段堆信息的用戶分配集合U.
1:P=E.Peb
2:S←?; /*初始化段堆集合*/
3:B←?; /*初始化后端分配集合*/
4:L←?; /*初始化大塊分配集合*/
5:H←P.ProcessHeaps;/*遍歷進(jìn)程全部NT堆和段堆*/
6: forh∈Hdo
7: ifh.Signature=0xddeeddee then /*根據(jù)簽名判斷堆類型*/
8: addhtoS;
9: end if
10: end for
11: fors∈Sdo
12: foru∈Udo
13: ifu.start=s.addr then
14:u.description← ‘Segment Heap’;/*描述段堆*/
15: if System version < 15063 then/*判斷Windows 10系統(tǒng)版本*/
16:B← Followlist(s.SegmentListHead);/*遍歷后端分配*/
17: else /*若系統(tǒng)版本高于15063則采用另一種方法遍歷后端分配*/
18:B← Followlist(s.SegContext[0].SegmentListHead)+Followlist(s.SegContext[1].SegmentListHead);
19: end if
20:L← TraverseAVLTree(s.LargeAllocMetadata);/*遍歷大塊分配*/
21: end if
22: forb∈Bdo
23: ifu.start←b.addr then
24:u.description← ‘Backend Alloc’;/*描述后端分配*/
25: end if
26: end for
27: forl∈Ldo
28: ifu.start←l.VirtualAddress then
29:u.description← ‘Large block Alloc’;/*描述大塊分配*/
30: end if
31: end for
32: end for
33: end for
34: returnU
在64位系統(tǒng)中既運(yùn)行64位進(jìn)程,也運(yùn)行32位進(jìn)程,后者這種情況稱為WOW64進(jìn)程。 WOW64進(jìn)程的每個(gè)線程擁有2個(gè)執(zhí)行上下文,分別由-TEB和-TEB32線程環(huán)境塊結(jié)構(gòu)維護(hù)。-TEB結(jié)構(gòu)中的DeallocationStack成員指向了內(nèi)存中線程棧的起始地址。通過WinDbg調(diào)試Windows 10 64位系統(tǒng)發(fā)現(xiàn),-TEB32結(jié)構(gòu)位于-TEB結(jié)構(gòu)的+0x2000偏移處,其DeallocationStack成員指向用戶地址空間的WOW64棧。
遍歷線程棧算法偽代碼如算法4所示。首先遍歷線程鏈表獲取進(jìn)程所有的線程對(duì)象,通過Teb成員獲取-TEB結(jié)構(gòu),如果結(jié)構(gòu)的起始地址在某個(gè)用戶分配的地址范圍內(nèi),那么將-TEB添加到相應(yīng)用戶分配的描述信息中。從-TEB結(jié)構(gòu)+0x2000的偏移量處獲取-TEB32結(jié)構(gòu),這個(gè)結(jié)構(gòu)也包含Dellocation-Stack成員,并且與-TEB結(jié)構(gòu)中同名成員指向不同的地址,當(dāng)分配地址與用戶分配的基地址相匹配時(shí),將WOW64棧分配信息寫入用戶分配的描述中。
算法4遍歷線程棧算法
輸入:用戶分配集合U;
輸出:包含段堆信息的用戶分配集合U.
1:T← Followlist(E.Pcb.ThreadListEntry);/*遍歷線程鏈表獲取所有線程對(duì)象*/
2: foru∈Udo
3: fort∈Tdo
4: teb←t.Teb; /*獲取TEB*/
5: ifE.Wow64Process then/*判斷是否為WOW64進(jìn)程*/
6: teb32← teb+0x2000;/*獲取-TEB32*/
7: stack32← teb32.DeallocationStack;/*獲取WOW64棧*/
8: if stack32.addr=u.Start then
9:u.description← ‘wow64 stack’;/*描述WOW64棧*/
10: end if
11: end if
12: end for
13: end for
14: returnU
本文基于Volatility和Rekall這2款開源內(nèi)存取證框架提供的基礎(chǔ)功能[14-15],實(shí)現(xiàn)了2款取證框架下的遍歷Windows 10 64位用戶地址空間插件Win10userspace。具體執(zhí)行步驟如下:
步驟1 讀取系統(tǒng)版本,確定配置文件;
步驟2 根據(jù)配置文件導(dǎo)入內(nèi)核符號(hào);
步驟3 解析VAD樹定義用戶分配;
步驟4 解析進(jìn)程句柄表以遍歷映射文件和共享內(nèi)存,將映射文件所在的磁盤路徑和共享內(nèi)存信息添加到輸出結(jié)果中;
步驟5 通過PEB結(jié)構(gòu)遍歷NT堆和段堆,將NT堆、塊分配、虛擬分配、段堆、后端分配和大塊分配信息添加到輸出結(jié)果中;
步驟6 通過PCB遍歷線程棧,若此時(shí)解析的進(jìn)程為WOW64進(jìn)程,還需遍歷WOW64棧。
步驟7 輸出所有用戶分配信息。
插件在Rekall和Volatility下運(yùn)行后結(jié)果如圖3~4所示。

圖3 Win10userspace-Rekall運(yùn)行結(jié)果

圖4 Win10userspace-Volatility運(yùn)行結(jié)果
本文選擇使用微軟官方提供的調(diào)試工具WinDbg作為基準(zhǔn),以WinDbg獲取的用戶分配數(shù)計(jì)為總數(shù)。如果WinDbg獲取的用戶分配起始地址與插件獲取的起始地址相同,則計(jì)為有效遍歷數(shù)。評(píng)價(jià)指標(biāo)為遍歷比,其計(jì)算方式為有效遍歷數(shù)占總數(shù)的百分比,遍歷比越高,說明方法對(duì)用戶地址空間遍歷得越完整。
作為測試進(jìn)程,選取開啟段堆機(jī)制的Caculator.exe 64位進(jìn)程,在Windows 10 64位系統(tǒng)進(jìn)行測試,系統(tǒng)版本號(hào)為1607,所有實(shí)驗(yàn)分別進(jìn)行10次,取平均值作為最終結(jié)果。
3.1.1 基于內(nèi)存轉(zhuǎn)儲(chǔ)測試
本文基于Volatility實(shí)現(xiàn)的Win10userspace插件與White[10]的userspace插件進(jìn)行對(duì)比,測試實(shí)驗(yàn)結(jié)果如表2所示。

表2 基于內(nèi)存轉(zhuǎn)儲(chǔ)測試結(jié)果對(duì)比
結(jié)果表明,userspace在Windows 10 64位系統(tǒng)仍能夠遍歷部分用戶分配,說明userspace插件的部分遍歷方法能夠在Windows XP、Windows 7和Windows 10系統(tǒng)中通用,而Win10userspace的遍歷方法來源于對(duì)Windows 10 64位系統(tǒng)用戶分配相關(guān)的元數(shù)據(jù)進(jìn)行解析,因此對(duì)Windows 10 64位系統(tǒng)更具針對(duì)性。映射文件、段堆和線程棧分配項(xiàng)沒有完全與總數(shù)相同,這是由于表中各個(gè)分配項(xiàng)的總數(shù)是使用WinDbg實(shí)時(shí)調(diào)試得出的,而Win10userspace中各個(gè)分配項(xiàng)計(jì)數(shù)是分析內(nèi)存轉(zhuǎn)儲(chǔ)得出的,在實(shí)時(shí)調(diào)試過程中內(nèi)存隨著時(shí)間動(dòng)態(tài)變化,使得實(shí)時(shí)調(diào)試與分析內(nèi)存轉(zhuǎn)儲(chǔ)的結(jié)果存在微小的不同。
3.1.2 基于實(shí)時(shí)響應(yīng)測試
Gavitt[9]提出的方法在Rekall中編寫了名為Vad的插件,微軟官方提供了用戶地址空間遍歷工具Vmmap[16],本文選取以上2個(gè)方法作為對(duì)比,測試實(shí)驗(yàn)結(jié)果如表3所示。

表3 基于實(shí)時(shí)響應(yīng)測試結(jié)果對(duì)比
結(jié)果表明,Vad只能夠獲取內(nèi)存映射文件,微軟官方軟件Vmmap能夠有效遍歷常見分配項(xiàng),但是對(duì)于共享內(nèi)存、堆塊分配、虛擬分配、段堆分配、后端分配和大塊分配沒有實(shí)現(xiàn)有效遍歷,Win10userspace能夠有效遍歷表中所有用戶分配項(xiàng)。雖然Vmmap也具有較高的百分比,但是微軟官方?jīng)]有公開Vmmap工具的源碼,無法得知工具運(yùn)行的內(nèi)部原理,這增加了對(duì)其研究和擴(kuò)展的難度。Win10userspace基于開源的Rekall框架,便于開發(fā)者和研究人員對(duì)插件分析和優(yōu)化。
Windows平臺(tái)大部分惡意軟件都是32位程序,原因之一是32位程序具有更好的兼容性,因此,評(píng)估插件能否有效遍歷WOW64進(jìn)程的用戶地址空間具有重要意義。本文選取常見的32位程序,在Windows 10 64位系統(tǒng)進(jìn)行測試,系統(tǒng)版本號(hào)為1607,所有實(shí)驗(yàn)分別進(jìn)行10次,取平均值作為最終結(jié)果。由于插件有效性在3.1節(jié)得到驗(yàn)證,下文實(shí)驗(yàn)結(jié)果不再詳細(xì)列出各分配項(xiàng)的具體計(jì)數(shù)。
3.2.1 基于內(nèi)存轉(zhuǎn)儲(chǔ)測試
基于轉(zhuǎn)儲(chǔ)測試WOW64進(jìn)程結(jié)果如表4所示。

表4 基于內(nèi)存轉(zhuǎn)儲(chǔ)測試結(jié)果對(duì)比
實(shí)驗(yàn)結(jié)果表明,Win10userspace能夠有效遍歷WOW64進(jìn)程的用戶地址空間,有效遍歷的百分比都保持在90%以上。而userspace的運(yùn)行結(jié)果表明,userspace插件的方法已經(jīng)不適用于Windows 10 64位系統(tǒng)。
3.2.2 基于實(shí)時(shí)響應(yīng)測試
表5為基于實(shí)時(shí)響應(yīng)測試WOW64進(jìn)程結(jié)果。

表5 基于實(shí)時(shí)響應(yīng)測試結(jié)果對(duì)比
實(shí)驗(yàn)結(jié)果表明,Win10userspace在實(shí)時(shí)響應(yīng)的情況下能夠有效遍歷常見WOW64進(jìn)程的用戶地址空間,有效遍歷百分比高于vad和Vmmap。
Windows 10系統(tǒng)更新頻繁,因此版本數(shù)量眾多,用戶地址空間布局隨著版本更新發(fā)生變化。為了驗(yàn)證插件在不同版本W(wǎng)indows 10 64位操作系統(tǒng)下的兼容性,本文對(duì)目前所有版本W(wǎng)indows 1064位系統(tǒng)進(jìn)行測試,測試進(jìn)程為Chrome.exe的64位和32位程序,所有實(shí)驗(yàn)分別進(jìn)行10次,取平均值作為最終結(jié)果。測試實(shí)驗(yàn)結(jié)果如表6所示。

表6 不同版本W(wǎng)indows 10 64位系統(tǒng)下插件兼容性測試結(jié)果
實(shí)驗(yàn)結(jié)果表明,Win10userspace能夠兼容表中所有版本的Windows 10 64位系統(tǒng),結(jié)果與前文的有效性測試結(jié)果相符合。從表中還發(fā)現(xiàn)同一版本下WOW64進(jìn)程的有效遍歷百分比略低于64位進(jìn)程,說明WOW64進(jìn)程地址空間相對(duì)于64位進(jìn)程更為復(fù)雜,存在部分插件無法遍歷的分配項(xiàng)或結(jié)構(gòu)。
本文選取7個(gè)近3年使用內(nèi)存注入攻擊技術(shù)的惡意軟件,使用逆向技術(shù)分析其內(nèi)存注入攻擊原理,惡意軟件的詳細(xì)信息如表7所示。

表7 惡意軟件樣本信息
在Windows 10 64位系統(tǒng)下運(yùn)行這些惡意軟件樣本,系統(tǒng)版本號(hào)為1607。運(yùn)行后分別基于內(nèi)存轉(zhuǎn)儲(chǔ)和實(shí)時(shí)響應(yīng)使用Win10userspace插件分析目標(biāo)進(jìn)程的用戶地址空間,運(yùn)行結(jié)果如表8所示。

表8 惡意軟件樣本測試結(jié)果
表中可疑用戶分配數(shù)表示在進(jìn)程用戶地址空間中可能包含惡意代碼的用戶分配數(shù),可疑用戶分配的判定條件需同時(shí)滿足以下兩點(diǎn):
1)用戶分配具有可執(zhí)行權(quán)限。
2)用戶分配的描述信息為空或不是映射文件。
Block等[17]研究表明,在絕大部分情況下,良性進(jìn)程中只有映射文件具有可執(zhí)行權(quán)限。若出現(xiàn)了同時(shí)滿足以上2點(diǎn)條件的用戶分配,那么這個(gè)用戶分配會(huì)被判定為可疑用戶分配。
測試結(jié)果表明,Win10userspace能夠有效遍歷目標(biāo)進(jìn)程的用戶地址空間,遍歷百分比能夠保持在90%以上。除了Olympic Destroyer樣本外,其余的目標(biāo)進(jìn)程中都出現(xiàn)了可疑用戶分配。通過逆向分析Olympic Destroyer樣本,發(fā)現(xiàn)該惡意軟件首先會(huì)在目標(biāo)進(jìn)程中以READWRITE權(quán)限分配內(nèi)存,隨后使用VirtualProtect()函數(shù)將用戶分配內(nèi)的頁面修改為EXECUTE-READWRITE。修改權(quán)限這一過程不會(huì)改變VAD樹中記錄的權(quán)限值,因此Win10userspace沒有輸出修改后的權(quán)限。
本文針對(duì)當(dāng)前內(nèi)存取證領(lǐng)域的用戶地址空間遍歷方法無法兼容Windows 10系統(tǒng),提出了一種基于VAD樹的用戶地址空間遍歷方法,滿足了目前對(duì)Windows 10 64位系統(tǒng)用戶地址空間遍歷的取證需求。經(jīng)過測試與分析,本文方法能夠有效獲取Windows 10 64位系統(tǒng)中64位進(jìn)程和WOW64進(jìn)程用戶分配的詳細(xì)信息,遍歷的完整度優(yōu)于現(xiàn)有方法;此外,本文針對(duì)不同版本W(wǎng)indows 10 64位系統(tǒng)測試了插件的兼容性,結(jié)果表明插件能夠適用于目前所有版本的Windows 10 64位系統(tǒng)。經(jīng)過應(yīng)用實(shí)例測試證明,插件在實(shí)際應(yīng)用過程中能夠重現(xiàn)進(jìn)程用戶地址空間詳細(xì)布局,輔助取證分析人員快速找出被注入惡意代碼的內(nèi)存區(qū)域。
由于Windows系統(tǒng)的不完全開源性,用戶地址空間中仍存在部分無法描述的區(qū)域,針對(duì)此問題,未來的研究可專注于Windows系統(tǒng)內(nèi)存元數(shù)據(jù)的調(diào)試和解析以提高遍歷用戶地址空間中可描述分配的百分比。此外,常見的內(nèi)存注入攻擊針對(duì)用戶進(jìn)程堆棧緩沖區(qū)和映射文件區(qū)域注入惡意代碼,本文方法能夠在保證不流失有效數(shù)字證據(jù)的前提下有效遍歷這些易受到注入的用戶分配,因此未來的研究也可基于本文的方法進(jìn)一步研究如何自動(dòng)化檢測和提取用戶地址空間中被注入惡意代碼的區(qū)域,以提高取證工作的效率。