Stuxnet蠕蟲病毒(超級工廠病毒)是世界上首個專門針對工業控制系統編寫的破壞性病毒,能夠利用對windows系統和西門子SIMATIC WinCC系統的7個漏洞進行攻擊。特別是針對西門子公司的SIMATIC WinCC監控與數據採集 (SCADA) 系統進行攻擊,由於該系統在我國的多個重要行業套用廣泛,被用來進行鋼鐵、電力、能源、化工等重要行業的人機互動與監控。 傳播途徑:該病毒主要通過隨身碟和區域網路進行傳播。歷史“貢獻”:曾造成伊朗核電站推遲發電。 2010-09-25,進入中國。
Stuxnet又名“震網”,是針對微軟系統以及西門子工業系統的最新病毒,目前已感染多個國家及地區的工業系統和個人用戶,此病毒可通過網路傳播,與以往病毒不同,其代碼非常精密 曾造成伊朗核電站推遲發電的全球首個“超級工廠病毒”Stuxnet目前已經侵入我國。瑞星12年9月25日發布的預警顯示,國內已有近500萬網民及多個行業的領軍企業遭Stuxnet蠕蟲病毒攻擊,而且由於安全制度上的缺失,該病毒還存在很高的大規模傳播風險。 據瑞星安全專家介紹,Stuxnet蠕蟲病毒是世界上首個專門針對工業控制系統編寫的破壞性病毒,能夠利用對windows系統和西門子SIMATIC WinCC系統的7個漏洞進行攻擊。特別是針對西門子公司的SIMATIC WinCC監控與數據採集 (SCADA) 系統進行攻擊,由於該系統在我國的多個重要行業套用廣泛,被用來進行鋼鐵、電力、能源、化工等重要行業的人機互動與監控。 Stuxnet及其變種是一種利用最新的Windows Shell漏洞傳播惡意檔案的蠕蟲。造成這個漏洞的原因是Windows 錯誤地分析捷徑,當用戶單擊特製捷徑的顯示圖示時可能執行惡意代碼(檔案帶有.LNK擴展名)。
在終端設備上開啟防火牆功能。
為終端設備上所有的套用系統安裝最新的補丁程式。
在終端上安裝防病毒系統,設定為實時更新病毒庫,並將病毒庫升級到最新版本。
在終端上的用戶設定最小用戶許可權。
在打開附屬檔案或通過網路接收檔案時,彈出安全警告或提示。
在打開網路連結時,發出安全警告或提示。
儘量避免下載未知的軟體或程式。
使用強口令,以保護系統免受攻擊。
兩個月前,賽門鐵克首次披露了W32.Stuxnet針對工業生產控制系統(ICS) 進行攻擊,如套用於管道和核動力工廠的控制系統。讀者可參見賽門鐵克2010年7月19日的部落格– “W32.Stuxnet 攻擊微軟零日漏洞利用USB設備大肆傳播”。
2010年9月29日,我們還將在Virus Bulletin 會議上發布一篇包含W32.Stuxnet詳盡技術細節的論文。同時我們也注意到,最近非常多的人開始對Stuxnet感染系統且不易檢測的事情表示關注。
在這篇部落格里,我們會深入探討Stuxnet的PLC感染方式和Rootkit功能,特別是以下幾個方面:
它如何選擇作為攻擊目標的工業生產控制系統;感染PLC代碼塊的方法;注入PLC的惡意代碼;在被感染Windows機器中的PLC Rootkit代碼。 這四點我們會分開講,因為用來實現這些目的的代碼差異很大。
Stuxnet的目的是通過修改PLC來改變工業生產控制系統的行為,包括攔截髮送給PLC的讀/寫請求,以此判斷系統是否為潛在的攻擊目標;修改現有的PLC代碼塊,並往PLC中寫入新的代碼塊;利用Rootkit功能隱藏PLC感染,躲避PLC管理員或程式設計師的檢測。這些任務之間差別很大,比如,在被感染的Windows 機器中隱藏感染代碼使用的是標準的C/C++ 代碼,而Stuxnet 試圖在工業生產控制系統及PLC中執行的惡意代碼則是用MC7位元組碼寫的。MC7 是PLC 環境中運行的一種彙編語言,並常用STL 進行編寫。
在討論Stuxnet攻擊PLC的技術之前,讓我們先來看看PLC是如何訪問和編寫的。
要進入PLC, 首先需要安裝特殊的軟體;Stuxnet 會專門針對編寫PLC某些模組的WinCC/Step 7軟體進行攻擊。安裝這些軟體後,程式設計師可以通過數據線連線PLC,以訪問其中的內容,重新配置PLC,下載程式至PLC,或調試之前載入的代碼。一旦PLC被配置和編譯後,Windows機器就可以斷開和PLC的聯繫了,PLC會自行運行。為了使您有一個更直觀的感受,下圖顯示了在實際操作中,實驗室里一些基本的設備配置:
下面的截圖顯示了Step7 STL編譯器中Stuxnet惡意代碼的一部分。其中,編寫Stuxnet功能代碼塊的MC7代碼的開始部分是可視的;下面顯示的代碼來自於反彙編後的FC1873模組。
Step 7 軟體使用庫檔案s7otbxdx.dll 來和PLC通信。當Step7 程式準備進入PLC時,它會調用該DLL檔案中不同的例程。例如,如果一個代碼塊需要用Step 7從PLC中讀出,那么,例程s7blk_read就會被調用到。s7otbxdx.dll中的代碼會進入PLC, 讀出其中的代碼,並把它傳回Step 7程式,如下圖所示:
現在讓我們看看當Stuxnet是如何進入PLC的。運行後,Stuxnet會將原始的s7otbxdx.dll檔案重命名為s7otbxsx.dll。然後,它將用自身取代原始的DLL檔案。現在,Stuxnet就可以攔截任何來自其他軟體的訪問PLC的命令。
被Stuxnet修改後的s7otbxdx.dll 檔案保留了原來的導出表,導出函式為109個,這就令Stuxnet可以應付所有相同的請求。大部分導出命令會轉發給真正的DLL,即重命名後的s7otbxsx.dll,並不會出現什麼難對付的狀況;事實上,109種導出形式中的93種都會照這樣處理。然而,真正的“詭計”使用在剩下的16種導出命令中。這16種導出不會被簡單的轉發,而是被改動後的DLL 攔截了。被攔截的導出命令為在PLC中讀、寫、定位代碼塊的例程。通過攔截這些請求,Stuxnet 可以在PLC 管理員沒有察覺的情況下,修改傳送至PLC 或從PLC返回的數據。同時,通過利用這些例程,Stuxnet 可以將惡意代碼隱藏在PLC 中。
為了更好的了解Stuxnet 如何進入和感染PLC,我們先來看看各種類型的數據。PLC 會處理由管理員載入到PLC的代碼和數據。這裡,我們將簡要介紹一下最常見的模組和他們的功能:
數據模組(DB)包含了程式相關的數據,比如數字,結構等。系統數據模組(SDB) 包含了PLC 的配置信息; 它們是根據連線到PLC 的硬體模組的數量/種類設立的。組織模組(OB) 是程式的入口。他們由CPU 循環執行。針對Stuxnet, 有兩個特別需要的OB:OB1 是PLC 程式的入口。它沒有特別的時間要求,總是循環執行。OB35 是一個標準的“看門狗”模組,系統會每100ms執行一次。這個功能可能包含了所有用於監控緊要輸入的邏輯,以達到立即回響,執行功能的目的。功能模組(FC)都是標準的代碼快。它們包含了會被PLC 執行的代碼。一般說來,OB1模組會引用至少一個FC 模組。下面的部分會詳細講述之前提到的威脅的四大方面。
Stuxnet會根據目標系統的特點,使用不同的代碼來感染PLC。
一個感染的序列包括了許多PLC 模組(代碼模組和數據模組),用以注入PLC來改變目標PLC 的行為。這個威脅包括了三個感染序列。其中兩個非常相似,功能也相同,我們將其命名為序列A和B。第三個序列我們命名為序列C。Stuxnet通過驗證“指紋”來判斷系統是否為計畫攻擊的目標。它會檢查:
PLC種類/家族:只有CPU 6ES7-417 和6ES7-315-2 會被感染。系統數據模組:SDB 會被解析;根據他們包含的數據,感染進程會選擇A,B或其它感染方式開始行動。當解析SDB 時,代碼會搜尋這兩個值是否存在-- 7050h and 9500h;然後根據這兩個數值的出現次數,選擇序列A 或B 中的一種來感染PLC。 代碼還會在SDB 模組的50h 子集中搜尋位元組序2C CB 00 01, 這個位元組序反映了通信處理器CP 342-5 (用作Profibus-DP) 是否存在。
而選擇序列C進行感染的條件則由其他因素構成。
Stuxnet使用“代碼插入”的感染方式。當Stuxnet 感染OB1時,它會執行以下行為:
增加原始模組的大小; 在模組開頭寫入惡意代碼;
在惡意代碼後插入原始的OB1 代碼。
Stuxnet也會用類似於感染OB1的方式感染OB35。它會用自身來取代標準的協同處理器DP_RECV 代碼塊,然後在Profibus (一個標準的用作分散式I/O的工業網路匯流排) 中掛鈎網路通信。
利用A/B方法的感染步驟如下:
檢查PLC 類型;
該類型必須為S7/315-2;
檢查SDB 模組,判斷應該寫入序列A 或B 中的哪一個;
找到DP_RECV,將其複製到FC1869,並用Stuxnet嵌入的一個惡意拷貝將其取代;
在序列中寫入惡意模組(總共20個),由Stuxnet 嵌入;
感染OB1,令惡意代碼可以在新的周期開始時執行;
感染OB35, 它將扮演“看門狗”的角色。
被注入OB1 功能的代碼是用來感染序列A 和B的。這些序列包含了以下模組:
代碼塊:FC1865 至FC1874, FC1876 至FC1880 (注意:FC1869並非Stuxnet的一部分,而是PLC的DP_RECV模組的一個拷貝);
數據模組:DB888 至DB891。 序列A 和B 用DP_RECV 掛鈎模組來攔截Profibus 中的數據包,並根據在這些模組中找到的數值,來構造其他的數據包並傳送出去。這由一個複雜的狀態機控制(狀態機被建立在上面提到的FC 模組中)。這個狀態機可部分受控於數據塊DB890 中的DLL。
在某些條件下,序列C會被寫入一個PLC。這個序列比A和B包含更多的模組:
FC6055 至FC6084;DB8062, DB8063;DB8061, DB8064 至DB8070 (在運行中產生)。 序列C主要為了將I/O信息讀寫入PLC的記憶體檔案映射的I/O 區域,以及外圍設備的I/O。
程式A/B 的控制流如下圖所示,在之前的Step7 編輯器的截圖中也有部分顯示(數據模組FC1873):
而序列C 的程式流則更加複雜,可以從下面的圖表中看到:
4. Rootkit
Stuxnet PLC rootkit代碼全部藏身於假冒的s7otbxdx.dll中。為了不被PLC所檢測到,它至少需要應付以下情況:
對自己的惡意數據模組的讀請求;對受感染模組(OB1 , OB35, DP_RECV) 的讀請求;可能覆蓋Stuxnet自身代碼的寫請求。 Stuxnet包含了監測和攔截這些請求的代碼,它會修改這些請求以保證Stuxnet 的PLC 代碼不會被發現或被破壞。下面列出了幾個Stuxnet用被掛鈎的導出命令來應付這些情況的例子:
s7blk_read: 監測讀請求,而後Stuxnet 會返回:真實請求的DP_RECV (保存為FV1869);錯誤信息,如果讀請求會涉及到它的惡意模組;OB1或OB35的乾淨版本的拷貝s7blk_write: 監測關於OB1/OB35的寫請求,以保證他們的新版本也會被感染。s7blk_findfirst / s7blk_findnext: 這些例程被用於枚舉PLC中的模組。惡意模組會被自動跳過。s7blk_delete: 監測對模組的“刪除”操作。 如上文所述,Stuxnet 是一個非常複雜的威脅,而其中的PLC 感染代碼令問題更加難以解決。僅僅關於注入的MC7代碼(我們於幾個月前通過逆向工程獲得)就可以討論很久。