3. Модули¶
Модули - это средство, которое YARA предоставляет для расширения своих возможностей. Они позволяют определить структуры данных и функции, которые могут использоваться в правилах для выражения более сложных условий. В этой главе вы найдете описание некоторых модулей, официально распространяемых с YARA, но вы также можете узнать, как писать свои собственные модули в Главе 4 [“Написание собственных модулей”](#ch_4).
3.1. Модуль PE¶
Модуль PE позволяет создавать более детализированные правила для PE-файлов с помощью атрибутов и функций формата PE-файла (детальную информацию о формате PE-файлов можно получить здесь. Этот модуль предоставляет большинство полей, присутствующих в заголовке PE и предоставляет функции, которые могут быть использованы для написания более выразительных и целевых правил. Рассмотрим несколько примеров:
import "pe"
rule single_section
{
condition:
pe.number_of_sections == 1
}
rule control_panel_applet
{
condition:
pe.exports("CPlApplet")
}
rule is_dll
{
condition:
pe.characteristics & pe.DLL
}
3.1.1. Описание¶
machine
Добавлено в версии 3.3.0.
Целочисленная переменная, содержащая одно из следующих значений:
- MACHINE_UNKNOWN
- MACHINE_AM33
- MACHINE_AMD64
- MACHINE_ARM
- MACHINE_ARMNT
- MACHINE_ARM64
- MACHINE_EBC
- MACHINE_I386
- MACHINE_IA64
- MACHINE_M32R
- MACHINE_MIPS16
- MACHINE_MIPSFPU
- MACHINE_MIPSFPU16
- MACHINE_POWERPC
- MACHINE_POWERPCFP
- MACHINE_R4000
- MACHINE_SH3
- MACHINE_SH3DSP
- MACHINE_SH4
- MACHINE_SH5
- MACHINE_THUMB
- MACHINE_WCEMIPSV2
Пример: pe.machine == pe.MACHINE_AMD64
checksum
Добавлено в версии 3.3.0.
Целочисленная переменная, хранящее значение поля CheckSum
из OptionalHeader
заголовка PE-файла
calculate_checksum
Добавлено в версии 3.3.0.
Функция, рассчитывающая значение контрольной суммы PE-файла
Пример: pe.checksum == pe.calculate_checksum()
subsystem
Целочисленная переменная, содержащая одно из следующих значений:
- SUBSYSTEM_UNKNOWN
- SUBSYSTEM_NATIVE
- SUBSYSTEM_WINDOWS_GUI
- SUBSYSTEM_WINDOWS_CUI
- SUBSYSTEM_OS2_CUI
- SUBSYSTEM_POSIX_CUI
- SUBSYSTEM_NATIVE_WINDOWS
- SUBSYSTEM_WINDOWS_CE_GUI
- SUBSYSTEM_EFI_APPLICATION
- SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
- SUBSYSTEM_EFI_RUNTIME_DRIVER
- SUBSYSTEM_XBOX
- SUBSYSTEM_WINDOWS_BOOT_APPLICATION
Пример: pe.subsystem == pe.SUBSYSTEM_NATIVE
timestamp
Переменная, содержащая значение поля TimeDateStamp
из FileHeader
заголовка PE-файла
pointer_to_symbol_table
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_FILE_HEADER::PointerToSymbolTable
. Используется, когда PE-образ имеет отладочную информацию COFF.
number_of_symbols
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_FILE_HEADER::NumberOfSymbols
. Используется, когда PE-образ имеет отладочную информацию COFF.
size_of_optional_header
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_FILE_HEADER::SizeOfOptionalHeader
. Это реальный размер опционального заголовка (OptionalHeader
). Равно 0xE0
для файлов PE32 и 0xF0
для файлов PE32+.
opthdr_magic
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::Magic
.
size_of_code
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfCode
. Это сумма размеров необработанных данных в разделах кода.
size_of_initialized_data
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfInitializedData
.
size_of_uninitialized_data
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfUninitializedData
.
entry_point
Смещение точки входа относительно начала файла или виртуальный адрес в зависимости от того, сканирует ли YARA файл или память процесса соответственно.
base_of_code
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::BaseOfCode
.
base_of_data
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::BaseOfData
. Это поле существует только в 32-разрядных PE-файлах.
image_base
Базовый адрес загрузки программы.
section_alignment
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SectionAlignment
. Когда Windows отображает PE-образ в память, все размеры секций (включая размер заголовка) выравниваются до этого значения.
file_alignment
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::FileAlignment
. Все смещения к данным секции в PE-файле выровнены по этому значению.
win32_version_value
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::Win32VersionValue
.
size_of_image
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfImage
. Это общий виртуальный размер заголовка и всех разделов.
size_of_headers
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfHeaders
. Это размер PE-заголовка PE, включая DOS_заголовок , заголовок файла, опциональный заголовок и все заголовки разделов. Когда PE-файл отображается в память, это значение подлежит выравниванию до SectionAlignment
.
characteristics
Битовое представление характеристик PE-файла из FileHeader
. Каждую характеристику можно проверить, выполнив побитовую операцию AND
со следующими константами:
- RELOCS_STRIPPED - Файл не содержит информации о базовых перемещений.
- EXECUTABLE_IMAGE - Файл является исполняемым (т. е. без неразрешенных внешних ссылок).
- LINE_NUMS_STRIPPED - Номера строк были удалены из файла. Этот флаг устарел и должен быть равен нулю.
- LOCAL_SYMS_STRIPPED - Локальные символы, удалены из файла. Этот флаг устарел и должен быть равен нулю.
- AGGRESIVE_WS_TRIM - Принудительное использование файла подкачки. Этот флаг устарел и должен быть равен нулю.
- LARGE_ADDRESS_AWARE - Программа может работать с адресами, большими 2 Гб.
- BYTES_REVERSED_LO - Байты машинного слова меняются местами (little endian). Этот флаг устарел и должен быть равен нулю.
- MACHINE_32BIT - Архитектура 32-разрядного слова.
- DEBUG_STRIPPED - Отладочная информация удалена из PE-файла и вынесена в отдельный .DBG файл.
- REMOVABLE_RUN_FROM_SWAP - Если образ находится на съемном носителе, то его нужно предварительно скопировать в файл подкачки.
- NET_RUN_FROM_SWAP - Если образ находится в сети, то его нужно предварительно скопировать в файл подкачки.
- SYSTEM - Системный файл.
- DLL - DLL-файл.
- UP_SYSTEM_ONLY - Файл должен исполняться только на однопроцессорной машине.
- BYTES_REVERSED_HI - Байты машинного слова меняются местами (big endian). Этот флаг устарел и должен быть равен нулю.
Пример: pe.characteristics & pe.DLL
linker_version
Объект с двумя целочисленными атрибутами, по одному для старшей и младшей цифры версии компоновщика.
- major - Старшая цифра версии компоновщика.
- minor - Младшая цифра версии компоновщика.
os_version
Объект с двумя целочисленными атрибутами, по одному для старшей и младшей цифры версии операционной системы.
- major - Старшая цифра версии операционной системы.
- minor - Младшая цифра версии операционной системы.
image_version
Объект с двумя целочисленными атрибутами, по одному для старшей и младшей цифры версии файла.
- major - Старшая цифра версии файла.
- minor - Младшая цифра версии файла.
subsystem_version
Объект с двумя целочисленными атрибутами, по одному для старшей и младшей цифры версии подсистемы.
- major - Старшая цифра версии подсистемы.
- minor - Младшая цифра версии подсистемы.
dll_characteristics
Битовое представление дополнительных характеристик PE-файла из OptionalHeader
. Не путайте эти характеристики с характеристиками из FileHeader
. Каждую характеристику можно проверить, выполнив побитовую операцию AND
со следующими константами:
- DYNAMIC_BASE - Файл может быть перемещен (файл совместимый с ASLR).
- FORCE_INTEGRITY
- NX_COMPAT - Файл совместимый с DEP.
- NO_ISOLATION
- NO_SEH - Файл не содержит структурированных обработчиков исключений, он должен быть настроен на использование SafeSEH.
- NO_BIND
- WDM_DRIVER - Файл является WDM-драйвером.
- TERMINAL_SERVER_AWARE - файл совместимый с сервером терминалов.
size_of_stack_reserve
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfStackReserve
. Это объем виртуальной памяти по умолчанию, который будет зарезервирован для стека.
size_of_stack_commit
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfStackCommit
. Это объем виртуальной памяти по умолчанию, который будет выделен для стека.
size_of_heap_reserve
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfHeapReserve
. Это объем виртуальной памяти по умолчанию, который будет зарезервирован для кучи основного процесса.
size_of_heap_commit
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::SizeOfHeapCommit
. Это объем виртуальной памяти по умолчанию, который будет выделен для кучи основного процесса.
loader_flags
Добавлено в версии 3.8.0.
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::LoaderFlags
.
number_of_rva_and_sizes
Переменная, содержащая значение IMAGE_OPTIONAL_HEADER::NumberOfRvaAndSizes
. Это число элементов в массиве IMAGE_OPTIONAL_HEADER::DataDirectory.
data_directories
Добавлено в версии 3.8.0.
Массив каталогов данных. Каждый каталог данных содержит виртуальный адрес и длину соответствующего каталога данных. Каждый каталог данных содержит следующие записи:
- virtual_address - Относительный виртуальный адрес (RVA) каталога данных. Если это ноль, то каталог данных отсутствует.
- size - Размер каталога данных в байтах.
Индекс записи каталога данных может иметь одно из следующих значений:
- IMAGE_DIRECTORY_ENTRY_EXPORT - Каталог для экспортируемых функций.
- IMAGE_DIRECTORY_ENTRY_IMPORT - Каталог для импортируемых функций.
- IMAGE_DIRECTORY_ENTRY_RESOURCE - Каталог для ресурсов.
- IMAGE_DIRECTORY_ENTRY_EXCEPTION - Каталог информации об исключениях.
- IMAGE_DIRECTORY_ENTRY_SECURITY - Указатель на таблицу сертификатов цифровых подписей. Если цифровая подпись отсутствует, будет содержать нули.
- IMAGE_DIRECTORY_ENTRY_BASERELOC - Каталог таблицы переадресации.
- IMAGE_DIRECTORY_ENTRY_DEBUG - Каталог для отладочной информации.
- IMAGE_DIRECTORY_ENTRY_TLS - Каталог TLS (локальной памяти потоков).
- IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG - Каталог конфигурации загрузки.
- IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT - Каталог для таблицы диапазонного импорта.
- IMAGE_DIRECTORY_ENTRY_IAT - Каталог для таблицы адресов импорта (IAT).
- IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT - Каталог для таблицы отложенного импорта. Структура таблицы отложенного импорта зависит от компоновщика.
- IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR - Каталог для заголовков .NET.
Пример: pe.data_directories[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].virtual_address != 0
number_of_sections
Число секций в PE-файле.
sections
Добавлено в версии 3.3.0.
Начинающийся с нуля массив объектов описания секций, по одному на каждую секцию, которые имеет PE-файл. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
- name - Имя секции.
- characteristics - Характеристики секции.
- virtual_address - Виртуальный адрес секции.
- virtual_size - Виртуальный размер секции.
- raw_data_offset - Смещение секции в файле.
- raw_data_size - Физический размер секции.
- pointer_to_relocations - Добавлено в версии 3.8.0. Переменная, содержащая значение IMAGE_SECTION_HEADER::PointerToRelocations.
- pointer_to_line_numbers - Добавлено в версии 3.8.0. Переменная, содержащая значение IMAGE_SECTION_HEADER::PointerToLinenumbers.
- number_of_relocations Добавлено в версии 3.8.0. Переменная, содержащая значение IMAGE_SECTION_HEADER::NumberOfRelocations.
- number_of_line_numbers - Добавлено в версии 3.8.0. Переменная, содержащая значение IMAGE_SECTION_HEADER::NumberOfLineNumbers.
Пример: pe.sections[0].name == ".text"
Каждую характеристику секции можно проверить, выполнив побитовую операцию AND со следующими константами:
- SECTION_CNT_CODE
- SECTION_CNT_INITIALIZED_DATA
- SECTION_CNT_UNINITIALIZED_DATA
- SECTION_GPREL
- SECTION_MEM_16BIT
- SECTION_LNK_NRELOC_OVFL
- SECTION_MEM_DISCARDABLE
- SECTION_MEM_NOT_CACHED
- SECTION_MEM_NOT_PAGED
- SECTION_MEM_SHARED
- SECTION_MEM_EXECUTE
- SECTION_MEM_READ
- SECTION_MEM_WRITE
Пример: pe.sections[1].characteristics & SECTION_CNT_CODE
overlay
Добавлено в версии 3.6.0.
Структура, содержащая следующие целочисленные элементы:
- offset - Смещение секции оверлея.
- size - размер секции оверлея.
Пример: uint8(0x0d) at pe.overlay.offset and pe.overlay.size > 1024
number_of_resources
Число ресурсов в PE-файле
resource_timestamp
Дата и время подключения ресурсов от ресурсного компилятора. Сохраняется в виде целого числа.
resource_version
Объект, содержащий два целых числа:
- major - Старшая цифра номера версии ресурсов.
- minor - Младшая цифра номера версии ресурсов.
resources
Добавлено в версии 3.3.0.
Начинающийся с нуля массив объектов описания ресурсов, по одному на каждый ресурс, который имеет PE-файл. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
- offset - Смещение на ресурс.
- length - Длина ресурса.
- type - Тип ресурса (integer).
- id - Идентификатор ресурса (integer).
- language - Язык ресурса (integer).
- type_string - Тип ресурса в виде строки, если указан.
- name_string - Имя ресурса в виде строки, если указан.
- language_string - Язык ресурса в виде строки, если указан.
Все ресурсы должны иметь определенный тип, идентификатор (имя) и язык. Они могут выражены либо целыми числами, либо в виде строк.
Пример: pe.resources[0].type == pe.RESOURCE_TYPE_RCDATA
Пример: pe.resources[0].name_string == “F\x00I\x00L\x00E\x00”
Типы ресурсов можно проверить с помощью следующих констант:
- RESOURCE_TYPE_CURSOR
- RESOURCE_TYPE_BITMAP
- RESOURCE_TYPE_ICON
- RESOURCE_TYPE_MENU
- RESOURCE_TYPE_DIALOG
- RESOURCE_TYPE_STRING
- RESOURCE_TYPE_FONTDIR
- RESOURCE_TYPE_FONT
- RESOURCE_TYPE_ACCELERATOR
- RESOURCE_TYPE_RCDATA
- RESOURCE_TYPE_MESSAGETABLE
- RESOURCE_TYPE_GROUP_CURSOR
- RESOURCE_TYPE_GROUP_ICON
- RESOURCE_TYPE_VERSION
- RESOURCE_TYPE_DLGINCLUDE
- RESOURCE_TYPE_PLUGPLAY
- RESOURCE_TYPE_VXD
- RESOURCE_TYPE_ANICURSOR
- RESOURCE_TYPE_ANIICON
- RESOURCE_TYPE_HTML
- RESOURCE_TYPE_MANIFEST
Для получения дополнительной информации см.:
http://msdn.microsoft.com/en-us/library/ms648009(v=vs.85).aspx
version_info
Добавлено в версии 3.2.0.
Словарь, содержащий информацию о версии PE-файла. Типичные ключи:
Comments
, CompanyName
, FileDescription
, FileVersion
, InternalName
, LegalCopyright
, LegalTrademarks
, OriginalFilename
, ProductName
, ProductVersion
Для получения дополнительной информации см.:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646987(v=vs.85).aspx
Пример: pe.version_info[“CompanyName”] contains "Microsoft"
number_of_signatures
Число authenticode-подписей в PE-файле.
signatures
Начинающийся с нуля массив объектов описания подписи, по одному для каждой authenticode-подписи в PE-файле. Обычно PE-файлы имеют одну подпись.
- thumbprint - Добавлено в версии 3.8.0. Строка, содержащая отпечаток (криптографический хэш) подписи.
- issuer - Строка, содержащая информацию об эмитенте подписи.
Вот несколько примеров:
"/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA"
"/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa
(c)10/CN=VeriSign Class 3 Code Signing 2010 CA"
"/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Code Signing CA 2"
- subject - Строка, содержащая информацию о субъекте.
- version - Номер версии.
- algorithm - Алгоритм, используемый в подписи. Обычно “sha1WithRSAEncryption”.
- serial - Строка, содержащая серийный номер.
Например:
"52:00:e5:aa:25:56:fc:1a:86:ed:96:c9:d4:4b:33:c7"
- not_before - Временная метка в формате Unix, с которой начинается срок действия этой подписи.
- not_after - Временная метка в формате Unix, на которой заканчивается срок действия этой подписи.
- valid_on(timestamp) - Функция возвращает
true
, если подпись действительна на дату, указанную меткой времениtimestamp
.
Например, выражение:
pe.signatures[n].valid_on(timestamp)
эквивалентно следующему выражению:
timestamp >= pe.signatures[n].not_before and timestamp <= pe.signatures[n].not_after
rich_signature
Структура, содержащая информацию о Rich-сигнатуре PE-файла. Подробное описание Rich-сигнатуры можно найти здесь.
- offset - Смещение начала Rich-сигнатуры. Будет не определено если Rich-сигнатура отсутствует.
- length - Длина Rich-сигнатуры, не включающая конечный маркер сигнатуры “Rich”.
- key - Ключ, для расшифровки данных с помощью
XOR
. - raw_data - Необработанные данные, как они отображаются в файле.
- clear_data - Данные после расшифровки.
- version(version, [toolid]) - Добавлено в версию 3.5.0. Функция, возвращающая
true
, если PE-файл имеет указанную версиюversion
в Rich-сигнатуре. Укажите необязательный аргументtoolid
для сопоставления только в том случае, если оба аргумента совпадают для одной записи. Более подробную информацию можно найти здесь.
Пример: pe.rich_signature.version(21005)
- toolid(toolid, [version]) - Добавлено в версии 3.5.0. Функция, возвращающая
true
, если PE-файл имеет указанный идентификаторtoolid
в Rich-сигнатуре. Укажите необязательный аргументtoolid
для сопоставления только в том случае, если оба аргумента совпадают для одной записи. Более подробную информацию можно найти здесь.
Пример: pe.rich_signature.toolid(222)
exports(function_name)
Функция, возвращающая true
, если PE-файл экспортирует функцию function_name
или false
в противном случае.
Пример: pe.exports("CPlApplet")
exports(ordinal)
Добавлено в версии 3.6.0.
Функция, возвращающая true
, если PE-файл экспортирует функцию по ординалу ordinal
или false
в противном случае.
Пример: pe.exports(72)
exports(/regular_expression/)
Добавлена в версии 3.7.1.
Функция, возвращающая true
, если PE-файл экспортирует функции в соответствии с регулярным выражением /regular_expression/
или false
в противном случае.
Пример: pe.exports(/^AXS@@/)
number_of_exports
Добавлено в версии 3.6.0.
Число экспортов в PE-файле.
number_of_imports
Добавлено в версии 3.6.0.
Число импортов в PE-файле.
imports(dll_name, function_name)
Функция, возвращающая true
, если PE-файл импортирует функцию function_name
из библиотеки dll_name
, или false
в противном случае (dll_name
не чувствительна к регистру).
Пример: pe.imports(“kernel32.dll”, “WriteProcessMemory”)
imports(dll_name)
Добавлено в версии 3.5.0.
Функция, возвращающая true
, если PE-файл импортирует что-либо из библиотеки dll_name
, или false
в противном случае (dll_name
не чувствительна к регистру).
Пример: pe.imports(“kernel32.dll”)
imports(dll_name, ordinal)
Добавлено в версии 3.5.0.
Функция, возвращающая true
, если PE-файл импортирует функцию по ординалу ordinal
из библиотеки dll_name
, или false
в противном случае (dll_name
не чувствительна к регистру).
Пример: pe.imports(“WS2_32.DLL”, 3)
imports(dll_regexp, function_regexp)
Добавлено в версии 3.8.0.
Функция, возвращающая true
, если PE-файл импортирует функции в соответствии с регулярным выражением function_regexp
из библиотеки в соответствии с регулярным выражением dll_regexp
или false в противном случае. dll_regexp
чувствителен к регистру, если не используется модификатор /i
в регулярном выражении, как показано ниже.
Пример: pe.imports(/kernel32.dll/i, /(Read|Write)ProcessMemory/)
locale(locale_identifier)
Добавлено в версии 3.2.0.
Функция, возвращающая true
, если PE-файл имеет ресурс с указанным идентификатором локали locale_identifier
. Идентификаторы локали являются 16-разрядными целыми числами и могут быть найдены здесь.
Пример: pe.locale(0x0419) // Россия (RU)
language(language_identifier)
Добавлено в версии 3.2.0.
Функция, возвращающая true
, если PE-файл имеет ресурс с указанным идентификатором языка language_identifier
. Идентификаторы языка представляют собой 8-разрядные целые числа и могут быть найдены здесь.
Пример: pe.language(0x0A) // Испания
imphash()
Добавлено в версии 3.2.0.
Функция, возвращающая хэш импорта или imphash для PE-файла. Imphash - это MD5-хэш таблицы импорта PE-файла после некоторой нормализации. Imphash для PE-файла может быть также вычислена с помощью pefile и вы можете найти больше информации в Mandiant’s blog.
Пример: pe.imphash() == "b8bb385806b89680e13fc0cf24f4431e"
section_index(name)
Функция, возвращающая индекс секции с именем name
(name
чувствительно к регистру).
Пример: pe.section_index(".TEXT")
section_index(addr)
Добавлено в версии 3.3.0.
Функция, возвращающая индекс секции с адресом addr
. Адрес addr
может быть смещением в файле или адресом в памяти.
Пример: pe.section_index(pe.entry_point)
is_dll()
Добавлено в версии 3.5.0.
Функция возвращает true
если PE-файл является DLL-библиотекой.
Пример: pe.is_dll()
is_32bit()
Добавлено в версии 3.5.0.
Функция возвращает true
если PE-файл является 32-битным.
Пример: pe.is_32bit()
is_64bit()
Добавлено в версии 3.5.0.
Функция возвращает true
если PE-файл является 64-битным.
Пример: pe.is_64bit()
rva_to_offset(addr)
Добавлено в версии 3.6.0.
Функция, возвращающая смещение в файле для RVA-адреса addr
.
Пример: pe.rva_to_offset(pe.entry_point)
3.2. Модуль ELF¶
Добавлено в версии 3.2.0.
Модуль ELF очень похож на модуль PE, но предназначен для анализа файлов типа ELF. Этот модуль предоставляет большинство полей, присутствующих в заголовке ELF-файлов. Рассмотрим несколько примеров:
import "elf"
rule single_section
{
condition:
elf.number_of_sections == 1
}
rule elf_64
{
condition:
elf.machine == elf.EM_X86_64
}
3.2.1. Описание¶
type
Целочисленная переменная с одним из следующих значений:
- ET_NONE - Тип файла не определен.
- ET_REL - Перемещаемый файл.
- ET_EXEC - Исполняемый файл.
- ET_DYN - Общий объектный файл.
- ET_CORE - Файл ядра.
Пример: elf.type == elf.ET_EXEC
machine
Целочисленная переменная с одним из следующих значений:
- EM_M32
- EM_SPARC
- EM_386
- EM_68K
- EM_88K
- EM_860
- EM_MIPS
- EM_MIPS_RS3_LE
- EM_PPC
- EM_PPC64
- EM_ARM
- EM_X86_64
- EM_AARCH64
Пример: elf.machine == elf.EM_X86_64
entry_point
Смещение точки входа в файле или виртуальный адрес в зависимости от того, сканирует ли YARA файл или память процесса соответственно.
number_of_sections
Число секций в ELF-файле.
sections
Начинающийся с нуля массив объектов описания секций, по одному на каждую секцию, которые имеет ELF-файл. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
- name - Имя секции.
Пример: elf.sections[3].name == ".bss"
size - Размер секции в байтах. За исключением секций типа
SHT_NOBITS
(см. типtype
секции ниже), секция занимаетsh_size
байт в файле. РазделSHT_NOBITS
может иметь ненулевой размер в памяти, но он не занимает места в файле.offset - Смещение от начала файла до первого байта секции. Один из типов секции
SHT_NOBITS
, который будет описан ниже, не занимает места в файле, а его элементoffset
определяет абстрактное размещение в файле.type - Целочисленная переменная с одним из следующих значений:
- SHT_NULL - Этим значением отмечены неактивные секции. Остальные поля описаний таких секций имеют неопределенное значение.
- SHT_PROGBITS - Раздел содержит информацию, формат и значение которой определяются исключительно программой (код, данные или что-либо еще).
- SHT_SYMTAB - Секция содержит таблицу символов.
- SHT_STRTAB - Секция содержит таблицу строк. Объектный файл может иметь несколько секций с таблицами строк.
- SHT_RELA - Секция содержит записи о перемещаемых адресах (relocations).
- SHT_HASH - Секция содержит хеш-таблицу имен для динамического связывания.
- SHT_DYNAMIC - Секция содержит информацию для динамического связывания.
- SHT_NOTE - Секция содержит дополнительную информацию.
- SHT_NOBITS - Секция этого типа не занимает места в файле, но в остальном напоминает секцию типа
SHT_PROGBITS
. - SHT_REL - Секция содержит записи о перемещаемых адресах.
- SHT_SHLIB - Этот тип секции зарезервирован.
- SHT_DYNSYM - Секция содержит набор символов для динамической компоновки.
flags - Целочисленная переменная, в которой содержатся флаги секции, определяемые следующим образом:
- SHF_WRITE - Секция содержит данные, которые должны быть доступны для записи во время выполнения процесса.
- SHF_ALLOC - Секция занимает память при работе процесса. Некоторые управляющие секции не располагаются в образе памяти объектного файла. Этот атрибут выключен у таких разделов.
- SHF_EXECINSTR - Секция содержит исполняемые машинные инструкции.
Пример: elf.sections[2].flags & elf.SHF_WRITE
- address - Добавлено в версии 3.6.0. Виртуальный адрес, с которого начинается секция.
number_of_segments
Добавлено в версии 3.4.0.
Число сегментов в ELF-файле.
segments
Добавлено в версии 3.4.0.
Начинающийся с нуля массив объектов описания сегментов, по одному на каждый сегмент, которые имеет ELF-файл. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
alignment - Значение согласно которому сегменты выровнены в памяти и в файле.
file_size - Число байт занимаемое сегментом в файле. Оно может быть равно нулю.
flags - Комбинация флагов сегмента:
- PF_R - Сегмент доступен для чтения.
- PF_W - Сегмент доступен для записи.
- PF_X - Исполняемый сегмент.
memory_size - Размер сегмента в памяти.
offset - Это поле содержит смещение от начала файла, по которому располагается первый байт сегмента.
physical_address - В системах, для которых важна физическая адресация, это поле содержит физический адрес сегмента.
type - Тип сегмента, определяемый одним из следующих значений:
- PT_NULL
- PT_LOAD
- PT_DYNAMIC
- PT_INTERP
- PT_NOTE
- PT_SHLIB
- PT_PHDR
- PT_LOPROC
- PT_HIPROC
- PT_GNU_STACK
virtual_address - Это поле содержит виртуальный адрес, по которому располагается первый байт сегмента в памяти.
dynamic_section_entries
Добавлено в версии 3.6.0.
Число записей в секции .dynamic
ELF-файла
dynamic
Добавлено в версии 3.6.0.
Начинающийся с нуля массив объектов, по одному на каждую запись секции .dynamic
ELF-файла. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
type - Значение, которое описывает тип секции
.dynamic
. Возможные значения:- DT_NULL
- DT_NEEDED
- DT_PLTRELSZ
- DT_PLTGOT
- DT_HASH
- DT_STRTAB
- DT_SYMTAB
- DT_RELA
- DT_RELASZ
- DT_RELAENT
- DT_STRSZ
- DT_SYMENT
- DT_INIT
- DT_FINI
- DT_SONAME
- DT_RPATH
- DT_SYMBOLIC
- DT_REL
- DT_RELSZ
- DT_RELENT
- DT_PLTREL
- DT_DEBUG
- DT_TEXTREL
- DT_JMPREL
- DT_BIND_NOW
- DT_INIT_ARRAY
- DT_FINI_ARRAY
- DT_INIT_ARRAYSZ
- DT_FINI_ARRAYSZ
- DT_RUNPATH
- DT_FLAGS
- DT_ENCODING
value - Значение, связанное с данным типом. Тип значения (адрес, размер и т. д.) зависит от типа записи.
symtab_entries
Добавлено в версии 3.6.0.
Число записей в таблице символов в ELF-файле.
symtab
Добавлено в версии 3.6.0.
Начинающийся с нуля массив описаний символьных объектов, по одному на каждую запись, найденную в SYMBTAB
ELF-файла. Доступ к отдельным символьным объектам можно получить с помощью оператора []
. Каждый символьный объект имеет следующие атрибуты:
name - Имя символа.
value - Значение, связанное с символом. Обычно, виртуальный адрес.
size - Размер символа.
type - Тип символа. Возможные значения:
- STT_NOTYPE
- STT_OBJECT
- STT_FUNC
- STT_SECTION
- STT_FILE
- STT_COMMON
- STT_TLS
bind - Атрибуты привязки символа. Возможные значения:
- STB_LOCAL
- STB_GLOBAL
- STB_WEAK
shndx - Индекс секции, с которым связан символ.
3.3. Модуль Cuckoo¶
Модуль Cuckoo позволяет создавать правила YARA на основе поведенческой информации, генерируемой Cuckoo sandbox. При сканировании PE-файла с помощью YARA вы можете передать дополнительную информацию о его поведении модулю cuckoo
и создавать правила, основанные не только на том, что содержит файл, но и на том, что он делает.
Warning
Этот модуль не встроен в YARA по умолчанию, чтобы узнать, как его включить, обратитесь к п. 1.1.
Для пользователей Windows: этот модуль уже включен в официальные бинарные файлы Windows.
Предположим, что вы заинтересованы в том, чтобы исполняемые файлы отправляли HTTP-запросы на http://someone.doingevil.com
. В предыдущих версиях YARA вам приходилось довольствоваться только этим:
rule evil_doer
{
strings:
$evil_domain = "http://someone.doingevil.com"
condition:
$evil_domain
}
Проблема с этим правилом заключается в том, что доменное имя может содержаться в файле по вполне обоснованным причинам, не связанным с отправкой HTTP-запросов на http://someone.doingevil.com
. Кроме того, вредоносный файл может содержать имя домена в зашифрованном или обфусцированном виде, в этом случае это правило будет полностью бесполезным.
Но теперь с модулем Cuckoo
вы можете взять отчет о поведении, сгенерированный для исполняемого файла вашей песочницей Cuckoo
, передать его вместе с исполняемым файлом в YARA и написать правило, подобное этому:
import "cuckoo"
rule evil_doer
{
condition:
cuckoo.network.http_request(/http:\/\/someone\.doingevil\.com/)
}
Конечно, вы можете смешать ваши связанные с поведением условия с обычными условиями на основе строк:
import "cuckoo"
rule evil_doer
{
strings:
$some_string = { 01 02 03 04 05 06 }
condition:
$some_string and
cuckoo.network.http_request(/http:\/\/someone\.doingevil\.com/)
}
Но как мы можем передать информацию о поведении модулю Cuckoo
? В случае использования командной строки необходимо использовать опцию -x
следующим образом:
$yara -x cuckoo=behavior_report_file rules_file pe_file
behavior_report_file
- это путь к файлу, содержащему файл поведения, сгенерированный песочницей Cuckoo
в формате JSON.
Если вы используете yara-python
, вы должны передать отчет о поведении в аргументе modules_data
для метода match
:
import yara
rules = yara.compile('./rules_file')
report_file = open('./behavior_report_file')
report_data = report_file.read()
rules.match(pe_file, modules_data={'cuckoo': bytes(report_data)})
3.3.1. Описание¶
network
- http_request(regexp) - Функция возвращает
true
, если программа отправила HTTP-запрос на URL-адрес, соответствующий регулярному выражениюregexp
.
Пример: cuckoo.network.http_request(/evil.com/)
- http_get(regexp) - Аналогичен
http_request()
, но учитывает только запросыGET
. - http_post(regexp) - Аналогичен
http_request ()
, но учитывает только запросыPOST
. - dns_lookup(regexp) - Функция возвращает
true
, если программа отправила запрос на разрешение имени домена, соответствующего указанному регулярному выражению.
Пример: cuckoo.network.dns_lookup(/evil.com/)
registry
- key_access(regexp) - Функция возвращает
true
, если программа произвела обращение к записи реестра, соответствующей регулярному выражениюregexp
.
Пример: cuckoo.registry.key_access(/\Software\Microsoft\Windows\CurrentVersion\Run/)
filesystem
- file_access(regexp) - Функция возвращает
true
, если программа произвела обращение к файлу, соответствующему регулярному выражениюregexp
.
Пример: cuckoo.filesystem.file_access(/autoexec.bat/)
sync
- mutex(regexp) - Функция возвращает
true
, если программа открыла и создала мьютекс, соответствующий регулярному выражениюregexp
.
Пример: cuckoo.sync.mutex(/EvilMutexName/)
3.4. Модуль Magic¶
Добавлено в версии 3.1.0.
Модуль Magic
позволяет определить тип файла, на основе вывода стандартной команды Unix - file.
Warning
Этот модуль не встроен в YARA по умолчанию, чтобы узнать, как его включить, обратитесь к п. 1.1.
Note
Для пользователей Windows: данный модуль не поддерживается Windows.
В этом модуле есть две функции: type ()
и mime_type ()
. Первая возвращает описательную строку, возвращаемую командой file
, например, если вы запустите file
для какого-либо документа PDF, вы получите что-то вроде этого:
$file some.pdf
some.pdf: PDF document, version 1.5
Функция type ()
в этом случае возвращает "PDF document, version 1.5"
. Использование функции mime_type ()
аналогично передаче аргумента --mime
для команды file
:
$file --mime some.pdf
some.pdf: application/pdf; charset=binary
mime_type ()
вернет "application/pdf"
без части charset
.
Немного поэкспериментировав с командой file
, вы можете узнать, какие выходные данные ожидать для разных типов файлов. Вот несколько примеров:
- JPEG image data, JFIF standard 1.01
- PE32 executable for MS Windows (GUI) Intel 80386 32-bit
- PNG image data, 1240 x 1753, 8-bit/color RGBA, non-interlaced
- ASCII text, with no line terminators
- Zip archive data, at least v2.0 to extract
type()
Функция, возвращающая строку с типом файла.
Пример: magic.type() contains "PDF"
mime_type()
Функция, возвращающая строку с типом MIME файла.
Пример: magic.mime_type() == "application/pdf"
3.5. Модуль Hash¶
Добавлено в версии 3.2.0.
Модуль Hash
позволяет вычислять хэши (MD5, SHA1, SHA256) из частей файла и создавать сигнатуры на основе этих хэшей.
Warning
Этот модуль зависит от библиотеки OpenSSL. Пожалуйста, обратитесь к п. 1.1 для получения информации о том, как встроить OpenSSL-зависимые функции в YARA.
Note
Для пользователей Windows: этот модуль уже включен в официальные бинарные файлы.
md5(offset, size)
Возвращает MD5-хэш для size
байтов, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен быть виртуальным адресом в адресном пространстве процесса. Возвращаемая строка всегда в нижнем регистре.
Пример: hash.md5(0, filesize) == "feba6c919e3797e7778e8f2e85fa033d"
md5(string)
Возвращает MD5-хэш строки string
.
Example: hash.md5(“dummy”) == "275876e34cf609db118f3d84b799a790"
sha1(offset, size)
Возвращает SHA1-хэш для size
байтов, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен быть виртуальным адресом в адресном пространстве процесса. Возвращаемая строка всегда в нижнем регистре..
sha1(string)
Возвращает SHA1-хэш строки string
.
sha256(offset, size)
Возвращает SHA256-хэш для size
байтов, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен быть виртуальным адресом в адресном пространстве процесса. Возвращаемая строка всегда в нижнем регистре..
sha256(string)
Возвращает SHA256-хэш строки string
.
checksum32(offset, size)
Возвращает 32-разрядную контрольную сумму для size
байтов, начиная со смещения offset
. Контрольная сумма - это сумма всех байтов (без знака).
checksum32(string)
Возвращает 32-разрядную контрольную сумму строки string
. Контрольная сумма - это сумма всех байтов (без знака).
3.6. Модуль Math¶
Добавлено в версии 3.3.0.
Модуль Math
позволяет вам вычислять определенные значения из частей вашего файла и создавать сигнатуры на основе этих результатов.
Note
Где отмечено, функции модуля возвращают числа с плавающей запятой. YARA может преобразовывать целые числа в числа с плавающей запятой во время большинства операций. Пример, приведенный ниже автоматически преобразует 7
в 7.0
, потому что тип возвращаемой функции энтропии - значение с плавающей запятой:
math.entropy(0, filesize) >= 7
Единственным исключением является случай, когда функции требуется число с плавающей запятой в качестве аргумента. Например, такая запись приведет к синтаксической ошибке, поскольку аргументы должны быть числами с плавающей запятой:
math.in_range(2, 1, 3)
entropy(offset, size)
Возвращает энтропию size
байт начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен содержать виртуальный адрес в адресном пространстве процесса. Возвращаемое значение - число с плавающей запятой.
Пример: math.entropy(0, filesize) >= 7
entropy(string)
Возвращает энтропию строки string
.
Пример: math.entropy(“dummy”) > 7
monte_carlo_pi(offset, size)
Возвращает процент от числа Pi при расчете числа Pi методом Монте-Карло с использованием последовательности чисел размером size
байт, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен содержать виртуальный адрес в адресном пространстве процесса. Возвращаемое значение - число с плавающей запятой.
Пример: math.monte_carlo_pi(0, filesize) < 0.0
monte_carlo_pi(string)
Возвращает процент от числа Pi при расчете числа Pi методом Монте-Карло с использованием строки string
.
serial_correlation(offset, size)
Возвращает значение коэффициента последовательной корреляции для size
байт, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен содержать виртуальный адрес в адресном пространстве процесса. Возвращаемое значение - число с плавающей запятой в пределах от 0.0 до 1.0.
Пример: math.serial_correlation(0, filesize) < 0.2
serial_correlation(string)
Возвращает значение коэффициента последовательной корреляции для строки string
.
mean(offset, size)
Возвращает среднее значение для size
байт, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен содержать виртуальный адрес в адресном пространстве процесса. Возвращаемое значение - число с плавающей запятой.
Пример: math.mean(0, filesize) < 72.0
mean(string)
Возвращает среднее значение для строки string
.
deviation(offset, size, mean)
Возвращает отклонение от среднего значения для size
байт, начиная со смещения offset
. При сканировании запущенного процесса аргумент offset
должен содержать виртуальный адрес в адресном пространстве процесса. Возвращаемое значение - число с плавающей запятой.
Среднее значение равномерно распределенной случайной выборки байтов равно числу 127.5, которое доступно как константа math.MEAN_BYTES
.
Пример: math.deviation(0, filesize, math.MEAN_BYTES) == 64.0
deviation(string, mean)
Возвращает отклонение от среднего значения для строки string
.
in_range(test, lower, upper)
Возвращает true
, если значение test
находится между нижним lower
и верхним upper
значениями. Сравнение производится включительно для lower
и upper
значений.
Пример: math.in_range(math.deviation(0, filesize, math.MEAN_BYTES), 63.9, 64,1)
max(int, int)
Добавлено в версии 3.8.0.
Возвращает максимум из двух целочисленных беззнаковых значений.
min(int, int)
Добавлено в версии 3.8.0.
Возвращает минимум из двух целочисленных беззнаковых значений.
3.7. Модуль dotnet¶
Добавлено в версии 3.6.0.
Модуль dotnet
позволяет создавать более детализированные правила для файлов .NET с помощью атрибутов и функций формата файлов .NET. Например:
import "dotnet"
rule not_exactly_five_streams
{
condition:
dotnet.number_of_streams != 5
}
rule blop_stream
{
condition:
for any i in (0..dotnet.number_of_streams - 1):
(dotnet.streams[i].name == "#Blop")
}
3.7.1. Описание¶
version
Строка с версией, содержащаяся в корне метаданных.
Пример: dotnet.version == "v2.0.50727"
module_name
Наименование модуля.
Example: dotnet.module_name == "axs"
number_of_streams
Число потоков в файле.
streams
Начинающийся с нуля массив объектов описания потоков, для каждого потока в файле. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
- name - Имя потока.
- offset - Смещение потока.
- size - Размер потока.
Пример: dotnet.streams[0].name == "#~"
number_of_guids
Количество идентификаторов в GUID-массиве.
guids
Начинающийся с нуля массив строк, по одной для каждого GUID. Доступ к отдельным объектам массива можно получить с помощью оператора []
.
Пример: dotnet.guids[0] == "99c08ffd-f378-a891-10ab-c02fe11be6ef"
number_of_resources
Число ресурсов в .NET-файле. Они отличаются от обычных ресурсов PE-файлов.
resources
Начинающийся с нуля массив объектов описания ресурсов, для каждого ресурса в файле. Доступ к отдельным объектам массива можно получить с помощью оператора []
. Каждый объект массива имеет следующие атрибуты:
- offset - Смещение на данные ресурса.
- length - Длина данных ресурса.
- name - Имя ресурса (в виде строки).
Пример: uint16be(dotnet.resources[0].offset) == 0x4d5a
assembly
Объект, содержащий информацию о сборке .NET:
- version - Объект с целочисленными значениями, представляющими информацию о версии для этой сборки. Атрибуты:
major minor build_number revision_number
- name - Строка, содержащая имя сборки.
- culture - Строка, содержащая
language/country/region
данной сборки.
Пример: dotnet.assembly.name == "Keylogger"
Пример: dotnet.assembly.version.major == 7 and dotnet.assembly.version.minor == 0
number_of_modulerefs
Число ссылок на модули в .NET-файле.
modulerefs
Начинающийся с нуля массив строк, по одной на каждую ссылку на модуль в .NET-файле. Доступ к отдельным объектам массива можно получить с помощью оператора []
.
Example: dotnet.modulerefs[0] == "kernel32"
typelib
Библиотека типа .NET-файла.
assembly_refs
Объект для справочной информации сборки .NET.
- version -Объект с целочисленными значениями, представляющими информацию о версии для этой сборки. Атрибуты:
major minor build_number revision_number
. - name - Строка, содержащая имя сборки.
- public_key_or_token - Строка, содержащая открытый ключ или токен, который идентифицирует автора этой сборки.
number_of_user_strings
Число пользовательских строк в .NET-файле.
user_strings
Начинающийся с нуля массив пользовательских строк, по одной на каждый поток, содержащийся в .NET-файле. Доступ к отдельным строкам можно получить с помощью оператора []
.
3.8. Модуль Time¶
Добавлено в версии 3.7.0.
Модуль Time
позволяет использовать временные условия в правилах YARA.
now()
Функция возвращает целое число - количество секунд с 1 января 1970 года.
Пример: pe.timestamp > time.now()