Author: [email protected]
最近群里提到TeslaCrypt的作者放出了主密鑰,簡單看了下,對他的加密流程比較感興趣。受條件限制,沒有拿到早期樣本(只拿到了晚一些的),放狗搜了搜也沒找到,但是找到了兩款解密程序。一款是Googulator開發的TeslaCrack,另外一款則是BloodDolly開發的TeslaDecoder。前者雖然開源,但支持解密的版本少于后者。本文通過分析及逆向樣本和這兩款工具,試圖了解TeslaCrypt的設計思路。
下文中所有圖片如無特殊說明,均為對BloodDolly開發的TeslaDecoder(簡稱“TD”)的逆向過程截圖。
TeslaCrypt(以及AlphaCrypt,下文統稱為“TC”)算是比較“成熟”的勒索軟件,其版本從0.2逐步升級到目前已知的最高版本4.0+(也不知道有沒有Insider Preview)。隨著版本的升級,其加密和密鑰處理技巧也在不斷升級。
勒索軟件的制作者為了打到目的,通常會給用戶一個比特幣錢包的地址。用戶向該錢包付款之后,可以得到一個解密密鑰,用此密鑰即可解密。有報告指出,不同的受害者需要向不同的錢包中打款,這暗示著比特幣錢包的生成過程可能與加密密鑰的產生存在一定關聯。因此,先大致了解下錢包是如何生成的。
比特幣錢包生成的基本步驟是:
如果想知道關于橢圓曲線算法的更多細節,有一篇文章比較適合參考閱讀。此外,TC還采用了ECDHE算法進行密鑰交換,只是將DH里的非對稱加密機制換成了橢圓曲線算法,其他變化不大,可以參考這里獲得更多細節。
TC被首次載入時,就生成了一對PublicBtcKey/PrivateBtcKey。其中,PublicBtcKey就是向用戶顯示的地址,而PrivateBtcKey則被發送給C&C服務器,以進行之后的轉賬操作。不同版本的TC,這一點是不變的。
TC作者本次公布的密鑰是四號密鑰,應用于TC3.0以及TC4.0版本。這兩個版本都采用了比較完整的分層密鑰機制,并且提高了樣本隱蔽性。TC4.0的準備過程如下:
現在TC已經做好了加密準備。TC的加密是以一個session為一環的,每次重啟、關閉計算機,都會終止當前的session,并啟動一個新的session。每次session里的加密細節是:
按照攻擊者的設定,用戶在被攻擊后,應該使用下面的流程來解密文件:
在TC4.0中,作者在每個文件頭里都保存了三個對解密必不可少的值:
此外還保存了:
而且,在密鑰沒有保存意義后,立刻用數據對相應的存儲區域進行清洗,防止安全/取證軟件獲取到解密密碼。通過這里也可以看出,病毒作者通過分析一些專殺工具和解密工具,對自己的技術也進行了升級。密鑰的分層機制也比較明確,在網絡里傳輸的數據,如果沒有Private_MalMaster,是無法解密BTC錢包地址的,而SessionKey的解密又依靠這個地址,從而保證除了攻擊者沒有第三方可以繞過邏輯解密文件。最后完成的3.x和4.x版本,基本可以作為密碼學應用的示范程序。在作者公布密鑰后,TD也嵌入了密鑰,并實現了上述的解密過程。
TC的老版本則沒有新版本這么“安全”了。對加密通道運用不當是比較常見的錯誤,在TC中也由發現。這是最早修復的漏洞,一個比較標志性的版本是v6,在v6之前,所有的文件都可以通過抓取感染后向CC通信的網絡流量來解密,但v6版本開始,這一做法便不能使用了。一種合理的猜想是,在舊版本的軟件中,可以直接解析出加密密鑰。對TD的分析證實了這一點。下圖是TD獲取網絡流量后,判定密鑰與比特幣地址是否相符的(以免解密錯誤):
之后,TD便將密鑰放入對應區域中,其他操作則與正常解密類似:
從V2版本到V5版本的TC,將傳輸的私鑰以特定方式進行的加密,各版本的密鑰也有所不同,但由于密鑰是硬編碼在程序里的,因此仍可以被TD直接提取出來,這就很尷尬了:
從TD的驗證邏輯推斷,舊版本的TC應該是向CC服務器直接發回了BTC地址和Private_BtcKey(或簡單加密后的Private_BtcKey):
因此,在v5版本的某個變種中,TC作者移除了部分數據,使TC無法驗證網絡請求中的BTC地址和私鑰是否相符,并在v6版本完全修改了向CC傳輸的數據,不再在通信中直接暴露加密密鑰,徹底的封堵了這個邏輯漏洞。然而,利用這個漏洞,需要用戶持續收集網絡流量,這在很多環境下不容易實現,因此這種方法的利用難度比較高。
第二個漏洞存在于TC的前兩個版本中。有一種比較簡單的方法,利用的主要是在加密設計過程中的漏洞。由于對數據存儲區域清洗不徹底,部分解密密鑰可能殘留在key.dat和注冊表中。獲取了部分密鑰,可以極大的降低TD的解密難度,而且由于設計過程問題比較嚴重,這樣獲得的密鑰不是SessionKey而是用戶主密鑰,這樣就可以直接解密所有文件了:
這個漏洞比較容易利用,修補難度也不高,因此只存活了兩個版本,就被勤勞的地下工作者修好了。
第三個漏洞就相對不太好利用。V7之前舊版本TC的弱點在于,在目標文件中保留了“RecoveryKey”或與之相似的參數。這個參數是由一個私鑰和用于加密該私鑰的乘積,其存在意義不明,位置和數量也隨版本變化。比如在.xyz格式的文件中,0x108偏移處的130個字節,保存的是文件私鑰Private_SessionKey與文件私鑰加密密碼Secret_Session的乘積。顯然,這個積可以被分解為多個質數的乘積,而Private_SessionKey的值可以由這些質數中的一個或多個相乘而來。這樣就產生了一個爆破思路:
這種方法能成功有兩個主要因素。最重要的一個是由于乘積的存在,增加了信息量,也就弱化了保密特性。而另一個因素則是由于攻擊者在這里采用了橢圓曲線算法。這種算法的保密關鍵點在于,解決ECDLP是困難的(在曲線Ep上給定一個點G,取任意一個整數k,那么可以證得點P=k*G容易在同一條曲線上找到。但是,如果選擇適當的參數,那么在已知P、G的情況下,求出k的群操作太慢了,而把G和Ep規定好,令k為私鑰,P為公鑰,就是橢圓曲線加密的基本原理),而不再一味依靠密鑰的位數。因此,在操作中,考慮到時間問題,一般把私鑰設定在160~300位,即使與RSA1024相比,這個長度也短的多,因此更容易被從素數表中挖掘出來(這里的“更”是相對與RSA1024來說的,實際上也需要相當量的算力和運氣)。解決這個漏洞比較簡單,可以修改加密流程,也可以簡單的刪除這個乘積。因此,在V7以及之后的版本中,取消了這個乘積數據,這樣對V7和V8版本的解密就只能依靠攻擊者給出的密鑰才能解密了。
以上是我根據舊版本Teslacrypt的解密代碼,了解到的一些漏洞信息。自己的密碼學比較菜,如有不妥,還希望各位給一點人生的經驗。