0 引言
計(jì)算機(jī)和計(jì)算機(jī)網(wǎng)絡(luò)已經(jīng)成為當(dāng)前企業(yè)、政府和其它各種組織的重要信息載體和傳輸渠道。但是,人們?cè)谙硎苡?jì)算機(jī)以及計(jì)算機(jī)網(wǎng)絡(luò)所帶來(lái)的方便性的同時(shí),信息安全也成為目前受到廣泛關(guān)注的問(wèn)題。美國(guó)聯(lián)邦調(diào)查局(FBI)和計(jì)算機(jī)安全機(jī)構(gòu) (CSl)等權(quán)威機(jī)構(gòu)的研究證明:超過(guò)80%的信息安全隱患是來(lái)自組織內(nèi)部。內(nèi)部的安全狀況較差,不僅會(huì)給攻擊者以可乘之機(jī),還會(huì)使已構(gòu)建的安全設(shè)施形同虛設(shè),為內(nèi)部安全違規(guī)事件的發(fā)生打開(kāi)方便之門(mén)。目前廣泛采用的安全設(shè)備和安全措施,均側(cè)重于對(duì)付外部的攻擊、侵犯和威脅,而無(wú)法阻止內(nèi)部不懷好意的員工盜取涉密信息并將其拷貝或傳播出去。因此,數(shù)據(jù)資源的保密以及非法外泄的防范已成為當(dāng)前迫在眉睫的安全需求。而利用USB存儲(chǔ)設(shè)備的單向控制技術(shù)可對(duì)接人計(jì)算機(jī)的存儲(chǔ)介質(zhì)進(jìn)行控制,以防止信息被有意或者無(wú)意地從移動(dòng)存儲(chǔ)設(shè)備泄漏出去。由于用戶(hù)可以根據(jù)需要設(shè)定存儲(chǔ)設(shè)備的使用權(quán)限(比如只讀或者讀寫(xiě)等),因此,該方法既保留了移動(dòng)設(shè)備的方便性,又堵截了移動(dòng)存儲(chǔ)設(shè)備可能帶來(lái)的安全隱患。
1 單向控制的設(shè)計(jì)與實(shí)現(xiàn)
本文采用對(duì)磁盤(pán)驅(qū)動(dòng)器進(jìn)行過(guò)濾的方法來(lái)實(shí)現(xiàn)USB存儲(chǔ)設(shè)備的單向控制。該技術(shù)以DDK中的filter為原形。采用標(biāo)準(zhǔn)的WDM過(guò)濾,可攔截所有對(duì)USB存儲(chǔ)設(shè)備的寫(xiě)操作,從而實(shí)現(xiàn)U盤(pán)的單向控制。其中過(guò)濾器驅(qū)動(dòng)程序是可選擇的驅(qū)動(dòng)程序,它可以給設(shè)備增加值或修改設(shè)備行為,而且,該過(guò)濾器驅(qū)動(dòng)程序能服務(wù)于一個(gè)或多個(gè)設(shè)備。由于頂層的過(guò)濾器驅(qū)動(dòng)程序主要是為某一設(shè)備提供增值特征,而低層過(guò)濾器驅(qū)動(dòng)程序則主要修改設(shè)備的硬件行為。所以,本文選擇使用低層設(shè)備過(guò)濾器驅(qū)動(dòng)程序,來(lái)監(jiān)視和修改磁盤(pán)驅(qū)動(dòng)器的I/0請(qǐng)求。
1.1 驅(qū)動(dòng)程序的基本結(jié)構(gòu)
一個(gè)WDM驅(qū)動(dòng)程序的基本結(jié)構(gòu)包括一組必要的,通過(guò)系統(tǒng)定義的標(biāo)準(zhǔn)驅(qū)動(dòng)程序函數(shù),同時(shí)還有一些可選的標(biāo)準(zhǔn)函數(shù)與內(nèi)部函數(shù)(取決于驅(qū)動(dòng)程序的類(lèi)型和下層設(shè)備)。對(duì)于所有的驅(qū)動(dòng)程序,不管它們?cè)诟綄衮?qū)動(dòng)程序鏈中所處的是那一層,都必須有一組基本的標(biāo)準(zhǔn)函數(shù)來(lái)處理IRP。一個(gè)驅(qū)動(dòng)程序是否必須執(zhí)行附加標(biāo)準(zhǔn)函數(shù),取決于該驅(qū)動(dòng)程序的類(lèi)型和下層設(shè)備是控制一個(gè)物理設(shè)備的驅(qū)動(dòng)程序,還是在一個(gè)物理設(shè)備驅(qū)動(dòng)程序之上的驅(qū)動(dòng)程序,同時(shí)也取決于下層物理設(shè)備的屬性。控制物理設(shè)備的最低層驅(qū)動(dòng)程序比較高層驅(qū)動(dòng)程序擁有更多所要求的函數(shù),較高層的驅(qū)動(dòng)程序一般將IRP傳送給較低層的驅(qū)動(dòng)程序來(lái)處理。
下面所列是本驅(qū)動(dòng)程序所需要的標(biāo)準(zhǔn)驅(qū)動(dòng)程序函數(shù):
(1)DIiveEntry
該函數(shù)可用于初始化驅(qū)動(dòng)程序并設(shè)置其他標(biāo)準(zhǔn)函數(shù)的人口點(diǎn)。當(dāng)驅(qū)動(dòng)程序的DriverEntry函數(shù)被調(diào)用,它將直接在驅(qū)動(dòng)程序?qū)ο笾性O(shè)置Dispatch和Unload的入口點(diǎn),方法如下:
在驅(qū)動(dòng)程序?qū)ο髢?nèi)的DriverExtension中設(shè)置它的AddDevice函數(shù)的人口點(diǎn)方法如下:
DriverObject->DriverExtension一>AddDevice=DDAddDevice;
驅(qū)動(dòng)程序能定義若干Dispatch人口點(diǎn),但是它只能在其驅(qū)動(dòng)程序?qū)ο笾卸x一個(gè)AddDevice人口點(diǎn)和一個(gè)Unload人口點(diǎn)。
(2) AddDevice
AddDevice函數(shù)主要用于創(chuàng)建設(shè)備對(duì)象,地址在DriverObject->DriverExtension->AddDevice。
(3)Dispatch
該函數(shù)至少應(yīng)一個(gè)Dispatch人口點(diǎn)。因?yàn)橐靡粋€(gè)或多個(gè)主要功能來(lái)編碼處理IRP,以得到請(qǐng)求PnP、電源和I/O操作的IRP。
(4)Unload
如果驅(qū)動(dòng)程序能動(dòng)態(tài)地被裝載和/或者替換,還需要一個(gè)Unload人口點(diǎn),以釋放系統(tǒng)資源(諸如驅(qū)動(dòng)程序已分配的系統(tǒng)對(duì)象或者內(nèi)存等)。
1.2驅(qū)動(dòng)程序的實(shí)現(xiàn)
實(shí)現(xiàn)驅(qū)動(dòng)程序時(shí),首先要為設(shè)備定義GUID。驅(qū)動(dòng)程序使用設(shè)備名和GUID(globallv unique identifiers)來(lái)標(biāo)識(shí)不同的物理、邏輯或虛擬設(shè)備。PnP驅(qū)動(dòng)程序可注冊(cè)并激活一個(gè)與GUID連接的設(shè)備接口,應(yīng)用程序和其他系統(tǒng)組件則可通過(guò)接口對(duì)設(shè)備進(jìn)行I/O請(qǐng)求和控制,WDM用于過(guò)濾驅(qū)動(dòng)禁止給它們的設(shè)備對(duì)象命名,所以,要為設(shè)備定義GUID。
其次是應(yīng)為驅(qū)動(dòng)程序函數(shù)選擇名字。由于每個(gè)驅(qū)動(dòng)程序中都要包含標(biāo)準(zhǔn)的驅(qū)動(dòng)程序函數(shù),因此,應(yīng)使用一套區(qū)別于其他驅(qū)動(dòng)程序的函數(shù)命名機(jī)制,由于使程序更容易開(kāi)發(fā)、調(diào)試和測(cè)試。
此外,還要編寫(xiě)一個(gè)為AddDevice、DispatchPnP、DispatchPower和DispatchCreate函數(shù)設(shè)置入口點(diǎn)的 DriverEntry函數(shù),同時(shí)要編寫(xiě)一個(gè)完成內(nèi)容的AddDevice函數(shù)。這四個(gè)內(nèi)容。第一是調(diào)用IoCreateDevice以創(chuàng)建一個(gè)獨(dú)立設(shè)備對(duì)象:第二是調(diào)用IoAttachDeviceToDeviceStack。以把它自己加入設(shè)備棧,同時(shí)填寫(xiě)PDEVICE_EXTENSION;第三是調(diào)用IoRegisterDeviceInterface,并為它的設(shè)備暴露一個(gè)接口,暴露的接口可為訪問(wèn)該設(shè)備的應(yīng)用程序提供途徑:第四調(diào)用 IoSetDevi.ceInterfaceState,以激活它先前注冊(cè)的接口。
至此,過(guò)濾設(shè)備就可以在DeviceTree中看到了。
最后,應(yīng)為IRP_MJ_PNP請(qǐng)求編寫(xiě)一個(gè)基本DispatchPnP函數(shù)。該DispatchPnP函數(shù)必須準(zhǔn)備處理具體的PnP IRP,然后為IRP_MJ_POWER編寫(xiě)一個(gè)基本DispatchPower函數(shù),再為IRP_MJ_CREATE請(qǐng)求編寫(xiě)一個(gè)基本Dispatch Create函數(shù),同時(shí)攔截相應(yīng)的IRP請(qǐng)求,接著再為I/O控制請(qǐng)求編寫(xiě)一個(gè)基本DispatchDevCtrl函數(shù),以與應(yīng)用程序進(jìn)行通訊和處理具體的控制請(qǐng)求。
2單向控制關(guān)鍵技術(shù)分析
2.1 SCSI命令的分析
對(duì)應(yīng)于不同的過(guò)濾功能,其需要攔截的IRP也不相同。要對(duì)U盤(pán)進(jìn)行單向控制。就需要攔截所有的寫(xiě)操作,使U盤(pán)成為只讀的。但是,寫(xiě)U盤(pán)的時(shí)候,發(fā)送的并不是通常的IRP_MJ_WRITE請(qǐng)求,而是要分析相應(yīng)的SCSI命令,對(duì)SCSI命令的取得和操作大致有兩種。
第一種是得到當(dāng)前的SCSI命令,其格式為:
2.2單向控制的實(shí)現(xiàn)
系統(tǒng)進(jìn)行寫(xiě)操作時(shí),通常都是先寫(xiě)在緩存區(qū),然后經(jīng)過(guò)一定的延時(shí)后,才會(huì)寫(xiě)到真正的磁盤(pán)中。所以,當(dāng)攔截到SCSI命令中的SCSIOP WRITE后,雖然系統(tǒng)不會(huì)真正的寫(xiě)東西到U盤(pán)上,但卻要過(guò)很久才會(huì)提示延時(shí)寫(xiě)錯(cuò)誤。所以,本文采用了另外一種方法,即用軟件實(shí)現(xiàn)“帶寫(xiě)保護(hù)功能”的U 盤(pán),其效果與硬件實(shí)現(xiàn)的寫(xiě)保護(hù)方式一樣,從而實(shí)現(xiàn)了U盤(pán)的只讀。其軟件實(shí)現(xiàn)方法如下:
2.3 區(qū)分硬盤(pán)和U盤(pán)驅(qū)動(dòng)器
作為磁盤(pán)驅(qū)動(dòng)器的低層設(shè)備過(guò)濾器驅(qū)動(dòng)程序。在區(qū)分硬盤(pán)和U盤(pán)驅(qū)動(dòng)器時(shí),Device_Ob_iect->DeviceType的值并不能真正區(qū)分硬盤(pán)和U盤(pán)驅(qū)動(dòng)器。這個(gè)值對(duì)于U盤(pán)而言,第一次插入時(shí)是0x2d,但是,一旦被虛擬化成磁盤(pán)分區(qū)后,它將變成07。這和本地硬盤(pán)沒(méi)有任何區(qū)別。因此,如果采用IoGetDeviceProperty來(lái)獲得當(dāng)前物理設(shè)備對(duì)象的總線(xiàn)類(lèi)型的GUID,就往往會(huì)導(dǎo)致操作系統(tǒng)出現(xiàn)藍(lán)屏(系統(tǒng)死機(jī))。因?yàn)楹瘮?shù)調(diào)用要求在passive-level執(zhí)行。而不是dispatch— level。其代碼如下:
但是,由于符號(hào)鏈接的名稱(chēng)和光盤(pán)驅(qū)動(dòng)器的設(shè)備類(lèi)型將保持不變。所以,可以通過(guò)修改設(shè)備擴(kuò)展的內(nèi)部結(jié)構(gòu),并增加DeviceType項(xiàng),然后根據(jù)符號(hào)鏈接的名稱(chēng)和設(shè)備類(lèi)型來(lái)設(shè)置:deviceExtension->DeviceType
該方法對(duì)光盤(pán)和硬盤(pán)以及USB都有很好的支持。其代碼如下:
3 結(jié)束語(yǔ)
本文在分析了磁盤(pán)讀寫(xiě)技術(shù)的基礎(chǔ)上,采用對(duì)磁盤(pán)驅(qū)動(dòng)器進(jìn)行過(guò)濾的方法,給出了基于過(guò)濾驅(qū)動(dòng)的USB存儲(chǔ)設(shè)備的單向控制方法。這種技術(shù)的實(shí)現(xiàn)能有效解決涉密信息的外泄,是內(nèi)網(wǎng)安全的一種重要輔助手段。