[原創]Stuxnet蠕蟲(超級工廠病毒)驅動分析

gjden發表於2010-11-20
Stuxnet蠕蟲驅動分析

這裡只是分析文字, 貼圖影響速度, 就不貼了, 具體看附件pdf文件, 難免有錯誤之處, 歡迎指正!

一. Stuxnet蠕蟲(超級工廠病毒)簡單說明

能夠利用對windows系統和西門子SIMATIC WinCC系統的7個漏洞進行攻擊,被稱為是新時代網路戰爭開始的標誌,
也有人宣稱是"政府發動的網路戰爭、帶有聖經訊息、最高機密等",呵呵,有點雷人!

windows下最主要的傳播途徑是攻擊快捷方式自動執行漏洞(MS10-046), WindowsServer服務的遠端溢位漏洞
(MS08-067)以及列印後臺程式服務中的遠端程式碼執行漏洞(MS10-061)。

病毒成功攻擊了伊朗核電站,造成伊朗核電站推遲發電.由於能夠對西門子公司的SIMATIC WinCC監控與資料採集 
(SCADA) 系統進行攻擊,因此也能攻擊我國的鋼鐵、電力、能源、化工等重要行業,

Stuxnet超級工廠病毒直到2010-09-25,才在傳入國內網路.我是在近兩個月前才收到的,當時只需要簡單分析使用者態的部分樣本,因此沒有對驅動進行分析.後來閒著沒事時,就分析了驅動部分.不過,此病毒強大之處大部分都在使用者態實現.

二.Stuxnet蠕蟲(超級工廠病毒)驅動(mrxnet.sys)分析

從Stuxnet蠕蟲病毒樣本中提取出了兩個驅動檔案,mrxnet.sys(17k),mrxcls.sys(26k),其中驅動mrxnet.sys在蠕
蟲透過u盤驅動器傳播時被用來隱藏特定檔案,這個驅動是一個檔案系統過濾驅動,支援三種檔案系統ntfs,
fastfat和cdfs檔案系統.驅動檔案mrxcls.sys則被用於向使用者空間中注入程式碼,被注入的模組被放在一個配
置檔案中,這應該就是最初讓卡巴斯基頭痛的"父程式注入"技術,輕鬆地繞過卡巴.這裡單就只分析驅動mrxnet.sys.

入口處開始分析:

1.此驅動首先建立一個裝置型別為FILE_DEVICE_DISK_FILE_SYSTEM,裝置特徵為FILE_DEVICE_SECURE_OPEN,
裝置擴充套件為8位元組的無名裝置物件.這個驅動沒有控制裝置,因此不會跟使用者態交換資訊.

其中裝置擴充套件的類似如下定義:
DeviceExtension
{
PDEVICE_OBJECT LowerDevice;
PDEVICE_OBJECT RealDevice;
}
其中LowerDevice為本驅動的下層驅動,RealDevice為VPB中的RealDevice裝置,其實也就是檔案系統的卷裝置.

2.接下來註冊MajorFunction:

IRP_MJ_FILE_SYSTEM_CONTROL
IRP_MJ_DIRECTORY_CONTROL

這兩個派遣例程,這個驅動主要就處理這兩例程,其他的用一個例程處理,其實是直接pass了,不做任何處理.
兩個例程分別是FileSystemControl,DirControl.是本驅動核心功能的實現,留到最後闡述.

3.接著就是填充FastIoRoutines,驅動並沒填充所有的FastIoRoutines,這裡填充瞭如下:
FastIoCheckIfPossible;
FastIoRead;
FastIoWrite;
FastIoQueryBasicInfo;
FastIoQueryStandardInfo;
FastIoLock;
FastIoUnlockSingle;
FastIoUnlockAll;
FastIoUnlockAllByKey;
FastIoDeviceControl;
FastIoDetachDevice;
FastIoQueryNetworkOpenInfo;
MdlRead;
MdlReadComplete;
PrepareMdlWrite;
MdlWriteComplete;
FastIoReadCompressed;
FastIoWriteCompressed;
MdlReadCompleteCompressed;
MdlWriteCompleteCompressed;
FastIoQueryOpen;
這些FastIoRoutines沒有做什麼實質性的工作,只是把簡單判斷一下,然後呼叫下層驅動.

4.然後就是attach到檔案系統了,函式:AttatchTargetDrivers.
先獲取透過MmGetSystemRoutineAddress動態獲取ObReferenceObjectByName函式的地址,將其地址作為引數去
獲取檔案的驅動物件,檔案系統名為:
\\FileSystem\\ntfs
\\FileSystem\\fastfat
\\FileSystem\\cdfs
支援的檔案系統有ntfs,fastfat,cdfs.
這三個檔案系統名的地址被放在一個指標陣列中,這個指標陣列以後會被透過ObReferenceObjectByName獲取的
驅動物件覆蓋;

這裡有個迴圈,迴圈3次,分別去attach這三種檔案系統.
這個attach的函式是GetTargetDriverAndAttach(),函式有兩個引數,第一個引數是函式ObReferenceObjectBy
Name的地址,第二個引數是檔案系統檔名指標,這個引數即用來傳入檔案系統名地址,也用於獲取所得的驅動
物件指標.進入這個函式內部,函式先獲取檔案系統驅動物件,然後遍歷驅動物件的每個裝置物件進行attach,
attach 每個裝置物件的函式是TryToAttachDevice()

TryToAttachDevice()
這個函式有兩個引數,第一個是裝置物件(既是檔案系統的裝置物件),第二個是BOOLEAN型(這裡呼叫時傳入的為
true),用於判定這個檔案系統是被註冊(啟用),還是卸下.如是被註冊,則呼叫函式CreateFilterDeviceAndAtta
ch()否則Detach本驅動在檔案系統裝置棧中的裝置.

CreateFilterDeviceAndAttach()這個裝置有一個引數,引數為檔案系統的裝置.
這個函式只attach 裝置型別為磁碟檔案類裝置,CD_ROM檔案類裝置,網路檔案類裝置.
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_CD_ROM_FILE_SYSTEM
FILE_DEVICE_NETWORK_FILE_SYSTEM
先判斷裝置型別滿足以上條件,如果這個檔案系統裝置還沒有被attach,則建立一個本驅動的裝置attach到文
件系統裝置棧中,Attach是透過函式
AttachToFsDevie來實現的,這個函式很簡單,只是把attach裝置後,把下層裝置儲存於裝置擴充套件中.

這樣就完成了attach工作.

5.呼叫函式IoRegisterFsRegistrationChange註冊檔案系統變動回撥例程.這個例程也就是4講到的
TryToAttachDevice()函式,用於完成對動態啟用的檔案系統進行attach.

IRP_MJ_FILE_SYSTEM_CONTROL和IRP_MJ_DIRECTORY_CONTROL的派遣例程處理,這兩個例程都只處理
IRP_MN_MOUNT_VOLUME型別的次功能碼,主要是為了能在新的檔案系統被啟用時,做相應的處理.其他的
直接pass,不做處理.

1.FileSystemControlRoutine例程
首先獲取MinorFunction,判斷是否是IRP_MN_MOUNT_VOLUME,是則呼叫MnMountVolumeForFSC,否則pass;

2.MnMountVolumeForFSC()
函式先建立了一個裝置物件,然後初始化裝置擴充套件,在裝置擴充套件的第二成員裡儲存VPB中realDevice.然後是
自己實現了將當前裝置的Stack Location複製到下層裝置的Stack Location處,並且設定好完成例程,
Context和控制域.完成例程名為
CompleteRoutineForFSC.

3.完成例程CompleteRoutineForFSC.
完成例程的context引數傳進來是我們建立的過濾裝置物件,透過這個裝置物件得到原先儲存的vpb->RealDevice,
再根據這個裝置得到vpb然後在獲得VPB->DeviceObject,這個裝置則是檔案系統的卷裝置,為什麼要這麼做,
因為在mount之前我們建立的裝置的VPB可能在mount完成後就不同了,而完成後的VPB才是有效的.故這裡
先將檔案系統的卷裝置儲存在裝置擴充套件中,後在完成例程裡重新獲取.得到檔案系統的卷裝置物件後就可以
進行attach了.attach完成例程函式的主要工作也就算是完成了.

1.DirControlRoutine
其實重頭戲在函式DirControlRoutine中,這個函式主要實現檔案隱藏功能.
同樣也只處理IRP_MN_MOUNT_VOLUME,判斷後直接呼叫函式MnQueryDirectory.

2.MnQueryDirectory
這個函式先獲取查詢目錄(檔案)名,
如果檔名存在並且檔名長度76,且檔名前19個字元全是'{'的話,就放過(這裡有點不解,為什麼要設定這個例外呢.
),否則複製當前棧道下層棧,並設定完成例程IoCompleteRoutineForQueryDir,將irp直接下發,這裡棧的COPY和完
成例程的設定前面一樣,是自己實現的.

3完成例程IoCompleteRoutineForQueryDir
這個函式比較大,主要是做檔案過濾隱藏的.
先判斷IRP->IoStatus.Status是否成功,如果不成功則釋放相關資源並退出,然後就是獲取一些檔案相關的
偏移,從函式GetFileInforOffset中獲取EndOfFile Offset,FileName Offset,FileNameLength Offset.因為
這裡會因為檔案資訊類FileInformationClass的不同而會有不同的偏移.

得到偏移後就可以這裡涉及的檔案資訊類有
FileBothDirectoryInformation
FileDirectoryInformation
FileFullDirectoryInformation
FileIdBothDirectoryInformation
FileIdFullDirectoryInformation
FileNamesInformation

接著就是得到查詢資訊的緩衝,然後呼叫HideFile來隱藏檔案.

4.隱藏檔案函式HideFile
此函式中,從前面獲取的幾個偏移從緩衝中定位檔名地址,檔案長度,檔案結束位置.
然後就是呼叫兩個函式檔名過濾函式(CheckPostfix,CheckNameInvlidForTMP)來篩選病毒關心的檔案.
在函式CheckPostfix中判斷檔名是否是一".LNK"字尾的檔名,如是則符合隱藏規則,在函式CheckNameInvlid中,
如果檔案大小在0x1000~ 0x800000,檔名長度為12,檔案字尾名為".TMP",檔名第一個字元為"~",
並且檔名從第5個位元組到第8個位元組為數字,並且這些數字之和必須等於10,便符合規則.
符合以上兩種規則的檔案實施隱藏,隱藏處理是,如果條件符合,這把後面檔案記錄向前移動一個檔案記錄,
也就是覆蓋病毒關心的檔案記錄.
上傳的附件:

相關文章