2019年12月26日 星期四

病毒程式(Virus)的淺入介紹

第一次接觸病毒程式大約是在大學三年級,在此之前,就一直很好奇,要如何撰寫病毒的程式碼,那麼在大學期間就一直秉持著,想要學習一種技術,就必須自己實作它,所以就嘗試撰寫Linux平台上的病毒程式碼。

一、病毒的感染方式

Prepending是將病毒程式碼附著在程式碼之前,這種技術需要利用無作用的section來寫入病毒碼,因此可能沒有太多的空間可以使用,所以病毒碼就不能寫太大。



Appending是將病毒程式碼附著到程式碼的尾端,這樣就比較靈活,因為並不會限制病毒碼的大小,也是最常見的手法之一。



Cavity是將病毒碼附著在程式主體,因為程式碼中的不同函式之間可能會存在無意義的程式碼(0x90、0x00、0xcc等等),所以病毒可以利用這些無意義的程式碼塞入部分的病毒碼,因此病毒碼被分散在程式碼的各個地方。由於附著的病毒程式碼,並不會增加執行檔的長度,所以就非常難偵測是否被病毒感染。




二、實作Appending病毒程式

1. Entry point

程式的Entry point是0x08049a30,需要將他替換,或者Hook它,達到先運行我們的病毒程式碼。



2. Hooking

我們將原本的程式修改成push 0x805fe78(需要讀取Header,然後再決定病毒碼的起始位址)、ret,因此會它先執行我們的病毒碼(病毒程式碼的起始位址是0x805fe78),然後才會繼續運行主程式。



3. 標記已被感染的旗標

要將已被感染的程式碼做一下記號(0xaa),這樣才不會重複感染相同的程式。



4. 修改Program header

我們的病毒碼是放在程式的尾端,因此要確保它可以正常運行我們的病毒碼,所以要修改Program header。首先確認位址最靠近我們病毒碼的LOAD是否有覆蓋到我們的病毒碼,它的位址是0x805e0f4,長度是0x1211,那麼0x0805e0f4加0x1211是沒有覆蓋到我們的病毒碼,不過這邊注意它的對齊長度是0x1000,因此是0x0805e0f4加0x2000,所以有覆蓋到病毒碼,這樣就不須修改長度,接下來是確認運行權限,原本此LOAD的權限只有RW(讀、寫),所以需要改成現在的RWE(讀、寫、執行),才能順利的運行病毒程式碼。



5. 寫入病毒碼

將病毒碼寫入到程式的尾端,此病毒碼只會印出You has been Infection.的字串,如果要運行其他行為,需要再修改附著病毒碼的行為。



三、運行結果

此實作的病毒會感染ls(為了區別原來的ls,將它改名成ls2)的程式,它會先執行病毒的行為(印出You has been Infection.的字串),然後再顯示資料夾下的檔案名稱(ls原本的行為)。