Skip to content

Commit f303805

Browse files
committed
Introducing an example to restore files encrypred by a ransomware
1 parent 08cf819 commit f303805

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Restore after ransom infection
2+
## A Dropbox API sample app to show Python SDK and get rid of ransom in your dropbox
3+
4+
# How to run
5+
Make sure you've installed the Dropbox Python SDK by following the installation instructions ( https://www.dropbox.com/developers/documentation/python#install ).
6+
7+
Then, find this line in restore-after-ransom-infection.py and modify it to include your own access token.
8+
```TOKEN = ''```
9+
10+
From the example/backup-and-restore directory, run the script.
11+
```python3 restore-after-ransom-infection.py```
12+
13+
# Description
14+
## Functionality
15+
1. Gather files encrypted by a ransomwhere.
16+
Once encrypted a new encrypted copy of your files is saved into your dropbox; whereas the original copy is flagged as to be deleted. Your only task here is to identify the new extension (*.rap in my case) and to change the code accordingly.
17+
18+
2. For each file matching the regular expression the script gathers the latest revision of the original file and restores it if still flagged as deleted.
19+
20+
# API usage
21+
## New v2 endpoints
22+
This app uses the Dropbox API v2 endpoints files_list_folder, files_list_folder_continue, files_list_revisions, files_restore and files_delete.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'''
2+
This example shows how to interact with Dropbox API to restore files encrypted by a ransom.
3+
Even if a ransom deletes original files from the file-system, dropbox still keeps old copies.
4+
We restore the last available revision of a file.
5+
Optionally encrypted files can be deleted with no harm (they're unrecoverable anyway).
6+
'''
7+
8+
import dropbox
9+
import sys
10+
import re
11+
12+
files = []
13+
has_more = True
14+
15+
def gather_elements(folderList):
16+
for entry in folderList.entries:
17+
# rap here is the extension of ransom' encrypted file
18+
if re.search('.rap$', entry.name):
19+
files.append(entry.path_lower)
20+
21+
# Here goes the token generated by your dropbox app
22+
TOKEN = ''
23+
dbx = dropbox.Dropbox(TOKEN)
24+
dbx.users_get_current_account()
25+
folderList = dbx.files_list_folder('', recursive=True)
26+
27+
while has_more:
28+
gather_elements(folderList)
29+
if folderList.has_more:
30+
folderList = dbx.files_list_folder_continue(folderList.cursor)
31+
else:
32+
has_more = False
33+
34+
# Examine all the files encrypted by the ransom
35+
for f in files:
36+
try:
37+
# Check that it is still marked as deleted
38+
fileName = f.replace('.rap', '')
39+
# Take the version of the file before being encrypted
40+
last_revision = dbx.files_list_revisions(fileName,
41+
mode=dropbox.files.ListRevisionsMode('path', None), limit=1)
42+
# If not there yet, let's restore it
43+
if last_revision.is_deleted is True:
44+
print('Restoring {} with revision {} ...'.format(fileName,
45+
last_revision.entries[0].rev))
46+
dbx.files_restore(fileName, last_revision.entries[0].rev)
47+
else:
48+
# If it was already restored somehow, keep it untouched
49+
print('File {} was already in place, no action performed'.format(fileName))
50+
continue
51+
except Exception as ex:
52+
print(ex)
53+
continue
54+
sys.exit(0)
55+
56+
# To delete files, comment previous call to sys.exit(0)
57+
for f in files:
58+
try:
59+
print("Finally deleting {}".format(f))
60+
dbx.files_delete(f)
61+
except Exception as ex:
62+
print(ex)
63+
sys.exit(0)

0 commit comments

Comments
 (0)