宏病毒檢測問題 (轉)
宏檢測問題
Vesselin Bontchev
譯者 DoomLeo
用流行的辦公室應用(如 )裡的宏語言編寫的病毒變的非常的普遍。和只有一個實體的MS—DOS病毒不同,宏病毒通常由一整套數個獨立的宏組成。這引起了特定病毒的反病毒試圖準確識別這個病毒時產生的一些有趣的理論問題。兩個病毒的宏集能擁有相同的子集----或者一個宏集是另一個宏集的子集。本文論述了由此所引起的問題,其中有的問題如果是並非不可能解決的,其也是非常困難的。重點是病毒作者是如何開發出這些難點的,以及反病毒產品應如何提高以阻止這樣的、避免在錯誤識別內的病毒並試圖刪除錯誤的病毒變體而對檔案所造成的損壞。
1.識別具體病毒的需要
在我們開始處理宏病毒識別之前,值得提及一下為什麼通常具體的病毒識別尤其是具體的宏病毒識別非常重要。畢竟從歷史上來看,大多數掃描器的工作原理是透過找到病毒的一小部分,並把它當作一個‘掃描線索’去檢測該病毒的其它所有的例項。然而這種方法也存在幾種缺陷。首先,該方法帶來錯誤識別的真正危險----也就是說,將一種病毒(例如:一個破壞性的病毒)和另外一種病毒(例如:沒有破壞目的的病毒)混淆。在過去的一年中,我們看到一個反病毒製造商透過釋出一個新聞警告具有破壞性的病毒(TEDIOUS)即將爆發。根據該釋出會,該病毒傳播很快----當然它們敦促人人購買哪個反病毒製造商的反病毒程式。哪個新聞的釋出一開始在資深的反病毒的研究者中引起了困惑。即使我們拋開利用恐懼戰術說服公眾購買其產品所引起的倫理問題。眾所皆知TEDIOUS病毒並沒有傳播開來。最重要的是它也沒有一個爆發日期也沒有一個有效載體。也就是說沒有破壞的企圖。事實表明,所說的病毒製造商的掃描器使用掃描字串不能區別TEDIOUS和BANDUNG----後者是即能傳播又具有破壞性的病毒----因此導致了新聞釋出所引起的混淆,毫無疑問,對那些釋出新聞的人帶來了負面影響。相對而言這件事對使用者而言沒有什麼危害,但是我們很容易想象錯誤識別所帶來的相反的錯誤。也就是說,一個具有破壞性的病毒被反病毒製造商報告為無攻擊性的病毒而沒有向使用者報警。
其次,在去除病毒()時對所發現的病毒的精確識別由為重要。錯誤識別會導致企圖去除錯誤的病毒變體----使被感染體遭受致命的損壞而不能修復。這在DOS病毒領域已經足夠重要。然而在宏病毒領域甚至更為重要。因為,令人信服的是恰當移除DOS病毒的方法是用未染毒的複製覆蓋被感染體來破壞被染毒體。在這種情況下,無論染毒體內的病毒是否被準確識別是沒有太大關係----被感染體無論如何已被損壞了。然而,宏病毒通常存在於文件裡----其必定經常變化,並且其未染毒的備份複製通常不可用。因此,透過移除被感染文件內的宏病毒來殺滅宏病毒是必須的----並且最終重要的是正確的完成防毒,並不破壞文件和內部存在的使用者定義的宏。如果沒有準確識別病毒的方法,則這一目標完全不能足夠穩定的實現。
第三,準確識別病毒對技術支援的原因通常是必需的。使用者經常問我們“這個或那個病毒在做什麼?”----因為問題中的病毒在它們的機器中被發現並且它們想知道病毒會對它們的資料做些什麼?如果發現病毒的掃描器不能準確的識別病毒,正確回答這樣的問題通常是不可能的。通常一個具有巨大破壞力的病毒(如資料騙取病毒 WM/Wazzu.A)和其不做任何事情的變體之間的不同僅僅只是一個位元組----甚至是一個二進位制位。這種級別的識別僅憑掃描字串實際上是不可能達到的。達到這種水平的唯一方法是計算病毒體的不改變部分的所有二進位制位的某種校驗和來完成。
第四,準確的識別病毒對於正確的報告和跟蹤病毒的傳播是必要的。這類資訊的一個權威資源叫做WildList,由反病毒研究者Joe Wells維護。許多測試者將其用為哪些病毒包含在in-the-wild測試集裡的資訊源。近來,事實表明這一列表不能準確識別其羅列的一些病毒,使我們的掃描器在一個對比的評論中得到不利的評分。這一列表列舉了Plagiarist病毒。事實表明,有幾個不同的病毒,其都是Plagiarist家族成員,我們的掃描器可以檢測出其中之一----真正的“在野”病毒,其被最初報告給Joe Wells。然而它不能檢測出另外一個變體----這一變體並不“在野”。然而由於WildList提到的正是“Plagiarist”並不是識別具體的變體。一個測試者使用一個我們的掃描器不能檢測的病毒變體,並在評論中寫到我們的產品不能100%檢測in-the-wild病毒集所收錄的病毒。人們可以想象關於宏病毒相同的災禍。
第五,準確識別病毒可以強有利的阻止絕對錯誤。眾所周知僅用單一掃描字串檢測病毒的掃描器經常引起絕對錯誤----即,報告某些乾淨的檔案內包含有病毒,這些檔案包含了被掃描器用來檢測病毒的相同的位元組序列。相同情況下,準確的病毒檢測決不會導致這樣的災禍----因為如果它檢測到檔案內有病毒,她僅僅意味那兒有病毒;這毫無疑問,因為其每一個二進位制位被辯識並發現其存在。實際上,使用準確病毒識別的產品產生的絕對錯誤通常遠小於(幾乎沒有----除非其試圖檢測新的病毒變體,而這時準確病毒識別沒有被用到)依靠掃描字串的反病毒產品。
最後,準確病毒識別本質上是處理VBA宏病毒(既,宏病毒用和97工具包程式語言所編寫的)的唯一方法。這因為,由於其設計,VBA程式包含許多可變的區域(其包含公共標識區的指標----文件中所有VBA模組的公共部分)。其結果是,可能的掃描字串平均長度僅為兩位元組----顯然不適合所有的實際應用。這一問題可用超長萬用字元掃描字串部分地解決----即掃描字串內公共標識區域變數指標的位置上,包含‘不關心’的位元組。不幸的是,這也不是一個好的解決方法,因為不同的VBA程式碼片段可被編譯成為完全相同的映像----不同僅僅在於標識指標被解析之後。顯然,這將提高絕對錯誤的危險甚至情況會更糟。
由於所有上面提到的這些原因,我認為,準確檢測其宣稱可以檢測的病毒對特定病毒的反病毒產品(例如,掃描軟體和)是十分重要的。在宏病毒的情況,準確識別甚至更為重要,因為宏病毒行為的明顯改變只是其其中一個宏的極小的改變的結果。通常,我們自己的宏病毒掃描器嚴格地努力準確檢測其宣稱可檢測的每一個單個宏病毒----並且力勸所有其它的反病毒產品在其掃描器時也採用相同的方法。幸運的是許多廠商意識到準確宏病毒識別的益處----我們看到許多反病毒產品開始使用這個方法。在許多情況下,即使掃描器沒有應用準確檢測病毒的方法於其檢測的DOS病毒,其至少應用準確檢測病毒的方法於其檢測的宏病毒。
2.定義
每一個設計良好的反病毒方案應基於對它試圖解決的問題的仔細的定義。因此,設計一個用於檢測,識別、確認和移除宏病毒應基於對什麼是宏病毒是什麼的好的定義。在DOS病毒的世界,定義病毒為可以複製的程式是足夠了。在宏病毒的世界,然而情況並不這樣簡單。宏病毒並不必須由單個程式組成(即,一個單一宏)。它可以由許多宏組成(例如,病毒WM/Xenixos.A:De由兩打宏組成),其中一些或多或少的相互獨立。
獨立的含義是什麼?這包括三方面。第一,由於Worasic是解釋語言,所以容錯性高。也就是說,一個宏的一些部分被損壞----但是,如果其從不接收控制(或者接收到的控制很少----例如,如果是在病毒體裡),錯誤從不(或極少)出現。(事實上,這可以用於攻擊某種反病毒程式;參閱[Bontchev96]。)此外,用於複製的命令(例如 ,MacroCopy)通常佔用僅幾行(行數與將要複製的宏數一樣)。也就是說,錯誤恰好發生在病毒負責複製的部分的可能性相對很小。
第二,WordBasic有高效的錯誤撲捉功能----並且被病毒作者通常大量使用。例如,如果一個病毒在其宏的開始包含操作
On Error Resume Next
即使控制被轉換成不完整的行,程式將簡單的忽略錯誤並且從其後,WordBasic直譯器能夠解釋出某些含義的第一行繼續執行。
第三,許多宏病毒的編寫使用的巨大的冗餘。我們傾向與認為這是十分象是病毒作者的懶惰而不是其有遠見。如果它們想要製作一個病毒能夠截獲幾個的宏並且因此在好幾個可能的使用者行為中進行復制(例如,FileSaveAs,FileSave,FileNew等),容易做到的是在所有這些宏內複製病毒的複製部分程式碼而不是將其放在一個被所有這些宏的一個單一的宏。結果,即使病毒宏其中的一個被損壞不能再被使用(或者甚至完全丟失),病毒仍舊有繁殖能力----雖然其完全的行為好象有一些改變。
所有這些(還有下一節所描述的其它事實)迫使我們定義宏病毒不是單個的程式----而是宏的集合。特別的我們使用以下定義:
定義:宏病毒是能夠迴圈複製自身的一個或多個宏的集合。
以上定義的一些部分序言更進一步的說明。尤其是‘迴圈複製’我們所指的是一個被感染的檔案能夠傳播病毒到另一個文件,則另一文件能夠繼續傳播病毒,等等。如果某個宏集合只能在其它地方複製自己一次,那麼它並不被認為是病毒。(我們稱之為‘Intended’----因為病毒作者經常試圖製造病毒程式,但由於錯誤,病毒不能複製自身超過一次----病毒作者從未發現的缺陷,因為象多數的病毒作者,它害怕在自己的計算機上執行測試它。)
此外,許多宏病毒模仿第一個宏病毒WM/Concept.A,由存在於全域性模板和被感染檔案中,不同之處較少的宏集組成。因此,根據,認為宏病毒是可以複製的一對宏集是有意義的。病毒宏集其一在於被感染的文件中,另一個在於被感染的全域性模板中。
以上定義的主要結果是,不同的宏集組成不同的病毒----即使是一個宏集是另一個的子集。再者,即使一個宏集由兩個已知的宏集的一些元素組成,其仍然是第三個新病毒。當下一節討論不同的和新的病毒時,這一點必須牢記。
需要強調的是許多本文描述的宏病毒的識別問題與前面給出的術語‘宏病毒’的定義緊密相關。甚至其中有些似乎不可解決的問題在選擇該術語的其它定義時能夠被完全消除。
一個非常吸引人的定義依靠於認為宏病毒是完全獨立沒有任何關係的宏的觀點。例如,根據這種提議,文件中沒有包含WM/Concept.A病毒,相反,其被認為是包含了宏WM/Concept.A#AAAZAO(這個宏的兩個複製;第二個在Auten之下),WM/Concept.A#AAAZFS和WM/Concept.A#Payload。
不幸的是這種定義還存在其它的,十分困難的實際應用問題。例如,報告‘文件中有WM/Concept.A#AAAZFS病毒’似乎很蠢----因為這個宏只依靠自己而不被宏集的其它成員所支援是不能複製的,因此它不是病毒。此外,兩個已知病毒的宏在同一臺計算機中相遇,能夠導致病毒雜交產生新的自我複製的宏集。(這一過程的詳細描述,參閱[Botchev98]。)這一新的自我複製的宏集通常其特性和行為與原始的兩個宏集中的任何一個的特性和行為都十分不同----並且因此認為其是一個新病毒是十分有意義的。
由於此原因,我們在著一節的開始給出的定義是十分方便實用的。我們不強調其是完美的----但它顯然是目前我們可以討論的最好的一個。因此,我們的反病毒的產品(和我們認識到的其它幾個反病毒產品)基於這個定義。在本文的剩餘部分,我們將考慮由它引起的一些有趣的宏病毒識別問題。
3.容易的宏病毒識別問題
在這一節我們將討論一些相對容易解決的宏病毒識別問題。這些問題按難度增長的順序給出。
3.1.退化病毒或R病毒問題
隨著所謂的WM/Rapi.A病毒的出現,宏病毒識別的第一個問題就產生了。這一病毒有下面的宏組成:
Document: Global template
AutoOpen RpAO
RpAE RpAE
RpFO RpFO
RpFS RpFS
RpFSA RpFSA
RpTC ToolsCustomize
RpTM ToolsMacro
AutoExec
FileOpen
FileSave
FileSaveAs
然而由於此病毒的一個宏內一個缺陷,當病毒透過File/Save(相對應的File/SaveAs)被複制,它的一些宏沒有被複製。本質上這導致了一個新的宏集----仍舊是病毒並且因此是一個新病毒。這個新的退化病毒看起來是這樣的:
Document: Global template
AutoOpen RpAO
RpAE RpAE
RpFS RpFS
RpFSA RpFSA
RpTC
RpTM
AutoExec
FileSave
FileSaveAs
然而這一新的宏集並不穩定。它幾乎立即再次退化為一個新的、更為精簡的宏集。得到的第三個退化的宏集仍然具有複製自身的能力,它仍然不同於前兩個宏集----因此,它是一個新的病毒。此外,它變的穩定----在它不再繼續退化的意義上。它變為這樣:
Document: Global template
AutoOpen RpAO
RpAE RpAE
RpFS RpFS
AutoExec
FileSave
此退化的主要結果是每一個WM/Rapi族的主變種能夠潛在的產生兩個新的變種。例如,存在WM/Rapi.A會產生WM/Rapi.A1(退化的第二階段)和WM/Rapi.A2(退化的第三階段)。此外這樣的新變種相對經常的產生。由於病毒的AutoExec/RpAE 宏相對大並且不負責任何方式的複製過程(它包含病毒實體),它容易被損壞或奪取----也就是說,被另一個病毒或合法的宏工具包的其它同名宏所取代。(更多關於宏奪取的資訊,請參閱[Bontchev98]。)此外,由於這個宏在所有退化的三個時期被儲存,意味著單一主變種的損壞導致出現三個新的病毒。改變其它的一些宏(例如,ToolsMacro/RpTM)產生少於三個新的病毒變種,因為這些宏在退化的某些階段被丟失並且退化變種的結果與其它主變種退化所產生的變種相同。例如,WM/Rapi.C病毒只退化到WM/Rapi.C1;在第三步,先前所知的變種WM/Rapi.A2產生了。這一問題首先被David Chess([ChESS96])發現。其相對容易被解決----掃描器的只須包含WM/Rapi病毒幾乎每一個小修改的條目。然而,這將導致這個資料庫的大小令人煩惱的增長。此外,它有時令人產生迷惑----有些使用者很難理解一個包含一種病毒(WM/Rapi.A)的文件如何用兩個不同的病毒(WM/Rapi.A1,WM/Rapi.A2)感染它們的檔案,其最重要的是不同於原始的那個病毒。
3.2.宏丟失即Dzt病毒問題
WM/Dzt.A病毒被發現之後不久,第二個問題就出現了。這一病毒由下列宏組成:
Document: Global template
AutoOpen FileSave
FileSaveAs FileSaveAs
到此為止,一切正常。然而很快我們發現了一個新的WM/Dzt變種,WM/Dzt.B,其組成如下:
Document: Global template
AutoOpen FileSave
也就是說,病毒的第二個宏丟失了----新病毒仍然具有良好的自身複製能力!更糟的是,我們很快發現市場上的許多掃描器可以製造WM/Dzt.B,如果其不知道WM/Dzt.A以及其處於下列狀態:
1.系統的一個全域性模板被WM/Concept.A病毒感染而使其包含宏含了宏WM/Concept.A#AAAZAO,WM/Concept.A#AAAZFS,WM/Concept.A#FileSaveAs和WM/Concept.A#Payload。
2.隨後同一全域性模板被WM/Dzt.A病毒感染,結果它的內容變為WM/Concept.A#AAAZAO,WM/Dzt.A#FileSave,WM/Dzt.A#FileSaveAs和WM/Concept.A#Payload。值得注意的是,病毒WM/Dzt.A的宏FileSaveAs覆蓋了同名屬於病毒WM/Concept.A的宏。
3.沒能準確的檢測到宏病毒的防毒器判斷系統感染病毒WM/Concept.A----因為其不知道有病毒WM/Dzt.A並且防毒器在檔案裡發現了用於檢測病毒WM/Concept.A的掃描字串。因此防毒器試圖移除透過名字來辯識(而不是根據內容辯識)屬於病毒WM/Concept.A的宏。
結果包含了宏WM/Dzt.A#FileSave的全域性模板被保留下來----這正就是WM/Dzt.B病毒!換句話說防毒器產生了這個新的病毒變種。
這一問題可以透過讓防毒器總是完全準確地辯識染毒的宏集從而被容易的解決。也就是說,根據檢測病毒體的固定不變的部分而不是依靠宏的名字來確定其每一個真正的存在的單個的宏。於是,在上面的情況中殺度器會容易地注意到它所認為是WM/Concept.A病毒的一個宏擁有不同的內容。因此,這可能是一個新的病毒並且不應該防毒----相反,應該要求使用者提供一個病毒樣本。
3.3.可變宏集即CAP病毒問題
這一節所描述的問題比前一個問題明顯要困難的多。----並且許多反病毒產品對恰當的處理這個病毒的問題幾個月來無能為力,此病毒首次呈現出這個特性就引起了我們的注意。這就是WM/CAP.A病毒。
這個病毒由委內瑞拉的一個14歲男孩製作,在幾個星期內野火般的傳遍了世界----它仍舊是被經常報導的病毒之一。致使這種結果有接個原因。首先,此病毒與語言版本無關----它可以在世界所有的語言版本上執行。第二,被它感染的文件不表現許多其它WORD宏病毒所表現的典型徵兆----WORD並不總是儲存它們到模板目錄。第三,如上所述,許多反病毒的產品不能恰當的移除這個病毒,因此這個病毒在反病毒產品升級為能處理它之前有相當長的時間傳播。
這個病毒被設計成為由10或者15個宏組成。當感染一個英語版本的WORD系統時,它由宏AutoClose,AutoExec,AutoOpen,Cap,FileColse,FileOpen,FileSave,FileSaveAs,FileTemplates和ToolsMacro組成。宏FileTemplates和ToolsMacro為空。這種表現只為禁止系統的同名的宏,因此避免了‘行竊’的某些限制。保留的宏本質上只是呼叫宏CAP,宏CAP包含了大部分的病毒並負責自身的複製。
當感染一個非英語版的WORD,除過上面的10個宏外,還有另外5個宏。這5個宏本質上是宏FileColse,FileSave,FileSaveAs,FileTemplates和ToolsMacro不同名的複製,其名字決定於具體的WORD的語言版本。
為達到與WORD語言版本無關,病毒不能透過宏的名字來定位它的宏。相反,它檢測選單的結構,使用處理實現File/Close,File/Save,File/Save As,File/Templates和TollsMacro選單項的系統命令名來作為附加的5個宏的名字。這實際上使得病毒與WORD的語言版本無關。當然它與被感染系統的選單結構也無關。
再者,為了確定其宏能被複製,它們也不以宏的名字來定位(這使得與WORD的語言版本無關)。病毒在宏的描述裡使用百分號(%),並且在複製時,複製所有宏到被感染檔案時,宏的描述包含這個符號。同樣,為了完全確定不和其它任何宏‘雜交’,病毒從想要感染的文件內移除所有的宏。
不幸的是,由於病毒作者未預料到的WordBasic的怪癖,這一技巧沒有達到目的。事實證明,沒有描述的宏FOO被複製覆蓋有描述的宏Bar,結果是宏FOO的宏體替代了宏FOO宏體----然而宏的描述沒有被碰到並且保持為宏Bar的描述。(如果兩個宏都有描述,則宏FOO替代宏Bar。)結果與病毒作者的期望相反,病毒WM/CAP.A可以與其它病毒的宏或宏工具包的宏雜交----如果這些病毒感染一個已經感染了WM/CAP.A病毒的系統(或如果宏工具包到這個已被感染的系統)並且它包含了與病毒WM/CAP.A的宏同名但沒有描述的宏。
最後,由於病毒的所有的複製程式碼集中在宏CAP內並且所有其它的宏只是呼叫它,其它的任何宏損壞,替換甚至是刪除所產生的結果仍舊具有自身複製的能力,即仍舊是一個病毒。
這些特性的結果,會產生許多不同的自我複製的宏集,這取決於使用者的選單結構,使用者計算機所感染的病毒以及WM/CAP.A。唯一不變的似乎是宏CAP。另外的宏可以冠有奇怪的名字,可以被損壞、攫取甚至丟失(僅宏CAP和其它七個非空宏的其中一個就足夠肯定這個宏集是帶毒的),或者存在它們中的一些的多次複製(當然,宏的名字不同)。將所有這些不同的宏集視為不同的病毒變種明顯是愚蠢的。
因此,我們被迫修訂我們關於什麼是宏病毒的定義以適用於象WM/CAP.A這樣的畸形病毒。實際上我們現在定義病毒WM/CAP.A是包含宏CAP,其它八個宏的一個或數個例項(宏FileTemplates和ToolsMacro都為空,因此它們沒有區別),同時至少有一個例項為非空的宏。
如果以上的修訂看起來有些複雜是因為它確實複雜。不幸的是,它是到目前為止我們已發現的此類病毒中最好對付的一個。在反病毒產品中實現它也並不容易。作為一個臨時的、填補空白的解決方案,一些反病毒產品透過只檢測宏CAP來實現病毒檢測,並且如果在文件中發現了宏CAP,就刪除文件中的所有的宏。這並沒有聽起來的那樣糟,是因為此病毒會刪除所以任何方式所感染的文件中的所有的使用者宏。
當然,這整個方法(包括修訂定義和它的暫時的部分的解決方案)有一個討厭的缺點。在其複製期間,其會試圖攫取一個會極大改變其行為的宏。例如,一個從其它病毒攫取來的自動執行宏使WM/CAP.A會故意破壞一些資料----原始的病毒卻沒有這一點。使用者於是理所當然的想知道,被它的反病毒軟體所準確識別的病毒,象WM/CAP.A,一個已知無有意破壞性的病毒是如何突然在13號星期五開始顯示資訊並且刪除檔案。不幸的是,如果我們決定認為此病毒的所有可能的不同宏集是不同的病毒的話,將引起是分類和識別的混亂,看起來為解決此問題我們就必須付出這樣的代價。
3.4.塊複製即Cebu病毒問題
一段時間以前,我們的一個客戶發給我們一個文件,此文件被懷疑感染了一個新病毒。事實的確如此。這個病毒顯然由四個宏組成----AutoClose,AutoExec,AutoOpen和MsRun。(使用‘顯然’這樣不嚴密的術語的原因等一會就會清楚。)當然,只有宏AutoOpen負責病毒的複製。宏AutoClose也企圖複製病毒,但由於一個愚蠢的錯誤,總是失敗。宏AutoExec是戰鬥部,宏MsRun被用做“此檔案已被感染”的標記。
問題是病毒的作者顯然是一個沒有經驗的程式設計師,它作了一些沒根據的假設。實際上,它似乎斷定它病毒的宏是文件中唯一存在的宏。畢竟可能所有沒有染毒的文件在它看來沒有包含任何宏。因此,它作了如此的斷定並被象一條一條複製病毒的宏和指出是否文件或全域性模板被感染這樣複雜的事所困擾。有一個十分簡單的方法----只寫一個複製所有宏從當前文件到正在被感染的文件的迴圈就行了(這隻需要三行WordBasic程式碼)。
因此,如果被感染的檔案本身已經包含了一些宏的話會發生什麼呢?如果是這樣的,那麼這些宏將成為病毒的一部分並且被傳播到所有其它的被感染的文件。事實表明,病毒的宏集只能增加獲取新的的成員而決不會減少!
第二個問題是,當我們的客戶開始懷疑一個宏病毒不能被它的反病毒程式所檢測,它會ScanPort----自己的反宏病毒的反病毒工具。不幸的是,除了ScanPort只能Concept宏病毒外而幾乎不能檢測任何東西的事實以外,它本身由WordBasic編寫並且包含有數個宏。因此,當我們的客戶與我們聯絡時,它所有的文件都含有ScanPort的宏,令人十分不快。
隨後我們收到了同一病毒的另一樣本。它從另外的宏工具包攫取了宏,宏AutoExec和AutoOpen被某個反病毒宏所覆蓋並且宏MsRun完全丟失。然而這個宏集仍然具有自身複製的能力----也就是說,它是一個病毒。現在,我們稱這樣的病毒為‘塊複製器’。WM/Cebu.A(上面所描述的病毒)並不是此類病毒唯一的一個;還有另外的一對。看起來處理它們的實用方法是隻檢測負責複製的最少的宏,並且,一旦它們被檢測到,刪除被感染文件的所有宏。畢竟它們已經成為病毒的一部分。這一方法含有上一節所提到的相同的缺陷----一些被攫取的宏會導致病毒行為的劇烈變化。然而,這又似乎是為避免討厭的使用其它定義方法就會發生的分類混亂所值得付的代價。
4.較難的宏病毒識別問題
本節闡述一些更難的宏病毒識別問題。第一個問題只在很少的幾個反病毒產品中得到了解決。到目前為止,第二個問題尚無另人滿意的解決方案。
4.1.理查得(Richard)問題
下面這個有趣的問題是理查得.福特(Richard Ford)引起我們注意的----當時它是Command軟體的一個反病毒研究員,因此我們以它的名字命名此病毒。
讓我們假設我們已知的一個宏病毒FOO,是一個由宏集{A1,B1,C1}組成。然後有人拿到這個病毒,對其中的兩個宏進行了修改,因而產生了第二個病毒Bar,Bar是由宏集{A2,B1,C2}組成,其中A1與A2不同,C1與C2不同。該病毒不能被可以查殺已知病毒的具體病毒反病毒產品所識別。
反病毒產品能夠判斷出一個含有病毒Bar的檔案包含病毒FOO的變種,(也就是說,宏B1是反病毒產品能夠識別的)。能夠作到這一點,已經很不錯了,然而,如果反病毒產品企圖對該檔案進行防毒,它也只能移除宏B1----因為這是它能夠唯一識別的宏。
對此,我們假設所產生的宏集{A2,C2}能夠進行自身複製(即,是一個病毒)。當然,在複製過程中會產生一個錯誤----因為其企圖複製宏B1----一個不存在的宏,因為它已經被反病毒產品的所移除,然而,如果染毒的宏利用某些形式的錯誤陷阱(例如:Error Resume Next),複製過程將會成功的完成。
結果是反病毒產品可能產生一個新的、完全不同於現存的(即FOO和Bar)的病毒。多數反病毒製造商不願意知道它們的產品會產生新的病毒。
對該問題的解決有幾種可能的途徑。首先,有可能將掃描器和與某種歸納分析儀結合起來,並將所有可能的宏從發現了感染已知病毒的文件中刪除。不幸的是,正如[Bontchev96]中所演示的那樣,有可能利用一大系列的反歸納攻擊,並誘使歸納分析儀產生一個“錯誤否定”----即,使病毒不能被歸納分析儀所探測出來。
其次,一個防毒軟體能夠刪除所發現的被某一已知病毒(或某一已知病毒的變種)所感染的檔案內的所有的宏。不幸的是,很多的使用者歷來它們本身的宏,它們發現這個“解決方案”是令人非常不滿意的。根據我們的經驗來判斷,該解決方案從商業角度來看是行不通的。
第三,一個可能的途徑是永遠不對發現含有以知病毒殘體的文件進行防毒。該方法有一個很大的缺陷,那就是在很多情況下,完全可行並時不進行防毒是不夠現實的。該類例子包括錯誤殺除的病毒(如,當一些而不是全部的病毒的宏被使用者或一些低階的反病毒產品刪除時),宏被WORD破壞而不能繁殖的病毒,等等。
第四,可以將“刪除病毒殘體”這一動作為可選項(預設為關閉),使使用者在必要的時候將其開啟。不幸的是,經驗表明,大多數的使用者缺少在危險的情形下作出正確決定的所必要的反病毒知識和專業知識。我們可以肯定的是,無論開發商給什麼樣的警告,告訴使用者除非知道自己再做什麼,否則不要開啟這一選項,很多使用者以不恰當的方式使用該選項,或者只是“以防萬一”時將其開啟。事實上,值得爭論的是,是使用者本身而不是反病毒產品的對新病毒的產生應負責任,它們甚至使用WORD的組合命令來刪除一些病毒的宏而產生新的病毒。儘管如此,反病毒產品也不將這個責任推給沒有經驗的使用者反到還好些。
第五種方法由理查得.福特提出,該方法是對每一個具體的宏來確定判定其存在所必須出現的最小宏集,以用來安全的刪除病毒的殘體(被稱為病毒的最小安全子集)。例如,如果病毒WM/Conceot.A的除了宏PayLoad的所有宏在一個文件中被發現,顯然刪除這些宏是安全的。也就是說,刪除它們不會產生新的病毒,不論文件中是否含有其它的宏----因為宏PayLoad不再會被WM/Conceot.A執行並且其自身不具有病毒的特性。(注意。這只是舉個例子;我們並不能說WM/Conceot.A的其它三個宏組成了這個病毒的“最小安全子集”;完全有可能排除其它不是宏PayLoad的多餘的宏使宏集進一步縮小。)
該方法存在這樣的缺點,有時它會誤把新病毒當作一箇舊病毒的殘體而破壞(因此,對反病毒研究者來說,是“丟失”)。例如,讓我們假設也WM/Conceot.A病毒的變種,其與原來病毒的差異進在於其PayLoad宏的內容。根據上一段所描述的演算法所製作的防毒軟體會錯誤的把它當作原來病毒的殘體而將病毒的其它宏從文件中刪除。儘管這一行為是“安全的”(從它不會產生新病毒的意義上來講),檔案仍不能被恰當的修復(檔案還包含一個不需要的宏----PayLoad,而且這會使防毒軟體無法關閉它們的模板塊),並且對反病毒研究者來說,“丟失”了一個新的病毒變種。
對該方法的稍加改進是刪除那些名字與病毒的宏的名字“相同”,卻不包括在“最小安全子集”的宏。然而,首先我們認為透過名字對宏的識別是相當不安全、相當不可靠的(應該使用宏的校驗和和宏的長度),其次,這種改善仍不能解決新病毒變種“丟失”的問題。
對理查得問題,基於下面的觀察,我們已提出了一個較好的解決方案。如果檔案中所有發現的宏就是構成病毒殘體的宏的話,那麼顯然刪除它們是安全的。如果有任何多餘的宏存在,便有可能出現以下情況:
1、多餘的宏屬於某個已知病毒的新的,不被人所瞭解的病毒變種。刪除它們是否能夠產生新的病毒,新的病毒變種是否是有意製作的,或者是否是一個已知病毒的一個被隨即破壞的宏都無關緊要。所有這些情況下,我們都有一個新的病毒變種(儘管一些破壞可能導致一個不能執行的病毒)。因此,正確的方法是不要進行防毒(即使是病毒的殘體----也就是說這些宏可以被識別為一個已知病毒的變種),並且請求使用者提供一個病毒樣本。
2、多餘的宏屬於使用者。這種情況幾乎不可能發生----只有一個已經包含了合理的宏(這本身就十分罕見)的檔案被某種已知的病毒感染,並且不恰當的試圖刪除病毒----該做法僅僅刪除了病毒的一部分宏。由於這種情況相對罕見,我們認為不對文件進行防毒並且請求使用者提供一個病毒樣本。
3、檔案被不同的病毒感染,一個已知,一個完全未知,並且我們作了不恰當的努力刪除已知的病毒,該努力只刪除了病毒的一部分宏。在這種情況下,該檔案包含了一個新的病毒。請求使用者提供一個病毒樣本以便可以對新的病毒進行分析。因此,對不對文件進行防毒是值得的。大多數的使用者可以理解具體病毒的反病毒程式是不能夠殺滅未知病毒的。
以上所講的內容我們可以用如下簡單原則進寫概括:
刪除檔案中能確切識別的宏病毒的所有宏之後,被感染文件中的宏只是以知病毒的殘體,那麼刪除它們;否則不要刪除文件內的任何宏,並請求使用者提供一個病毒樣本。
4.2.伊格(Igor)問題
在討論理查得問題以及其可能的解決方案和對具體病毒識別的總體要求時,伊格.穆特克(Igor Muuttik),博士所羅門軟體的一個反病毒研究者將我們的注意力轉向理查得問題的自然擴充套件上,暗示這個擴充套件含有更多的危險([Muuttik98])。因此,我們以它的名字命名該問題。
讓我們設想一個已知的病毒,Foo由宏集{AotoOpen,Palyload}組成。當一個被感染的文件在一個乾淨的WORD環境中被開啟時,宏AotoOpen被執行。它檢測到自己從一個文件中執行(相對於從全域性模板中執行),就從被感染的的文件內複製宏AotoOpen和Palyload到全域性模板然後執行宏Palyload。當一個乾淨的文件在一個被感染的系統中被開啟時,宏AotoOpen又掌握控制。它檢測到自己從全域性模板中執行(相對於從一個文件中執行),就從全域性模板複製宏AotoOpen和Palyload到這個文件並且執行宏Palyload。
現在,讓我們假設一個病毒的作者得到這個病並毒建造了另外一個由宏集{AotoOpen,Palyload,AotoClose,NewPalyload}組成的病毒Bar。宏AotoOpen和Palyload與病毒Foo內相同名字的宏相一致並且以絕對相同的方式執行。另外,當一個被感染的文件在一個乾淨的WORD環境中被開啟,宏AotoOpen就被執行了。它檢測到自己從一個文件中執行(相對於從全域性模板中執行),就從被感染的的文件內複製宏AotoOpen和Palyload到全域性模板然後執行宏Palyload。當文件被關閉,宏AotoClose得到控制權。它檢測到存在宏AotoOpen和Palyload並且被複製到全域性模板。於是它也複製宏AotoClose,NewPalyload到全域性模板並且執行宏NewPalyload。同樣的,當一個被感染的文件在一個乾淨的WORD環境中被開啟時,宏AotoOpen被執行。它檢測到自己從一個文件中執行(相對於從全域性模板中執行),就從被感染的的文件內複製宏AotoOpen和Palyload到全域性模板然後執行宏Palyload。當文件被關閉,宏AotoClose得到控制權。它探測到自己從全域性模板中執行,檢測是否宏AotoOpen和Palyload存在並被複製到正在被感染的檔案中,然後也複製宏AotoClose,NewPalyload到這個文件並且執行宏NewPalyload。
如果一個只知道病毒Foo而不知道病毒Bar的掃描器掃描一個被病毒Bar感染的檔案,它看起來好象一個感染了病毒Foo的文件----即使掃描器精確識別它所知道的病毒所有宏的每一二進位制位。(應當注意的是所有的處理宏病毒的具體病毒反病毒程式對於這種攻擊是十分脆弱的,不論是進行精確的病毒檢測還是依賴於簡單的特徵碼檢測。)如果執行於防毒,它將會刪除它所認為的病毒Foo----也就是宏集{AotoOpen和Palyload}。
宏集{AotoClose,NewPalyload}將繼續保留在文件中。然而,以這種方法建造這些宏集是十分可能的,這些宏集組成了第三種不同的病毒,我們稱之為Snafu。事實上,當反病毒程式試圖從感染了病毒Bar的文件中刪除它所認為的病毒Foo時,這第三種病毒將由反病毒程式產生。
有人會爭論,病毒Bar實際上由兩個病毒,Foo和Snafu,組成。然而,如果宏集Snafu的宏複雜的方法(檢測這些宏是否存在,複製這些宏,執行這些宏,等等)引用宏集Foo的宏,這種將宏集Bar分為兩個宏集Foo和Snafu的做法使得事情變的含糊不清。再者,病毒Bar可能由許多宏組成並且將它們分為獨立的病毒子集會十分困難、不明顯的甚至存在幾種不同的分法。
上面描述的攻擊方法可以用十分狡猾的方法實現。子集宏Snafu可以不是一個病毒。相反的,它的宏(也就是NewPalyload)只用來檢測病毒Foo的宏是否存在。如果它們不存在,一個破壞性的“戰鬥部”被觸發。從使用者的角度來看,情況是這樣的:使用者執行掃描器。掃描器報告一個已知的具體的病毒(甚至可能聲稱對它已準確識別)並且對它進行刪除。使用者用WORD開啟一個“已消毒”的文件,結果上的資訊被銷燬。自然地,使用者可能譴責掃描器沒能作好這件工作。在這種情況下,爭論這個文件被兩個病毒Foo和Snafu所感染是十分困難的,因為Snafu自身不是一個病毒。因為它的宏在許多被感染的文件中出現,它甚至不是一個“特洛依”病毒。它僅僅是一個新病毒Bar的一部分。然而,沒有可靠的方法使不知道病毒Bar的掃描器指出文件不是被病毒Foo感染而是被病毒Bar感染。透過取得一個流行的病毒,如WM/Concept.A或WM/Wazzu.A,並按上面介紹的方法來設定陷阱,實現這種攻擊十分容易的。
只有這個問題部分解決方案似乎可行。掃描器應該刪除被感染檔案中的所有的宏,並且使用者必須知道這是唯一殺除宏病毒的方法。有用的是,如果具體病毒掃描器與某種歸納分析器聯合,文件中發現包含以知病毒時,所有懷疑的宏(可以自身複製宏)應該從文件中刪除。不幸的是,如[Bontchev96]所述,有許多方法用來攻擊歸納分析器並迫使它們產生錯誤否定-----即,使病毒不能被歸納分析儀所探測出來。
4.3.宏名識別的重要性
乍一看來,對一個宏病毒掃描器來說,只識別屬於病毒的宏的宏體已經足夠了,不需要特別留意它們的名字。的確,改變一個宏的名字可以將一個宏病毒轉為非病毒。例如,病毒WM/Wazzu.A由單個名為autoOpen的宏組成。如果將其改成其它名字,例如ButoOpen,它將變的不能複製(甚至手動執行----因為宏體用名字“autoOpen”來定位自己),也就是說,它不再是病毒。
然而,這種特性看起來十分膚淺的。首先,改回宏名是使用者容易作到的,因此,警告使用者文件中包含的宏可被十分容易的轉換為能複製的宏病毒是值得的。第二,宏名看起來屬於病毒的環境而不是病毒自身。類似的,一個副檔名優先伴隨的DOS病毒如果其寄居的副檔名從COM改為其它副檔名,它將停止複製。
不幸的是,事情並不象其一看起來的那樣簡單。設想下面的例子([Chess97]):
一個宏病毒,Foo,由兩的宏,AutoOpen和Bar組成。宏AutoOpen複製自己到正被感染的文件(或全域性模板)。然後,它檢測宏Bar是否存在。如果宏Bar存在,它正常複製;否則破壞性的戰鬥部被觸發。到目前為止,一切正常。其中的技巧是宏Bar的內容與病毒WM/Wazzu.A的宏autoOpen一樣。
現在,如果一個不知道病毒Foo也沒有注意病毒宏名字的掃描器遭遇一個感染了這個病毒的文件,它會產生伊格問題。它將會“識別”出病毒WM/Wazzu.A並且刪除宏Bar,因此留下了有良好自身複製能力的宏AutoOpen。因此,掃描器產生了一個新病毒。另一方面,對於堅持象識別病毒宏的宏體一樣識別識別宏名在上面描述的情況中不會出現這樣的問題。它將會報告文件被感染(由於在文件內發現已知病毒宏的宏體)但會宣告它包含了一個新的病毒----因為宏名不匹配而且文件內還有其它的宏。
5.VBA5識別問題
Office 97 的到來和一種新的宏程式語言在它應用程式中的普及,VBA5,給我們帶來了一大堆新的宏病毒識別問題。雖然許多問題沒有上一節所說的困難的宏病毒識別問題那麼複雜,反病毒製造商仍然應該知道這些問題。大部分這些問題的引起是由於當包含有WORD宏病毒和EXCEL宏病毒的文件用各自的Office 97的應用程式開啟時,存在的WORD宏病毒和EXCEL宏病毒被自動的用VBA5語言重寫。不幸的是,正如我們所見,這種轉換是不直截了當的、不合乎邏輯的、有缺陷的和不明確的。
5.1.空行
事實表明,不論從WordBasic還是從VBA3轉換為VBA5,在轉換時,在程式的開始加一空行。對它自己來說,著並不很糟。不幸的是,Excal97包含雙向的轉換。也就是說,當它開啟一個包含VB3模組的Excal95工作簿時轉換它們為VB5模組。然而,允許Excal97的工作簿被存為Excal95格式----並且,不象Word97,然後把VB5模組向下轉換為VB3模組。(當儲存Word97的文件為Word6.x/7.x時Word97的轉換隻是簡單的忽略VB5模組。)
實際上,你可以將一個VBA3的模組轉換為一個VBA5模組,這在模組的一開始加入一空行。然後你可以將這個VBA5模組轉換回VBA3的模組,空行仍被保留。如果你現在再將轉換過的VBA3的模組再轉換為一個VBA5模組,另外的一個空行又被新增在模組的一開始。在有宏病毒的情況,一個組織剛剛轉換到Office 97並且仍舊有許多Office 95的機器,這樣的“向上/下轉換”迴圈許多次(因為使用者希望以舊的格式儲存檔案以便於與還沒有升級的機器保持相容)----因此,在病毒的開始處加入了許多的空行。但是,這仍舊是同一病毒。因此,反病毒程式在識別VBA(3或5)病毒時,應該忽略空行。
或者至少似乎應該忽略Excel病毒一開始的空行。不幸的是,情況要要比這稍微複雜一些。
最初的錯誤跡象由病毒W97M/ambler.A---Word97土生土長的(即不是已存的WM病毒向上轉換的結果)病毒帶來。這一個病毒為了哄騙Tools/Macro對話方塊並秘密提供一些基本的表格所設計為包含了許多使用者的表格。當我們複製它,我們注意到病毒程式碼的校驗和包含了使用者的表格,這些表格隨不同的複製而不同。如它表現的那樣,病毒的每次複製,一個空行被插入到一個使用者表格的程式碼中。不斷的複製導致不斷插入新的空行。更糟的是,空行不是插入在程式碼的開始,而是在程式碼中的任何位置,在表格的定義和被設計用來處理與表格不同部分相關的不同事件(例如,滑鼠的點選) 的過程的執行程式碼之間。為什麼會有這樣的現象的原因已超出了我們理解範圍。這應當去問微軟。
總之,看起來在識別VBA宏病毒時忽略空行是明智的,不論它是用VBA3還是用VBA5寫成的,不論是Excel病毒還是Word病毒,無論是空行處於病毒程式碼的什麼地方。
5.2.空格
另一個WM病毒向上轉換為W97M病毒的識別問題由轉換器採用對空格一般處理和對製表符特出處理的方法所引起。最初的報告來自Dmitry Gryaznov,就職於博士所羅門的一個反病毒研究者所發現的一些可疑的資訊([Gryaznov97])。根據它提供的情況,病毒W97M/Appder.A的第一次繁殖(即,在新病毒獲取機會複製之前,就立即被轉換器所產生)不知何故與它的複製體不同。
仔細的檢查揭示此不同由包含一個製表符的運算元和它結尾的撇號註解引起的。這促使我們研究在不同位置包含製表符WordBasic宏如何向上轉換為VBA5模式。結果十分有趣。
應當注意的是,製表符在VBA5不存在。如果在編輯一個VBA5程式時按下製表鍵,輸入的是一些空格。空格的確切數目決定於游標的當前位置和VBA5編輯器Tools/Options/Editor/Tab的寬度設定的內容。然而,製表符在WordBasic可以自由的使用,並常被用來縮排行。
顯然,當WordBasic程式到VBA5時,轉換器將對那些製表符進行處理。它所做的十分合乎邏輯----至少第一眼看起來如此。轉換器用上面所述的“製表符寬”項的當前設定轉換製表符為相應數目的空格,因此,看起來程式至少被基本保留下來。
不幸的是,當包含這樣的製表符的WM病毒被向上轉換時麻煩出現了。事實上,這意味著如果一個WM病毒包含有許多用於行縮排的製表符,不同對製表符寬度設定的計算機將從一個相同的WM病毒產生不同的W97M病毒。而且,使用者可能不知道此項的設定值,或者根本不知道存在此設定。顯然,如果認為所有的這些W97M病毒是不同的,是非常不方便的。因此,它們被認為是相同的,認為是一個病毒。由於我們通常不知道,是否WM病毒在製造時包含了一些用於行縮排的製表符,所以在識別一個染毒的VBA5模組時,行的縮排必須被忽略。
但這並不是全部。如它所表現的,製表符只能被用做行縮排。唯一的好訊息是它可被用於其它的地方並不多。如果使用者插入多餘的空格到一個運算子中間,WordBasic和VB5將自動丟棄它。WordBasic當宏編輯視窗被關閉時丟棄它們(因此,它表現為多餘的空格在第二次宏被開啟編輯時被刪除),而VBA5編輯器當游標離開所編輯的行是刪除這些空格(因此,這種變化可以馬上表現出來)。例如,行
X = 2 * 2
被自動的轉換為
X = 2 * 2
但並不總是這樣。有幾個例外,在下面給出。
首先,空格在撇號註解的前面。即,行
X = 2 * 2 ' This is a comment
和
X = 2 * 2 ' This is a comment
產生不同的程式碼。在VBA5裡,撇號註解開始的位置包含在第一個“撇號註解”的P程式碼指令的運算元里。
第二,空格在運算子:“:”後出現。即,行
X = 2 : Y = 4
和
X = 2 : Y = 4
產生不同的程式碼。在VBA5裡,第二個運算子的開始位置包含在“:”P程式碼的引數裡。
第三,空格在Dim宣告裡AS關鍵字之前出現。即
Dim X As Integer
和
Dim X As Integer
產生不同的程式碼。這種情況比上兩種情況稍微複雜一點。看起來VBA5能夠用兩種不同的Dim P程式碼指令,一種用於“在As之前沒有空格的Dim”,另一種用於“在As之前有空格的Dim”。第二個的P程式碼指令包含一個附加的運算元,含有As關鍵字在行內的位置。
第四,空格可以用來一個縮排被寫成數行的VBA5行的不同部分(在行尾用字元“_”表示續行符)。這與WordBasic裡(這裡字元“”被用做續行符)分割行的一部分用製表符來縮排是一樣的。因此,當計算VBA5模組的校驗和時,用於續行的VBA5P程式碼指令相應部分應被忽略。
由於上面所描述的所有情況在WordBasic裡有相同的情況,並且WordBasic裡相同情況可以把製表符當作空格的一部分,著意味著這樣的行向上轉換的不同決定於VBA5P編輯器製表符寬度的設定。因此,當識別VBA宏病毒時上面所提到的與空格相關的P程式碼指令的運算子應當忽略。
另一個與空格相關的問題是由VBA註解中連續的空格引起的。簡單的說,VBA3允許註解中有連續的空格,而VBA5卻不允許(並且刪除這些空格)。下面的例子表明了這個問題。
1)執行Excel95,產生一個新的空的工作簿,然後插入一個模組頁。
2)在模組頁輸入下面的短程式:
' The following comment has trailing spaces:
'
Sub Test()
MsgBox "This is a test.", vbOKOnly + vbInformation, "Test"
End Sub
在第二行,開始的撇號後輸入幾個空格。在游標離開註解裡包含有連續空格的行後,如果使游標再回到這一行,然後按End鍵,游標立即回到撇號的後面,好象沒有了連續的空格一樣。恐怕不是這樣的,相反儲存工作簿到一個檔案,檢查生成的P程式碼,就會發現連續的空格(與你輸入的個數一樣)在那裡。
3)退出Excel 95,執行Excel 97開啟上一步產生的文件。VBA3宏將被向上轉換為VBA5宏。用Excel 97將被轉換的文件以Excel 95格式(而不是Excel 97格式)儲存到另一個檔案,這又宏將向下轉換為VBA3格式。
檢查新檔案的P程式碼,會發現不僅在開始初加入了一個空行,而且註釋中的連續的空格也不見了。
因此,識別一個VBA病毒時忽略註解中的連續的空格。
事實上,還有一種空格被應用的情況,然而,可以證明,這種情況沒有引起任何宏病毒的識別問題。尤其製表符可以用於字串中。然而,轉換器處理這種問題十分漂亮,它找出字串中的所有這些字元,並替換為Chr(9) 。例如,WordBasic行
x$ = "This is a Tab -> 被向上轉換為下面的VBA5行:
x$ = "This id a Tab ->" + Chr(9) + "
5.3不確定的向上轉換
由於以上的兩個問題迫使我們在識別一個VBA病毒時忽略空行和空格(用於縮排或其它),這引起出現兩個(或更多)不同WM病毒能被向上轉換為同一個W97M病毒的真正可能。例如,我們研究表明,三個不同的病毒WM/Wazzu----Q,W和AD----會向上轉換為同一個W97M/Wazz病毒。(如果使用的是Word的一個早期的beta版,當然正式發行版可以識別WM/Wazzu病毒並拒絕向上轉換它們。)這種不確定的向上轉換同樣會發生在一些其它的WM病毒身上。
在類似這種情況中,如何命名這些被向上轉換的病毒是不清楚的。通常具體的WM病毒向上轉換後被分配與原始的病毒相同的名字和變種的聯合和W97M平臺的字首。例如,由向上轉換病毒WM/Wazzu.A到VBA5病毒所產生的病毒被命名為W97M/Wazzu.A。然而,向上轉換不確定的事實打破了這個命名方案。
為了彌補這個問題,我們建議,在這種情況下當向上轉換不確定時,由它產生的病毒被標記為能夠產生它的最低的變種名。即,在上面的例子中,得到的W97M/Wazzu病毒被命名為W97M/Wazzu.K,而不是W97M/Wazzu.Q或者W97M/Wazzu.AC。
5.4識別符號中字母的大小寫
如在本文的其它地方所提到的那樣,檔案中所有VBA(包括VBA3和VBA5)模組共享一個共用的識別符號區(變數名,過程名等)。但不全是這樣。此外,當一個新的模組被定位,而且其使用識別符號與已存模組的相同,則沒有新的識別符號被加入到共用的識別符號區。問題是,當檢測到新的識別符號與已存在的“相同”,字母的大小寫被忽略。
這讓人十分迷惑。例如,如果建立一個VBA模組包含下行的內容
fOO = Bar
然後建立另一個模組,包含下行的內容
bAR = Foo
然後開啟編輯第一個模組,它的內容如下所示
Foo = bAR
哪一個是使用者最先輸入的並不十分明確。實際上,這兩行可以輸入到同一個模組內,並且當輸入第二個時,第一個字母的大小寫被改變。
在相應宏病毒識別方面應該怎麼辦呢?這需要在計算模組的校驗和和分解指向共用識別符號區的指標時(這些指標必須被分解,因為一些十分不同的程式可以被編譯為同一個P程式碼,只是被這些指標指向的標識不同,因此如果這些指標不被分解,對宏病毒的識別會不準確甚至引起錯誤的判斷),忽略識別符號的字母的大小寫。
不幸的是,在VBA5的環境中,帶來了另外的問題。忽略識別符號字母的大小寫通常在對比它們之前透過無條件的轉換它們為大寫或小寫的方法來實現。但是,VBA5的識別符號允許包含外國(即非ASCII)字元。例如,Francais 在這兒是一個合法識別符號。
不幸的是,沒有簡單可靠的方法轉換外國字元為大寫或小寫。 API 包含有用於這個目的的一些(如,AnsiUpper)。然而,它們只適用與Windows程式(即DOS的病毒掃描器不能使用它們)。再者,它們只能在合適的語言版本的Windows環境中正常工作。例如,函式AnsiUpper只能在換捷克語的Windows(或者Windows環境被設為捷克語)環境中才可以正確的轉換捷克語字元到相應的捷克語的大寫字元。
一個依靠這些函式的掃描器在識別VBA5病毒時產生的問題暗示,如果在錯誤的Windows版本中掃描文件,會錯過一個包含有外國字元的識別符號的病毒。很明顯,這種情況不能被接受,特別是病毒本身被存心作成在那種環境中複製沒有一點問題。
此問題最好的解決方案是在轉換識別符號為大寫和生成校驗和之前,將包含在識別符號內所有的非ASCII字元轉換為一些普通的ASCII字元(例如“_”)。這種解決方案所導致的識別演算法不能區分兩個差別十分小的病毒,但總比完全錯過一個病毒要好的多。
5.5其它VBA5識別問題
不祥WordBasic,VBA含有不是一層而是兩層級別的設定。第一層是模組,與WordBaic的宏基本一樣。第二層是模組的函式和子程式。它們中被宣告為Public(預設的宣告)的那些在Tools/Macro對話方塊可以被看到。
VBA病毒的功能的兩層設定使理查得問題和伊格問題可能在出現兩個層上。並且,一旦VBA病毒被寫成不僅可以攫取其VBA包的模組而且可以攫取這些模組的獨立的函式和子程式,這種情況就會發生。
解決這兩種問題的方法看起來類似(所以,伊格問題的解決方法將同樣不存在);它們將被應用與兩個層上。實際上,改變宏病毒的定義認為宏病毒是一組模組,每一個模組由一組函式和子程式組成,並且將模組當作集合來識別而不但是一個整體,是有道理的。不幸的是,這可能需要一些反病毒產品的一些大的重新設計,被事實所迫之前(即,在VBA子程式攫取病毒被製造之前),這好象不會發生。
6.人工製造的宏病毒檢測問題
上面幾節所討論的宏病毒識別問題可以被稱作“自然的”。也就是說,它們的發生不是因為所有宏病毒的一些固有特性(例如,它們不是由單個程式,而是由一系列的宏組成),就是因為宏程式語言及其環境的一些設計缺點。在這最後一節,我們將考慮由病毒作者為了使識別它們的病毒更為困難而人為創造的一些問題。這些問題的分涉及到多型性(也就是宏病毒在自身複製過程中修改自身的能力)的不同形式。
我們將實現多型性的不同方法的故意的概括描述,因為我們想減少本文對病毒作者有用的部分。同樣,我們只列出處理這些問題的基本思想。不幸的是,目前我們的解決方案詳細公開的描述可能使它們容易被攻擊。因此,除非達到我們能夠提出更穩健的解決方案,否則我們仍然依靠透過隱匿來保密,不論這種保護有多麼不可靠。
6.1.插入無用行
宏病毒界中多型性的最簡單形式是透過在病毒程式碼中任意的位置插入無用的行來實現的。它們是WordBaisc運算子,不對病毒的執行產生任何影響並且可以插入到病毒程式碼的任何位置而對病毒的操作沒有任何害(或修改)。通常許多這些無用行由隨機產生的註釋組成----但它們幾乎可以是任何動西,如變數分配,空函式呼叫等。
處理多型性的這種形式的最簡單的方法是使反病毒程式在識別病毒的宏時能夠識別用於不同多型性病毒的無用指令並跳過它們。不幸的是這種方法有兩個嚴重的缺點。
首先,無用的運算子幾乎有無窮的選擇。因而不同的多型性病毒何以(並且是經常)採用不同的運算子用做“填充物”。如果一個掃描器認識一系列的無用運算子(被用於掃描器已知的多型性病毒),一個採用不同的無用運算子的新的多型性病毒的出現,將使掃描器必須升級以便於能夠處理新的運算子。我們強調的是掃描器的程式將必須升級----僅僅升級病毒檢測資訊資料庫是不夠的。這種需要將妨礙掃描器完全透過它的資料庫來的嘗試。更糟的是,在許多情況下,由於識別演算法的改變用來跳過某些後加入的運算子,以前的基於這種演算法的資料庫內所有條目將必須修正或者升級。這個過程十分耗時而且容易出錯。
第二。病毒作者可能直接瞄準這種方法。例如,讓我們假設一個已知的多型性宏病毒使用下面的程式段作為無用的填充物。
If then
:
EndIf
這裡,是永遠不為真。如果一個宏病毒掃描器決定透過跳過整個If...EndIf程式塊來處理這種型別的多型性,那麼另一個被完全寫成僅僅使用運算子,,...,的病毒會被掃描器的演算法完全跳過。
為了處理這類問題,掃描器必須有更靈活的特定病毒的演算法來忽略無用的運算子,並且這種演算法應能被掃描器的資料庫所整個控制。
6.2.修改變數字串
另一個被多型性病毒所經常應用的技巧是,使病毒隨機改變它所用到的識別符號(通常被用為變數名)。當然,這種隨機改變總在發生----的確,同一個識別符號總是被另一個隨機產生的名字所代替。同樣,病毒也可以以隨機的方式改變所使用的一些文字字串的內容。
回擊這兩個技巧相對容易一些。為了解決文字字串的改動問題,在識別病毒的宏(或模組)時,用於多型性病毒的文字字串可以被簡單的忽略。
解決隨機識別符號的技巧稍微複雜一點。掃描器應當建立一個用於宏或模組的識別符號的表,並且替換每一個識別符號為任意的數字(例如,001,002,003等),使同一個識別符號總被替換成同一個數字,不同的識別符號總被替換成不同的數字。一旦病毒體被這樣封裝,就可以計算它的校驗和了,而且是唯一的一個,無論病毒如何在複製的過程中改變它的識別符號。
6.3.行
另一種可能的多型性可以透過交換附近的程式碼行來實現,這些行的嚴格的順序對病毒的正常執行是不重要的。就我們所知,現在沒有以知的病毒使用這個技巧,但這很容易實現。幸運的是,它同樣容易被反擊。
為了解決這個問題,使用精確病毒識別的病毒掃描器應該基於每行的計算病毒宏(或模組)的校驗和。然後每一行的部分校驗和應當相互異或,以組成宏(或模組)的最終的校驗和。當用這種方法計算,其校驗和與任何行的交換都無關。
6.3.註釋行和非註釋行
用於多型性病毒的下一個技巧由增加和刪除病毒體某些行之前的註釋來實現。這種方法的影響完全改變了這些行內在的表現,並且因此改變可病毒整體的表現。在已知的多型性宏病毒中,WM/Dakota病毒在很大程度上採用這種多型性。它將一個宏的整個內容儲存為註釋模式(它伴隨一隨機字元散佈,為了使它的每一個複本看起來不同)。在執行中,病毒刪除註釋,使這個宏可以執行並執行它的任務。
解決多型性這種辦法的簡單方法是忽略這個註釋行。不幸的是,它有降低識別準確性的缺點。
6.5.
當宏被當作“只執行體”複製時 Word使用的宏體的加密(與一位元組長的密碼異或;密碼自身儲存在文件中)是微不足道的,並且市場上的許多宏病毒掃描器容易的識破它。此外,病毒作者不能控制所使用的特定的加密密碼也不能改變它。最後,這種加密在Word97中不可用----在被保護的工程不能複製它們各處的模組。因此,這種加密不適合實現多型性。
然而,對病毒作者來說,實現一些其它的病毒體的加密方法是可能的。這透過把病毒體的行當作為文字字串並使用某種擾亂字串來處理它們。這是一個相對慢的過程,但病毒作者很少有興趣編制有的程式碼。病毒WM/Slow和WM/UglyKid
是應用這樣的自定義的加密法的多型性宏病毒的例子。
有幾種可能的的辦法對付多型性這種方法。不幸的是,它們中的多數依靠病毒中的多型性機制的具體執行----即,依靠具體的病毒。最簡單的方法是把病毒加密部分當作文字字串並忽略它們。這種方法對付WM/Slow時工作很好。不幸的是,它有降低識別準確度的缺點。
更老到的方法的是實現至少是部分的WordBasic(或VBA)模擬器並模擬在執行時病毒執行的部分----直到加密的部分被解密,隨後,它可以被識別了。這中辦法實現起來十分困難。然而我們希望在不久以後,出現更多的多型性病毒,這是恰當處理這類病毒的需要。
6.6.寄生感染
當前存在的病毒所採用的感染技術基本類似於DOS病毒的寫覆蓋和伴隨病毒。然而,如[Bontchev96]所描述的,為什麼真正的寄生感染沒有被實現沒有實際的原因。這樣的寄生病毒不能自身包含;相反,它們尋找其文件中其它的它們試圖感染的宏,並修改這些宏來或者完全包含它們的病毒宏,或者至少呼叫它們。由於很少遇到使用者宏,所以只採用這種感染方式的病毒好象不可能成功的傳播。然而,這種技術可以聯合傳統方法,使病毒在缺少可感染的使用者宏時可以藉助於這個傳統的方法。這種聯合的感染策略既保證了病毒傳播又使對它的識別(有時候是刪除)變的十分困難。
已知的病毒中沒有病毒故意使用寄生感染。然而,一些病毒(如WM/s)可以修改一些特殊名字(如FileSaveAs)的宏,如果它試圖感染的文件中已經存在這些特殊名字的宏。幸運的是,雖然這不是故意的(),這種情況一旦發生,已存在的宏只是被破壞並且病毒不能正常工作。然而,寄生感染技術的徹底實現是十分容易設想的。
為了準確識別這些病毒,宏病毒掃描器不得不借助與識別DOS病毒中的寄生病毒類似的方法。替換使用整個病毒宏體的單一的校驗和,掃描器將必須在它的資料庫內引入包含由產生校驗和的位元組範圍組成的病毒的映像。再者,掃描器將必須具有某種機制,這種機制被設計成為可以跟蹤可以傳輸控制到病毒體的使用者宏內部的指令,這與DOS掃描器採用的跟蹤最初的JMP和定位DOS程式中病毒的入口點的機制相似。
7.參考書目
[Bontchev96] Vesselin Bontchev,"Possible Macro Virus Attacks And How to Prevent Them" computers & security, 1996, Vol.15, No.7, pp.595-626
[Chess96] David Chess, 私人資訊
[Chess97] David Chess, 私人資訊
[Ford96] Richard Ford, 私人資訊
[Gryaznov97] Dmitry Gryaznov, 私人資訊
[Muttik96] Igor Muttik, 私人資訊
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-958399/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 檢測磁碟空間問題
- 檢測ftp連線問題FTP
- android檢測卡頓問題,recycleview卡頓AndroidView
- 美新冠病毒檢測曝出新問題:檢測結果不大準 檢測試劑不可靠
- 如何檢測 Web 服務請求丟失問題Web
- 表空間檢測異常的問題診斷
- 檢測和解決Android應用的效能問題Android
- 網路故障智慧檢測系統和小型路由器檢測系統問題與思路路由器
- CLR中程式碼訪問安全檢測實現原理(轉)
- 關於線上檢測主執行緒卡頓的問題執行緒
- 前端問題檢查前端
- *NIX入侵檢測方法(轉)
- Linux入侵檢測(轉)Linux
- 測試CMS同步問題測試CMS同步問題
- 章標題檢測軟體哪個好?檢測標題有訣竅
- 自動檢測ARouter路由地址分組使用衝突問題路由
- Aircheck G2如何檢測wifi無法連線問題AIWiFi
- C++--問題27--如何檢測記憶體洩漏C++記憶體
- 簡單介紹Pygame 精準檢測影像碰撞的問題GAM
- 告別人工檢測,SMT智慧首件檢測儀問世
- BFD雙向轉發檢測
- 中文標題相似度檢測
- 急!請教用optimizeit檢測記憶體洩漏的問題?記憶體
- jmeter 壓測問題JMeter
- 微信域名攔截檢測介面 檢測域名是否被微信停止訪問
- 基於 PTS 壓測輕鬆玩轉問題診斷
- 差錯檢測和糾正 (轉)
- 駭客避開檢測的手段(轉)
- 關於如何使用機器學習來做異常檢測的7個問題機器學習
- 檢測和解決 SQL Server2000 SP4中問題SQLServer
- [爆棧熱門 iOS 問題] 檢測手機上網路通不通iOS
- Halcon缺陷檢測例項轉OpenCV實現(二) PCB印刷缺陷檢測OpenCV
- 測試面試問題(二)面試
- iOS測試奇葩問題iOS
- 測試跨域問題跨域
- 用測試網站來檢測安全級別(轉)網站
- 目標檢測入門系列手冊一:定位 + 分類問題的解法
- Node.js 應用的記憶體洩漏問題的檢測方法Node.js記憶體