作者:Hcamael & 0x7F@知道創宇404實驗室
時間:2018年12月4日
英文版本:http://www.bjnorthway.com/978/
0x00 前言
近日,互聯網上爆發了一種名為 lucky 的勒索病毒,該病毒會將指定文件加密并修改后綴名為 .lucky。
知道創宇404實驗室的煉妖壺蜜罐系統最早于2018年11月10日就捕捉到該勒索病毒的相關流量,截止到2018年12月4日,該病毒的 CNC 服務器依然存活。
根據分析的結果可以得知 lucky 勒索病毒幾乎就是 Satan 勒索病毒,整體結構并沒有太大改變,包括 CNC 服務器也沒有更改。Satan 病毒一度變遷:最開始的勒索獲利的方式變為挖礦獲利的方式,而新版本的 lucky 勒索病毒結合了勒索和挖礦。
知道創宇404實驗室在了解該勒索病毒的相關細節后,迅速跟進并分析了該勒索病毒;著重分析了該病毒的加密模塊,并意外發現可以利用偽隨機數的特性,還原加密密鑰,并成功解密了文件,Python 的解密腳本鏈接: https://github.com/knownsec/Decrypt-ransomware。
本文對 lucky 勒索病毒進行了概要分析,并著重分析了加密流程以及還原密鑰的過程。
0x01 lucky 病毒簡介
lucky 勒索病毒可在 Windows 和 Linux 平臺上傳播執行,主要功能分為「文件加密」、「傳播感染」與「挖礦」。
文件加密
lucky 勒索病毒遍歷文件夾,對如下后綴名的文件進行加密,并修改后綴名為 .lucky:
bak,sql,mdf,ldf,myd,myi,dmp,xls,xlsx,docx,pptx,eps,
txt,ppt,csv,rtf,pdf,db,vdi,vmdk,vmx,pem,pfx,cer,psd
為了保證系統能夠正常的運行,該病毒加密時會略過了系統關鍵目錄,如:
Windows: windows, microsoft games, 360rec, windows mail 等等
Linux: /bin/, /boot/, /lib/, /usr/bin/ 等等
傳播感染
lucky 勒索病毒的傳播模塊并沒有做出新的特色,仍使用了以下的漏洞進行傳播:
1.JBoss反序列化漏洞(CVE-2013-4810)
2.JBoss默認配置漏洞(CVE-2010-0738)
3.Tomcat任意文件上傳漏洞(CVE-2017-12615)
4.Tomcat web管理后臺弱口令爆破
5.Weblogic WLS 組件漏洞(CVE-2017-10271)
6.Windows SMB遠程代碼執行漏洞MS17-010
7.Apache Struts2遠程代碼執行漏洞S2-045
8.Apache Struts2遠程代碼執行漏洞S2-057
挖礦
該勒索病毒采用自建礦池地址:194.88.105.5:443,想繼續通過挖礦獲得額外的收益。同時,該礦池地址也是 Satan 勒索病毒變種使用的礦池地址。
運行截圖

0x02 病毒流程圖
lucky 勒索病毒的整體結構依然延續 Satan 勒索病毒的結構,包括以下組件:
預裝載器:fast.exe/ft32,文件短小精悍,用于加載加密模塊和傳播模塊
加密模塊:cpt.exe/cry32,加密模塊,對文件進行加密
傳播模塊:conn.exe/conn32,傳播模塊,利用多個應用程序漏洞進行傳播感染
挖礦模塊:mn32.exe/mn32,挖礦模塊,連接自建礦池地址
服務模塊:srv.exe,在 windows 下創建服務,穩定執行
流程圖大致如下:

lucky 勒索病毒的每個模塊都使用了常見的殼進行加殼保護,比如 UPX,MPRESS,使用常見的脫殼軟件進行自動脫殼即可。
0x03 加密流程
對于一個勒索病毒來說,最重要的就是其加密模塊。在 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 為預設的字符串序列,其值為:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
4.generate_session()
加密模塊中使用該函數為每個用戶生成一個標識,用于區分用戶;其仍然使用隨機數從預設的字符串序列中隨機選出字符,最后組成一個長度為 16 字節的 session,并存入到 C:\\Windows\\Temp\\Ssession 文件下。

其中 byte_56F800 字符串為:
ABCDEFGHIJPQRSTUVWdefghijklmnopqrstuvwx3456789
5.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,
txt,ppt,csv,rtf,pdf,db,vdi,vmdk,vmx,pem,pfx,cer,psd
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,通知用戶遭到了勒索軟件加密。
加密前后文件對比:

0x04 密鑰還原
在討論密鑰還原前,先來看看勒索病毒支付后流程。
如果作為一個受害者,想要解密文件,只有向攻擊者支付 1BTC,并把被 RSA 算法打包后的 AES 密鑰提交給攻擊者,攻擊者通過私鑰解密,最終返回明文的 AES 密鑰用于文件解密;可惜的是,受害者即便拿到密鑰也不能立即解密,lucky 勒索病毒中并沒有提供解密模塊。
勒索病毒期待的解密流程:

那么,如果能直接找到 AES 密鑰呢?
在完整的分析加密過程后,有些的小伙伴可能已經發現了細節。AES 密鑰通過 generate_key() 函數生成,再來回顧一下該函數:

利用當前時間戳作為隨機數種子,使用隨機數從預設的字符串序列中選取字符,組成一個長度為 60 字節的密鑰。
隨機數=>偽隨機數
有過計算機基礎的小伙伴,應該都知道計算機中不存在真隨機數,所有的隨機數都是偽隨機數,而偽隨機數的特征是「對于一種算法,若使用的初值(種子)不變,那么偽隨機數的數序也不變」。所以,如果能夠確定 generate_key() 函數運行時的時間戳,那么就能利用該時間戳作為隨機種子,復現密鑰的生成過程,從而獲得密鑰。
確定時間戳
爆破
當然,最暴力的方式就是直接爆破,以秒為單位,以某個有標志的文件(如 PDF 文件頭)為參照,不斷的猜測可能的密鑰,如果解密后的文件頭包含 %PDF(PDF 文件頭),那么表示密鑰正確。
文件修改時間
還有其他的方式嗎?文件被加密后會重新寫入文件,所以從操作系統的角度來看,被加密的文件具有一個精確的修改時間,可以利用該時間以確定密鑰的生成時間戳:

如果需要加密的文件較多,加密所花的時間較長,那么被加密文件的修改時間就不是生成密鑰的時間,應該往前推移,不過這樣也大大減少了猜測的范圍。
利用用戶 session
利用文件修改時間大大減少了猜測的范圍;在實際測試中發現,加密文件的過程耗時非常長,導致文件修改時間和密鑰生成時間相差太多,而每次都需要進行檢查密鑰是否正確,需要耗費大量的時間,這里還可以使用用戶 session 進一步縮小猜測的范圍。
回顧加密過程,可以發現加密過程中,使用時間隨機數生成了用戶 session,這就成為了一個利用點。利用時間戳產生隨機數,并使用隨機數生成可能的用戶 session,當找到某個 session 和當前被加密的用戶 session 相同時,表示該時刻調用了 generate_session() 函數,該函數的調用早于文件加密,晚于密鑰生成函數。

找到生成用戶session 的時間戳后,再以該時間為起點,往前推移,便可以找到生成密鑰的時間戳。
補充:實際上是將整個還原密鑰的過程,轉換為尋找時間戳的過程;確定時間戳是否正確,盡量使用具有標志的文件,如以 PDF 文件頭 %PDF 作為明文對比。
還原密鑰
通過上述的方式找到時間戳,利用時間戳就可以還原密鑰了,偽代碼如下:
sequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
key = []
timestamp = 1542511041
srand(timestamp)
for (i = 0; i < 60; i++) {
key[i] = sequence[rand() % 0x3E]
}
文件解密
拿到了 AES 密鑰,通過 AES_ECB 算法進行解密文件即可。
其中注意兩點:
1. 解密前先去除文件末尾的內容(由 RSA 算法打包的密鑰內容)
2. 針對文件大小做不同的解密處理。
0x05 總結
勒索病毒依然在肆掠,用戶應該對此保持警惕,雖然 lucky 勒索病毒在加密環節出現了漏洞,但仍然應該避免這種情況;針對 lucky 勒索病毒利用多個應用程序的漏洞進行傳播的特性,各運維人員應該及時對應用程序打上補丁。
除此之外,知道創宇404實驗室已經將文中提到的文件解密方法轉換為了工具,若您在此次事件中,不幸受到 lucky 勒索病毒的影響,可以隨時聯系我們。
References:
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
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/758/