CIH病毒的分析與清除
CIH病毒的分析與清除
勁 鬆
E_mail:[email protected]
一九九九年七月二十六日
.
一年前的7月26日,一個名叫CIH的計算機病毒首次露面,襲擊了美國,病毒發作時直接往計算機主機板BIOS晶片和硬碟寫亂碼,破壞力非常大,可造成主機無法啟動,硬碟資料全部被清洗。一個月後,該病毒在中國大陸出現,給多家計算機應用單位造成嚴重損失。今年4月26日該病毒又一次在全球總爆發,據有關報道,全球有六千萬臺電腦受到破壞,大量重要資料無法復原,災情嚴重者,連計算機主機板硬體也不得不更換。僅一天,由於CIH病毒發作,在中國大陸受損的電腦總數約有卅六萬臺, 所造成的直接、間接經濟損失超過十億元人民幣。
CIH病毒是一種檔案型病毒,又稱Win95.CIH、Win32.CIH、PE_CIH,是第一例感染Windows95/98環境下PE格式(Portable Executable Format)EXE檔案的病毒。
不同於以往的DOS型病毒,CIH病毒是建立在WINDOW95/98平臺。由於微軟WINDOWS平臺的不斷髮展,DOS平臺已逐漸走向消亡,DOS型病毒也將隨之退出歷史的舞臺。隨之而來的是攻擊Windows系統病毒走上計算機病毒的前臺。可以預測,在未來幾年內,連同巨集病毒在內,Windows平臺將會是造病毒和反病毒的主戰場。
因此,剖析CIH病毒機理,掌握在Windows平臺下病毒駐留和傳染方法,對於預防、檢測和清除CIH病毒,預防未來新型Windows病毒,在反病毒的戰場上掌握主動權,都具有十分重要的意義。
目前CIH病毒有多個版本,典型的有:CIHv1.2:四月二十六日發作,長度為1003個位元組,包含字元:CIHv1.2TTIT;CIHv1.3:六月二十六日發作,長度為1010個位元組,包含字元:CIHv1.3TTIT;CIHv1.4:每月二十六日發作,長度為1019個位元組,包含字元:CIHv1.4TATUNG。其中,最流行的是CIHv1.2版本。本文將作重對該版本進行剖析。
病毒的表現形式、危害及傳染途徑
CIH病毒是一種檔案型病毒,其宿主是Windows 95/98系統下的PE格式可執行檔案即.EXE檔案,就其表現形式及症狀而言,具有以下特點:
受感染的.EXE檔案的檔案長度沒有改變;
DOS以及WIN 3.1 格式(NE格式)的可執行檔案不受感染,並且在Win NT中無效。
用資源管理器中“工具>查詢>檔案或資料夾”的“高階>包含文字”查詢.EXE特徵字串----“CIH v”,在查詢過程中,顯示出一大堆符合查詢特徵的可執行檔案。
若4月26日開機,顯示器突然黑屏,硬碟指示燈閃爍不停,重新開機後,計算機無法啟動。
病毒的危害主要表現在於病毒發作後,硬碟資料全部丟失,甚至主機板上的BIOS中的原內容被會徹底破壞,主機無法啟動。只有更換BIOS,或是向固定在主機板上的BIOS中重新寫入原來版本的程式,才能解決問題。
該病毒是通過檔案進行傳播。計算機開機以後,如果運行了帶病毒的檔案,其病毒就駐留在Windows的系統記憶體裡了。此後,只要運行了PE格式的.EXE檔案,這些檔案就會感染上該病毒。
病毒的執行機制
同傳統的DOS型病毒相比,無能是在記憶體的駐留方式上還是傳染的方式上以及病毒攻擊的物件上,CIH病毒都於眾不同,新穎獨到。病毒的程式碼不長,CIHv1.2只有1003個位元組,其他版本也大小差不多。它繞過了微軟提供的應用程式介面,繞過了ActiveX、C++甚至C,使用匯編,利用VxD(虛擬裝置驅動程式)介面程式設計,直接殺入Windows核心。它沒有改變宿主檔案的大小,而是採用了一種新的檔案感染機制即碎洞攻擊(fragmented cavity attack),將病毒化整為零,拆分成若干塊,插入宿主檔案中去;最引人注目的是它利用目前許多BIOS晶片開放了可重寫的特性,向計算機主機板的BIOS埠寫入亂碼,開創了病毒直接進攻計算機主機板晶片的先例。可以說CIH病毒提供了一種全新的病毒程式方式和病毒發展方向。下面對該病毒作進一步的剖析,該病毒程式由三部分組成。
CIH病毒的駐留(初始化)
當執行帶有該病毒的.EXE時,由於該病毒修改了該檔案程式的入口地址(Address of EntryPoint),首先調入記憶體執行的是病毒的駐留程式,駐留程式長度為184位元組,其駐留主要過程如下:
用SIDT指令取得IDT base address(中斷描述符表基地址),然後把IDT的INT 3 的入口地址改為指向CIH自己的INT3程式入口部分;
執行INT 3指令,進入CIH自身的INT 3入口程式,這樣,CIH病毒就可以獲得Windows最高級別的許可權(Ring 0級),可在Windows的核心執行各種操作(如終止系統執行,直接對記憶體讀寫、截獲各種中斷、控制I/O埠等,這些操作在應用程式層Ring 3級是受到嚴格限制的)。病毒在這段程式中首先檢查除錯暫存器DR0的值是否為0,用以判斷先前是否有CIH病毒已經駐留。
如果DR0的值不為0,則表示CIH病毒程式已駐留,病毒程式恢復原先的INT 3入口,然後正常退出INT3,跳到過程9;
如果DR0值為0,則CIH病毒將嘗試進行駐留。首先將當前EBX暫存器的值賦給DR0暫存器,以生成駐留標記,然後呼叫INT 20中斷,使用VxD call Page Allocate系統呼叫,請求系統分配2個PAGE大小的Windows系統記憶體(system memory),Windows系統記憶體地址範圍為C0000000h~FFFFFFFFh,它是用來存放所有的虛擬驅動程式的記憶體區域,如果程式想長期駐留在記憶體中,則必須申請到此區段內的記憶體。
如果記憶體申請成功,則從被感染檔案中將原先分成多塊的病毒程式碼收集起來,並進行組合後放到申請到的記憶體空間中;
再次呼叫INT 3中斷進入CIH病毒體的INT 3入口程式,呼叫INT20來完成呼叫一個IFSMgr_InstallFileSystemApiHook的子程式,在Windows核心中檔案系統處理函式中掛接鉤子,以擷取檔案呼叫的操作,這樣一旦系統出現要求開啟檔案的呼叫,則CIH病毒的傳染部分程式就會在第一時間截獲此檔案;
將同時獲取的Windows預設的IFSMgr_Ring0_FileIO(核心檔案輸入/輸出)服務程式的入口地址保留在DR0暫存器中,以便於CIH病毒呼叫;
恢復原先的IDT中斷表中的INT 3入口,退出INT 3;
根據病毒程式內隱藏的原檔案的正常入口地址,跳到原檔案正常入口,執行正常程式。
病毒的感染
CIH病毒的傳染部分實際上是病毒在駐留記憶體過程中呼叫Windows 核心底層函式IFSMgr_InstallFileSystemApiHook函式掛接鉤子時指標指示的那段程式。這段程式共586位元組,感染過程如下:
檔案的截獲
每當系統出現要求開啟檔案的呼叫時,駐留記憶體的CIH病毒就截獲該檔案。病毒呼叫INT20的VxD call UniToBCSPath系統功能呼叫取回該檔案的名和路徑。
EXE檔案的判斷
對該檔名進行分析,若副檔名不為“.EXE”,不傳染,離開病毒程式,跳回到Windows核心的正常檔案處理程式上;
PE格式.EXE判別
目前,在Windows 95/98以及Windows NT,可執行檔案.EXE採用的是PE格式。PE格式檔案不同於MS-DOS檔案格式和WIN 3.X(NE格式,Windows and OS/2 Windows 3.1 execution File Format)。PE格式檔案由檔案頭和程式碼區(.text Section)、資料區(.data Section)、只讀資料區(.rdata Section)、資源資訊區(.rsrc Section)等檔案實體部分組成。其中檔案頭又由MS-DOS MZ頭、MS-DOS真實模式短程式、PE 檔案標識(Signature)、PE檔案頭、PE檔案可選頭以及各個Sections頭組成。其格式結構圖見圖1。
Windows PE格式檔案結構的詳細分析可到下列網址查閱:
http://www.microsoft.com/win32dev/base/pefile.htm
CIH病毒感染的就是PE格式可執行檔案!
當病毒確認該檔案是.EXE檔案後,開啟該檔案,取出該檔案的 PE檔案識別符號(Signature),進行分析,若Signature=”00455000”(00PE00),則表明該檔案是PE格式的可執行檔案,且尚未感染,跳到過程4,對其感染;否則,認為是已感染的PE格式檔案或該檔案是其它格式的可執行檔案,如MS-DOS或WIN 3.X NE格式,不進行感染,而直接跳到病毒發作模組上執行;
4.病毒首塊的寄生計算:
以往的檔案型病毒,通常是將病毒程式追加到正常檔案的後面,通過修改程式首指標,來執行病毒程式的。這樣,受感染的檔案的長度會增加。CIH病毒則不是。它利用了PE格式檔案的檔案頭和各個區(Section)都可能存在自由空間碎片這一特性,將病毒程式拆成若干不等的塊,見縫插針,插到感染檔案的不同的區(Section)內。
CIH病毒的首塊程式是插在PE檔案頭的自由空間內的。病毒首先從檔案的第134位元組處讀入82個位元組,這82個位元組包含了該檔案的程式入口地址(address of EntryPoint),檔案的分割槽數(Number of Section),第一個Section header 首址以及整個檔案頭大小(Size of Headers=MS header+PE file header+PE optional header+PE section headers+自由空間)等引數。以計算病毒首塊存放的位置和大小。
通常PE格式檔案頭的大小為1024位元組,而MS header為128位元組,PE file header(包括PE Signature)為24位元組,PE optional header為224位元組,以上共376位元組,Section headers 大小是根據Sections 數量來確定的,但每個Section的大小是固定的,為40位元組。一般情況下,Section有5~6個即.text區、.bbs區、.data區、idata區、rsrc區以及reloc區。這樣計算下來,整個檔案頭有408~448位元組的自由空間提供給病毒使用。
在PE格式檔案頭的自由空間裡,CIH病毒首先佔用了(Section數+1)*8個位元組數的空間(本文稱為病毒塊連結串列指標區),用於存放每個病毒塊的長度(每塊4位元組)和塊程式在檔案裡的首地址(每塊4位元組)。然後將計算出的可寄存在檔案頭內的病毒首塊位元組數,送入病毒連結串列指標區;修改PE檔案頭,用病毒入口地址替換PE檔案頭原檔案程式入口地址,而將原檔案的入口地址儲存在病毒程式的第94位元組內,以供病毒執行完後回到正常檔案執行上來。
由於病毒的首塊部分除了病毒塊連結串列指標區外必須包含病毒的184位元組駐留程式,若檔案頭的自由空間不足,病毒不會對該檔案進行感染。只是將該檔案置上已感染標誌。
5.病毒其餘塊的寄生計算
剩餘的病毒程式碼是分塊依次插入到各Section裡的自由空間裡的。
要確定該區(Section)是否有自由空間,可通過檢視Section Header裡的引數確定。Section Headers區域是緊跟在PE Optional Header 區域後面。每個Section Header共佔40個位元組,由Name(區名)、VirtSize(本已使用大小)、RVA(本區的虛擬地址)、PhysSize(區物理大小)、Phys off(本區在檔案中的偏移量)和Flags(標誌)組成。其結構如下所示:
typedef struct _IMAGE_SECTION_HEADER {
UCHAR Name[8];
ULONG VirtSize;
ULONG RVA;
ULONG PhysSize;
ULONG Pyus off;
ULONG PointerToRelocations;
ULONG PointerToLinenumbers;
USHORT NumberOfRelocations;
USHORT NumberOfLinenumbers;
ULONG Flags;
} IMAGE_SECTION_HEADER
病毒將整個Section Headers讀入記憶體,取第一個Section Header,計算出該Section的自由空間(=PhysSize-VirtSize),以確定可存放到該區的病毒塊位元組數;計算出病毒塊在該區的物理存放位置(=Physoff+VirtSize);計算出病毒塊在該檔案的邏輯存放位置(=VirtSize+RVA+ImageBase);修改VirtSize(=該塊病毒長度+原VirtSize);修改Flags,置該區為已初始化資料區和可讀標誌;將該區的病毒塊長度和邏輯指標引數寫入病毒連結串列指標區相應區域;求出病毒剩餘長度,並取下一個Section Header。反覆前面的操作,直到病毒全部放入為止。
6.寫入病毒
病毒程式在前面只是計算出了病毒的分塊、長度和插入到檔案的位置等引數,將這些引數用PUSH指令壓入棧中。在計算完所有病毒存放位置後,才從棧中POP出進行寫盤操作。寫盤的步驟如下:
以逆序將各塊病毒寫入檔案各區(Section)相應的自由空間中;
將病毒首塊寫入檔案頭自由空間內;
將病毒塊連結串列指標區寫入檔案頭;
將修改後的Section Headers寫回檔案;
將修改後的PE File Header 和 PE File Option Header寫回檔案
置病毒感染標誌,將IFSMgr_Ring0_FileIO程式的第一個位元組(通常是55h=‘U’,即PUSH EBP的操作程式碼)寫到PE檔案識別符號(Signature)‘PE’的前一地址內(原為00h),‘00PE0000’改為了‘UPE0000’。
病毒讀入檔案和寫入檔案都是通過呼叫系統核心的IFSMgr_Ring0_FileIO的讀(EAX=0000D600)和寫(EAX=0000D601)功能實現的。
病毒在PE格式檔案中存放位置見圖2。
病毒的發作
1.病毒發作條件判斷
在CIHv1.4中,病毒的發作日期是4月26日,病毒從COMS的70、71埠取出系統當前日期,對其進行判斷:
MOV AX,0708
OUT 70,AL
IN AL,71 取當前系統月份->AL
XCHG AL,AH
OUT 70,AL
IN AL,71 取當前系統日->AL
XOR AX,0426 是否為4月26日
JZ 病毒發作程式
如果系統當前日期不是4月26日,則離開病毒程式,回到檔案的原正常操作上去;若正好是4月26日,則瘋狂的CIH病毒破壞開始了!
2.病毒的破壞
①通過主機板的BIOS埠地址0CFEH和0CFDH向BIOS引導塊(boot block)內各寫入一個位元組的亂碼,造成主機無法啟動。
為了儲存BIOS中的系統基本程式,BIOS先後採用了兩種不同的儲存晶片:ROM和PROM。ROM(只讀儲存器)廣泛應用於x86時代,它所儲存的內容不可改變,因而在當時也不可能有能夠攻擊BIOS的病毒;然而,隨著快閃記憶體(FlashMemory)價格的下跌,奔騰機器上BIOS普遍採用PROM(可程式設計只讀儲存器),它可以在12伏以下的電壓下利用軟體的方式,從BIOS埠中讀出和寫入資料,以便於進行程式的升級。
CIH病毒正是利用快閃記憶體的這一特性,往BIOS裡寫入亂碼,造成BIOS中的原內容被會徹底破壞,主機無法啟動。
所幸的是,CIH只能對少數型別的主機板BIOS構成威脅。這是因為,BIOS的軟體更新是通過直接寫埠實現的,而不同主機板的BIOS埠地址各不相同。現在出現的CIH只有1K,程式量太小,還不可能儲存大量的主機板和BIOS埠資料。它只對埠地址為0CFEH和0CFD的BIOS(據有關資料為Intel 430TX chipset、部分Pentium chipsets)進行攻擊。
②覆蓋硬碟
通過呼叫Vxd call IOS_SendCommand直接對硬碟進行存取,將垃圾程式碼以2048個扇區為單位,從硬碟主引導區開始依次迴圈寫入硬碟,直到所有硬碟(含邏輯盤)的資料均被破壞為止。
病毒的清除
目前,檢測和清除CIH病毒的程式已有很多, KV300、瑞星、Norton Antiviurs,這些殺病毒工具都非常有效。受CIH病毒破壞後系統如何恢復的文章也有不少。這裡本文只給出一般的檢測和清除方法和程式。
病毒的檢測
①利用“資源管理器”進行搜尋
具體的搜尋方法為:首先開啟“資源管理器”,選擇其中的選單功能“工具>查詢>檔案或資料夾”,在彈出的“查詢檔案”設定視窗的“名稱和位置”輸入中輸入查詢路徑及檔名(如:*.EXE),然後在“高階>包含文字”欄中輸入要查詢的特徵字串----“CIH v”,最後點取“查詢鍵”即可開始查詢工作。如果在查詢過程中,顯示出一大堆符合查詢特徵的可執行檔案,則表明你的計算機上已經感染了CIH病毒。
但這種方法中存在著一個致命的缺點,那就是:如果使用者已感染了CIH病毒,那麼這樣一個大面積的搜尋過程實際上也是在擴大病毒的感染面。
②Debug檢測PE Signature
用\windows\command\debug.com檢測.EXE。
通過“程式”進入“MS-DOS方式”,在MS-DOS方式下:
DEBUG XXX.EXE
-D CS:3F 41
如果顯示的值是0x554550(“UPE”),則該檔案有可能已經感染了CIH病毒。
病毒的清除
根據以上分析,筆者用匯編語言編寫了KILL_CIH.EXE,能自動搜尋各級子目錄下的所有.EXE檔案,對其進行CIH病毒檢測和消除。其源程式KILL_CIH.ASM可通過E_mail向筆者獲取。E_mail: [email protected]