Диагноз: вы написали чистый код, а VirusTotal говорит «троян»
Вы собрали билд, всё работает, тесты зелёные. Из любопытства (или по просьбе заказчика) загружаете .exe на VirusTotal — и видите: 3/68, Trojan.Generic, Suspicious.Cloud. Сердце ёкнуло. Заказчик уже пишет в Telegram с капслоком.
Стоп. Сделайте глубокий вдох. В большинстве случаев это false positive — ложное срабатывание антивирусного движка. В этой статье разберём, как работает VirusTotal, почему он ругается на чистый софт, как правильно интерпретировать отчёт и что делать разработчику, когда антивирусы неправы.
После прочтения вы получите: чёткое понимание механизмов детектирования, практические инструменты диагностики и готовые аргументы для разговора с напуганным заказчиком.
Что такое VirusTotal и как он работает
VirusTotal — это не антивирус. Это агрегатор, который запускает загруженный файл через 60–70 антивирусных движков одновременно и показывает сводный отчёт. Принадлежит Google (куплен в 2012 году), используется специалистами по безопасности, разработчиками и параноидальными заказчиками по всему миру.
Как это работает технически:
- Вы загружаете файл → VirusTotal вычисляет его хеш (MD5, SHA1, SHA256).
- Если хеш уже есть в базе — возвращает кешированный результат.
- Если нет — отправляет файл на проверку всем подключённым движкам: Kaspersky, ESET, Avira, Symantec, Windows Defender, ClamAV и десяткам других.
- Каждый движок возвращает результат: чисто или имя угрозы.
- VirusTotal показывает статистику: сколько движков из скольких сработали.
Ключевой момент: 3/70 — это не «вирус», это статистический шум. Три движка из семидесяти что-то заподозрили. Шестьдесят семь — нет. Это совсем не то же самое, что приговор.
Почему VirusTotal показывает вирус почти на любой .exe
Ложные срабатывания — системная проблема, а не исключение. Разберём пять основных причин false positive.
Причина 1 — Heuristic detection (эвристика)
Heuristic detection — это не поиск по базе сигнатур, а анализ поведения и структуры файла. Движок смотрит: какие API вызывает программа, как работает с памятью, реестром, сетью.
Проблема в том, что многие легитимные операции выглядят подозрительно:
CreateRemoteThread— используется инжекторами вредоносов, но также легитимными отладчиками и профайлерами.- Запуск PowerShell из кода — стандартная практика в enterprise-инструментах и автоматически «красный флаг» для эвристики.
- Запись в реестр в
HKLM\Software\Microsoft\Windows\CurrentVersion\Run— автозапуск, который делают и вирусы, и любые нормальные программы с автостартом. - Обращение к
%TEMP%, распаковка файлов в рантайме, самообновление.
Эвристика по природе своей агрессивна. Она жертвует точностью ради покрытия. Для антивирусного вендора лучше дать false positive, чем пропустить реальный malware.
Причина 2 — Generic-сигнатуры
Взгляните на названия типичных срабатываний:
Trojan.GenericWin32.Malware.GenSuspicious.Cloud.7.EPHeuristic.HEUR/AGEN.1234567
«Generic» и «Gen» в названии — это прямой сигнал: движок не знает, что именно он нашёл. Это широкая сигнатура, которая срабатывает на целый класс файлов с похожими характеристиками. Trojan.Generic — это не «мы нашли конкретный троян Х». Это «что-то похожее на класс угроз».
Конкретная, опасная сигнатура выглядит иначе: Trojan.Win32.Emotet.a, Ransomware.Locky.gen, Backdoor.Win32.Agent.xyz — здесь есть семейство, вариант, конкретная угроза. Generic — нет.
Причина 3 — Packed и obfuscated файлы
Если вы используете упаковщики исполняемых файлов — ждите срабатываний. Популярные инструменты:
- UPX — простейший компрессор, почти гарантирует 2–5 детектов.
- Themida / WinLicense — защита от реверс-инжиниринга, антивирусы ненавидят.
- VMProtect — виртуализация кода, выглядит как обфускация вредоноса.
- Инсталляторы NSIS, Inno Setup, InstallShield — встроенные движки распаковки вызывают подозрения.
С точки зрения антивируса, packed exe на VirusTotal — это красный флаг. Вредоносы упаковывают код, чтобы уклониться от детектирования. Защищённый легитимный код выглядит точно так же.
Причина 4 — Отсутствие цифровой подписи (unsigned exe)
Неподписанный исполняемый файл (unsigned exe) не имеет репутации. Windows SmartScreen, WD SmartScreen и облачные движки работают по принципу «доверяй, но проверяй» — а без подписи проверять особо нечего.
Важно понимать разницу:
- Подписанный ≠ безопасный. Malware может быть подписан украденным или купленным сертификатом. Это случается.
- Неподписанный ≠ вирус. Огромное количество легитимного корпоративного и open-source софта распространяется без code signing просто потому, что сертификат стоит денег (от $100/год для OV до $400+/год для EV).
Но с точки зрения VirusTotal и репутационных движков, unsigned exe с нулевой историей — кандидат на подозрение.
Причина 5 — Новый файл без репутации
Облачные антивирусы используют репутационный анализ: если файл с таким хешем видели миллионы пользователей и никто не пожаловался — скорее всего, он чистый. Новый файл, который никто ещё не видел, репутации не имеет.
Это называется zero-day эвристика или reputation-based detection. Первые несколько часов/дней после публикации любой новый .exe потенциально «подозрителен» — просто потому что он новый. Со временем, если пользователи не жалуются, репутация растёт и детекты пропадают сами.
Когда это действительно проблема
Не все срабатывания одинаково безобидны. Вот практическая шкала оценки:
| Количество детектов | Интерпретация | Действие |
|---|---|---|
| 1–3 / 70 | Статистический шум, скорее всего false positive | Проверить тип сигнатур, успокоиться |
| 4–9 / 70 | Пограничная зона, требует анализа | Смотреть детали: Generic или конкретная угроза? |
| 10–15 / 70 | Повод серьёзно проверить файл | Анализ поведения, проверка зависимостей |
| 15–39 / 70 | Высокая вероятность реальной угрозы | Глубокий аудит кода, sandbox execution |
| 40+ / 70 | Почти наверняка вредонос | Не запускать, изолировать, расследовать |
Тип сигнатуры важнее числа. Два срабатывания с именами Backdoor.Win32.Agent.xyz от Kaspersky и ESET — это серьёзнее, чем десять срабатываний с Suspicious.Cloud.Generic от малоизвестных движков.
Как правильно интерпретировать отчёт VirusTotal
Отчёт VirusTotal состоит из нескольких вкладок. Большинство смотрят только на число детектов и закрывают вкладку. Это ошибка.
Вкладка Detection
Список всех движков и результатов. Смотрите на:
- Авторитет движка. Kaspersky, ESET, Symantec, Microsoft — это топ-уровень с хорошей репутацией. Движки типа CMC, CAT-QuickHeal, Zillya — менее известны и дают больше false positive.
- Название сигнатуры. Generic/Gen/Heuristic/Suspicious — пограничная зона. Конкретное семейство — повод задуматься.
- Консенсус топ-движков. Если Microsoft Defender, Kaspersky и ESET говорят «чисто» — остальные три срабатывания скорее всего false positive.
Вкладка Details
Метаданные файла: хеши, размер, дата компиляции, секции PE-файла, импорты. Здесь видно: упакован ли файл, есть ли подозрительные секции, соответствует ли timestamp реальности.
Вкладка Behavior
Самая важная для анализа. Показывает, что файл делал в sandbox execution — в изолированной виртуальной машине. Какие файлы создавал, какие реестровые ключи менял, какие сетевые запросы делал, какие процессы запускал.
Если в Behavior нет ничего подозрительного — скорее всего, файл чистый, а детекты статичные.
Вкладка Relations
Связанные файлы, домены, IP-адреса. Если .exe при запуске обращается к известным C2-серверам или скачивает payload с подозрительных доменов — это уже не false positive.
Вкладка Community
Комментарии сообщества. Иногда здесь можно найти «это легитимный инсталлятор X версии Y, не вирус» — что сразу снимает вопрос.
Что делать разработчику, если VirusTotal ругается
Практический план действий. Не паниковать, а диагностировать.
Шаг 1 — Проверить, упакован ли файл
# Используем Detect It Easy (DIE) — бесплатный инструмент die your_app.exe # Или через командную строку: # PEiD, ExeinfoPE — аналогичные инструменты # Ищем признаки: UPX, Themida, ASProtect, MPRESS и т.д.
Если файл упакован UPX — попробуйте распаковать и снова проверить:
upx -d your_app.exe # Затем снова загрузить на VirusTotal
Шаг 2 — Пересобрать без пакера
Если UPX или другой пакер добавляется автоматически (например, в настройках компилятора) — отключите его и соберите чистый бинарник. В большинстве случаев число детектов резко падает.
# В CMake — убрать strip и упаковку: # set_target_properties(myapp PROPERTIES LINK_FLAGS_RELEASE "") # В Python PyInstaller — без UPX: pyinstaller --noupx your_script.py # В NSIS <a title="Docker Compose — установка, команды и настройка контейнеров" href="https://it-apteka.com/docker-compose-ustanovka-komandy-i-nastrojka-kontejnerov/" target="_blank" rel="noopener" data-wpil-monitor-id="580">— проверить настройки</a> компрессии инсталлятора
Шаг 3 — Добавить code signing
Цифровая подпись не гарантирует отсутствие false positive, но снижает их количество и устанавливает репутацию файла в SmartScreen. Для коммерческого ПО — это обязательный шаг.
# Подписать с помощью signtool (Windows SDK): signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /f your_cert.pfx /p password your_app.exe # Проверить подпись: signtool verify /pa your_app.exe
Сертификаты для code signing: DigiCert, Sectigo (Comodo), GlobalSign. OV-сертификат стоит ~$100–200/год, EV — $300–500/год. EV даёт SmartScreen-репутацию сразу, без накопления.
Шаг 4 — Отправить sample на false positive review
Большинство вендоров принимают образцы для ручного анализа. Если вы уверены, что файл чистый:
- Microsoft: Microsoft Security Intelligence — Submit a file
- Kaspersky: Kaspersky Threat Intelligence Portal
- ESET: samples@eset.com или через веб-форму
- VirusTotal: В самом отчёте есть кнопка «Report as clean» — сигнализирует вендорам о возможном false positive
Срок рассмотрения — от нескольких часов до нескольких дней. После ручного анализа сигнатуру удаляют из базы.
Шаг 5 — Проверить зависимости и подозрительные API
# Dependencies (бывший Dependency Walker) — смотрим импорты DLL # Process Monitor от Sysinternals — что делает exe при запуске # Через dumpbin (Visual Studio Tools): dumpbin /imports your_app.exe | findstr -i "create inject thread virtual alloc" # Подозрительные API, которые триггерят эвристику: # CreateRemoteThread, VirtualAllocEx, WriteProcessMemory # NtUnmapViewOfSection, ZwCreateSection # Запуск cmd.exe / powershell.exe как дочернего процесса
Если ваш легитимный код использует эти API по объективным причинам — задокументируйте это и будьте готовы объяснить заказчику.
Почему даже чистый софт может иметь 1–3 детекта
Это не баг, это особенность устройства индустрии. Несколько причин:
ML-модели и переобучение. Современные антивирусы активно используют машинное обучение. Модели обучены на миллионах образцов malware — и иногда переобучаются, находя паттерны там, где их нет. Ваш чистый код случайно попадает в «статистическое соседство» с вредоносами.
Агрессивная коммерческая эвристика. AV-вендоры конкурируют за показатель detection rate в независимых тестах (AV-TEST, AV-Comparatives). Повышение чувствительности улучшает detection rate, но увеличивает false positive. Маркетинг важнее точности.
Устаревшие сигнатуры. Некоторые движки не обновляют базы часто и держат широкие сигнатуры, которые давно пора уточнить. Ваш файл попадает под старое правило по структурному совпадению.
Совпадение по коду. Если вы используете общедоступные библиотеки (open-source) или стандартные runtime-библиотеки, которые также входят в состав известных вредоносов — срабатывание по этому коду вполне вероятно.
VirusTotal и паранойя заказчиков
Реальный сценарий, знакомый каждому разработчику:
Вы сдали проект. Заказчик, вместо того чтобы тестировать функциональность, первым делом запускает .exe на VirusTotal. Видит 2/68. Открывает Telegram. Следующие сорок минут вы объясняете, что не вставляли троян в его CRM.
Как аргументировать профессионально, не теряя лицо:
Аргумент 1: Процент детектов. «Два движка из шестидесяти восьми дали срабатывание. Шестьдесят шесть — нет. Если бы это был реальный троян, соотношение было бы обратным.»
Аргумент 2: Тип сигнатуры. «Посмотрите на названия: Suspicious.Cloud.Generic и Heuristic.HEUR/AGEN. Это Generic-детекты — широкие правила, срабатывающие на целые классы файлов. Не конкретный вирус с именем и семейством.»
Аргумент 3: Авторитет движков. «Microsoft Defender, Kaspersky и ESET говорят «чисто». Эти три движка — индустриальный стандарт. Два движка, которые сработали — CMC и VBA32 — известны высоким уровнем false positive.»
Аргумент 4: Вкладка Behavior. «Откройте вкладку Behavior в отчёте VirusTotal. Там показано, что программа делала в изолированной среде. Никаких подозрительных сетевых запросов, никакого изменения системных файлов, никакого скрытого запуска процессов.»
Аргумент 5: Отправьте на review. «Мы прямо сейчас отправим файл на false positive review в Microsoft и Kaspersky. Если это действительно ложное срабатывание — через 24–48 часов детекты исчезнут.»
Этот набор аргументов работает в 95% случаев. Если заказчик продолжает настаивать после всех этих объяснений — проблема уже не техническая.
Чек-лист: что делать, если VirusTotal показывает вирус
Шаг 1. Подсчитайте количество детектов. 1–3 из 70 — скорее всего false positive, не паниковать.
Шаг 2. Посмотрите тип сигнатур. Generic/Heuristic/Suspicious — красный флаг невысокий. Конкретное семейство от топового вендора — повод разбираться серьёзно.
Шаг 3. Проверьте упаковку. Используйте Detect It Easy или PEiD. Если файл упакован UPX — распакуйте и перепроверьте.
Шаг 4. Проверьте цифровую подпись. Unsigned exe без репутации триггерит эвристику. Добавьте code signing, если распространяете ПО коммерчески.
Шаг 5. Откройте вкладку Behavior. Если sandbox execution не показал ничего подозрительного — детекты статичные, файл чистый.
Шаг 6. Отправьте на false positive review к вендорам, которые дали срабатывание. Укажите, что это легитимный коммерческий софт.
Шаг 7. Если детектов 15+ и среди них — Kaspersky, ESET, Microsoft — это уже не false positive. Проводите полноценный аудит кода и зависимостей.
Вывод
VirusTotal — мощный инструмент, но не приговор. Это агрегатор семидесяти движков с разными алгоритмами, эвристиками, ML-моделями и разным уровнем агрессивности. False positive — это норма индустрии, а не исключение.
1–3 детекта с Generic-сигнатурами от малоизвестных движков при зелёных результатах от Microsoft, Kaspersky и ESET — это не вирус. Это особенность того, как устроено современное обнаружение угроз.
Умение правильно читать отчёт VirusTotal — такой же профессиональный навык, как умение читать stack trace или linter output. Знайте своё оружие.
Пишите в комментарии, если столкнулись с нестандартным срабатыванием или заказчик продолжает настаивать — разберём конкретный кейс. Подписывайтесь на телеграм-канал, чтобы не пропустить следующие рецепты из IT-аптеки.



