1、 xxxx接收到圖片后,不會明文存儲在磁盤,因為不安全,都是加密后存儲在特定目錄的,截圖如下(請忽略兩個jpg的文件,這是我為了做測試人為添加的,xxxx原始是不會存這些圖片的):
可以看到圖片都是以dat格式存儲的。用010editor打開:全是沒意義的數據,圖片的頭信息完全找不到!
既然都是加密存儲的,在xxxx軟件中是怎么看到圖片的了? 換句話說,xxxx軟件都是怎么解密這些圖片的了?
2、正式介紹解密之前,先做個位運算知識的鋪墊:異或 XOR
(1)兩個bit做XOR,如果不同那么結果為1;如果相同結果為0; 打個比方:男女在一起才能生娃,同性在一起是不行的!也就是:1^1=0, 0^0=0, 但是1^0=1;
(2)XOR最大的作用: 對稱加密! 比如明文是0xA=1010, 密鑰是0xB=1011,那么密文=A^B=0x1; 解密時,用密鑰^密文即可,這里便是0x1^B=A,成功得到明文;
(3)XOR最大的特性:明文、密鑰、密文三個的關系像個三角形,其中任意兩個異或,都能得到第三個!比如上面用加密的算法是A^B=0x1;解密的算法是B^0x1=A; 但是用明文A^密文0x1也能得到密鑰B; 這個特性有啥用了:
- 明文、密鑰、密文只能對外公布一個,一般公開密文(這不廢話么?)
- 曾經有人利用該特性找到了windwos PG保護的密鑰(用IDA靜態分析找到明文,windbg動態分析找到密文,兩個異或就找到了密鑰)
- 也有人利用這個特性做PE文件保護(原理和PG保護類似),PE文件的代碼和數據都加密存儲,直到執行前才在內存解密得到真正的代碼
- 密文和明文大小是一樣的(后面會根據這個猜圖片的加密方式)
(4)XOR對稱加密的另一大特點:計算方式簡單! XOR本質是位運算,CPU內部的硬件電路是可以直接實現的,一條XOR的匯編指令就能完成計算,理論上只需要1ns的時間(這里擴展一下:其實CPU內部的加減乘除都是通過XOR實現的);只要key的長度足夠,短時間內想要通過暴力窮舉是不可能的。比如key的長度是1024bit,那么key就有2的1024次方個。和同為對稱加密的AES算法比,效率高太多了!所以用XOR加密是非常廣泛的!
(5)XOR最后一個優點:因為是按照位計算的,所以計算的時間和復雜度只和位數相關,和數據實際數值無關!這么做的好處是啥了? 防止側信道攻擊!比如只要密碼位數一定,不論是數字,還是字母,還是特殊符號,解密的時間都一樣,不會因為字符不同而導致時間不同!
3、 之前找過xxxx接受消息的call,這里繼續下斷點,然后再手機上通過文件助手發條消息,斷下來了:
這里已經能看到消息的部分內容了,但OD顯示的長度有限,看不全,所以這里需要CE輔助:注意地址的配置,這里就要選Unicode了
下面就是圖片的數據格式:是xml的;從字段的名稱看,有AES密鑰、cdn的密鑰、cdn的url、md5等信息;圖片還有大圖和midimg(從字面猜測應該是中等大小的圖片,大概率是在聊天窗展示的那種);可惜的是沒有找到圖片保存的名字和位置;
<?xml version="1.0"?> <msg> <img aeskey="7a40664635a1aac64816c8deff4a39b0" encryver="0" cdnthumbaeskey="7a40664635a1aac64816c8deff4a39b0" cdnthumburl="304f020100044830460201000204513ea50e02033d14ba02047851fb3a020460376bb60421777875706c6f61645f66696c6568656c7065723730375f31363134323434373838020401090a020201000400" cdnthumblength="3967" cdnthumbheight="90" cdnthumbwidth="120" cdnmidheight="0" cdnmidwidth="0" cdnhdheight="0" cdnhdwidth="0" cdnmidimgurl="304f020100044830460201000204513ea50e02033d14ba02047851fb3a020460376bb60421777875706c6f61645f66696c6568656c7065723730375f31363134323434373838020401090a020201000400" length="1" md5="5733041f60a14ce9f4d75be1bb49a213" hevc_mid_size="176859" /> </msg>
繼續往下,終於找到了圖片存放的位置和名字,如下:
用同樣的方法再CE里面能看到圖片加密后bat文件的全稱和存放路徑(就是剛才說的那個目錄):
根據bat文件的名字和路徑,把加密前后的圖片都放進010editor中對比:加密后的文件已經面目全非,連圖片頭信息都沒了,不過加密后文件有個最大的特征:大小和加密前完全一樣!
那么有沒有可能用XOR來加密的了? 怎么驗證了?
4、這里就要用到剛才提到的XOR特點:密文、密鑰、明文三者像三角形的關系其中任意兩個異或,都能得到第三個!明文圖片的第一個字節是FF,密文第一個字節是B3,FF^B3=4C,那么4C是不是key了? 為了邏輯嚴密,需要交叉驗證:第二個明文是D8,這時已經知道key=4C了,D8^4C=0x94,居然剛好等於第二個密文,4C就是key看來沒錯了!為了謹慎,我們再用密文交叉驗證試試:第三個密文是B3,那么解密算法就是B3^4C=0xFF,剛好等於第三個明文!此時,通過三次明文、密文、密鑰的交叉驗證,實錘了加密算法是XOR、密鑰是4C!
最后解密的POC如下:
#include <stdio.h> #include <string.h> #include <fstream> #include <iostream> using namespace std; const char* filename = "decryptPic\\07a00a9454f983ca808cd1a6028d581c.dat"; int main(int argc, char** argv) { std::ifstream streamReader(filename, std::ios::binary); //以二進制的形式讀取文件 streamReader.seekg(0, std::ios::end);//跳轉到尾部 unsigned filesize = streamReader.tellg();//得到文件大小 char* _data = new char[filesize]; char* _decrypt = new char[filesize]; printf("length is:%d\n", filesize); streamReader.seekg(0, std::ios::beg);//跳轉到開始 streamReader.read(_data, filesize); streamReader.close(); for (int i=0;i< filesize;i++) { //std::cout << _data[i]; /* //https://www.coder.work/article/2223646 參考這里,打印的時候必須轉成(unsigned char),否則默認會以4字節、也就是unsinged int打印 */ //printf("%1x",(unsigned char)_data[i]); _decrypt[i] = _data[i] ^ 0x4c;//解密 //printf("%1x", (unsigned char)_decrypt[i]);//從010editor看是對的 } std::ofstream ofs; ofs.open("decryptPic\\decript.jpg", ios::out | ios::app | ios::binary, _SH_DENYNO); ofs.write(_decrypt, filesize); ofs.close(); return 0;
效果:成功解密,生成decrypt.jpg圖片!
以后寫勒索病毒,完全可以復用這段代碼對文件加密,然后讓對方用比特幣支持,想想都刺激.......