2017年6月16日 星期五

Wannacry病毒深度技術分析(四)-佈局篇



分析完了MS17 010漏洞
我們把重心再回到Wannacry本身上面
這一次要分析的是它的加密和勒索前的佈局部分
這部分是隨著Wannacry的變種變化最多的
在此我們以初版的Wannacry為主來研究

第一篇文章
我們提到了Wannacry執行到一個
RunRansomware函式
其中CreateMssecsvc是感染與傳播部分
已經在前幾篇分析完畢
現在我們要回到這裡
從另一個函式ExtractTasksche開始
目前的分析位置
mssecsvc.exe在這裡首先載入Kernel32.dll
以找出自己需要的函式
如下圖,他們為:

CreatProcess
CreateFile
WriteFile
Closehandle


接著mssecsvc.exe呼叫FindResource把Tasksche.exe的內容找出來
先把已經存在於C:\windows\底下的Tasksche.exe改名成C:\Windows\qeriuwjhrf


我們可以用PE工具打開mssecsvc.exe找出裡面的Resource


英文的R為微軟SDK中的macro MAKEINTRESOURCE(0x727)的結果

然後把Load好的Resource用剛才得到的WriteFile API 
把內容寫到C:\Windows\Tasksche.exe中
這樣子作的目的是防止有人先用虛構的Tasksche.exe來防止Wannacry寫入該檔案


從上面的程式碼可以看到
在寫完檔案的同時就呼叫CreateProrcess把Tasksche.exe叫了起來
mssecsvc.exe的任務到此就結束了

勒索程式Tasksche.exe

Tasksche.exe是勒索程式的主要安裝包
勒索程式的其他雜項部分
幾乎都可以在這個exe裡面見到
之後用到他們時我們會個別介紹


偽裝自身

Tasksche.exe把自己的檔案資訊改成微軟Diskpart程式的樣子
企圖蒙混好奇檢查檔案資訊的受害者


啟動

Taskche.exe啟動前會先檢查是否有帶參數啟動
如果沒有的話就把自己註冊成系統服務
以便常駐於系統內


註冊系統的程式碼和mssecsvc.exe差不多
產生一個隨機的Key在註冊表的啟動區
我這裡就不贅述了,只附上結果,如下圖


tasksche.exe接著為了之後的工作方便
會在系統的註冊表設定Working Directory


緊接著tasksche.exe把它resource裡的檔案找了出來
用的仍然是和前面一樣的方式-FindResource
代號是0x80A,MAKEINTRESOURCE(0x80A)即為XIA


使用PE工具打開tasksche.exe
我們即可看到XIA裡的資源
從開頭的magic number 「PK
我們可以合理的推測它是一個ZIP壓縮檔


事實上你甚至可以直接用7z直接解開tasksche.exe
只不過解開需要密碼
要找到密碼很簡單,用很多方式都可以找到
下圖用Immunity動態跟蹤便可以清楚看到密碼為「WNcry@2ol7


解開後的tasksche.exe如右圖
這裡先簡單描述它們的用途
之後用到他們時會再另外作說明

Tasksche.exe加密包說明

檔案
描述
\msg
各種語言版本的勒索提示訊息
b.wnry
bmp圖檔桌布,提示受害者檔案被加密
c.wnry
Wannacry的設定檔
r.wnry
純文字檔,提示勒索Q&A
s.wnry
Tor客戶端的壓縮檔
t.wnry
Wannacry真正的加密模組
taskdl.exe
刪除加密過程中的暫存檔
taskse.exe
Wannacry的提權程式
u.wnry
就是@WanaDecryptor@.exe
f.wnry
加密過程中出現,可免費解密的檔案列表

解開檔案後
tasksche.exe會讀取c.wnry的內容


c.wnry的內容如下:


gx7ekbenv2riucmf.onion, 57g7spgrzlojinas.onion, xxlvbrloxvriy2c5.onion, 76jdd2ir2embyv47.onion, cwwnhwhlz52maqm7.onion 都是暗網的地址


Tor客戶端可以藉這些網址連到作者在暗網架設的伺服器
作者藉此以追蹤感染的狀況,並把解密的key送到這裡

至於https://dist.torproject.org/torbrowser/6.5.1/tor-win32-0.2.9.10.zip
感覺是前一版Wannacry的設定
畢竟這版本的Wannacry Tor客戶都端已經內建了

讀取到設定檔後
tasksche.exe會把三個隨機字串挑一個寫到c.wnry裡


這三個隨機字串都是Wannacry作者的比特幣(BTC)地址


tasksche.exe接著為了工作的隱蔽性
會執行命令「attrib +h .」以隱藏自身目錄


接著執行命令「icacls . /grant Everyone:F /T /C /Q」

給予Wannacry底下所有的目錄和檔案所有權限,如上圖

為了讓tasksche.exe擁有加解密能力
tasksche.exe動態載入advapi32.dll以取得加密相關API的位址,如下圖


同時也載入kernel32.dll

以取得讀寫/搬移/刪除 檔案的API,如下圖


得到ImportKey函式的地址後
tasksche.exe把程式自帶的RSA2 public key import進記憶體中
長度為1172bytes,如下圖


然後tasksche.exe開始解密t.wnry
一開始先解析t.wnry的標頭,確定檔案格式正確
如檔頭一開始是不是「WANACRY!」、Private Key size是不是0x100、檔案大小不能大於0x6400000等等


上述檢查都通過了之後,tasksche.exe開始解密Private Key,即進入DecryptPrivateKey函式


這個函式的功能就如同命名一樣直觀
呼叫Windows API的CryptDecrypt把從t.wnry身上讀取到的Private Key給解密,如上圖


解密結束後再對解密後的Key作KeyExpansion
然後進行真正的AES解密動作,其實這就是AES-128-CBC加解密的過程,如上圖

解密後的t.wnry其實是個DLL,它就是真正的加密模組
對tasksche.exe動態跟蹤它解密t.wnry的瞬間
便能看到taskseche內部的記憶體內多出個PE檔案,如下圖


tasksche.exe把它解密後
會將它正式載入記憶體,如下圖


載入記憶體後,tasksche.exe取得t.wnry的TaskStart函式地址,
然後呼叫它
至此程式的執行就轉移到了解密的t.wnry上了,如下圖


這裡很特別的是Wannacry不直接用Windows API載入解密後t.wnry
而是自己寫程式碼載入,如GetProcess、LoadLibrary和FreeLibrary都是自己寫的
應該是為了避免被防毒軟體偵測到,也增加資訊安全人員跟蹤原始碼的難度
目前的分析位置

t.wnry的加密準備工作

解密後的t.wnry在執行時
和最外層的Launcher.dll一樣
都不會存到硬碟後執行
而是直接在行程的記憶體內部執行的

在t.wnry開始加密前

它會檢查系統的 Mutex-Global\MsWinZonesCacheCounterMutexA 是否存在
如果是的話代表程式正在運作,當即退出執行
如下圖


有的人會藉由事先建立這Mutex來阻止Wannacry的加密動作
不過這應該防不了其他變種

接著檢查自己的行程是否為System帳戶
檢查結果決定了要不要執行taskse.exe,如下圖


接著初始化需要的API
先從加解密的Crypt系列開始
從advapi32.dll中撈出CryptImportKey、Cryptencrypt...等等
如下圖


再來是讀寫檔案系列的API
從kernel32.dll中撈出來
這部分和tasksche.exe的作法幾乎是一樣的,連程式碼都雷同
如下圖


如果沒找到存在的Mutex,那當然自己要試著建一個啦
建好Mutex之後t.wnry設定他讓所有人都可讀取
方便判斷是否重複執行,如下圖


t.wnry同時會判斷00000000.dky是否存在,如果00000000.dky存在
則拿它與00000000.pky配對檢查這兩把key是否合法,如下圖


如果上述兩個檢查條件-新建Mutex和00000000.dky存在的檢查都失敗
Wannacry會認為加密任務已經完成
於是會先另外開一條執行緒SeTaskscheAutoStart
然後自己掛著讓執行緒去執行,如下圖


這條執行緒會建立一個無窮迴圈,每隔30秒執行一次
除了透過提權程式Taskse.exe來執行@WanaDecryptor.exe@ (u.wnry) 外
還會把tasksche.exe的執行命令寫到HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
以便重開機後再次進行加密,如下圖


反之,如果上述檢查通過的話
會先從t.wnry本身載入一個RSA Public Key
然後呼叫CryptoGenerateKey產生一組RSA加密算法的Session Key
產生完畢後,把這組Key的Public部分透過ExportKey2File去呼叫CryptExportKey
把內容寫到00000000.pky裡
同時把這組Key的Private Key部分寫到00000000.eky裡
完整程式碼如下圖


00000000.pky即為受害者的Session public key,00000000.eky則為他的Pair
每個受害者的Session public/private key pair都是唯一的

接著t.wrny會檢查00000000.res是否能正常讀取,不能則刪除它
然後呼叫CryptGenRandom產生的隨機8個bytes,如下圖


這8bytes的內容之後會寫入00000000.res中


緊接著t.wnry會一口氣生出5個執行緒
這5個執行緒每個都有個別的用途,如下圖:


LoopOverWriteResFile函式會每隔25秒就把目前加密的檔案總數、總容量、目前時間等受害者資訊
寫到00000000.res中,如下圖


LoopCheckEncryptFileValid則是每5秒就檢查00000000.dky和00000000.pky的Key配對是否合法

其實它就是呼叫前面分析過的函式IsDecodeKeyValid,如下圖


Key配對的檢查結果會存到全域變數gDecodeKeyInvalid裡
t.wnry在加密的過程中三不五時的就會把它拿出來檢查

EnumAllDrive會每隔3秒就列舉受害者電腦裡所有的磁碟代號
並檢查是否有新的裝置插入如USB等
如果有的話,就開新的執行緒加密它!如下圖


加密後,EnumAllDrive會試著抹除原始檔案的痕跡以防止使用者用硬碟救援軟體恢復檔案
在這裡講的話大家會比較沒感覺,所以之後的加密篇我們再來分析他

RunTaskdl執行緒會每隔30秒就執行taskdl.exe
刪除已加密的原始檔案,如下圖
這是作者設計的保險機制,以防檔案刪不乾淨


最後一個SetTaskscheAutoStart執行緒,一樣是每30秒執行一次
和前面檢查Mutex和00000000.dky失敗所執行的函式是相同的
這裡把程式碼裡面的RunTaskse拿出來講好了
Taskse.exe前面已經提過是提權程式
RunTaskse函式會檢查目前的使用者是否有管理者權限或是不是SYSTEM帳號
不是的話,就執行taskse.exe來啟動@WanaDecryptor@.exe,如下圖


我們會在之後的勒索篇裡分析taskse.exe啟動的WanaDecryptor的用途

t.wnry的加密佈局

t.wnry在執行加密任務前仍然有一系列的佈局要做
但離真正的加密僅有一步之遙
首先它會把前面提到的u.wnry拷貝成@WanaDecryptor@.exe」
然後寫一個Batch檔案
內容是用VB script把@WanaDecryptor@.exe做成一個捷徑 (Link)
再去執行這個Batch檔做成@WanaDecryptor@.exe的捷徑,如下圖所示


再來t.wnry會讀取r.wnry的內容
並把三個字串變數替換掉:付款比特幣金額、帳戶和「解密程式」檔名
然後寫成新的檔案@Please_Read_Me@.txt」,如下圖


下圖是r.wnry和@Please_Read_Me@.txt的比較


由這些地方都被做成變數可知,勒索軟體有越來越模組化的傾向
事實上現在有的勒索病毒甚至都上雲端SaaS化了...
這樣的趨勢就是越來越多欠缺背景知識的人只要他們有心,都能製作勒索病毒

Wannacry分析系列文:
Wannacry病毒深度技術分析(一)-傳播篇
Wannacry病毒深度技術分析(二)-系統漏洞篇
Wannacry病毒深度技術分析(三)-漏洞利用篇
Wannacry病毒深度技術分析(四)-佈局篇
Wannacry病毒深度技術分析(五)-加密篇
Wannacry病毒深度技術分析(六)-勒索篇