利用勒索軟體Locky的漏洞來免疫系統

wyzsk發表於2020-08-19
作者: netwind · 2016/05/05 15:06

From:https://www.lexsi.com/securityhub/abusing-bugs-in-the-locky-ransomware-to-create-a-vaccine/?lang=en

0x00 簡介


在2009年,我們利用免疫系統的概念來保護工作站或者伺服器免受快速傳播的蠕蟲病毒Conficker的入侵。讓我們來看一下是否能把這一防禦概念用在勒索軟體Locky上。

下面我們將對系統進行一些小的修改,來打造一個免疫系統,在不需要使用者互動的情況下,部分或者完全地阻止惡意程式在執行的時候對系統造成的危害。很明顯,我們必須要讓“疾病”到來之前使免疫系統取得控制權.......

這些小的改動可以是一個特別的互斥體或者一個登錄檔鍵的建立或者一個簡單的系統引數的修改,但是這些改動不能對使用者造成任何不便。這裡有一個反例,Locky在開始執行的時候回檢查系統語言,它不會感染系統語言是俄語的系統:

p1

因此,把系統語言改為俄語可以免受其感染,但是這樣會給很多人造成使用上的不方便。

0x01 利用訪問控制列表ACL 來阻止Locky登錄檔項的建立


在檢查完語言後,Locky會嘗試建立登錄檔項HKCU\Software\Locky ,如果建立失敗,它就會立即終止。

p2

當這個鍵被建立以前我們利用ACLs來阻止任何人開啟這個鍵,這樣系統就得到了免疫。

p3

0x02 登錄檔鍵completed 的值


Locky會檢查登錄檔項HKCU\Software\Locky的鍵,查詢ID(被感染機器系統標識),pubkey(伺服器上的公鑰,後面詳述), paytext(以它指定的語言格式,顯示給使用者的文字) 和completed值。最後一項的值代表著對使用者系統的加密過程是否結束。按照Locky的定義:如果completed被設定為1,同時id值為正確的系統識別符號,那麼它將停止執行。

p4

這個識別符號生成的演算法比較簡單,我們在測試機器上產生的結果如下:

  1. GetWindowsDirectoryA() : C:\WINDOWS
  2. GetVolumeNameForVolumeMountPointA(C:\WINDOWS) : \\?\Volume{ b17db400-ae8a-11de-9cee-806d6172696f}
  3. md5({b17db400-ae8a-11de-9cee-806d6172696f}) : 1d9076e6fd853ab665d25de4330fee06
  4. 把上面的結果裡字母轉為大寫,並取前16位: 1D9076E6FD853AB6

建立這樣兩個鍵值,其中id的值隨著系統不同而不同,這樣就能阻止Locky加密系統檔案。

p5

0x03 破壞RSA金鑰


在加密檔案前,Locky會傳送一個HTTP POST請求到它的C&C伺服器,傳送明文如下:

#!bash
(gdb) hexdump 0x923770 0x65
88 09 0c da 46 fd 2c de 1d e8 e4 45 89 18 ae 46 |....F.,....E...F|
69 64 3d 31 44 39 30 37 36 45 36 46 44 38 35 33 |id=1D9076E6FD853|
41 42 36 26 61 63 74 3d 67 65 74 6b 65 79 26 61 |AB6&act=getkey&a|
66 66 69 64 3d 33 26 6c 61 6e 67 3d 66 72 26 63 |ffid=3&lang=fr&c|
6f 72 70 3d 30 26 73 65 72 76 3d 30 26 6f 73 3d |orp=0&serv=0&os=|
57 69 6e 64 6f 77 73 2b 58 50 26 73 70 3d 32 26 |Windows+XP&sp=2&|
78 36 34 3d 30                                  |x64=0

第一行是後面字串的MD5值,這個資料在傳送前會進行簡單的編碼:

p6

用類似的演算法可以解碼返回資料:

p7

這兩個演算法可以用幾行Python程式碼實現:

#!python
def encode(buff):
  buff = md5(buff).digest() + buff
  out = ""
  key = 0xcd43ef19
  for index in range(len(buff)):
    ebx = ord(buff[index])
    ecx = (ror(key, 5) - rol(index, 0x0d)) ^ ebx
    out += chr(ecx & 0xff)
    edx = (rol(ebx, index & 0x1f) + ror(key, 1)) & 0xffffffff
    ecx = (ror(index, 0x17) + 0x53702f68) & 0xffffffff
    key = edx ^ ecx
  return out
def decode(buff):
  out = ""
  key = 0xaff49754
  for index in range(len(buff)):
    eax = (ord(buff[index]) - index - rol(key, 3)) & 0xff
    out += chr(eax)
    key += ((ror(eax, 0xb) ^ rol(key, 5) ^ index) + 0xb834f2d1) & 0xffffffff
  return out

解碼後資料如下:

#!bash
00000000: 3af6 b4e2 83b1 6405 0758 854f b971 a80a :.....d..X.O.q..
00000010: 0602 0000 00a4 0000 5253 4131 0008 0000 ........RSA1....
00000020: 0100 0100 2160 3262 90cb 7be6 9b94 d54a ....!`2b..{....J
00000030: 45e0 b6c3 f624 1ec5 3f28 7d06 c868 ca45 E....$..?(}..h.E
00000040: c374 250f 9ed9 91d3 3bd2 b20f b843 f9a3 .t%.....;....C..
00000050: 1150 5af5 4478 4e90 0af9 1e89 66d2 9860 .PZ.DxN.....f..`
00000060: 4b60 a289 1a16 c258 3754 5be6 7ae3 a75a K`.....X7T[.z..Z
00000070: 0be4 0783 9f18 46e4 80f7 8195 be65 078e ......F......e..
00000080: de62 3793 2fa6 cead d661 e7e4 2b40 c92b .b7./....a..+@.+
00000090: 23c9 4ab3 c3aa b560 2258 849c b9fc b1a7 #.J....`"X......
000000a0: b03f d9b1 e5ee 278c bf75 040b 5f48 9501 .?....'..u.._H..
000000b0: 80f6 0cbf 2bb4 04eb a4b5 7e8d 30ad f4d4 ....+.....~.0...
000000c0: 70ba f8fb ddae 7270 9103 d385 359a 5a91 p.....rp....5.Z.
000000d0: 4995 9996 3620 3a12 168e f113 1753 d18b I...6 :......S..
000000e0: fdac 1eed 25a1 fa5c 0d54 6d9c dcbd 9cb7 ....%..\.Tm.....
000000f0: 4b8e 1228 8b70 be13 2bfd face f91a 8481 K..(.p..+.......
00000100: dc33 185e b181 8b0f ccbd f89d 67d3 afa8 .3.^........g...
00000110: c680 17d8 0100 6438 4eba a7b7 04b1 d00f ......d8N.......
00000120: c4fc 94ba                               ....

前16個位元組是後面位元組的MD5值,從偏移0x10處開始我們可以發現一個BLOB_HEADER結構:

  • type 0x06 = PUBLICKEYBLOB
  • version 0x02
  • 2 reserved bytes
  • ALG_ID 0xa400 = CALG_RSA_KEYX

這是一個RSA公鑰,因此下面是RSAPUBKEY結構:

  • magic RSA1 = public key
  • key size: 0x800 = 2048 bits
  • exponent 0x10001 = 65537
  • modulus 2160…94ba

這個結構(除去MD5 hash部分)儲存在上面提到的pubkey鍵值裡,如果這個值存在,並且是一個錯誤的值,那麼系統裡的檔案既不會被改名,也不會被加密。下圖中,把pubkey用一個NULL位元組填充,然後在測試機器上執行Locky,儘管Locky對txt格式的檔案具有針對性,但是這時候桌面上的檔案monfichier.txt 並沒有發生變化。

p8

另外如果pubkey是一個RSA 1024金鑰,檔案將會被改名,但是不會被加密(“ceci est un secret”,法語:“這是一個秘密”):

p9

0x04 獲取RSA 私鑰


Locky有另外一個設計漏洞:如果pubkey的值存在,Locky用pubkey加密檔案的時候不做任何驗證,允許我們強制使用我們自己掌控的一個公鑰來加密檔案,同時我們又知道這個公鑰相對應的私鑰。

下面的C程式碼將生產一個BLOB_HEADER 格式的RSA 2048 金鑰對,用來作為pubkey的值:

#!cpp
#define RSA2048BIT_KEY 0x8000000
CryptAcquireContext(&hCryptProv, "LEXSI", NULL, PROV_RSA_FULL, 0);
CryptGenKey(hCryptProv, AT_KEYEXCHANGE, RSA2048BIT_KEY|CRYPT_EXPORTABLE, &hKey);
// Public key
CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLen);
pbPublicKey = (BYTE *)malloc(dwPublicKeyLen);
CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbPublicKey, &dwPublicKeyLen);
hPublicKeyFile = CreateFile("public.key", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hPublicKeyFile, (LPCVOID)pbPublicKey, dwPublicKeyLen, &lpNumberOfBytesWritten, NULL);

// Private key
CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLen);
pbPrivateKey = (BYTE *)malloc(dwPrivateKeyLen);
CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKey, &dwPrivateKeyLen);
hPrivateKeyFile = CreateFile("private.key", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hPrivateKeyFile, (LPCVOID)pbPrivateKey, dwPrivateKeyLen, &lpNumberOfBytesWritten, NULL);

透過上述程式碼,我們生成一個.reg檔案,匯入登錄檔後,我們就可以強制Locky用我們設定的RSA公鑰。

讓我們仔細看看Locky是怎麼加密檔案的。當透過CryptAcquireContext()函式獲得一個指向PROV_RSA_AES結構的CSP(密碼庫)控制程式碼後,透過CryptImportKey()函式匯入pubkey鍵值裡包含有公鑰的二進位制資料,然後它把檔案按<id><16個隨機字元>.locky格式改名。它透過CryptGenRandom()函式來產生16個隨機字元:

p10

#!bash
(gdb) hexdump 0x009ef8a0 16
9d 86 d3 42 48 3a 45 04 1a cb 95 1c 77 90 8f 7c

這些位元組將會被複制到由CryptImportKey()函式匯入的BLOB_HEADER 結構的後面。

#!bash
(gdb) hexdump 0x009ef784 0x1c
08 02 00 00 0e 66 00 00 10 00 00 00 9d 86 d3 42 
48 3a 45 04 1a cb 95 1c 77 90 8f 7c
  • type 0x08 = PLAINTEXTKEYBLOB
  • version 0x02
  • 2 reserved bytes
  • ALG_ID = 0x660e = CALG_AES_128
  • key size = 0x10 bytes

這是一個AES-128 金鑰,然後GetSetKeyParam()函式會被呼叫,對其下斷,這裡我們可以獲得更多關於這個金鑰是如何被使用的資訊:

#!bash
(gdb) x/w $esp+4
0x9ef830: 0x00000004

(gdb) x/w *(int*)($esp+4+4)
0x9ef858: 0x00000002

記憶體值4在第二個引數裡,代表 KP_MODE ,可以允許自定義操作模式;記憶體值2在第三個引數裡,代表CRYPT_MODE_ECB。CryptEncrypt()函式用RSA公鑰來加密AES的金鑰,獲取到的結果如下:

#!bash
(gdb) hexdump 0x9ef8a0 256
64 ab 20 75 75 56 ae f4 af 20 7f 38 81 d7 d6 56 |d. uuV... .8...V|
22 89 92 6e 30 e0 61 d2 24 f0 a1 d6 2a 20 7f 6c |"..n0.a.$...* .l|
e0 10 cc ab 26 62 33 66 71 8d 93 4c 04 61 8a 9a |....&b3fq..L.a..|
86 e7 f4 75 58 ae 8a 68 96 1f a8 69 15 aa 2f e7 |...uX..h...i../.|
8b cd ca 2e b0 7b e1 89 5f 3e 65 61 4c 0b 43 5e |.....{.._>eaL.C^|
60 3b 17 48 0e d2 08 80 bd 4d e2 38 5b 51 c9 82 |`;.H.....M.8[Q..|
26 bf 94 8a 45 40 82 62 1e 88 42 aa 35 2a 3e 58 |&...E@.b..B.5*>X|
d2 7d 03 4d cd d4 e6 3b 7d 44 e9 5f dc 4d 1c 4b |.}.M...;}D._.M.K|
27 a9 39 0c 74 ed 46 97 60 af 3a 97 3f 89 33 28 |'.9.t.F.`.:.?.3(|
bf 27 67 57 f8 c5 4e 03 72 45 60 88 03 e5 11 98 |.'gW..N.rE`.....|
6f 49 af 92 72 69 db ec b7 c7 51 9a 05 f2 34 e0 |oI..ri....Q...4.|
17 e4 1b 7e c5 97 ff 3d 42 5d ff a5 69 a4 58 f8 |...~...=B]..i.X.|
3b bd 9f 84 6e a5 c7 81 4e 0e aa 5d 40 ff 06 01 |;...n...N..]@...|
e9 ee 3c e5 0f b2 b4 80 af 56 c5 b8 25 af 11 2e |..<......V..%...|
22 82 c1 f1 93 50 b2 a4 76 98 46 2e db 6c 76 bb |"....P..v.F..lv.|
b5 1e 70 44 41 e2 15 31 f9 02 7d 92 7a e5 73 17 |..pDA..1..}.z.s.|

這個資料和.locky檔案裡的一致。

然後Locky產生一個0x800位元組用0填充的緩衝空間,並且每行結尾用一位元組計數:

#!bash
(gdb) hexdump 0x00926598 0x800
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06 |................|
[...]
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7a |...............z|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7b |...............{|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7c |...............||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7d |...............}|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7e |...............~|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f |................|

然後CryptEncrypt()函式會使用上面產生的金鑰來對這些位元組進行AES-128-ECB加密,然後得到如下資料(它是用來進行異或加密的K):

#!bash
0x00926598: fc d3 bb 90 ac 1e 1e 6e 76 88 09 52 66 76 71 fc 
0x009265a8: d5 e2 07 fd a5 0c 02 50 d0 83 4e 9b 95 1c 0b 60 
0x009265b8: 3f c5 49 e5 df b2 05 56 bd ce eb f6 0d 70 9f 62 
0x009265c8: 98 f1 e8 b7 e2 8e d8 97 7f a1 83 14 2b db 82 98 
0x009265d8: 5b 4a 94 f7 fb 60 81 cd bb c7 a2 33 60 b1 c0 c7 
0x009265e8: 1c c5 c7 40 af 7c ea 4b e2 74 b0 32 c2 37 5e fa 
0x009265f8: cf 40 69 9b 81 92 b8 f1 77 79 83 97 32 19 75 a6 
[...]
0x009267c8: 96 9a 1d bd 9b 03 33 2f d5 e7 a7 fc ac fc 09 c9 
0x009267d8: f6 bd c5 73 ce 9e ce bc fd e4 ef 6f 06 dd 7d 15 
0x009267e8: 7d 95 e6 18 78 87 46 ba 75 5e 58 2e f8 ba 5c 14 
0x009267f8: 3d a9 f3 d3 af ef 0b 39 00 ae 0c 32 2b fd 37 eb 
0x00926808: 3f 3a 68 11 b8 d1 ae e7 28 40 0a 20 33 31 8f 7e 
0x00926818: c3 8f 55 2a 5f b5 31 26 02 41 d7 e3 84 c5 79 9b 
[...]

第一個要加密的元素就是檔名。Locky先分配0x230位元組空間,用0填充,

先把檔名複製進緩衝區,然後再與K進行異或加密。例如,如下我們觀察前3位元組:

#!bash
(gdb) p/x $edx // 加密KEY
$3 = 0x90bbd3fc
(gdb) hexdump $edi 64 //XOR 加密前
2a a1 1b d4 6d 00 6f 00 6e 00 66 00 69 00 63 00 |*...m.o.n.f.i.c.|
68 00 69 00 65 00 72 00 2e 00 74 00 78 00 74 00 |h.i.e.r...t.x.t.|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
(gdb) hexdump $edi 64 //XOR 加密後 #1
d6 72 a0 44 6d 00 6f 00 6e 00 66 00 69 00 63 00 |.r.Dm.o.n.f.i.c.|
68 00 69 00 65 00 72 00 2e 00 74 00 78 00 74 00 |h.i.e.r...t.x.t.|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

再看4-7位元組

#!bash
(gdb) p/x $eax // key 
$4 = 0x6e1e1eac
(gdb) hexdump $edi 64 // XOR 加密後#2
d6 72 a0 44 c1 1e 71 6e 6e 00 66 00 69 00 63 00 |.r.D..qnn.f.i.c.|
68 00 69 00 65 00 72 00 2e 00 74 00 78 00 74 00 |h.i.e.r...t.x.t.|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

以此類推,加密結果與加密後的.locky檔案一致。

然後Locky以同樣的方式來加密檔案內容,但是KEY 從偏移0x230處(本場景中在0x009267c8處)開始。這不可能是一個隨機的選擇,因為如果Locky的開發者採用相同KEY來加密,那麼檔案內容解密將會是非常順利成章的。實際上,儲存檔名的0x230位元組幾乎全是0,對這些位元組進行異或操作後,在.locky檔案裡可以看到結果,這樣在不知道AES相應的金鑰的情況下,我們可以分析出相當大比例的KEY。

檔案內容加密如下:

#!bash
(gdb) p/x $edx
$5 = 0xbd1d9a96 // key stream from offset 0x230 (0x009267c8)
(gdb) hexdump $edi 64 //before XOR
63 65 63 69 20 65 73 74 20 75 6e 20 73 65 63 72 |ceci est un secr|
65 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |et..............|
(gdb) hexdump $edi 64 //after XOR #1
f5 ff 7e d4 20 65 73 74 20 75 6e 20 73 65 63 72 |..~. est un secr|
65 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |et..............|

這裡和.locky檔案開頭部分一致。

如果檔案大小大於初始化時候的緩衝區,Locky將透過CryptEncrypt()函式以同樣的佈局加密其餘的緩衝空間,並增加計數:

#!bash
(gdb) hexdump *(int*)($esp+4+4+4+4) 128
0x009255e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80
0x009255f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81
0x00925600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 82
[...]
(gdb) hexdump *(int*)($esp+4+4+4+4) 128
0x009255e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
0x009255f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01
0x00925600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02
[...]

最終一個.Locky檔案佈局如下:

p11

可以按以下步驟來解密:

  1. 用我們的私鑰來解密RSA加密的緩衝區,獲得16位元組資料
  2. 用這16位元組資料作為AES-128-ECB金鑰來加密一個增量常數緩衝區(用0填充,結尾計數的資料)
  3. 用上面結果的前0x230位元組作為KEY來對檔名進行異或解密
  4. 把從0x230處開始的資料作為KEY 來對檔案內容進行異或解密

第一步用C程式碼實現如下:

#!cpp
// Importing the RSA private key
hPrivateKeyFile = CreateFile("private.key", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
dwPrivateKeyLen = GetFileSize(hPrivateKeyFile, NULL);
pbPrivateKey = (BYTE *)malloc(dwPrivateKeyLen);
ReadFile(hPrivateKeyFile, pbPrivateKey, dwPrivateKeyLen, &dwPrivateKeyLen, NULL);
CryptImportKey(hCryptProv, pbPrivateKey, dwPrivateKeyLen, 0, 0, &hKey);

// Reading the RSA buffer
hEncryptedFile = CreateFile("encrypted.rsa", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
dwEncryptedDataLen = GetFileSize(hEncryptedFile, NULL);
pbEncryptedFile = (BYTE *)malloc(dwEncryptedDataLen);
ReadFile(hEncryptedFile, pbEncryptedFile, dwEncryptedDataLen, &dwEncryptedDataLen, NULL);

// Decrypting the AES key
CryptDecrypt(hKey, NULL, TRUE, 0, pbEncryptedFile, &dwEncryptedDataLen);
hClearFile = CreateFile("aeskey.raw", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hClearFile, (LPCVOID)pbEncryptedFile, dwEncryptedDataLen, &lpNumberOfBytesWritten, NULL);

獲取到AES金鑰:

#!bash
$ xxd aeskey.raw
9d86 d342 483a 4504 1acb 951c 7790 8f7c

透過上面的金鑰,用Python程式碼實現解密檔名和檔案內容如下:

#!python
#! /usr/bin/env python
from Crypto.Cipher import AES
print "UnLocky - Locky decryption tool, CERT-LEXSI 2016
key = "9d86d342483a45041acb951c77908f7c".decode("hex")
# NB: small files only here
counter = ""
for i in range(0x80):
  counter += "\x00"*15 + chr(i)
keystream = AES.new(key, AES.MODE_ECB).encrypt(counter)
data = open("1D9076E6FD853AB6C931AFE2B33C3AF9.locky").read()
enc_size = len(data) - 0x230 - 0x100 - 0x14
enc_filename = data[-0x230:]
enc_content  = data[:enc_size]
clear_filename = ""
for i in range(0x230):
  clear_filename += chr(ord(enc_filename[i]) ^ ord(keystream[i]))
print "[+] File name:"
print clear_filename
clear_content = ""
for i in range(enc_size):
  clear_content += chr(ord(enc_content[i]) ^ ord(keystream[0x230+i]))
print "[+] Content:"
print clear_content

我們看看它是否能解密檔案:

#!bash
$ ./unlocky.py
UnLocky - Locky decryption tool, CERT-LEXSI 2016
[+] File name:
monfichier.txt // "myfile.txt"

[+] Content:
ceci est un secret // "this is a secret"

0x05 總結


Locky已經肆虐很久了,這裡提供了一些簡單的方法,在不需要任何反病毒或者安全工具的前提下,可以防止使用者系統檔案被加密,並保護系統為原樣。比如,可以使用本文提到的4個“疫苗”中的一個“疫苗”:強制替換用來加密AES KEY的RSA公鑰。

透過上面的分析,Locky並不是直接透過AES-128-ECB來加密檔案,而是透過AES-128-ECB來加密一個增量緩衝區,並把結果分為兩部分,分別作為異或加密檔名和檔案內容的KEY,看上去和CTR非常類似。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章