أفضل ممارسات استعلام التتبع المتقدمة
احصل على النتائج بشكل أسرع وتجنب المهلات أثناء تشغيل الاستعلامات المعقدة عن طريق تحسين استعلاماتك. للحصول على إرشادات حول تحسين أداء الاستعلام:
- نصائح التحسين العامة - في هذه المقالة
-
join
تحسين عامل التشغيل - في هذه المقالة -
summarize
تحسين عامل التشغيل - في هذه المقالة - سيناريوهات الاستعلام - في هذه المقالة
- أفضل ممارسات استعلام Kusto - تتضمن عدة سيناريوهات لجعل استعلامك أكثر كفاءة
- تحسين استعلامات السجل في Azure Monitor - يحتوي على إرشادات إضافية لتحسين الاستعلام
- تحسين استعلامات KQL (فيديو) - الطرق الأكثر شيوعا لتحسين استعلامك
فهم حصص موارد وحدة المعالجة المركزية
اعتمادا على حجمه، لكل مستأجر حق الوصول إلى كمية محددة من موارد وحدة المعالجة المركزية المخصصة لتشغيل استعلامات التتبع المتقدمة. للحصول على معلومات مفصلة حول معلمات الاستخدام المختلفة، اقرأ عن حصص التتبع المتقدمة ومعلمات الاستخدام.
بعد تشغيل الاستعلام، يمكنك مشاهدة وقت التنفيذ واستخدام الموارد الخاصة به (منخفض، متوسط، مرتفع). يشير High إلى أن الاستعلام استغرق المزيد من الموارد لتشغيله ويمكن تحسينه لإرجاع النتائج بشكل أكثر كفاءة.
يجب على العملاء الذين يقومون بتشغيل استعلامات متعددة بانتظام تعقب الاستهلاك وتطبيق إرشادات التحسين في هذه المقالة لتقليل التعطيل الناتج عن تجاوز الحصص النسبية أو معلمات الاستخدام.
نصائح التحسين العامة
حجم الاستعلامات الجديدة — إذا كنت تشك في أن الاستعلام سيرجع مجموعة نتائج كبيرة، فقم بتقييمها أولا باستخدام عامل تشغيل العد. استخدم الحد أو مرادفاته
take
لتجنب مجموعات النتائج الكبيرة.تطبيق عوامل التصفية مبكرا — تطبيق عوامل تصفية الوقت وعوامل التصفية الأخرى لتقليل مجموعة البيانات، خاصة قبل استخدام دالات التحويل وتحليلها، مثل substring()أو replace()أو trim()أو toupper()أو parse_json(). في المثال أدناه، يتم استخدام دالة التحليل extractjson() بعد أن تقلل عوامل تشغيل التصفية من عدد السجلات.
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "UsbDriveMount" | where DeviceName == "user-desktop.domain.com" | extend DriveLetter = extractjson("$.DriveLetter", AdditionalFields)
يحتوي على دقات تحتوي على — لتجنب البحث في المحاولات الفرعية داخل الكلمات دون داع، استخدم
has
عامل التشغيل بدلا منcontains
. تعرف على عوامل تشغيل السلسلةالبحث في أعمدة معينة — ابحث في عمود معين بدلا من تشغيل عمليات البحث عن النص الكامل عبر جميع الأعمدة. لا تستخدم
*
للتحقق من جميع الأعمدة.حساسة لحالة الأحرف للسرعة - عمليات البحث الحساسة لحالة الأحرف أكثر تحديدا وأكثر أداء بشكل عام. أسماء عوامل تشغيل السلسلة الحساسة لحالة الأحرف، مثل
has_cs
وcontains_cs
، تنتهي بشكل عام ب_cs
. يمكنك أيضا استخدام عامل تشغيل==
يساوي الحساس لحالة الأحرف بدلا من=~
.التحليل، لا تستخرج — كلما أمكن، استخدم عامل تشغيل التحليل أو دالة تحليل مثل parse_json().
matches regex
تجنب عامل تشغيل السلسلة أو دالة extract() ، وكلاهما يستخدم التعبير العادي. احجز استخدام التعبير العادي لسيناريوهات أكثر تعقيدا. اقرأ المزيد حول تحليل الوظائفتصفية الجداول وليس التعبيرات — لا تقم بالتصفية على عمود محسوب إذا كان بإمكانك التصفية على عمود جدول.
لا توجد مصطلحات مكونة من ثلاثة أحرف — تجنب المقارنة أو التصفية باستخدام مصطلحات ذات ثلاثة أحرف أو أقل. لا تتم فهرسة هذه الشروط وستتطلب مطابقتها المزيد من الموارد.
العرض بشكل انتقائي — اجعل نتائجك أسهل في الفهم من خلال عرض الأعمدة التي تحتاج إليها فقط. يساعد عرض أعمدة معينة قبل تشغيل الانضمام أو عمليات مماثلة أيضا على تحسين الأداء.
join
تحسين عامل التشغيل
يدمج عامل تشغيل الربط صفوفا من جدولين عن طريق مطابقة القيم في أعمدة محددة. تطبيق هذه التلميحات لتحسين الاستعلامات التي تستخدم عامل التشغيل هذا.
جدول أصغر إلى اليسار — يطابق
join
عامل التشغيل السجلات الموجودة في الجدول على الجانب الأيسر من عبارة الصلة بالسجلات الموجودة على اليمين. من خلال وجود الجدول الأصغر على اليسار، ستحتاج إلى مطابقة عدد أقل من السجلات، وبالتالي تسريع الاستعلام.في الجدول أدناه، نقوم بتقليل الجدول
DeviceLogonEvents
الأيسر لتغطية ثلاثة أجهزة محددة فقط قبل الانضمام إليهIdentityLogonEvents
بواسطة معرفات الأمان الخاصة بالحساب.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
استخدم نكهة الصلة الداخلية — نكهة الصلة الافتراضية أو إلغاء تكرار صلة innerunique الصفوف في الجدول الأيسر بواسطة مفتاح الصلة قبل إرجاع صف لكل تطابق إلى الجدول الأيمن. إذا كان الجدول الأيسر يحتوي على صفوف متعددة بنفس القيمة للمفتاح
join
، إلغاء تكرار هذه الصفوف لترك صف عشوائي واحد لكل قيمة فريدة.يمكن أن يترك هذا السلوك الافتراضي معلومات مهمة من الجدول الأيسر يمكن أن توفر رؤى مفيدة. على سبيل المثال، سيعرض الاستعلام أدناه رسالة بريد إلكتروني واحدة فقط تحتوي على مرفق معين، حتى إذا تم إرسال نفس المرفق باستخدام رسائل بريد إلكتروني متعددة:
EmailAttachmentInfo | where Timestamp > ago(1h) | where Subject == "Document Attachment" and FileName == "Document.pdf" | join (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256
لمعالجة هذا القيد، نطبق نكهة الصلة الداخلية عن طريق تحديد
kind=inner
لإظهار جميع الصفوف في الجدول الأيسر مع قيم مطابقة في اليمين:EmailAttachmentInfo | where Timestamp > ago(1h) | where Subject == "Document Attachment" and FileName == "Document.pdf" | join kind=inner (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256
ضم السجلات من نافذة زمنية — عند التحقيق في أحداث الأمان، يبحث المحللون عن الأحداث ذات الصلة التي تحدث في نفس الفترة الزمنية تقريبا. يؤدي تطبيق نفس النهج عند استخدام
join
أيضا إلى الاستفادة من الأداء عن طريق تقليل عدد السجلات التي يجب التحقق منها.يتحقق الاستعلام أدناه من أحداث تسجيل الدخول في غضون 30 دقيقة من تلقي ملف ضار:
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
. ينطبق الاستعلام أدناه علىTimestamp > ago(1h)
كلا الجدولين بحيث ينضم فقط إلى السجلات من الساعة الماضية:EmailAttachmentInfo | where Timestamp > ago(1h) | where Subject == "Document Attachment" and FileName == "Document.pdf" | join kind=inner (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256
استخدم تلميحات للأداء — استخدم التلميحات مع
join
عامل التشغيل لإرشاد الواجهة الخلفية لتوزيع الحمل عند تشغيل العمليات كثيفة الموارد. تعرف على المزيد حول تلميحات الانضمامعلى سبيل المثال، يساعد تلميح التبديل العشوائي على تحسين أداء الاستعلام عند ضم الجداول باستخدام مفتاح ذي علاقة أساسية عالية - مفتاح يحتوي على العديد من القيم الفريدة - مثل
AccountObjectId
في الاستعلام أدناه:IdentityInfo | where JobTitle == "CONSULTANT" | join hint.shufflekey = AccountObjectId (IdentityDirectoryEvents | where Application == "Active Directory" | where ActionType == "Private data retrieval") on AccountObjectId
يساعد تلميح البث عندما يكون الجدول الأيسر صغيرا (حتى 100000 سجل) والجدول الأيمن كبير للغاية. على سبيل المثال، يحاول الاستعلام أدناه الانضمام إلى بعض رسائل البريد الإلكتروني التي تحتوي على مواضيع محددة مع جميع الرسائل التي تحتوي على ارتباطات في
EmailUrlInfo
الجدول:EmailEvents | where Subject in ("Warning: Update your credentials now", "Action required: Update your credentials now") | join hint.strategy = broadcast EmailUrlInfo on NetworkMessageId
summarize
تحسين عامل التشغيل
يقوم عامل تشغيل التلخيص بتجميع محتويات جدول. تطبيق هذه التلميحات لتحسين الاستعلامات التي تستخدم عامل التشغيل هذا.
ابحث عن قيم مميزة - بشكل عام، استخدم
summarize
للعثور على قيم مميزة يمكن أن تكون متكررة. قد يكون من غير الضروري استخدامه لتجميع الأعمدة التي لا تحتوي على قيم متكررة.في حين أن رسالة بريد إلكتروني واحدة يمكن أن تكون جزءا من أحداث متعددة، فإن المثال أدناه ليس استخداما
summarize
فعالا لأن معرف رسالة الشبكة لرسالة بريد إلكتروني فردي يأتي دائما بعنوان مرسل فريد.EmailEvents | where Timestamp > ago(1h) | summarize by NetworkMessageId, SenderFromAddress
summarize
يمكن استبدال عامل التشغيل بسهولة بproject
، مما يؤدي إلى نفس النتائج مع استهلاك موارد أقل:EmailEvents | where Timestamp > ago(1h) | project NetworkMessageId, SenderFromAddress
المثال التالي هو استخدام أكثر كفاءة لأنه
summarize
يمكن أن يكون هناك مثيلات مميزة متعددة لعنوان المرسل الذي يرسل بريدا إلكترونيا إلى نفس عنوان المستلم. هذه المجموعات أقل تميزا ومن المحتمل أن يكون لها تكرارات.EmailEvents | where Timestamp > ago(1h) | summarize by SenderFromAddress, RecipientEmailAddress
تبديل الاستعلام - في حين
summarize
أنه من الأفضل استخدامه في الأعمدة ذات القيم المتكررة، يمكن أن يكون لنفس الأعمدة أيضا علاقة أساسية عالية أو أعداد كبيرة من القيم الفريدة.join
مثل عامل التشغيل، يمكنك أيضا تطبيق تلميح التبديل العشوائي معsummarize
لتوزيع تحميل المعالجة ومن المحتمل أن يحسن الأداء عند التشغيل على أعمدة ذات علاقة أساسية عالية.يستخدم
summarize
الاستعلام أدناه لحساب عنوان البريد الإلكتروني المميز للمستلم، والذي يمكن تشغيله بمئات الآلاف في المؤسسات الكبيرة. لتحسين الأداء، فإنه يتضمنhint.shufflekey
:EmailEvents | where Timestamp > ago(1h) | summarize hint.shufflekey = RecipientEmailAddress count() by Subject, RecipientEmailAddress
سيناريوهات الاستعلام
تحديد العمليات الفريدة باستخدام معرفات العملية
تتم إعادة تدوير معرفات العمليات (PIDs) في Windows وإعادة استخدامها للعمليات الجديدة. من تلقاء نفسها، لا يمكن أن تعمل كمعرفات فريدة لعمليات محددة.
للحصول على معرف فريد لعملية على جهاز معين، استخدم معرف العملية مع وقت إنشاء العملية. عند ضم البيانات أو تلخيصها حول العمليات، قم بتضمين أعمدة لمعرف الجهاز (إما DeviceId
أو DeviceName
)، ومعرف العملية (ProcessId
أو InitiatingProcessId
)، ووقت إنشاء العملية (ProcessCreationTime
أو InitiatingProcessCreationTime
)
يبحث الاستعلام المثال التالي عن العمليات التي تصل إلى أكثر من 10 عناوين IP عبر المنفذ 445 (SMB)، وربما يتم فحصها لمشاركات الملفات.
مثال على الاستعلام:
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
بحيث ينظر إلى عملية واحدة، دون خلط عمليات متعددة بنفس معرف العملية.
أسطر أوامر الاستعلام
هناك العديد من الطرق لإنشاء سطر أوامر لإنجاز مهمة. على سبيل المثال، يمكن للمهاجم الرجوع إلى ملف صورة بدون مسار، أو بدون ملحق ملف، أو باستخدام متغيرات البيئة، أو مع علامات الاقتباس. يمكن للمهاجم أيضا تغيير ترتيب المعلمات أو إضافة علامات اقتباس ومسافات متعددة.
لإنشاء استعلامات أكثر دواما حول أسطر الأوامر، قم بتطبيق الممارسات التالية:
- حدد العمليات المعروفة (مثل net.exe أو psexec.exe) عن طريق المطابقة في حقول اسم الملف، بدلا من التصفية على سطر الأوامر نفسه.
- تحليل أقسام سطر الأوامر باستخدام الدالة parse_command_line()
- عند الاستعلام عن وسيطات سطر الأوامر، لا تبحث عن تطابق تام على وسيطات متعددة غير مرتبطة بترتيب معين. بدلا من ذلك، استخدم التعبيرات العادية أو استخدم عوامل تشغيل منفصلة متعددة.
- استخدم تطابقات غير حساسة لحالة الأحرف. على سبيل المثال، استخدم
=~
وin~
وcontains
بدلا من==
وin
و.contains_cs
- للتخفيف من تقنيات تعتيم سطر الأوامر، ضع في اعتبارك إزالة علامات الاقتباس، واستبدال الفواصل بمسافات، واستبدال مسافات متتالية متعددة بمسافة واحدة. هناك تقنيات تعتيم أكثر تعقيدا تتطلب أساليب أخرى، ولكن هذه التعديلات يمكن أن تساعد في معالجة الأساليب الشائعة.
توضح الأمثلة التالية طرقا مختلفة لإنشاء استعلام يبحث عن الملفnet.exe لإيقاف خدمة جدار الحماية "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"
استيعاب البيانات من مصادر خارجية
لدمج القوائم الطويلة أو الجداول الكبيرة في الاستعلام الخاص بك، استخدم عامل تشغيل البيانات الخارجية لاستيعاب البيانات من URI محدد. يمكنك الحصول على البيانات من الملفات بتنسيقات TXT أو CSV أو JSON أو تنسيقات أخرى. يوضح المثال أدناه كيف يمكنك استخدام قائمة شاملة من تجزئات SHA-256 الضارة التي يوفرها MalwareBazaar (abuse.ch) للتحقق من المرفقات على رسائل البريد الإلكتروني:
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
تحليل السلاسل
هناك وظائف مختلفة يمكنك استخدامها لمعالجة السلاسل التي تحتاج إلى تحليل أو تحويل بكفاءة.
سلسلة | دالة | مثال الاستخدام |
---|---|---|
أسطر الأوامر | parse_command_line() | استخراج الأمر وجميع الوسيطات. |
مسارات | parse_path() | استخراج مقاطع مسار ملف أو مجلد. |
أرقام الإصدارات | parse_version() | قم بفك هيكلة رقم إصدار يحتوي على ما يصل إلى أربعة أقسام وما يصل إلى ثمانية أحرف لكل مقطع. استخدم البيانات التي تم تحليلها لمقارنة عمر الإصدار. |
عناوين IPv4 | parse_ipv4() | تحويل عنوان IPv4 إلى عدد صحيح طويل. لمقارنة عناوين IPv4 دون تحويلها، استخدم ipv4_compare(). |
عناوين IPv6 | parse_ipv6() | تحويل عنوان IPv4 أو IPv6 إلى رمز IPv6 المتعارف عليه. لمقارنة عناوين IPv6، استخدم ipv6_compare(). |
للتعرف على جميع دالات التحليل المدعومة، اقرأ عن دوال سلسلة Kusto.
ملاحظة
قد لا تتوفر بعض الجداول في هذه المقالة في Microsoft Defender لنقطة النهاية. قم بتشغيل Microsoft Defender XDR للبحث عن التهديدات باستخدام المزيد من مصادر البيانات. يمكنك نقل مهام سير عمل التتبع المتقدمة من Microsoft Defender لنقطة النهاية إلى Microsoft Defender XDR باتباع الخطوات الواردة في ترحيل استعلامات التتبع المتقدمة من Microsoft Defender لنقطة النهاية.
المواضيع ذات الصلة
- وثائق لغة استعلام Kusto
- معلمات الاستخدام والحصص النسبية
- معالجة أخطاء التتبع المتقدمة
- نظرة عامة متقدمة حول الصيد
- التعرّف على لغة الاستعلام
تلميح
هل تريد معرفة المزيد؟ تفاعل مع مجتمع أمان Microsoft في مجتمعنا التقني: Microsoft Defender XDR Tech Community.