方 飛, 李 兵
(內(nèi)江師范學(xué)院物理學(xué)電子信息工程系,四川 內(nèi)江 641112)
隨著網(wǎng)絡(luò)應(yīng)用的廣泛,網(wǎng)絡(luò)攻擊行為日趨嚴(yán)重,防火墻也在網(wǎng)絡(luò)信息安全領(lǐng)域承擔(dān)著十分重要的角色。在Windows下實(shí)現(xiàn)數(shù)據(jù)載包有如下幾種方式[1-2]:①用戶態(tài)下的網(wǎng)絡(luò)數(shù)據(jù)包攔截方式有:Winsock Layered Service Provider、Windows包過濾接口;替換系統(tǒng)自帶的WINSOCK動(dòng)態(tài)連接庫;②利用驅(qū)動(dòng)程序攔截網(wǎng)絡(luò)數(shù)據(jù)包的方式有:TDI過濾驅(qū)動(dòng)程序、NDIS中間層驅(qū)動(dòng)程序、Win2k Filter-Hook Driver、NDIS Hook Driver、小端口驅(qū)動(dòng)程序。每一種技術(shù)都有其局限性,在用戶態(tài)下進(jìn)行數(shù)據(jù)包攔截最致命的缺點(diǎn)就是只能在Winsock層次上進(jìn)行,而對于網(wǎng)絡(luò)協(xié)議棧中底層協(xié)議的數(shù)據(jù)包無法進(jìn)行處理,對于一些木馬和病毒來說很容易避開這個(gè)層次的防火墻[3]。現(xiàn)今的防火墻不再單純的使用某一種技術(shù)來實(shí)現(xiàn),從技術(shù)的角度講,IMD具有最強(qiáng)的功能,但是由于其安裝的復(fù)雜性,因此很少被用于個(gè)人防火墻,TDI已經(jīng)網(wǎng)絡(luò)狀態(tài)控制的主要技術(shù)。
在Windows系統(tǒng)中,網(wǎng)絡(luò)協(xié)議棧的核心協(xié)議由TDI傳輸驅(qū)動(dòng)程序(協(xié)議驅(qū)動(dòng)程序)實(shí)現(xiàn),傳輸驅(qū)動(dòng)程序Tcpip.sys是Windows TCP/IP協(xié)議的內(nèi)核模式實(shí)現(xiàn),它通過創(chuàng)建三個(gè)設(shè)備對象DeviceTcp,DeviceUdp和DeviceIp來實(shí)現(xiàn)TCP/IP協(xié)議中的TCP, UDP, IP等核心協(xié)議,基于TCP/IP協(xié)議的應(yīng)用程序的網(wǎng)絡(luò)數(shù)據(jù)操作都是通過訪問這幾個(gè)設(shè)備來進(jìn)行的[4]。 TDI傳輸驅(qū)動(dòng)程序通過創(chuàng)建設(shè)備對象來代表特定的協(xié)議,上層的TDI客戶能夠獲得一個(gè)代表協(xié)議的文件對象并且通過IRP與協(xié)議進(jìn)行網(wǎng)絡(luò)通信,這些IRP在傳輸驅(qū)動(dòng)程序的Dispatch例程中進(jìn)行處理。在TDI層面上攔截網(wǎng)絡(luò)數(shù)據(jù)包可以通過一個(gè)驅(qū)動(dòng)程序來 HOOK傳輸驅(qū)動(dòng)程序中的Dispatch例程缺點(diǎn)是 HOOK技術(shù)并非微軟公開支持的技術(shù)[5]。另外在TDI層面上可以采用分層驅(qū)動(dòng)程序技術(shù)進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)包的攔截,即將一個(gè)驅(qū)動(dòng)程序掛接到TDI傳輸驅(qū)動(dòng)程序之上,當(dāng)TDI客戶向協(xié)議發(fā)出請求時(shí),這個(gè)驅(qū)動(dòng)程序先于傳輸驅(qū)動(dòng)程序得到這個(gè)請求,當(dāng)協(xié)議向 TDI客戶傳輸數(shù)據(jù)時(shí),這個(gè)驅(qū)動(dòng)程序先于TDI客戶得到數(shù)據(jù),這樣就可以在驅(qū)動(dòng)中對網(wǎng)絡(luò)數(shù)據(jù)包進(jìn)行過濾,TDI過濾驅(qū)動(dòng)程序掛接Tcpip.sys后的分層結(jié)構(gòu)如圖1所示。
圖1 TDI驅(qū)動(dòng)掛接前后示意圖
在TDI驅(qū)動(dòng)程序設(shè)計(jì)時(shí)添加自己的驅(qū)動(dòng)于tcpip.sys之上,在包處理過程中將過濾驅(qū)動(dòng)模塊加入到TDI Interface處,攔載核心模式請求 IRP_MJ_INTERNEL_DEVICE_CONTROL下的除打開和關(guān)閉文件對象之外的各內(nèi)部傳輸函數(shù)據(jù)處理操作TDI_XXX請求,獲取整個(gè)通信過程中的數(shù)據(jù),根據(jù)定義的規(guī)則進(jìn)行過濾,并對每一上網(wǎng)程序向用戶通告,從而有效的防止非法程序連接網(wǎng)絡(luò),TDI實(shí)現(xiàn)的總體結(jié)構(gòu)如圖2[5]。在驅(qū)動(dòng)設(shè)計(jì)中,驅(qū)動(dòng)程序如何時(shí)實(shí)現(xiàn)對上網(wǎng)程序的控制,應(yīng)用層如何同驅(qū)動(dòng)進(jìn)行通信,內(nèi)存的分配及釋放,當(dāng)驅(qū)動(dòng)需要資源無法得到滿足量,可能會(huì)造成系統(tǒng)的崩潰,這些都必須在驅(qū)動(dòng)進(jìn)行處理。
防火墻的一項(xiàng)重要功能就是當(dāng)未知有應(yīng)用程序時(shí)試圖連接網(wǎng)絡(luò)時(shí),向用戶通知程序的相關(guān)信息。進(jìn)程號唯一標(biāo)識用戶的進(jìn)程,通過TDI獲得當(dāng)前試圖連接網(wǎng)絡(luò)的進(jìn)程ID號,將該ID號通過通信模塊傳輸至界面程序,并在應(yīng)用程序部分獲取進(jìn)程的詳細(xì)信息顯示給用戶,在該等待用戶處理過程中必須使用驅(qū)動(dòng)處理等待狀態(tài),然后用戶將確認(rèn)信息傳輸至驅(qū)動(dòng)以進(jìn)行以后的處理。TDI驅(qū)動(dòng)中可以在許多事件中以獲得上網(wǎng)進(jìn)程的ID號,在TDI_CREATE處理過程中會(huì)創(chuàng)建一個(gè)FILE_FULL_EA_INFORMATION類型的對象,當(dāng)創(chuàng)建控制對象時(shí)就可以獲取進(jìn)程ID號通告應(yīng)用程序,主要是在TDI_CREATE時(shí)進(jìn)行處理,因?yàn)榇藭r(shí)處理可以防止連接的創(chuàng)建并節(jié)約資源,其處理流程如圖4所示,處理后的相應(yīng)效果如圖3所示,在實(shí)際應(yīng)用中,還應(yīng)在在提示中還可以加入允許或禁止或其它選擇項(xiàng)。
要實(shí)現(xiàn)用戶對驅(qū)動(dòng)的控制,其前提是應(yīng)用層與驅(qū)動(dòng)程序間的相互通信。在網(wǎng)卡接收/發(fā)送過程中,驅(qū)動(dòng)程序緩存報(bào)文,并通過IO方式或者共享內(nèi)存方式應(yīng)用層有報(bào)文需要處理。在100 Mb/s速率下,以上兩種方式都可以滿足需要,較簡便的方式就是使用有緩沖的IO方式,應(yīng)用層處理完畢相同的方式向驅(qū)動(dòng)程序遞交結(jié)果[4]。在應(yīng)用程序使用CreateFile的打開驅(qū)動(dòng)程序MyTDI.sys時(shí),驅(qū)動(dòng)程序利用IoCreate SynchronizationEvent在BaseNamedObjects下創(chuàng)建一個(gè)有名的事件tdirequest,然后應(yīng)用程序使用OpenEvent打開此有名事件即可。設(shè)計(jì)時(shí)應(yīng)注意tdirequest創(chuàng)建時(shí)機(jī),否則可以不創(chuàng)建成功,或造成事件只能讀(Waitxxxx),不能寫(SetEvent/ResetEvent)。驅(qū)動(dòng)對應(yīng)用層讀請求應(yīng)立即返回,否則將失去用事件通知的意義,當(dāng)應(yīng)用程序發(fā)現(xiàn)有事件,應(yīng)該在一個(gè)循環(huán)中讀取,直到讀取失敗,表明沒有數(shù)據(jù)可讀;否則會(huì)漏掉后續(xù)數(shù)據(jù),而沒有及時(shí)讀取,事件通告處理流程如圖5所示,關(guān)鍵源代碼如下所示。
圖2 TDI處理基本流程
圖3 QQ上網(wǎng)時(shí)用戶端通告信息
圖5 應(yīng)用層和驅(qū)動(dòng)程序的通信
NTSTATUS filter_init (void)化命名事件
{ NTSTATUS status;
if (g_queue.event_handle == NULL)
{ UNICODE_STRING str;
OBJECT_ATTRIBUTES oa;
RtlInitUnicodeString(&str,
L"\BaseNamedObjects\tdirequest");
InitializeObjectAttributes(&oa, &str, 0, NULL, NULL);
status
ZwCreateEvent(&g_queue.event_handle,
EVENT_ALL_ACCESS,&oa, ynchronizationEvent, FALSE);
if (status != STATUS_SUCCESS) {
return status; }}
if (g_queue.event == NULL) {
status = ObReferenceObjectByHandle(
g_queue.event_handle, EVENT_ALL_ACCESS, NULL,
KernelMode, &g_queue.event, NULL);
if (status != STATUS_SUCCESS) {
return status;}
}
return STATUS_SUCCESS;
}
在應(yīng)用程序部分加上該行代碼 g_event = OpenEvent(SYNCHRONIZE, FALSE, "tdirequest");就可以打開命名事件并共同操作該事件。
驅(qū)動(dòng)程序在執(zhí)行時(shí)由于創(chuàng)建文件對象或加入過濾規(guī)則都需要?jiǎng)討B(tài)分配內(nèi)存空間,由于網(wǎng)絡(luò)驅(qū)動(dòng)的代碼常常在較高的IRQL等級執(zhí)行而不允許頁錯(cuò)誤,因而通常不能使用可分頁內(nèi)存。非分頁內(nèi)存在整個(gè)系統(tǒng)中是一個(gè)有限的資源,其數(shù)量依賴于系統(tǒng)使用的類型和系統(tǒng)可用的物理內(nèi)存,NT提 供 ExAllocatePool、ExAllocatePoolWithQuota 、ExAllocate PoolWithTag及ExAllocatePoolWithQuotaTa例程給內(nèi)核驅(qū)動(dòng)來分配內(nèi)存[2-3],調(diào)用這些函數(shù)來請求內(nèi)存時(shí),必須要指定請求的內(nèi)存的類型是NonPagedPool(請求分配一個(gè)不可分頁的內(nèi)存)還是PagedPool(請求分配一個(gè)可分頁的內(nèi)存)。在設(shè)計(jì)中使用了ExAllocatePool從非分頁的池中來實(shí)現(xiàn)對內(nèi)存空間的動(dòng)態(tài)分配,為了保證在分配空間,其它進(jìn)行對內(nèi)存塊的請求,使用了一個(gè)自旋鎖以保護(hù)對內(nèi)存塊列表的修改。由于非分頁內(nèi)存在整個(gè)系統(tǒng)中是一個(gè)有限的資源,因此當(dāng)空間不需要時(shí)必須釋放存儲空間,實(shí)現(xiàn)部分源代碼如下:
//分配內(nèi)存空間
KeAcquireSpinLock(&guard, &irql);
data = (struct prefix *) ExAllocatePool(
NonPagedPool,sizeof(struct prefix)+size+sizeof(struct postfix));
KeReleaseSpinLock(&guard, irql);
//釋放內(nèi)存單元
KeAcquireSpinLock(&guard, &irql);
memset(data->data, 0xc9, data->size);// 用 0xc9 填充ExFreePool(data);
KeReleaseSpinLock(&guard, irql)。
TDI過濾驅(qū)動(dòng)程序已經(jīng)作為網(wǎng)絡(luò)狀態(tài)控制的主要技術(shù)在防火墻中得到廣泛應(yīng)用,由于TDI不能獲取未經(jīng)過傳輸層的數(shù)據(jù)包(如 ICMP包),因而還需同其它過濾技術(shù)相結(jié)合。在TDI設(shè)計(jì)中,除了需要考慮通信及內(nèi)存分配的問題外,還需要考慮當(dāng)錯(cuò)誤的有效處理,因?yàn)轵?qū)動(dòng)程序出錯(cuò)往往引起系統(tǒng)的崩潰,而在過濾規(guī)則鏈的查詢中還應(yīng)該提高效率,在設(shè)計(jì)使用了HASH表的方法。在設(shè)計(jì)中可以對處于 PASSIVE_ LEVEL的主動(dòng)事件進(jìn)行交互處理,并由用戶決定是否進(jìn)行過濾等操作,但對一些類似 TDI_EVENT_CONNECT的被動(dòng)事件,其工作于 DISPATCH_LEVEL,不能設(shè)置等待,否則會(huì)藍(lán)屏。在TDI中還可以進(jìn)行內(nèi)容過濾,但是其效率必須的改進(jìn)是以后應(yīng)該研究的內(nèi)容。
[1] 杜江,王天平,羅文龍.基于主機(jī)的網(wǎng)絡(luò)防火墻技術(shù)及其實(shí)現(xiàn)方法[J].重慶郵電學(xué)院學(xué)報(bào):自然科學(xué)版,2002,14(03):26-29.
[2] 楊立身,張萍,陳艷格.基于IPv4/v6下的IPSec與防火墻協(xié)同問題研究[J].通信技術(shù),2008,41(06):119-121.
[3] 劉益洪,陳林.基于防火墻的網(wǎng)絡(luò)安全技術(shù)分析[J].通信技術(shù),2008,41(06):136-138.
[4] 周子平,杜月云.企業(yè)級防火墻的技術(shù)與選擇[J].通信技術(shù),2009,42(04):117-119.
[5] 高澤勝,陶宏才.基于 NDIS_HOOK技術(shù)的個(gè)人防火墻的研究與實(shí)現(xiàn)[J].成都信息工程學(xué)院學(xué)報(bào),2004(09):327-329.