作者:Hcamael & 0x7F@知道創宇404實驗室
時間:2018年12月4日
近日,網際網路上爆發了一種名為 lucky 的勒索病毒,該病毒會將指定文件加密並修改後綴名為 .lucky。
知道創宇404實驗室的煉妖壺蜜罐系統最早於2018年11月10日就捕捉到該勒索病毒的相關流量,截止到2018年12月4日,該病毒的 CNC 伺服器依然存活。
根據分析的結果可以得知 lucky 勒索病毒幾乎就是 Satan 勒索病毒,整體結構並沒有太大改變,包括 CNC 伺服器也沒有更改。Satan 病毒一度變遷:最開始的勒索獲利的方式變為挖礦獲利的方式,而新版本的 lucky 勒索病毒結合了勒索和挖礦。
知道創宇404實驗室在了解該勒索病毒的相關細節後,迅速跟進並分析了該勒索病毒;著重分析了該病毒的加密模塊,並意外發現可以利用偽隨機數的特性,還原加密密鑰,並成功解密了文件,Python 的解密腳本連結: https://github.com/knownsec/Decrypt-ransomware。
本文對 lucky 勒索病毒進行了概要分析,並著重分析了加密流程以及還原密鑰的過程。
lucky 勒索病毒可在 Windows 和 Linux 平臺上傳播執行,主要功能分為「文件加密」、「傳播感染」與「挖礦」。
「文件加密」
lucky 勒索病毒遍歷文件夾,對如下後綴名的文件進行加密,並修改後綴名為 .lucky:
bak,sql,mdf,ldf,myd,myi,dmp,xls,xlsx,docx,pptx,eps,為了保證系統能夠正常的運行,該病毒加密時會略過了系統關鍵目錄,如:
Windows: windows, microsoft games, 360rec, windows mail 等等「傳播感染」
lucky 勒索病毒的傳播模塊並沒有做出新的特色,仍使用了以下的漏洞進行傳播:
JBoss反序列化漏洞(CVE-2013-4810)
JBoss默認配置漏洞(CVE-2010-0738)
Tomcat任意文件上傳漏洞(CVE-2017-12615)
Tomcat web管理後臺弱口令爆破
Weblogic WLS 組件漏洞(CVE-2017-10271)
Windows SMB遠程代碼執行漏洞MS17-010
Apache Struts2遠程代碼執行漏洞S2-045
Apache Struts2遠程代碼執行漏洞S2-057
「挖礦」
該勒索病毒採用自建礦池地址:194.88.105.5:443,想繼續通過挖礦獲得額外的收益。同時,該礦池地址也是 Satan 勒索病毒變種使用的礦池地址。
運行截圖:
lucky 勒索病毒的整體結構依然延續 Satan 勒索病毒的結構,包括以下組件:
預裝載器:fast.exe/ft32,文件短小精悍,用於加載加密模塊和傳播模塊流程圖大致如下:
lucky 勒索病毒的每個模塊都使用了常見的殼進行加殼保護,比如 UPX,MPRESS,使用常見的脫殼軟體進行自動脫殼即可。
對於一個勒索病毒來說,最重要的就是其加密模塊。在 lucky 勒索病毒中,加密模塊是一個單獨的可執行文件,下面對加密模塊進行詳細的分析。(以 Windows 下的 cpt.exe 作為分析樣例)
1. 脫去upx
cpt.exe 使用 upx 進行加殼,使用常見的脫殼工具即可完成脫殼。
2. 加密主函數
使用 IDA 加載脫殼後的 cpt.exe.unp,在主函數中有大量初始化的操作,忽略這些操作,跟入函數可以找到加密邏輯的主函數,下面對這些函數進行標註:
generate_key: 生成 60 位隨機字符串,用於後續加密文件。
wait_sleep: 等待一段時間。
generate_session: 生成 16 位隨機字符串,作為用戶的標誌(session)。
lucky_crypto_entry: 具體加密文件的函數。
send_info_to_server: 向伺服器報告加密完成。
大致的加密流程就是函數標註的如此,最後寫入一個文件 c:\\_How_To_Decrypt_My_File_.Dic,通知用戶遭到了勒索軟體加密,並留下了比特幣地址。
3. generate_key()
該函數是加密密鑰生成函數,利用隨機數從預設的字符串序列中隨機選出字符,組成一個長度為 60 字節的密鑰。
byte_56F840 為預設的字符串序列,其值為:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567894. generate_session()
加密模塊中使用該函數為每個用戶生成一個標識,用於區分用戶;其仍然使用隨機數從預設的字符串序列中隨機選出字符,最後組成一個長度為 16 字節的 session,並存入到 C:\\Windows\\Temp\\Ssession 文件下。
其中 byte_56F800 字符串為:
ABCDEFGHIJPQRSTUVWdefghijklmnopqrstuvwx34567895. lucky_crypto_entry()
文件名格式該函數為加密文件的函數入口,提前拼接加密文件的文件名格式,如下:
被加密的文件的文件名格式如下:
[nmare@cock.li]filename.AiVjdtlUjI9m45f6.lucky其中 filename 是文件本身的名字,後續的字符串是用戶的 session。
通知伺服器在加密前,還會首先向伺服器發送 HTTP 消息,通知伺服器該用戶開始執行加密了:
HTTP 數據包格式如下:
GET /cyt.php?code=AiVjdtlUjI9m45f6&file=1&size=0&sys=win&VERSION=4.4&status=begin HTTP/1.1文件篩選在加密模塊中,lucky 對指定後綴名的文件進行加密:
被加密的後綴名文件包括:
bak,sql,mdf,ldf,myd,myi,dmp,xls,xlsx,docx,pptx,eps,6. AES_ECB 加密方法
lucky 使用先前生成的長度為 60 字節的密鑰,取前 32 字節作為加密使用,依次讀取文件,按照每 16 字節進行 AEC_ECB 加密。
除此之外,該勒索病毒對於不同文件大小有不同的處理,結合加密函數的上下文可以得知,這裡我們假設文件字節數為 n:
對於文件末尾小於 16 字節的部分,不加密
若 n > 10000000 字節,且當 n > 99999999 字節時,將文件分為 n / 80 個塊,加密前 n / 16 個塊
若 n > 10000000 字節,且當 99999999 <= n <= 499999999 字節時,將文件分為 n / 480 個塊,加密前 n / 16 個塊
若 n > 10000000 字節,且當 n > 499999999 字節時,將文件分為 n / 1280 個塊,加密前 n / 16 個塊
對於每個文件在加密完成後,lucky 病毒會將用於文件加密的 AES 密鑰使用 RSA 算法打包並添加至文件末尾。
7. 加密完成
在所有文件加密完成後,lucky 再次向伺服器發送消息,表示用戶已經加密完成;並在 c:\\_How_To_Decrypt_My_File_.Dic,通知用戶遭到了勒索軟體加密。
加密前後文件對比:
在討論密鑰還原前,先來看看勒索病毒支付後流程。
如果作為一個受害者,想要解密文件,只有向攻擊者支付 1BTC,並把被 RSA 算法打包後的 AES 密鑰提交給攻擊者,攻擊者通過私鑰解密,最終返回明文的 AES 密鑰用於文件解密;可惜的是,受害者即便拿到密鑰也不能立即解密,lucky 勒索病毒中並沒有提供解密模塊。
勒索病毒期待的解密流程:
那麼,如果能直接找到 AES 密鑰呢?
在完整的分析加密過程後,有些的小夥伴可能已經發現了細節。AES 密鑰通過 generate_key() 函數生成,再來回顧一下該函數:
利用當前時間戳作為隨機數種子,使用隨機數從預設的字符串序列中選取字符,組成一個長度為 60 字節的密鑰。
1. 隨機數=>偽隨機數
有過計算機基礎的小夥伴,應該都知道計算機中不存在真隨機數,所有的隨機數都是偽隨機數,而偽隨機數的特徵是「對於一種算法,若使用的初值(種子)不變,那麼偽隨機數的數序也不變」。所以,如果能夠確定 generate_key() 函數運行時的時間戳,那麼就能利用該時間戳作為隨機種子,復現密鑰的生成過程,從而獲得密鑰。
2. 確定時間戳
爆破當然,最暴力的方式就是直接爆破,以秒為單位,以某個有標誌的文件(如 PDF 文件頭)為參照,不斷的猜測可能的密鑰,如果解密後的文件頭包含 %PDF(PDF 文件頭),那麼表示密鑰正確。
文件修改時間還有其他的方式嗎?文件被加密後會重新寫入文件,所以從作業系統的角度來看,被加密的文件具有一個精確的修改時間,可以利用該時間以確定密鑰的生成時間戳:
如果需要加密的文件較多,加密所花的時間較長,那麼被加密文件的修改時間就不是生成密鑰的時間,應該往前推移,不過這樣也大大減少了猜測的範圍。
利用用戶 session利用文件修改時間大大減少了猜測的範圍;在實際測試中發現,加密文件的過程耗時非常長,導致文件修改時間和密鑰生成時間相差太多,而每次都需要進行檢查密鑰是否正確,需要耗費大量的時間,這裡還可以使用用戶 session 進一步縮小猜測的範圍。
回顧加密過程,可以發現加密過程中,使用時間隨機數生成了用戶 session,這就成為了一個利用點。利用時間戳產生隨機數,並使用隨機數生成可能的用戶 session,當找到某個 session 和當前被加密的用戶 session 相同時,表示該時刻調用了 generate_session() 函數,該函數的調用早於文件加密,晚於密鑰生成函數。
找到生成用戶session 的時間戳後,再以該時間為起點,往前推移,便可以找到生成密鑰的時間戳。
補充:實際上是將整個還原密鑰的過程,轉換為尋找時間戳的過程;確定時間戳是否正確,儘量使用具有標誌的文件,如以 PDF 文件頭 %PDF 作為明文對比。
3. 還原密鑰
通過上述的方式找到時間戳,利用時間戳就可以還原密鑰了,偽代碼如下:
sequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
key = []
timestamp = 1542511041
srand(timestamp)
for (i = 0; i < 60; i++) {
key[i] = sequence[rand() % 0x3E]
}
4. 文件解密
拿到了 AES 密鑰,通過 AES_ECB 算法進行解密文件即可。
其中注意兩點:
解密前先去除文件末尾的內容(由 RSA 算法打包的密鑰內容)
針對文件大小做不同的解密處理。
勒索病毒依然在肆掠,用戶應該對此保持警惕,雖然 lucky 勒索病毒在加密環節出現了漏洞,但仍然應該避免這種情況;針對 lucky 勒索病毒利用多個應用程式的漏洞進行傳播的特性,各運維人員應該及時對應用程式打上補丁。
除此之外,知道創宇404實驗室已經將文中提到的文件解密方法轉換為了工具,若您在此次事件中,不幸受到 lucky 勒索病毒的影響,可以隨時聯繫我們。
🔗
參 考 鏈 接
tencent:
https://s.tencent.com/research/report/571.html
綠盟:
https://mp.weixin.qq.com/s/uwWTS_ta29YlYntaZN3omQ
深信服:
https://mp.weixin.qq.com/s/zA1bK1sLwaZsUvuOzVHBKg
Python 的解密腳本:
https://github.com/knownsec/Decrypt-ransomware
往 期 熱 門