震網蠕蟲中的一個Bug差點令其“出師未捷身先死”
由于內部代碼中存在一個Bug,使其可以感染古老的Windows系統。超級蠕蟲病毒震網(Stuxnet)差一點暴露,從而無法完成破壞。
業內眾所周知,該病毒可以隱秘地破壞控制離心機的計算機系統。它由美國和以色列的神秘黑客所設計,被用于破壞位于伊朗那達茲郡的鈾濃縮設施。該病毒導致伊朗的濃縮鈾項目推遲了兩年之久,但由于其自身的代碼缺陷,震網差點未能發揮作用。
為了完成行動目標,Stuxnet必須保證自己無法被伊朗人檢測到。不幸的是,一個編程錯誤可能會讓它傳播到較老版本的Windows上。由于病毒并不支持老版本的Windows,這可能會引發系統崩潰,大量的出現的系統藍屏可能會引起那達茲核試驗室工作人員們的注意。
and與or的故事
在上周結束的RSA安全大會上,BlueCoat的技術分析人員表示,當震網開始引發Windows 95和Windows 98系統崩潰時,它的任務可能還沒開始就即將結束。
“震網編程團隊里的某個人可能度過了糟糕的一天,并將代碼中的and錯誤地寫成了or。結果是,震網在執行安裝策略時會進行or檢查,這導致它會自動注入所有版本的Windows,甚至是Win 95和Win 98這些它并不支持的操作系統。”
“類似一種在某個項目上花費了很多年時間,但由于造成了遠程系統崩潰,突然前功盡棄的意思。”
不過從實際情況來看,震網還是在2010年被發現之前成功地干擾了離心機。這可能是因為碰巧震網在那時沒有碰到任何運行老版本Windows的機器,也有可能是伊朗科學家對Win 95和Win 98的藍屏錯誤早就習以為常。
同病相憐的Conficker
安全研究人員還發現,震網并不是唯一一個存在Bug的著名惡意軟件。Conficker蠕蟲自身存在的Bug也削弱了其自身的潛在破壞力。
Conficker 蠕蟲攻擊網絡上的Windows設備,從理論上講,它幾乎可以感染任何人。但由于負責生成隨機地址的代碼中存在一個Bug,它只能掃描到IPv4總地址數量的四分之一:它的隨機數生成函數會產生15位的整數,從0到0x7fff(0~RAND_MAX),它調用這個函數兩次,本意是生成一個32位的 IPv4地址。不過,事實上它生成的只是30位整數,比32位的整數還差了兩位。
“如果你連續攻擊受害者,會很容易被檢測到,因此黑客在這方面采取了聰明的辦法,每次攻擊一個隨機地址。”
“有趣的事情在于,RAND_MAX變量只有15位,這意味著當Conficker通過調用兩次該函數來生成IP地址時,得到的只是一個30位隨機數,這導致病毒并沒有掃描整個地址空間,而只是掃描了其中的四分之一。”
如果企業的客戶由于這個原因并沒有感染該蠕蟲,他們可能要感謝自己的好運了。
與Bug有緣的惡意軟件
還有更多的例子。2007年被披露的風暴(Storm)蠕蟲由于更新版本時的一個錯誤而變成了和風細雨。黑客在更新病毒版本、編寫代碼中關于選取入侵系統類型的部分時,將Windows錯拼成了Windoss。(有點敬業精神好不好?)
2014 年被披露的活力狗熊(Energetic Bear),又名蜻蜓(DragonFly),是一個用于滲透和破壞系統的惡意軟件。該軟件在安全研究人員的手里變成了小玩具,因為研究人員找到了它從緩存中計算公鑰和私鑰的方式,獲得受害者自由訪問列表的方式,甚至是它未來版本的架構細節。
通過同樣的方法,利用SimpleLocker被加密的安卓文件也可以被恢復。在總結銀行木馬Yaludle的漏洞時,安全人員表示,“SQL注入很漂亮,但不講衛生”。
以彼之道,還施彼身
惡意軟件分析并不只是逆向工程師的工作,只要做足準備,研究人員利用系統漏洞甚至可以控制攻擊者發動攻擊的服務器。
舉例而言,安全研究人員可以輕而易舉地將Conficker無害化。一旦該病毒注入了一臺電腦,就會從MaxMind上下載IP-地理地址數據庫,以找到自己在真實世界所處的位置。由于Conficker并不攻擊烏克蘭的電腦,如果這個數據庫中的所有IP都映射到烏克蘭,那么會引發蠕蟲自殺,停止傳播。通過向Conficker推送改動后的MaxMind數據庫,安全人員完全可以擊敗Conficker的攻擊。
我們鼓勵每一個人都來做這些事。”
(回復“malwarebug”,可獲得演講資料地址)
提醒:
研究人員在RSA大會上展示的PPT和他們的演講內容有所不一樣。PPT上顯示的代碼實際上表明,Stuxnet并不會向Win 95和Win98系統上傳播,這可能是因為研究人員所展示的是Stuxnet的修復版。他們所闡釋的通過逆向工程發現的Bug只是老版本的內容,因此他們有可能只是將Stuxnet代碼中正確的一部分拿了出來,而在會議上介紹了那些有缺陷的部分。
以下C語言部分展示了Stuxnet進行x86安裝檢測的源代碼:
if ( GetVersionExW(&OsVersion)
&& OsVersion.dwPlatformId == VER_PLATFORM_WIN32_NT
&& (OsVersion.dwMajorVersion >=5 || OsVersion.dwMajorVersion <= 6))
Install();
安全人員表示,以下這行代碼
(OsVersion.dwMajorVersion >=5 || OsVersion.dwMajorVersion <= 6))
對于Windows 9x、XP、200x、Vista和7而言都會返回True,這是沒錯的。但是這段代碼
OsVersion.dwPlatformId == VER_PLATFORM_WIN32_NT
對Windows 9x系統會返回False,因為Windows 95和Windows 98的dwPlatformId值都是1,VER_PLATFORM_WIN32_NT是2。因此,如果按照以上代碼來運行,Install()永遠不會在Windows 9x版本上被調用。