Вступление

Краткий обзор

VirusTotal API 3 версии на данный момент находится в стадии бета-версии. Данная версия заменит VirusTotal API 2 версии с течением определенного времени. Версия 3 VirusTotal API основана на спецификации http://jsonapi.org/ и была разработана с учетом простоты использования и единообразия.

irusTotal API 3 версии следует принципам REST и имеет предсказуемые, ориентированные на ресурсы URL-адреса. В этой версии API для запросов и ответов (в том числе и ответов с информацией об ошибках) используется JSON.

Warning

VirusTotal API 3 версии уже достаточно стабилен, однако некоторые несовместимые изменения по-прежнему возможны. Мы рекомендуем вам начать использовать его для экспериментов и не критически важных проектов.

Различия публичного и Premium API

Хотя многие функции, предоставляемые API VirusTotal, свободно доступны всем зарегистрированным пользователям, некоторые из них доступны только нашими премиум-клиентами. Эти функции составляют VirusTotal Premium API, и они будут соответствующим образом идентифицированы в этом описании.

Premium API - это компонент расширенных сервисов VirusTotal для профессионалов.

Публичный (открытый) API, с другой стороны, представляет собой набор функций, доступных для всех пользователей без каких-либо затрат. Единственное, что вам нужно для использования открытого API, это зарегистрироваться в сообществе VirusTotal и получить ключ API, как описано в разделе “Начало работы”.

Note

Ограничения публичного API

  • Публичный API ограничен 4 запросами в минуту и 1000 запросами в день.
  • Публичный API не должен использоваться в коммерческих продуктах или услугах.
  • Публичный API не должен использоваться в бизнес-процессах, которые не вносят новых файлов.

Note

Основные моменты Premium API

  • Premium API не имеет ограничений по скорости запросов или суточных ограничений. Ограничения регулируются SLA (соглашением об уровне услуг).
  • Premium API возвращает больше данных об угрозах и предоставляет больше функциональных возможностей.
  • Premium API регулируется SLA (соглашением об уровне услуг), который гарантирует готовность данных.

Premium API имеет следующие преимущества перед публичным API:

  • Позволяет выбрать частоту запросов и суточную квоту, которая наилучшим образом соответствует вашим потребностям.
  • Позволяет загружать образцы для дальнейшего исследования, а также данные о сетевом трафике, которые они генерируют при выполнении, и подробные отчеты о выполнении.
  • Возможно получение дополнительной информации об объектах, обработанных VirusTotal, например: предупреждения потока кода VBA для документов, исходные метаданные, выходные данные ExifTool, выходные данные IDS для зарегистрированных сетевых трасс, рейтинги популярности доменов, сертификаты SSL и т. д.
  • Включает метаданные, сгенерированные исключительно VirusTotal: первая дата отправки файла, список имен файлов, с которыми файл был отправлен в VirusTotal, страны отправки, распространенность и т. д.
  • Предоставит вам доступ к информации о поведении файлов, созданной в результате выполнения Windows PE, DMG, Mach-O и APK файлов в виртуализированной среде песочницы.
  • Предоставляет сведения о “белых списках” и доверенных источниках.
  • Позволяет задавать правила для запросов образцов, например: образцы с определенной сигнатурой; образцы, которые обнаружены более чем 10 антивирусными движками; образцы, которые содержат нужный раздел PE с определенным хэшем и т.д. Эти модификаторы поиска могут быть объединены для создания сложных запросов.
  • Позволяет задавать правила для запросов URL, доменов, IP-адресов, например: все домены, зарегистрированные одним и тем же злоумышленником; все домены с TTL записи DNS A менее 5 секунд и т.д.
  • Предоставляет возможность кластеризации файлов и поиска похожих файлов.
  • Показывает расширенные связи, которые недоступны в публичном API, например: встроенные домены; встроенные IP-адреса; контактные домены и т. д.
  • Позволяет программно взаимодействовать с VT Hunting, включая получение уведомлений о правилах YARA или автоматический запуск заданий ретро-поиска.
  • Имеет строгое соглашение о предоставлении услуг (SLA), которое гарантирует доступность и готовность данных.

В частности, Premium API поддерживает следующие основные варианты использования:

  • Автоматизация рабочих процессов с помощью набора данных VirusTotal, включая программное расширение предупреждений.
  • Интеграция VirusTotal с вашим SIEM, SOAR, EDR или AV для целей расширения получаемой информации, а не обнаружения.
  • Скачивание файлов для дальнейшего изучения в автономном режиме.
  • Полная характеристика любого вида угрозы, которую можно наблюдать: файлы, URL-адреса, Домены, IP-адреса, SSL-сертификаты и т. д.

Начало работы

Для использования API необходимо зарегистрироваться в сообществе VirusTotal Community. Как только у вас будет действительная учетная запись VirusTotal Community, вы найдете свой личный ключ доступа к API в разделе личных настроек. Этот ключ - все, что вам нужно для использования VirusTotal API.

Warning

VirusTotal API не должен использоваться в коммерческих продуктах или услугах, он не может использоваться в качестве замены антивирусных продуктов и не может быть интегрирован в любой проект, который может нанести прямой или косвенный ущерб антивирусной индустрии. Несоблюдение этих условий приведет к немедленному запрету доступа нарушителя к VirusTotal API.

Warning

При любых обстоятельствах Условия предоставления услуг и Политика конфиденциальности VirusTotal должны соблюдаться.

По умолчанию любой зарегистрированный пользователь VirusTotal Community имеет право на ключ API, который позволяет ему взаимодействовать с базовым набором функций API. Расширенные вызовы доступны через Premium API, который требует специальных привилегий. Свяжитесь с нами, если вы хотите узнать больше о том, как получить доступ к Premium API.

https://i.imgur.com/LFvGYQi.png

Аутентификация

Для аутентификации с помощью API вы должны включить заголовок x-apikey со своим личным ключом API во все ваши запросы. Ваш ключ API можно найти в пользовательском меню вашей учетной записи VirusTotal:

https://i.imgur.com/tby8XLV.png

Ваш ключ доступа к API несет все ваши привилегии, поэтому держите его в безопасности и не делитесь им ни с кем. Всегда используйте HTTPS вместо HTTP для выполнения ваших запросов.

Ответы API

В большинстве случаев ресурс VirusTotal API возвращает ответ в формате JSON. Если не указано иное, ответ на успешный запрос будет иметь следующий формат:

Структура ответа

{
  "data": <response data>
}

<response data> обычно представляет собой объект или список объектов, однако это не всегда так. Примером этого является функция /files/upload_url, которая возвращает URL-адрес.

Ошибки

API VirusTotal следует обычным кодам ответа HTTP для указания успеха или неудачи. Коды в диапазоне 2xx указывают на успех. Коды в диапазоне 4xx указывают на ошибку в запросе (например, отсутствует параметр или ресурс не найден). Коды в диапазоне 5xx указывают на ошибку на серверах VirusTotal, что бывает крайне редко.

Неудачные запросы возвращают дополнительную информацию об ошибке в формате JSON:

Формат ответа в случае ошибки

{
  "error": {
    "code": "<error code>",
    "message": "<a message describing the error>"
  }
}

Код ошибки code представляет собой строку с одним из значений, приведенных в ниже.

Сообщение message содержит ,более подробную информацию об ошибке.

  • 409 - Ошибка типа “AlreadyExistsError”. Ресурс уже существует.
  • 401 - Ошибка типа “AuthenticationRequiredError”. Выполнение операции возможно аутентифицированным пользователем. Убедитесь, что вы предоставили свой ключ доступа к API.
  • 400 - Ошибка типа “BadRequestError”. Запрос API является недопустимым или неправильным.
  • 403 - Ошибка типа “ForbiddenError”. Выполнение запрошенной операции невозможно.
  • 400 - Ошибка типа “InvalidArgumentError”. Некоторые аргументы, переданные в запросе неверные.
  • 404 - Ошибка типа “NotFoundError” - Запрошенный ресурс не найден.
  • 429 - Ошибка типа “QuotaExceededError”. Превышение одной из квот на число запросов(минутной, ежедневной или ежемесячной). Ежедневные квоты сбрасываются каждый день в 00: 00 UTC.
  • 429 - Ошибка типа “TooManyRequestsError”. Большое число запросов.
  • 401 - Ошибка типа “UserNotActiveError”. Учетная запись пользователя не активна.
  • 401 - Ошибка типа “WrongCredentialsError”.- Ключ доступа к API является неверным.
  • 503 - Ошибка типа “TransientError”. Временная ошибка сервера. Повторная попытка запроса может сработать.

Ключевые концепции

VirusTotal API (версии 3) базируется на трех ключевых понятиях: объекты (objects), коллекции (collections) и отношения (relationships).

Объект - это любой элемент, который может быть получен или обработан с помощью API. Файлы, URL-адреса, доменные имена и наборы правил поиска VirusTotal - это некоторые типы объектов, предоставляемые API.

Коллекция - это набор объектов. Объекты в коллекции обычно имеют один и тот же тип, но есть несколько исключений из этого правила. Некоторые операции API выполняются с объектами, а некоторые - с коллекциями.

Отношения - это связи между объектами, например: файл может быть связан с другим файлом, потому что один из файлов является ZIP-архивом, который содержит другой файл, URL-адрес может быть связан с файлом, потому что файл был загружен с URL-адреса, доменное имя связано со всеми URL-адресами в этом домене.

Объекты

Объект является ключевым понятием в API VirusTotal. Каждый объект имеет идентификатор и тип. Идентификаторы уникальны среди объектов одного типа. Это означает, что пара (тип, идентификатор) однозначно идентифицирует любой объект в API. В этой документации эти пары (тип, идентификатор) называются дескрипторами объектов.

Каждый объект имеет связанный с ним URL-адрес со следующей структурой:

https://www.virustotal.com/api/v3/{collection name}/{object id}

Обычно {collection name} - это множественная форма типа объекта, например, files - это коллекция, содержащая все объекты типа file, а analyses - это коллекция, содержащая все объекты analysis. Формат {object id} варьируется от одного типа объекта к другому.

GET-запрос на URL объекта возвращает информацию об этом объекте в следующем формате:

Пример ответа

{
  "data": {
    "type": "{object type}",
    "id": "{object id}",
    "links": {
      "self": "https://www.virustotal.com/api/v3/{collection name}/{object id}"
    },
    "attributes" : {
      "integer_attribute": 1234,
      "string_attribute": "this is a string",
      "dictionary_attribute": { "one": 1, "two": 2 },
      "list_attribute": [ "foo", "bar", "baz" ]
    },
    "relationships" : {
       ..
    }
  }
}

Помимо идентификатора и типа, объект имеет набор атрибутов и отношений. Атрибуты могут быть любого типа, поддерживаемого JSON, включая списки и словари. Поле attributes всегда присутствует во всех объектах, а поле relationships является необязательными, в зависимости от того, просили ли вы включить данное поле при отправке запроса. Данный вопрос будет подробно обсуждаться в разделе “Отношения”.

Каждый тип объекта имеет свой собственный заранее определенный набор атрибутов, вы не сможете добавлять или удалять атрибуты, вы можете только изменять значения существующих (в случае если они доступны для записи). Для изменения значений атрибутов объекта необходимо отправить PATCH-запрос по URL объекта. Если вы попытаетесь изменить атрибут только для чтения, вы получите сообщение об ошибке. PATCH-запрос должен содержать атрибуты, которые вы хотите изменить в структуре, подобной той, что показана в приведенном ниже примере. Любой атрибут, не включенный в запрос, останется неизменным.

Пример PATCH-запроса

{
  "data": {
    "type": "{object type}",
    "id": "{object id}",
    "attributes" : {
      "integer_attribute": 1234,
      "string_attribute": "this is a new string",
    }
  }
}

Обратите внимание, что идентификатор id и тип объекта object включены в PATCH-запрос, и они должны соответствовать указанным в URL.

Некоторые типы объектов также можно удалить, отправив DELETE-запрос на удаление по URL объекта.

Коллекции

Коллекции - это наборы объектов. Для большинства типов объектов существует коллекция верхнего уровня, представляющая все объекты этого типа. Доступ к этим коллекциям можно получить с помощью URL-адреса, например:

https://www.virustotal.com/api/v3/{collection name}

Большинство операций в API VirusTotal осуществляется путем отправки запросов к коллекции. Например, вы можете проанализировать файл, отправив POST-запрос в /api/v3/files, который успешно добавит новый элемент в коллекцию файлов. Вы можете создать новый набор правил VT Hunting, отправив POST-запрос в `/api/v3 /intelligence/hunting_rulesets. Отправка POST-запроса в коллекцию обычно приводит к созданию новых объектов.

Аналогично, DELETE-запрос, отправляемый в коллекцию, приводит к удалению всех объектов в этой коллекции. Конечно, для определенных коллекций, таких как files, urls или analyses нет метода DELETE для запросов, но вы можете использовать DELETE-запрос с /api/v3/intelligence/hunting_notifications, который, как вы уже поняли, удаляет все ваши уведомления VT Hunting.

Большинство коллекций являются итеративными, вы можете извлечь все объекты в коллекции, отправив в коллекцию последовательные GET-запросы. На каждый запрос вы получаете ряд объектов и курсор cursor, который можно использовать для продолжения итерации. Приведенный ниже фрагмент иллюстрирует ответ на GET-запрос на /api/v3/{collection name}.

Пример ответа коллекции

{
    "data": [
      { .. object 1 .. },
      { .. object 2 .. },
      { .. object 3 .. }
    ],
    "meta": {
      "cursor": "CuABChEKBGRhdGUSCQjA1.."
    },
    "links": {
        "next": "https://www.virustotal.com/api/v3/{collection name}?cursor=CuABChEKBGRhdGUSCQjA1..",
        "self": "https://www.virustotal.com/api/v3/{collection name}"
    }
}

Как следует из поля next в разделе links, вы можете использовать cursor в качестве параметра при последующем вызове для получения следующего набора объектов. Вы также можете использовать параметр limit для управления количеством объектов, возвращаемых при каждом вызове.

Отношения

Отношения - это способ, которым API-интерфейс VirusTotal выражает связи или зависимости между объектами. Объект может быть связан с объектами того же или другого типа. Например, файловый объект может быть связан с некоторым другим файловым объектом, который содержит первый, или файловый объект может быть связан с объектами URL, представляющими URL, встроенные в файл.

Отношения могут быть вида “один к одному” или “один ко многим”, в зависимости от того, связан объект с одним объектом или с несколькими объектами.

При извлечении какого-либо объекта с помощью GET-запроса можно также получить его связи с другими объектами. Это можно сделать, указав отношение, которое вы хотите получить в параметре relationships:

https://www.virustotal.com/api/v3/{collection name}/{object id}?relationships={relationship}

Можно указать несколько отношений в параметре relationships, перечислив их имена через запятую:

https://www.virustotal.com/api/v3/{collection name}/{object id}?relationships={relationship 1},{relationship 2}

Объекты, возвращаемые такими запросами, включают словарь отношений, где ключи - это имена запрашиваемых отношений, а значения - это либо дескриптор объекта (если отношение одно к одному), либо коллекция, как описано в разделе “Коллекции” (если отношение одно ко многим). Однако обратите внимание, что эти коллекции содержат не все связанные объекты, а только их дескрипторы (т. е. их тип и идентификатор).

Отношения в объекте

{
  "type": "{object type}",
  "id": "{object id}",
  "links": {
    "self": "https://www.virustotal.com/api/v3/{collection name}/{object id}"
  },
  "attributes" : {
     ..
  },
  "relationships" : {
     "{one-to-one relationship}": {
       "data": {
         "id": "www.google.com",
         "type": "domain"
       },
       "links": {
         "related": "https://www.virustotal.com/api/v3/{collection name}/{object id}/{one-to-one relationship}",
         "self": "https://www.virustotal.com/api/v3/{collection name}/{object id}/relationships/{one-to-one relationship}"
       }
     },
     "{one-to-many relationship}": {
       "data": [
         { .. object descriptor 1 .. },
         { .. object descriptor 2 .. },
         { .. object descriptor 3 .. }
       ],
       "meta": {
         "cursor": "CuABChEKBGRhdGUSCQjA1LC...",
       },
       "links": {
         "next": "https://www.virustotal.com/api/v3/{collection name}/{object id}/relationships/{one-to-many relationship}?cursor=CuABChEKBGRhdGUSCQjA1LC...",
         "self": "https://www.virustotal.com/api/v3/{collection name}/{object id}/relationships/{one-to-many relationship}"
       },
     },
    "{relationship 2}": { ... },
    "{relationship 3}": { ... }
  }
}

Если вы внимательно посмотрите на поле links для связи в приведенном выше примере, вы увидите, что URL в поле self выглядит следующим образом:

https://www.virustotal.com/api/v3/{collection name}/{object id}/relationships/{relationship}

Отношения “один ко многим” - это просто коллекции, содержащие объекты, которые каким-то образом связаны с основным объектом, поэтому они обычно имеют свой собственный URL, который можно использовать для перебора связанных объектов, отправляя GET-запросы на этот URL, как описано в разделе [“Коллекции”](#collections). При этом имеется два URL-адреса:

https://www.virustotal.com/api/v3/{collection name}/{object id}/relationships/{relationship}
https://www.virustotal.com/api/v3/{collection name}/{object id}/{relationship}

Первый URL - это коллекция, содержащая только дескрипторы (тип и идентификатор) для связанных объектов, второй - полные объекты со всеми их атрибутами. Если вас интересует только тип и идентификатор связанных объектов, вы должны использовать первый, так как более эффективно извлекать только дескрипторы, чем полные объекты.

Еще одно важное различие между обеими функциями заключается в том, что {object id}/relationships/{relationship} представляет отношение как независимую сущность и может поддерживать операции, которые изменяют отношение без изменения объектов. Напротив, {object id}/{relationship} представляет связанные объекты, а не отношение. Например, если вы хотите предоставить пользователю разрешения на просмотр графика, вы можете использовать:

POST https://www.virustotal.com/api/v3/graphs/{id}/relationships/viewers

Эта функция получает пользовательский дескриптор, она не изменяет ни пользователя, ни график, она просто создает связь между ними. С другой стороны, когда вы создаете новый комментарий для файла, вы используете:

POST https://www.virustotal.com/api/v3/files/{id}/comments

И в этом случае вы не только изменяете связь между файлом и комментарием, но и создаете новый объект комментария.