查看單個文章
舊 2004-09-20, 03:22 PM   #2 (permalink)
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設

要討論怎樣反病毒,就必須從病毒技術本身的討論開始。正是所謂「知己知彼,百戰不殆」。

很難想像一個毫無病毒寫作經驗的人會成為殺毒高手。目前國內一些著名反病毒軟體公司的研發隊伍中不乏病毒寫作高手。

只不過他們將同樣的技術用到了正道上,以『毒』攻『毒』。


當今的病毒與DOS和WIN3.x時代下的從技術角度上看有很多不同。


最大的轉變是:啟始區病毒減少了,而指令碼型病毒開始氾濫。

原因是在當今的操作系統下直接改寫磁牒的啟始區會有一定的難度(DOS則沒有保護,允許使用INT13直接寫入磁碟),而且啟始區的改動很容易被發現,並且微軟在設計操作系統時加強了對啟始區的程序行為管理,寫一個完美的啟始區病毒難度很大,所以很少有人再寫了;而指令碼病毒以其傳播效率高且容易編寫而深得病毒作者的青睞。


但是最最落後的殺毒引擎也就是只關於靜態程式碼的殺毒引擎都能幹掉該種病毒(病毒庫搞好就行)。


要討論的技術主要來自於二進制外殼型病毒(感染文件的病毒),並且這些技術大都和操作系統底層機制或386以上CPU 的保護模式相關,值得研究。

DOS下的外殼型病毒主要感染 16位的COM或EXE文件,由於DOS沒有(文件和啟始區)保護,它們能夠輕鬆地進行駐留,減少可用記憶體(通過修改MCB鏈),修改系統程式碼,攔截系統服務或中斷。


而到了WIN9X和WINNT/2000時代,搞個執行其上的32位WINDOWS病毒變得難了點。


由於存在頁面保護,你不可能修改系統的程式碼頁(如果你強到連操作系統程式碼都能改,偶無話可說)。


由於I/O許可位圖中的規定,你也不能進行直接連接阜訪問(29A的一個美女[聽說叫 Mercy.Chan]可以通過彙編方法直接訪問連接阜的目的,但是沒有見過指出事例程式碼。

知道得給介紹一下她的程序程式碼)WINDOWS中你不可能像在 DOS中那樣通過截獲INT21H來攔截所有文件操作。


總之,你以一個用戶態權限執行,你的行為將受到操作系統嚴格的控制,不可能再像DOS下那樣為所欲為了(在xp中,這種權限管理極為嚴格,大致分成了4-8個等級)。


WINDOWS下採用的可執行文件格式和DOS下的 EXE截然不同(普通程序採用PE格式,驅動程式採用LE),所以病毒的感染文件的難度增大了(PE和LE比較複雜,中間分了若干個節,如果感染錯了,將導致文件不能繼續執行)。

當今病毒的新技術太多,隨便介紹幾個。

1.系統核心態病毒

386及以上的CPU實現了4個特權級模式(WINDOWS只用到了其中兩個),其中特權級0(Ring0)是留給操作系統程式碼,設備驅動程式程式碼使用的,它們工作於系統核心態;而特權極3(Ring3)則給普通的用戶程序使用(我想知道一個問題,ring1,2是幹什麼的?),它們工作在用戶態。


執行於處理器核心態的程式碼不受任何的限制,可以自由地訪問任何有效位址,進行直接連接阜訪問。


而執行於用戶態的程式碼則要受到處理器的諸多檢查,它們只能訪問映射其位址空間的頁表項中規定的在用戶態下可訪問頁面的虛擬位址,且只能對工作狀態段(TSS)中I/O許可位圖(I/O Permission Bitmap)中規定的可訪問連接阜進行直接訪問(此時處理器狀態和控制標誌暫存器EFLAGS中的IOPL通常為0,指明當前可以進行直接I/O的最低特權等級是Ring0)。


以上的討論只限於保護模式操作系統,像DOS這種真真實模式操作系統則沒有這些概念,其中的所有程式碼都可被看作執行在核心態。既然執行在核心態有如此之多的優勢,那麼病毒當然沒有理由不想得到Ring0。


處理器模式從Ring3向Ring0的切換發生在控制權轉移時,有以下兩種情況:
訪問使用門的長轉移指令CALL,訪問中斷門或陷阱門的INT指令。具體的轉移細節由於涉及複雜的保護檢查和堆疊切換,不再贅述,請參閱相關資料。


現代的操作系統通常使用中斷門來提供系統服務,通過執行一條陷入指令來完成模式切換,在INTEL X86上這條指令是INT,如在WIN9X下是INT30(保護模式回調),在LINUX下是INT80,在WINNT/2000下是INT2E。


用戶模式的服務程序(如系統DLL)通過執行一個INTXX來請求系統服務,然後處理器模式將切換到核心態,工作於核心態的相應的系統程式碼將服務於此次請求並將結果傳給用戶程序。


在即將發佈的xp-sp2中採用所謂增強的記憶體頁面保護將會更為嚴格的控制用戶權限,據說在訪問記憶體位址時得到的將是經過系統映射處理的對應記憶體範圍,在記憶體實位址與用戶層之間,搞了一個類似於轉換傳輸協定的東西,害的很多軟體都不能執行,應為他們總是試突按照原有的HAL層訪問規則進行工作。


2.駐留病毒

駐留病毒是指那些在記憶體中尋找合適的頁面並將病毒自身拷貝到其中且在系統執行期間能夠始終保持病毒程式碼的存在。


駐留病毒比那些直接感染(Direct- action)型病毒更具隱蔽性,它通常要截獲某些系統操作來達到感染傳播的目的。


進入了核心態的病毒可以利用系統服務來達到此目的,如CIH病毒通過使用一個由VMM匯出的服務VMMCALL _PageAllocate在大於0xC0000000的位址上分配一塊頁面空間。

而處於用戶態的程序要想在程序結束後仍駐留程式碼的部分於記憶體中似乎是不可能的,因為無論用戶程序分配何種記憶體都將作為工作佔用資源的一部分,一旦工作結束,所佔資源將立即被釋放。所以我們要做的是分配一塊工作結束後仍可保持的記憶體。



病毒寫作小組29A的成員GriYo 運用的一個技術很有創意:
他通過CreateFileMappingA 和MapViewOfFile新增了一個區域對象並映射它的一個視口到自己的位址空間中去,並把病毒體搬到那裡,由於文件映射所在的虛擬位址處於共享區域(能夠被所有工作看到,即所有工作用於映射共享區內虛擬位址的頁表項全都指向相同的物理頁面),所以下一步他通過向Explorer.exe中注入一段程式碼(利用WriteProcessMemory來向其它工作的位址空間寫入資料),而這段程式碼會從Explorer.exe的位址空間中再次申請開啟這個文件映射。


如此一來,即便病毒結束,但由於Explorer.exe還對映射頁面保持引用,所以一份病毒體程式碼就一直保持在可以影響所有工作的記憶體頁面中直至Explorer.exe結束(我直接試過該種方法,在xp下注意要寫一個空循環語句,以免被踢出處理佇列)。



另外還可以通過修改系統動態連接模組(DLL)來進行駐留。


WIN9X下系統DLL(如Kernel32.dll 映射至BFF70000)處於系統共享區域(2G-3G),如果在其程式碼段空隙中寫入一小段病毒程式碼則可以影響其它所有工作。

但Kernel32.dll 的程式碼段在用戶態是只能讀不能寫的。


所以必須先通過特殊手段修改其頁保護內容;而在WINNT/2000/xp系統DLL所在頁面被映射到工作的私有空間(如 Kernel32.dll 映射至77ED0000)中,並具有寫時拷貝內容,即沒有工作試突寫入該頁面時,所有工作共享這個頁面;
而當一個工作試圖寫入該頁面時,系統的頁面錯誤處理程式碼將收到處理器的異常,並檢查到該異常並非訪問違例,同時分配給引發異常的工作一個新頁面,並拷貝原頁面內容於其上且更新工作的頁表以指向新分配的頁。


這種共享記憶體的最佳化給病毒的寫作帶來了一定的麻煩,病毒不能像在WIN9X下那樣僅修改Kernel32.dll一處程式碼便可一勞永逸。


它需要利用 WriteProcessMemory來向每個工作映射Kernel32.dll的位址寫入病毒程式碼,這樣每個工作都會得到病毒體的一個副本,這在病毒界被稱為多工作駐留或每工作駐留(Muti-Process Residence or Per-Process Residence )。


文中列舉方法在xp-sp1下略作修改即可使用 ,大部分為在程式碼段內加入空循環 。


在sp2下,很多時候報如下檔案檔案類型的錯誤不可訪問的記憶體位址段.........。
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次