揭露恶意软件:Python 中的 VirusTotal API 世界之旅!

这里有一些有趣的 Python 代码,可让您从 VirusTotal 获取恶意软件报告并进行比较。听起来很有趣,不是吗?让我们仔细看看它。

介绍

该代码首先导入必要的库,例如用于处理 HTTP 请求的 requests 和用于在终端中输出漂亮文本的 colorama。

VirusTotalAPI 类

接下来,定义 VirusTotalAPI 类,它允许您与 VirusTotal API 进行交互。它在初始化时接受您的 API 密钥,并具有 download_report 方法,可以通过哈希值下载文件的报告。

报表管理类

以下 ReportManager 类使报表的处理变得更加容易。它将报告缓存到磁盘,因此不必再次下载。 get_report 方法检查报告是否在缓存中,如果没有,则通过 VirusTotalAPI 加载它。

检测比较器类

DetectionComparator 类是我们节目中真正的明星!它会比较两个报告并确定哪些防病毒引擎检测到新威胁,哪些引擎停止检测它们,以及哪些引擎更改了结果。这有助于跟踪恶意软件检测的变化。

检测打印机类

最后,DetectionPrinter 类负责将比较结果精美地输出到终端。它使用 colorama 库以不同颜色突出显示新的、删除的和更改的检测。

主要功能

在主函数中,类被初始化,报告被加载,结果被比较和显示。您可以更改文件哈希值以进行测试或使用您的 VirusTotal API 密钥。

完整代码

import requests
import json
import os
from colorama import init, Fore, Style

init()  # Инициализация colorama


class VirusTotalAPI:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://www.virustotal.com/vtapi/v2"

    def download_report(self, file_hash):
        url = f"{self.base_url}/file/report?apikey={self.api_key}&resource={file_hash}"
        response = requests.get(url)
        if response.status_code == 200:
            return response.json()
        else:
            print(f"Ошибка при загрузке отчета для хеша {file_hash}")
            return None


class ReportManager:
    def __init__(self, api_key):
        self.api = VirusTotalAPI(api_key)

    def get_report(self, file_hash):
        filename = f"C:/temp/{file_hash}.json"
        if os.path.exists(filename):
            print(f"Отчет для хеша {file_hash} уже существует на диске.")
            with open(filename) as f:
                return json.load(f)
        else:
            report = self.api.download_report(file_hash)
            if report:
                with open(filename, 'w') as f:
                    json.dump(report, f)
            return report


class DetectionComparator:
    def compare(self, report1, report2):
        new_detections = {}
        removed_detections = {}
        changed_detections = {}

        for engine, result in report2['scans'].items():
            if engine in report1['scans']:
                if result['detected'] != report1['scans'][engine]['detected']:
                    if result['detected']:
                        new_detections[engine] = {
                            'old_result': report1['scans'][engine]['result'],
                            'new_result': result['result']
                        }
                    else:
                        removed_detections[engine] = {
                            'old_result': report1['scans'][engine]['result'],
                            'new_result': result['result']
                        }
                elif result['detected'] and result['result'] != report1['scans'][engine]['result']:
                    changed_detections[engine] = {
                        'old_result': report1['scans'][engine]['result'],
                        'new_result': result['result']
                    }
            else:
                if result['detected']:
                    new_detections[engine] = {
                        'old_result': None,
                        'new_result': result['result']
                    }

        for engine, result in report1['scans'].items():
            if engine not in report2['scans']:
                if result['detected']:
                    removed_detections[engine] = {
                        'old_result': result['result'],
                        'new_result': None
                    }

        return new_detections, removed_detections, changed_detections


class DetectionPrinter:
    def print_detections(self, new_detections, removed_detections, changed_detections):
        if new_detections:
            print("Новые детекты:")
            for engine, results in new_detections.items():
                print(
                    f"{Fore.GREEN}{engine}{Style.RESET_ALL}: {results['old_result']} -> {Fore.RED}{results['new_result']}{Style.RESET_ALL}")
        if removed_detections:
            print("Удаленные детекты:")
            for engine, results in removed_detections.items():
                print(
                    f"{Fore.RED}{engine}{Style.RESET_ALL}: {Fore.RED}{results['old_result']}{Style.RESET_ALL} -> {Fore.GREEN}{results['new_result']}{Style.RESET_ALL}")
        if changed_detections:
            print("Измененные детекты:")
            for engine, results in changed_detections.items():
                print(
                    f"{engine}: {Fore.YELLOW}{results['old_result']}{Style.RESET_ALL} -> {Fore.RED}{results['new_result']}{Style.RESET_ALL}")


def main():
    api_key = ""
    hash1 = "2593f6685eb741cac83c2529e5d69fda18a82007e1c4fc721bfa6c286c678db2"
    hash2 = "cc6ed492e33761a111a2717823f5f1f6de9365aa22e042364eadefe16c1024a8"

    if not os.path.exists(r"C:\temp"):
        os.makedirs(r"C:\temp")

    report_manager = ReportManager(api_key)
    report1 = report_manager.get_report(hash1)
    report2 = report_manager.get_report(hash2)

    if report1 and report2:
        comparator = DetectionComparator()
        new_detections, removed_detections, changed_detections = comparator.compare(report1, report2)

        printer = DetectionPrinter()
        printer.print_detections(new_detections, removed_detections, changed_detections)


if __name__ == "__main__":
    main()

就是这样!现在您已经了解这段代码是如何工作的以及它的作用了。不要忘记运行它并在终端中查看结果。祝你学习 Python 愉快!