【问题标题】:CryptoLocker - restore Drive file version with Python scriptCryptoLocker - 使用 Python 脚本恢复 Drive 文件版本
【发布时间】:2017-07-13 05:44:15
【问题描述】:

长话短说,我感染了 CryptoLocker 病毒。我的“正常”本地文件不是问题,因为我备份了这些文件。但我使用的是 Google Drive Sync 客户端,我所有的 Drive 文件都被加密了。我没有备份它们,因为我认为 Google 云端硬盘已保存并且我的数据存储在世界各地(我知道是我的错)。

现在我可以看到 Google Drive 提供了版本控制。这意味着我的旧上传仍在服务器上。我可以逐个文件恢复以前的版本,但要恢复几千个文件,祝你好运。 我联系了 Google G Suite 支持团队(我正在为我的业务使用 Google G Suite)并询问他们是否可以通过一次批量操作恢复最新版本。答案是“不,你必须逐个文件”。因此,我在互联网上查找脚本、工具等。

我找到了一个 Python 脚本“bitbucket.org/sn-ps/cyclick/EBbEG”,它应该允许我恢复预览工作版本。

  1. 安装python“python.org/ftp/python/2.7.12/python-2.7.12.msi”。

  2. 运行“CMD”。

  3. 下载 pip 模块“bootstrap.pypa.io/get-pip.py”。

  4. 将其复制到“脚本”文件夹。

  5. 通过 CMD "python get-pip.py" 运行脚本。

  6. 开启 Drive API 并生成 OAuth 客户端 ID:developers.google.com/drive/v3/web/quickstart/python

  7. 下载 json 文件,将其放在“.credentials”文件夹中,并将其重命名为“client_secret.json”。 (如第 28 行所述)

  8. 在 CMD "pip install --upgrade google-api-python-client" 下安装谷歌库。

  9. 然后我复制了脚本并将其保存为“cleanup.py”。

# This script removes the file revision created by the Zepto Ransomware and 
# renames the file back to what it was before infection.
# This file CHANGES the drive. USE IT AT YOUR OWN RISK. I'M NOT RESPONSIBLE FOR ANY LOSE.
# 
# Requirements : 
#  * Avoid encoding problem by setting the python encoding before running the script
#   $ export PYTHONIOENCODING=utf8
#  * Turn on the Drive API and generate a OAuth client ID : https://developers.google.com/drive/v3/web/quickstart/python

from __future__ import print_function
import httplib2
import os
import json

from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive API Python Quickstart'

def get_credentials():
    """
    Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
      os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir, 'drive-python-quickstart.json')

    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
      flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
      flow.user_agent = APPLICATION_NAME
      if flags:
        credentials = tools.run_flow(flow, store, flags)
      else: 
        # Needed only for compatibility with Python 2.6
        credentials = tools.run(flow, store)
      print('Storing credentials to ' + credential_path)
    return credentials

def deleteFilesWithSuffix(suffix, service):
  results = service.files().list(
      corpus="domain",
      spaces="drive",
      pageSize=1000,
      orderBy="folder,modifiedTime desc,name",
      q="name contains '" + suffix + "'",
      fields="nextPageToken, files(id, name)"   
        ).execute()
  items = results.get('files', [])
  if not items:
    print('No files found.')
  else:
    for item in items:
      if item['name'].endswith(suffix):
        try:
          deleteFile = service.files().delete(fileId=item['id']).execute()
          print("Deleted file : " + item['name'])
        except Exception as e:
          print("Could not delete file : " + item['name'] + ". Details : " + str(e))

def renameFile(fileId, originalFilename, service):
  try:
    print("Renaming file " + fileId + " to " + originalFilename)
    service.files().update(fileId=fileId, body={'name': originalFilename}, fields='name').execute()
  except Exception as e:
    print("Could not rename file " + fileId + " / Details : " + str(e))

def revertFiles(suffix, service):
  results = service.files().list(
      corpus="domain",
      spaces="drive",
      pageSize=1000,
      orderBy="folder,modifiedTime desc,name",
      #q="modifiedTime > '2016-09-04T12:00:00'",
      q= "name contains '" + suffix + "'",
      fields="nextPageToken, files(id, name)"   
      ).execute()
  items = results.get('files', [])
  if not items:
    print('No files found.')
  else:
      for item in items:
        details = service.files().get(fileId=item['id'], fields="lastModifyingUser,name").execute()
        if details['name'].endswith(suffix):
            print("About to handle file " + details['name'] + " having id " + item['id'])
            revs = service.revisions().list(fileId=item['id'], fields="kind,revisions").execute()
            allrev = revs['revisions']
            lastRev = allrev[-1]
            if not lastRev['originalFilename'].endswith(suffix):
              # there was a rename problem during previous run -> fix it 
              originalFilename = lastRev['originalFilename']
              renameFile(item['id'], originalFilename, service)
            elif len(allrev) > 1:
                origRev = allrev[-2]
                if lastRev['originalFilename'].endswith(suffix):
                  try:
                    print("Removing last revision of file " + details['name']) 
                    revDel = service.revisions().delete(fileId=item['id'], revisionId=lastRev['id']).execute()
                    originalFilename = origRev['originalFilename']
                    renameFile(item['id'], originalFilename, service)
                  except Exception as e:
                    print("Could not process file : " + details['name'] + " / Details : " + str(e))

def main():
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('drive', 'v3', http=http)

    deleteFilesWithSuffix('_HELP_instructions.html', service)
    revertFiles('zepto', service)

if __name__ == '__main__':
    main()
  1. 我通过 CMD “python cleanup.py”运行了脚本。

我收到一条错误消息:

C:\Python27\Scripts>python cleanup.py
Traceback (most recent call last):
  File "cleanup.py", line 133, in <module>
    main()
  File "cleanup.py", line 125, in main
    credentials = get_credentials()
  File "cleanup.py", line 48, in get_credentials
    credentials = store.get()
  File "C:\Python27\lib\site-packages\oauth2client\client.py", line 407, in get
    return self.locked_get()
  File "C:\Python27\lib\site-packages\oauth2client\file.py", line 54, in locked_get
    credentials = client.Credentials.new_from_json(content)
  File "C:\Python27\lib\site-packages\oauth2client\client.py", line 302, in new_from_json
    module_name = data['_module']
KeyError: '_module'

我做错了什么?是不是凭证/jason 文件有问题?

现在我在这里向你们寻求帮助。也许我们可以让这个脚本运行,这样我就可以恢复我的文件的最新工作版本。

非常感谢您提供的任何帮助。

【问题讨论】:

    标签: python google-drive-api virus


    【解决方案1】:

    看看这个页面? https://github.com/hut6/google-drive-restore

    您检查了第 1 步吗?

    您必须将 Google Admin SDK 和 Google Drive API 添加到客户端 谷歌开发者控制台。下载 JSON 凭证文件,然后 将其添加到根目录为credentials.json

    【讨论】:

    • 我同时启用了“Google Admin SDK”和“Google Drive API”,但仍然出现相同的错误消息。该错误是否可能与凭据(json文件)有关?我将 json 文件放在 C: 根目录下,也在 C: 上的文件夹“.credentials”中,并在我的用户文件夹中执行相同的步骤。不用找了。有什么想法吗?
    猜你喜欢
    • 2017-07-13
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 2021-09-04
    • 2020-04-23
    相关资源
    最近更新 更多