-
Notifications
You must be signed in to change notification settings - Fork 1
/
medusa_unlocker.py
135 lines (105 loc) · 3.9 KB
/
medusa_unlocker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from Crypto.Cipher import AES
import binascii
import struct
import sys
import os
from medusa_tools import get_aes_key, get_medusa_dump, byte_entropy
from tools import scan_crypted_file
def unlock(key, path):
# define AES mode for medusa locker
mode = AES.MODE_CBC
iv_key = b"0000000000000000"
cipher_key = binascii.unhexlify(key)
with open(path, "rb") as f:
cipherdata = f.read()
path_tmp = path.split(".")
decrypt_path = ".".join(path_tmp[:-1])
print("decrypt: "+decrypt_path)
datasize_b = cipherdata[-24:-16]
data_size = struct.unpack("<Q", datasize_b)
print("original file size: " + str(data_size[0])+"byte")
dummy_byte = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
cipherdata = dummy_byte + cipherdata[0:-536]
print("load file size: " + str(len(cipherdata)) + "byte")
context = AES.new(cipher_key, mode, iv_key)
cleardata = context.decrypt(cipherdata)[16:data_size[0]+16]
with open(decrypt_path, "wb") as f:
f.write(cleardata)
return decrypt_path
def medusa_unlocker(mode=False, dump=None, input_file=None,key = None):
# encrypted filename extension
ext = "encrypted"
# get memory dump
if(mode=="test"):
dump_path = dump
elif(mode == "key"):
dump_path = True
else:
dump_path = get_medusa_dump()
if(bool(dump_path)):
pass
else:
raise EnvironmentError("Failed to dump medusa process")
# search AES key from memory dump
if(mode == "key"):
_256bitAESkeys = [key]
else:
_256bitAESkeys = get_aes_key(dump_path, 256)
# check whether _256bitAESkeys is valid with file byte_base entropy
is_key_valid = False
for key in _256bitAESkeys:
print("Candidate key: " + str(key))
i = 0
ent_sum = 0.0
ave_ent = 0.0
if(mode):
print(input_file)
with open(unlock(key, input_file), "rb") as f:
sample = f.read()
ave_ent = byte_entropy(sample)
else:
for file in scan_crypted_file(ext=ext):
print(file)
if(i > 5):
ave_ent = ent_sum / i
break
with open(unlock(key, file), "rb") as f:
sample = f.read()
ent_sum += byte_entropy(sample)
i += 1
print("average entropy: " + str(ave_ent))
if(ave_ent < 0.95):
is_key_valid = True
break
else:
print(
"Files entropy is big, so they aren't decrypted correctly with this key.")
if(is_key_valid):
print("found valid key: " + str(key))
else:
raise EnvironmentError("not found valid key from memory")
# decrypt all files with found valid key
if(mode):
pass
else:
for file in scan_crypted_file(ext=ext):
unlock(key, file)
if __name__ == "__main__":
if(len(sys.argv) < 2):
print("usage: with no option: automatically scan aes key from memory and decrypt files.")
print("medusa_unlocker.py test memory.dump encrypted_file_path : scan aes key from dump and decrypt file.")
elif(sys.argv[1] == "run"):
medusa_unlocker()
elif(len(sys.argv) < 3):
print("usage: with no option: automatically scan aes key from memory and decrypt files.")
print("medusa_unlocker.py test memory.dump encrypted_file_path : scan aes key from dump and decrypt file.")
elif(sys.argv[1] == "test" and sys.argv[2] and sys.argv[3]):
print("test mode")
medusa_unlocker(mode = "test",dump= os.path.abspath(
sys.argv[2]),input_file= os.path.abspath(sys.argv[3]))
elif(sys.argv[1] == "key" and sys.argv[2] and sys.argv[3]):
print("key mode")
medusa_unlocker(mode = "key", input_file = os.path.abspath(
sys.argv[2]), key = sys.argv[3])
else:
pass