王 暢
(杭州國際服務工程學院,浙江 杭州 310000)
基于規(guī)范的入侵檢測技術在描述和實施安全策略方面起著指導性作用,本文把安全策略看做是監(jiān)控一個程序的執(zhí)行使其行為不會破壞系統(tǒng)安全的準則。從執(zhí)行的角度看,Java程序的行為可以粗略的看成是方法調用序列,有些方法可能是本地方法,會調用C語言函數(shù)庫,某些C庫函數(shù)又可能調用系統(tǒng)調用,這些都構成系統(tǒng)的潛在威脅。為了消除一些不正當?shù)恼{用序列可能給系統(tǒng)帶來的威脅,一個基于模式的檢測方法被應用到系統(tǒng)安全領域當中,這一方法的核心是如何定義和實施安全策略。以系統(tǒng)調用為例,如果將系統(tǒng)調用抽象為事件,那么系統(tǒng)調用的參數(shù)就成了事件參數(shù),在系統(tǒng)調用序列中,一些系統(tǒng)調用的規(guī)律性出現(xiàn)將被理解成一種模式。反過來,這樣的模式就能夠匹配許許多多這樣的系統(tǒng)調用序列,以檢查這些系統(tǒng)調用序列是否安全。這便是基于模式的檢測方法的核心思想。安全策略可以定義在系統(tǒng)調用上,也可以定義在 JNC上,然而無論是定義在哪一級,都和安全策略的組織形式無關,下面從事件開始討論安全策略的組織形式。事件:是安全策略中最基本概念,是模式的組成部分,也是最簡單的模式,是某一事件集中的元素,包括事件名和參數(shù),可以將 JNC調用或系統(tǒng)調用以及它們的返回看成事件。當被監(jiān)控程序的執(zhí)行匹配了為其定制的某一模式,監(jiān)控程序將采取包括終止其執(zhí)行在內的手段來保護系統(tǒng)安全,這便是規(guī)則。
通過修改Kaffe源碼實現(xiàn)Java代碼的執(zhí)行監(jiān)控,改進了安全策略實施框架:安全策略首先用SPDL語言定義出來,然后經過編譯轉換成擴展自動機EFSA的中間表示,最后在監(jiān)控程序的輔助下強制實施。進程級的監(jiān)視對于在Java層面所看不到的Linux系統(tǒng)調用部分仍然是有效的。整個安全策略的實施過程分為兩種情況,第一種情況:監(jiān)視進程(父進程 moni)首先啟動,在讀取安全策略之后把它編譯成擴展有限自動機 (EFSA)的形式,利用 fork()和 exec()系統(tǒng)調用啟動經過修改的 Kaffe。此時,監(jiān)視進程和 Kaffe進程同時工作:Kaffe的作用是解釋 Java字節(jié)碼,處理可能來自用戶的輸入和輸出;父進程的作用是監(jiān)視子進程的運行,實施安全策略,可能對子進程發(fā)出強制措施的指令,并寫入監(jiān)控記錄,直到子進程終止,父進程退出。父子進程互通消息是通過信號實現(xiàn)的。在另一種情形下,也就是安全策略的事件集為 JNC調用的情形,父進程在編譯完安全策略后,就進入等待狀態(tài),直到子進程退出。這時,Kaffe在解釋主函數(shù)之前載入安全策略的 EFSA模型,安全策略的實施引擎將作為動態(tài)鏈接庫的形式在 Kaffe上執(zhí)行。整個程序的模塊組成主要有四大部分:(1)支持模塊:主要有Hash表,雙向鏈表,數(shù)組,讀寫文件緩沖區(qū)等。讀寫文件緩沖主要是為了提高讀寫速度,提高程序效率,其中寫緩沖可以寫入文件,也可以寫入屏幕緩沖區(qū),或管道等,根據程序具體情況或有不同,給程序帶來極大靈活性。(2)安全策略分析模塊:包括詞法分析,語法分析和語義分析。(3)EFSA內部表示:包括 EFSA內部表示的各種表結構和將這些結構寫入或讀出文件的方法。表結構包括變量表,事件表,轉換表和終止狀態(tài)表,當需要寫入文件時,把這些表數(shù)據安順序寫入寫緩存;當需要讀出文件內容時,通過詞法分析程序,按照EFSA文件格式順序讀取內容到內部表示。(4)安全策略實施模塊:通過一種實施機制實施 EFSA模型。在本文看來,實施模塊與實施機制是不一樣的,實施機制是具體到與系統(tǒng)相關的情況,或是進程級的監(jiān)視,或是進程內部實現(xiàn),包括派生 kaffe進程,注冊信號和監(jiān)視系統(tǒng)調用等,是面向系統(tǒng)調用或 JNC調用的。
安全策略語言經過編譯以后,得到一種EFSA形式的內部表示,這種內部表示不僅要包含安全策略語言提供全部信息,還要求實施過程的效率要高。分析過程包括詞法分析,語法分析和語義分析。詞法分析的另一個作用是將字符串常量轉換為字符串內部數(shù)據,存入 Hash表中,獲得字符串的句柄。無論是模式子樹還是表達式子樹,它們都是已經按照操作符的優(yōu)先級順序表示的,模式子樹將在語義分析時轉化為自動機,表達式子樹將在語義分析時轉換為可執(zhí)行的二叉樹表示。語義分析是分析過程中最關鍵的一環(huán),因為它要將語法樹轉換為 EFSA內部表示。轉換過程包括三個主要方面:一是在構造變量表的過程中,要解決變量類型,重名和初始化等問題;二是將用正則表達式表示的模式轉化為自動機的過程;三是將可執(zhí)行的表達式轉化為二叉樹的表示形式,以方便執(zhí)行。下面分別討論三個方面。1.在構造變量表時,作如下規(guī)定:(1)規(guī)定全局變量聲明或在事件參數(shù)表中出現(xiàn)的變量為變量的定義性出現(xiàn),在表達式或語句中出現(xiàn)的變量為變量的使用性出現(xiàn),定義性出現(xiàn)的變量需要解決類型,重名問題,使用性出現(xiàn)的變量需要解決類型相容性的問題。(2)全局變量需要聲明,指定類型,且不能重名。(3)局部變量(又稱規(guī)則變量)根據事件集中事件的描述確定其類型。(4)用變量名和規(guī)則編號的二元結構標識一個變量,指定全局變量的規(guī)則編號可以為任意,這樣規(guī)則變量之間可以互相不影響,若全局變量和局部變量重名,則認為是全局變量。2.實際上,構造自動機的過程,是確定狀態(tài)轉換矩陣和事件表兩個過程。3.主要是將樹形結構的表達式轉換為二叉樹形式。表達式子樹在一般情況下每個節(jié)點之多有兩個子節(jié)點,但序列運算符除外(如函數(shù)調用實參和語句序列),這時只需要將序列運算符下多個子節(jié)點順序的轉成二叉樹即可。
在實施之前,還需要將內部表示中的狀態(tài)轉換矩陣變成圖結構,因為用稀疏矩陣表示的狀態(tài)轉換表很不利于查找,所有將其轉換為鄰接表表示。本文最終要實現(xiàn)的是一個監(jiān)控程序,是基于Linux操作系統(tǒng)上的用戶級的一個進程監(jiān)視另一個進程。監(jiān)控程序的實現(xiàn)分三步:第一步,修改 Kaffe源碼,重新編譯 Kaffe。Kaffe在解釋執(zhí)行 Java主方法前,根據命令行參數(shù)中的最后一個參數(shù)決定是由監(jiān)視進程實施安全策略,還是由自己,若是由監(jiān)視進程實施,則發(fā)送一個開始監(jiān)視的信號給監(jiān)視進程;若是由自己實施,則需要載入 EFSA模型和實施引擎。主要的監(jiān)視工作應該在 Kaffe中 sysdepCallMethod()函數(shù)之前和之后插入代碼完成。第二步,用 ptrace()系統(tǒng)調用進行進程監(jiān)視機制,因為 Java語言提供的本地方法調用,使得連Kaffe自己也不知道它所要解釋的Java方法有沒有進行系統(tǒng)調用,所以必須用進程級的監(jiān)視,這才是監(jiān)視進程的工作重點。
監(jiān)視進程在fork()調用和exec(kaffe)調用之間要進行ptrace(PTRACE_TRACEME)調用,使Kaffe處于被監(jiān)視狀態(tài),之后監(jiān)視進程的每次ptrace(PTRACE_SYSCALL)中斷說明Kaffe進行系統(tǒng)調用或返回。其中,ptrace(PTRACE_PEEKUSER可以獲得系統(tǒng)調用號,用參數(shù) ptrace(PTRACE_GETREGS,®s)可以獲得系統(tǒng)調用的相關參數(shù)信息,用ptrace(PTRACE_PEEKUSER)可以獲得系統(tǒng)調用返回值的信息。第三步,給出實施細節(jié)。從事件發(fā)生開始,首先查找從當前狀態(tài)表出發(fā)的是否有與之匹配的邊,再匹配參數(shù)類型,給變量賦值,檢查條件表達式是否為真,然后更新當前狀態(tài)表,更新環(huán)境,最后如果當前狀態(tài)表與終止狀態(tài)表有交,則執(zhí)行終止狀態(tài)所對應的動作函數(shù)。
[1]金成植.程序理論和技術[M],吉林大學出版社,1997
[2]劉磊等.編譯程序的設計與實現(xiàn)[M],高等教育出版社,2004