Разоблачаем вредоносное ПО: путешествие в мир VirusTotal API на Python

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Перед нами увлекательный код на Python, который позволяет получать отчеты о вредоносном ПО от VirusTotal и сравнивать их. Звучит интригующе, не правда ли? Давайте рассмотрим его подробнее.

1712416461068.png



Вступление​


Код начинается с импорта необходимых библиотек, таких как requests для работы с HTTP-запросами и colorama для красивого вывода текста в терминале.

Спойлер: Импорт библиотек
Python: Скопировать в буфер обмена
Код:
import requests
import json
import os
from colorama import init, Fore, Style

Класс VirusTotalAPI​


Далее определяется класс VirusTotalAPI, который позволяет взаимодействовать с API VirusTotal. Он принимает ваш API-ключ при инициализации и имеет метод download_report для загрузки отчета о файле по его хэш-сумме.

Спойлер: Класс VirusTotalAPI
Python: Скопировать в буфер обмена
Код:
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

Класс ReportManager​


Следующий класс ReportManager упрощает работу с отчетами. Он кэширует отчеты на диск, чтобы не загружать их повторно. Метод get_report проверяет, есть ли отчет в кэше, и если нет, загружает его через VirusTotalAPI.

Спойлер: Класс ReportManager
Python: Скопировать в буфер обмена
Код:
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

Класс DetectionComparator​


Класс DetectionComparator - настоящая звезда нашего шоу! Он сравнивает два отчета и определяет, какие антивирусные движки обнаружили новые угрозы, какие перестали их обнаруживать, и какие изменили свои результаты. Это помогает отслеживать изменения в детекции вредоносного ПО.

Спойлер: Класс DetectionComparator
Python: Скопировать в буфер обмена
Код:
class DetectionComparator:
    def compare(self, report1, report2):
        new_detections = {}
        removed_detections = {}
        changed_detections = {}

        # Сложная логика сравнения отчетов...

Класс DetectionPrinter​


Наконец, класс DetectionPrinter отвечает за красивый вывод результатов сравнения в терминал. Он использует библиотеку colorama для выделения новых, удаленных и измененных детектов разными цветами.

Спойлер: Класс DetectionPrinter
Python: Скопировать в буфер обмена
Код:
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}")
        
        # Вывод удаленных и измененных детектов...

Основная функция​


В главной функции main происходит инициализация классов, загрузка отчетов и вызов сравнения и вывода результатов. Вы можете изменить хэш-суммы файлов для тестирования или использовать свой API-ключ VirusTotal.

Спойлер: Функция main
Python: Скопировать в буфер обмена
Код:
def main():
    api_key = "" # Ваш API-ключ VirusTotal
    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)

Полный код
Python: Скопировать в буфер обмена
Код:
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!
 
Сверху Снизу