Рекомендации по использованию запросов расширенного выслеживанияAdvanced hunting query best practices

Важно!

Улучшенный Центр безопасности Microsoft 365 теперь доступен в общедоступной предварительной версии.The improved Microsoft 365 security center is now available. Этот новый интерфейс Центра безопасности Microsoft 365 объединяет Defender для конечной точки, Defender для Office 365, Microsoft 365 Defender и другие решения.This new experience brings Defender for Endpoint, Defender for Office 365, Microsoft 365 Defender, and more into the Microsoft 365 security center. Узнайте о новых возможностях.Learn what's new.

Область применения:Applies to:

  • Microsoft 365 DefenderMicrosoft 365 Defender

Применяем эти рекомендации, чтобы быстрее получать результаты и избегать периодов времени во время работы сложных запросов.Apply these recommendations to get results faster and avoid timeouts while running complex queries. Дополнительные руководства по повышению производительности запросов см. в статье Рекомендации по использованию запросов Kusto.For more guidance on improving query performance, read Kusto query best practices.

Понимание квот ресурсов ЦПUnderstand CPU resource quotas

В зависимости от его размера каждый клиент имеет доступ к определенному объему ресурсов ЦП, выделенным для работы с расширенными запросами на охоту.Depending on its size, each tenant has access to a set amount of CPU resources allocated for running advanced hunting queries. Подробные сведения о различных ограничениях службы читайте в материале "Расширенные квоты на охоту и параметры использования".For detailed information about various service limits, read about advanced hunting quotas and usage parameters.

Клиенты, регулярно запускающие несколько запросов, должны отслеживать потребление и применять рекомендации по оптимизации в этой статье, чтобы свести к минимуму нарушения в результате превышения квот или параметров использования.Customers who run multiple queries regularly should track consumption and apply the optimization guidance in this article to minimize disruption resulting from exceeding quotas or usage parameters.

Общие советы по оптимизацииGeneral optimization tips

  • Размер новых запросов— Если вы подозреваете, что запрос возвращает большой набор результатов, сначала оцените его с помощью оператора подсчета.Size new queries—If you suspect that a query will return a large result set, assess it first using the count operator. Используйте ограничение или его синоним, take чтобы избежать больших наборов результатов.Use limit or its synonym take to avoid large result sets.

  • Применяйте фильтры на ранних стадиях применяйте фильтры времени и другие фильтры, чтобы уменьшить набор данных, особенно перед использованием функций преобразования и анализа, таких как substring(), replace(), trim(), toupper() или parse_json().Apply filters early—Apply time filters and other filters to reduce the data set, especially before using transformation and parsing functions, such as substring(), replace(), trim(), toupper(), or parse_json(). В приведенной ниже примере функция размыва используется после того, как операторы фильтрации сократили количество записей.In the example below, the parsing function extractjson() is used after filtering operators have reduced the number of records.

    DeviceEvents
    | where Timestamp > ago(1d)
    | where ActionType == "UsbDriveMount" 
    | where DeviceName == "user-desktop.domain.com"
    | extend DriveLetter = extractjson("$.DriveLetter", AdditionalFields)
    
  • Имеет биты содержит- Чтобы избежать поиска подстройки в словах излишне, используйте has оператора, а contains не .Has beats contains—To avoid searching substrings within words unnecessarily, use the has operator instead of contains. Узнайте о операторах строкиLearn about string operators

  • Посмотрите в определенных столбцах. Посмотрите в определенный столбец, а не выполняется полный текстовый поиск во всех столбцах.Look in specific columns—Look in a specific column rather than running full text searches across all columns. Не используйте для * проверки всех столбцов.Don't use * to check all columns.

  • Деликатный для скорости— поиски, чувствительные к конкретным случаям, являются более конкретными и, как правило, более исполняемыми.Case-sensitive for speed—Case-sensitive searches are more specific and generally more performant. Имена чувствительных к делу операторовстрок, таких как has_cs и , как contains_cs правило, заканчиваются _cs .Names of case-sensitive string operators, such as has_cs and contains_cs, generally end with _cs. Кроме того, можно использовать оператора равного с чувствительностью к == делу. =~You can also use the case-sensitive equals operator == instead of =~.

  • Размыть, не извлекать -По возможности, используйте оператора размыва или функции размыва, как parse_json().Parse, don't extract—Whenever possible, use the parse operator or a parsing function like parse_json(). Избегайте matches regex оператора строки или функции extract()( оба из которых используют регулярное выражение.Avoid the matches regex string operator or the extract() function, both of which use regular expression. Зарезервировать использование регулярного выражения для более сложных сценариев.Reserve the use of regular expression for more complex scenarios. Узнайте больше о функциях размыканияRead more about parsing functions

  • Фильтрация таблиц не выражений— не фильтруйте вычисляемую колонку, если можно фильтровать столбец таблицы.Filter tables not expressions—Don't filter on a calculated column if you can filter on a table column.

  • Нет трех характерных терминов— избегайте сравнения или фильтрации с помощью терминов с тремя символами или меньше.No three-character terms—Avoid comparing or filtering using terms with three characters or fewer. Эти термины не индексироваться, и их соответствие потребует дополнительных ресурсов.These terms are not indexed and matching them will require more resources.

  • Project выборочно— сделайте результаты более понятными, проецив только нужные столбцы.Project selectively—Make your results easier to understand by projecting only the columns you need. Проецация определенных столбцов перед запуском присоединяющихся или аналогичных операций также помогает повысить производительность.Projecting specific columns prior to running join or similar operations also helps improve performance.

Оптимизация join оператораOptimize the join operator

Оператор объединения объединяет строки из двух таблиц, соединяя значения в указанных столбцах.The join operator merges rows from two tables by matching values in specified columns. Используйте эти советы для оптимизации запросов, которые используют этот оператор.Apply these tips to optimize queries that use this operator.

  • Более малая таблица слева — оператор соединяет записи в таблице слева от заявления о присоединиться к записям join справа.Smaller table to your left—The join operator matches records in the table on the left side of your join statement to records on the right. Если таблица меньше слева, потребуется соблюсти меньше записей, что ускорит запрос.By having the smaller table on the left, fewer records will need to be matched, thus speeding up the query.

    В таблице ниже мы уменьшаем левую таблицу, чтобы охватить только три конкретных устройства перед присоединением к ней с помощью DeviceLogonEvents IdentityLogonEvents SID-данных учетной записи.In the table below, we reduce the left table DeviceLogonEvents to cover only three specific devices before joining it with IdentityLogonEvents by account SIDs.

    DeviceLogonEvents 
    | where DeviceName in ("device-1.domain.com", "device-2.domain.com", "device-3.domain.com")
    | where ActionType == "LogonFailed"
    | join
        (IdentityLogonEvents
        | where ActionType == "LogonFailed"
        | where Protocol == "Kerberos")
    on AccountSid
    
  • Используйте внутренний примыкающий к нему аромат — аромат соедините по умолчанию или строки deduplicates innerunique-join в левой таблице ключом соединителя перед возвращением строки для каждого совпадения в правую таблицу. Use the inner-join flavor—The default join flavor or the innerunique-join deduplicates rows in the left table by the join key before returning a row for each match to the right table. Если в левой таблице имеется несколько строк с одинаковым значением для ключа, эти строки будут отлажены, чтобы оставить одну рандомную строку для каждого join уникального значения.If the left table has multiple rows with the same value for the join key, those rows will be deduplicated to leave a single random row for each unique value.

    Это поведение по умолчанию может оставить важные сведения из левой таблицы, которые могут предоставить полезные сведения.This default behavior can leave out important information from the left table that can provide useful insight. Например, в приведенном ниже запросе будет содержаться только одно сообщение, содержащее определенное вложение, даже если это же вложение было отправлено с помощью нескольких сообщений электронной почты:For example, the query below will only show one email containing a particular attachment, even if that same attachment was sent using multiple emails messages:

    EmailAttachmentInfo
    | where Timestamp > ago(1h)
    | where Subject == "Document Attachment" and FileName == "Document.pdf"
    | join (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256 
    

    Чтобы решить это ограничение, мы применяем аромат внутреннего присоединяния, указав, чтобы показать все строки в левой таблице со значениями в kind=inner правой части:To address this limitation, we apply the inner-join flavor by specifying kind=inner to show all rows in the left table with matching values in the right:

    EmailAttachmentInfo
    | where Timestamp > ago(1h)
    | where Subject == "Document Attachment" and FileName == "Document.pdf"
    | join kind=inner (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256 
    
  • Регистрация записей из окне времени . При расследовании событий безопасности аналитики изучают связанные события, которые происходят примерно в тот же период времени.Join records from a time window—When investigating security events, analysts look for related events that occur around the same time period. Применение такого же подхода при использовании также приносит пользу производительности, уменьшая количество записей join для проверки.Applying the same approach when using join also benefits performance by reducing the number of records to check.

    Запрос ниже проверяет события с логотипом в течение 30 минут после получения вредоносного файла:The query below checks for logon events within 30 minutes of receiving a malicious file:

    EmailEvents
    | where Timestamp > ago(7d)
    | where ThreatTypes has "Malware"
    | project EmailReceivedTime = Timestamp, Subject, SenderFromAddress, AccountName = tostring(split(RecipientEmailAddress, "@")[0])
    | join (
    DeviceLogonEvents 
    | where Timestamp > ago(7d)
    | project LogonTime = Timestamp, AccountName, DeviceName
    ) on AccountName 
    | where (LogonTime - EmailReceivedTime) between (0min .. 30min)
    
  • Применение фильтров времени с обеих сторон — Даже если вы не изучаете определенное окно времени, применение фильтров времени как на левом, так и на правом столах может уменьшить количество записей для проверки и повышения join производительности.Apply time filters on both sides—Even if you're not investigating a specific time window, applying time filters on both the left and right tables can reduce the number of records to check and improve join performance. Ниже приведен запрос, применимый к обеим таблицам, чтобы он присоединялся только к записям за Timestamp > ago(1h) прошедший час:The query below applies Timestamp > ago(1h) to both tables so that it joins only records from the past hour:

    EmailAttachmentInfo
    | where Timestamp > ago(1h)
    | where Subject == "Document Attachment" and FileName == "Document.pdf"
    | join kind=inner (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256 
    
  • Используйте подсказки для производительности— Используйте подсказки с оператором, чтобы проинструктация backend для распределения нагрузки при работе с ресурсоемкими join операциями.Use hints for performance—Use hints with the join operator to instruct the backend to distribute load when running resource-intensive operations. Дополнительные новости о подсказках о вступивLearn more about join hints

    Например, подсказка перетасовки помогает повысить производительность запроса при присоединении к таблицам с помощью ключа с высокой кардиналиальностью — ключа с множеством уникальных значений, таких как в нижеуказаемом AccountObjectId запросе:For example, the shuffle hint helps improve query performance when joining tables using a key with high cardinality—a key with many unique values—such as the AccountObjectId in the query below:

    IdentityInfo
    | where JobTitle == "CONSULTANT"
    | join hint.shufflekey = AccountObjectId 
    (IdentityDirectoryEvents
        | where Application == "Active Directory"
        | where ActionType == "Private data retrieval")
    on AccountObjectId 
    

    Подсказка на трансляцию помогает, если левая таблица небольшая (до 100 000 записей), а правая — очень большая.The broadcast hint helps when the left table is small (up to 100,000 records) and the right table is extremely large. Например, в приведенной ниже области запрос пытается присоединиться к нескольким электронным письмам с определенными субъектами со всеми сообщениями, содержащими ссылки в EmailUrlInfo таблице:For example, the query below is trying to join a few emails that have specific subjects with all messages containing links in the EmailUrlInfo table:

    EmailEvents 
    | where Subject in ("Warning: Update your credentials now", "Action required: Update your credentials now")
    | join hint.strategy = broadcast EmailUrlInfo on NetworkMessageId 
    

Оптимизация summarize оператораOptimize the summarize operator

Оператор сводки агрегирует содержимое таблицы.The summarize operator aggregates the contents of a table. Используйте эти советы для оптимизации запросов, которые используют этот оператор.Apply these tips to optimize queries that use this operator.

  • Найдите различные значения. В общем, используйте summarize для поиска различных значений, которые могут быть повторяющимися.Find distinct values—In general, use summarize to find distinct values that can be repetitive. Это может быть ненужным, чтобы использовать его для агрегированных столбцов, которые не имеют повторяющихся значений.It can be unnecessary to use it to aggregate columns that don't have repetitive values.

    Хотя одно сообщение электронной почты может быть частью нескольких событий, пример ниже не является эффективным, так как сетевой ИД сообщения для отдельного электронного письма всегда поставляется с уникальным адресом summarize отправитель.While a single email can be part of multiple events, the example below is not an efficient use of summarize because a network message ID for an individual email always comes with a unique sender address.

    EmailEvents  
    | where Timestamp > ago(1h)
    | summarize by NetworkMessageId, SenderFromAddress   
    

    Оператор можно легко заменить, что дает потенциально те же результаты, но при этом потребляет summarize project меньше ресурсов:The summarize operator can be easily replaced with project, yielding potentially the same results while consuming fewer resources:

    EmailEvents  
    | where Timestamp > ago(1h)
    | project NetworkMessageId, SenderFromAddress   
    

    В следующем примере используется более эффективное использование, так как может быть несколько различных экземпляров адреса отправитель отправки электронной почты на summarize тот же адрес получателя.The following example is a more efficient use of summarize because there can be multiple distinct instances of a sender address sending email to the same recipient address. Такие комбинации менее отличаются друг от друга и могут иметь дубликаты.Such combinations are less distinct and are likely to have duplicates.

    EmailEvents  
    | where Timestamp > ago(1h)
    | summarize by SenderFromAddress, RecipientEmailAddress   
    
  • Перетасовка запроса . Хотя лучше всего использовать в столбцах с повторяющимися значениями, те же столбцы также могут иметь высокий кардинальный характер или большое количество summarize уникальных значений.Shuffle the query—While summarize is best used in columns with repetitive values, the same columns can also have high cardinality or large numbers of unique values. Как и оператор, вы также можете применить подсказку перетасовки для распределения нагрузки на обработку и потенциально повысить производительность при работе на столбцах join с summarize высокой кардинальностью.Like the join operator, you can also apply the shuffle hint with summarize to distribute processing load and potentially improve performance when operating on columns with high cardinality.

    В приведенного ниже запросе используется для подсчета определенного адреса электронной почты получателя, который может работать в сотнях тысяч summarize в крупных организациях.The query below uses summarize to count distinct recipient email address, which can run in the hundreds of thousands in large organizations. Чтобы повысить производительность, он включает hint.shufflekey в себя:To improve performance, it incorporates hint.shufflekey:

    EmailEvents  
    | where Timestamp > ago(1h)
    | summarize hint.shufflekey = RecipientEmailAddress count() by Subject, RecipientEmailAddress
    

Сценарии запросовQuery scenarios

Определение уникальных процессов с помощью идентификации процессовIdentify unique processes with process IDs

Идентификаторы процессов (PID) в Windows перерабатываются и используются для новых процессов.Process IDs (PIDs) are recycled in Windows and reused for new processes. Они не могут служить уникальными идентификаторами для определенных процессов сами по себе.On their own, they can't serve as unique identifiers for specific processes.

Чтобы создать уникальный идентификатор для процесса на определенном компьютере, идентификатор процесса нужно использовать вместе со временем создания процесса.To get a unique identifier for a process on a specific machine, use the process ID together with the process creation time. При объединении или обобщении данных по процессам рекомендуется включать столбцы для идентификатора компьютера (либо DeviceId, либоDeviceName), идентификатора процесса (ProcessId или InitiatingProcessId) и времени создания процесса (ProcessCreationTime или InitiatingProcessCreationTime)When you join or summarize data around processes, include columns for the machine identifier (either DeviceId or DeviceName), the process ID (ProcessId or InitiatingProcessId), and the process creation time (ProcessCreationTime or InitiatingProcessCreationTime)

В приведенном ниже примере запроса обнаружены процессы, имеющие доступ к более чем 10 IP-адресам через порт 445 (SMB) с одновременным возможным сканированием файловых ресурсов.The following example query finds processes that access more than 10 IP addresses over port 445 (SMB), possibly scanning for file shares.

Пример запросаExample query:

DeviceNetworkEvents
| where RemotePort == 445 and Timestamp > ago(12h) and InitiatingProcessId !in (0, 4)
| summarize RemoteIPCount=dcount(RemoteIP) by DeviceName, InitiatingProcessId
InitiatingProcessCreationTime, InitiatingProcessFileName
| where RemoteIPCount > 10

В запросе указаны одновременно и InitiatingProcessId, и InitiatingProcessCreationTime. Благодаря этому запрос относится к одному единственному процессу, и при этом исключаются многочисленные другие процессы с аналогичным идентификатором процесса.The query summarizes by both InitiatingProcessId and InitiatingProcessCreationTime so that it looks at a single process, without mixing multiple processes with the same process ID.

Строки команд запросовQuery command lines

Создать командную строку для выполнения задачи можно разными способами.There are numerous ways to construct a command line to accomplish a task. Например, злоумышленник может ссылаться на файл изображений без пути, без расширения файла, с помощью переменных среды или с кавычками.For example, an attacker could reference an image file without a path, without a file extension, using environment variables, or with quotes. Злоумышленник также может изменить порядок параметров или добавить несколько кавычках и пробелах.The attacker could also change the order of parameters or add multiple quotes and spaces.

Чтобы создать более надежные запросы вокруг командных строк, применяйте следующие практики:To create more durable queries around command lines, apply the following practices:

  • Определите известные процессы (например,net.exe илиpsexec.exe) путем совпадения на полях имен файлов, а не фильтрации на самой командной строке.Identify the known processes (such as net.exe or psexec.exe) by matching on the file name fields, instead of filtering on the command-line itself.
  • Разделы командной строки parse с помощью функции parse_command_line()Parse command-line sections using the parse_command_line() function
  • При запросе аргументов командной строки искать точное совпадение для нескольких несвязанных аргументов в определенном порядке не имеет смысла.When querying for command-line arguments, don't look for an exact match on multiple unrelated arguments in a certain order. Вместо этого используются регулярные выражения или несколько отдельных аргументов, содержащих операторы.Instead, use regular expressions or use multiple separate contains operators.
  • Совпадения используются без учета регистра.Use case insensitive matches. Например, используйте =~ in~ , и вместо , contains и == in contains_cs .For example, use =~, in~, and contains instead of ==, in, and contains_cs.
  • Чтобы смягчить методы запутывания командной строки, рекомендуется удалить кавычка, заменить запятые пробелами и заменить несколько последовательных пробелов одним пространством.To mitigate command-line obfuscation techniques, consider removing quotes, replacing commas with spaces, and replacing multiple consecutive spaces with a single space. Существуют более сложные методы запутывания, которые требуют других подходов, но эти настройки могут помочь в решении распространенных.There are more complex obfuscation techniques that require other approaches, but these tweaks can help address common ones.

В следующих примерах покажите различные способы создания запроса, который ищет файлnet.exe, чтобы остановить службу брандмауэра "MpsSvc":The following examples show various ways to construct a query that looks for the file net.exe to stop the firewall service "MpsSvc":

// Non-durable query - do not use
DeviceProcessEvents
| where ProcessCommandLine == "net stop MpsSvc"
| limit 10

// Better query - filters on file name, does case-insensitive matches
DeviceProcessEvents
| where Timestamp > ago(7d) and FileName in~ ("net.exe", "net1.exe") and ProcessCommandLine contains "stop" and ProcessCommandLine contains "MpsSvc" 

// Best query also ignores quotes
DeviceProcessEvents
| where Timestamp > ago(7d) and FileName in~ ("net.exe", "net1.exe")
| extend CanonicalCommandLine=replace("\"", "", ProcessCommandLine)
| where CanonicalCommandLine contains "stop" and CanonicalCommandLine contains "MpsSvc" 

Ingest data from external sourcesIngest data from external sources

Чтобы включить длинные списки или большие таблицы в запрос, используйте оператора externaldata для пользования данными из указанного URI.To incorporate long lists or large tables into your query, use the externaldata operator to ingest data from a specified URI. Вы можете получать данные из файлов в TXT, CSV, JSON или других форматах.You can get data from files in TXT, CSV, JSON, or other formats. В приведенной ниже примере показано, как можно использовать обширный список хеш-файлов SHA-256, предоставляемых MalwareBazaar (abuse.ch) для проверки вложений в сообщениях электронной почты:The example below shows how you can utilize the extensive list of malware SHA-256 hashes provided by MalwareBazaar (abuse.ch) to check attachments on emails:

let abuse_sha256 = (externaldata(sha256_hash: string )
[@"https://bazaar.abuse.ch/export/txt/sha256/recent/"]
with (format="txt"))
| where sha256_hash !startswith "#"
| project sha256_hash;
abuse_sha256
| join (EmailAttachmentInfo 
| where Timestamp > ago(1d) 
) on $left.sha256_hash == $right.SHA256
| project Timestamp,SenderFromAddress,RecipientEmailAddress,FileName,FileType,
SHA256,ThreatTypes,DetectionMethods

Строки parseParse strings

Существуют различные функции, которые можно использовать для эффективного обработки строк, которые нуждаются в размыве или преобразовании.There are various functions you can use to efficiently handle strings that need parsing or conversion.

StringString ФункцияFunction Пример использованияUsage example
Командные строкиCommand-lines parse_command_line()parse_command_line() Извлекать команду и все аргументы.Extract the command and all arguments.
ПутиPaths parse_path()parse_path() Извлечение разделов пути файла или папки.Extract the sections of a file or folder path.
Номера версийVersion numbers parse_version()parse_version() Деконструировать номер версии с четырьмя разделами и до восьми символов в разделе.Deconstruct a version number with up to four sections and up to eight characters per section. Чтобы сравнить возраст версии, используйте разносчетные данные.Use the parsed data to compare version age.
Адреса IPv4IPv4 addresses parse_ipv4()parse_ipv4() Преобразование адреса IPv4 в длинный ряд.Convert an IPv4 address to a long integer. Чтобы сравнить адреса IPv4 без их преобразования, используйте ipv4_compare().To compare IPv4 addresses without converting them, use ipv4_compare().
Адреса IPv6IPv6 addresses parse_ipv6()parse_ipv6() Преобразование адреса IPv4 или IPv6 в каноническую нотацию IPv6.Convert an IPv4 or IPv6 address to the canonical IPv6 notation. Чтобы сравнить адреса IPv6, используйте ipv6_compare().To compare IPv6 addresses, use ipv6_compare().

Чтобы узнать обо всех поддерживаемых функциях размыва, ознакомьтесь с функциями строк Kusto.To learn about all supported parsing functions, read about Kusto string functions.

Примечание

Некоторые таблицы в этой статье могут быть недоступны в Microsoft Defender для конечной точки.Some tables in this article might not be available in Microsoft Defender for Endpoint. Включи Microsoft 365 Defender, чтобы искать угрозы с помощью дополнительных источников данных.Turn on Microsoft 365 Defender to hunt for threats using more data sources. Вы можете переместить расширенные процессы охоты из Microsoft Defender для endpoint в Microsoft 365 Defender, следуя шагам в миграции расширенных запросов охоты из Microsoft Defender для конечной точки.You can move your advanced hunting workflows from Microsoft Defender for Endpoint to Microsoft 365 Defender by following the steps in Migrate advanced hunting queries from Microsoft Defender for Endpoint.