Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
Sentinel-Queries — Microsoft Sentinel KQL क्वेरी और ट्यूटोरियल का चयनित संग्रह — खतरों की खोज, Azure AD साइन-इन लॉग का विश्लेषण, विसंगतियों का पता लगाने और कुशल डिटेक्शन पैटर्न बनाने के लिए। | Kitploit
उपकरण/GitHubGitHub/reprise99/sentinel-queries
रक्षात्मक उपकरणखतरा खुफियालर्निंग और शिक्षाचयनित संसाधनविसंगति का पता लगानालॉग विश्लेषण
GitHubreprise99/sentinel-queries

Sentinel-Queries

Microsoft Sentinel KQL क्वेरी और ट्यूटोरियल का चयनित संग्रह — खतरों की खोज, Azure AD साइन-इन लॉग का विश्लेषण, विसंगतियों का पता लगाने और कुशल डिटेक्शन पैटर्न बनाने के लिए।

रिपॉजिटरी देखें
1.6k3826 महीने पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

Microsoft Sentinel के लिए KQL

Microsoft Sentinel के लिए KQL का उपयोग करने के लिए कुछ टिप्स, ट्रिक्स और उदाहरण।

  1. परिचय
  2. एक KQL क्वेरी की संरचना
  3. मूल बातें
    1. Time मूल बातें
    2. Where मूल बातें
    3. Project मूल बातें
    4. Summarize मूल बातें
    5. Render मूल बातें
    6. Parse और Split मूल बातें

परिचय

Kusto Query Language वह भाषा है जिसका उपयोग Azure Monitor, Azure Data Explorer और Azure Log Analytics में किया जाता है (Microsoft Sentinel अंदरूनी रूप से यही उपयोग करता है)। मुझे KQL के संबंध में यह विज़ुअलाइज़ेशन हमेशा उपयोगी लगा है -

KQL विज़ुअलाइज़ किया गया

हम KQL का उपयोग करके अपने बड़े डेटा सेट के भीतर से खतरों, डिटेक्शन, पैटर्न और विसंगतियों को खोजने के लिए सटीक और कुशल क्वेरी बनाना चाहते हैं।

एक KQL क्वेरी की संरचना

नीचे दी गई क्वेरी को एक उदाहरण के रूप में लें```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

root@kitploit:~
जब हम इस तरह की क्वेरी चलाते हैं, तो पहली पंक्ति Microsoft Sentinel को बताती है कि डेटा के लिए किस तालिका में देखना है, इसलिए इस मामले में हम SigninLogs तालिका खोजना चाहते हैं, जहाँ Azure AD साइन-इन डेटा भेजा जाता है। आप तालिकाओं की सूची [यहाँ](https://docs.microsoft.com/en-us/azure/sentinel/data-source-schema-reference) देख सकते हैं।

Microsoft Sentinel फिर आपकी क्वेरी को क्रमिक रूप से चलाएगा, इसलिए वह प्रत्येक पंक्ति को एक-एक करके तब तक चलाएगा जब तक वह अंत तक नहीं पहुँच जाता, या आपको कोई त्रुटि नहीं होती। तो आइए अपनी क्वेरी को पंक्ति दर पंक्ति तोड़ें।```kql
SigninLogs

तो सबसे पहले हमने अपनी SigninLogs तालिका चुनी है।```kql SigninLogs | where TimeGenerated > ago(14d)

root@kitploit:~
इसके बाद हम Sentinel को इस तालिका में पिछले 14 दिनों के डेटा को देखने के लिए कहते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

आगे हम Sentinel से केवल उन लॉग्स को खोजने के लिए कहते हैं जहाँ UserPrincipalName "[email protected]" के बराबर है```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0"

root@kitploit:~
फिर हम केवल उन लॉग्स को देखते हैं जहाँ ResultType == 0 है, जो Azure AD में एक सफल लॉगऑन है।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"

अगला, हम केवल Microsoft Teams में साइन-इन की तलाश करते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

root@kitploit:~
हमारी अंतिम पंक्ति project ऑपरेटर का उपयोग करती है, ताकि हमारे लॉग्स से केवल 4 फ़ील्ड्स लौटाए जाएँ, इसलिए हम केवल TimeGenerated, Location, IPAddress और UserAgent ही देख पाएँगे जो हमारे SigninLogs डेटा से लौटाए गए हैं।

इस तरह आप क्वेरी बनाते हैं, अब मूल बातें।

## मूल बातें

### समय की मूल बातें

Microsoft Sentinel और KQL समय फ़िल्टर के लिए अत्यधिक अनुकूलित हैं, इसलिए यदि आप उस डेटा की समय अवधि जानते हैं जिसे आप खोजना चाहते हैं, तो आपको तुरंत समय सीमा फ़िल्टर कर देनी चाहिए। पिछले 14 दिनों के लॉग्स प्राप्त करना, फिर नीचे दी गई क्वेरी जैसे उपयोगकर्ता नाम की खोज करना -```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

पहले उपयोगकर्ता नाम और फिर समय अवधि खोजने की तुलना में कहीं अधिक कुशल है, जैसे -```kql SigninLogs | where UserPrincipalName == "[email protected]" | where TimeGenerated > ago(14d)

root@kitploit:~
KQL के पास विशिष्ट समय अवधियों की क्वेरी करने के लिए कई विकल्प हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)

पहले उदाहरण के अनुसार, यह पिछले 14 दिनों की खोज करेगा।```kql SigninLogs | where TimeGenerated > ago(14h)

root@kitploit:~
आप घंटे भी कर सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14m)

और मिनट।

KQL समय सीमा के बीच क्वेरी करने का भी समर्थन करता है -```kql SigninLogs | where TimeGenerated between (ago(14d) .. ago(7d))

root@kitploit:~
यह 14 दिन पहले और 7 दिन पहले के बीच का SigninLogs डेटा खोजेगा।```kql
SigninLogs
| where TimeGenerated between (ago(14h) .. ago(7h))

14 घंटे और 7 घंटे पहले के बीच।```kql SigninLogs | where TimeGenerated between (ago(14m) .. ago(7m))

root@kitploit:~
और 14 मिनट पहले से 7 मिनट पहले के बीच।

### Where मूल बातें

Where एक ऑपरेटर है जिसका उपयोग आप अपने द्वारा लिखे जाने वाले लगभग हर क्वेरी में करेंगे। इसी तरह आप Microsoft Sentinel को विशिष्ट डेटा खोजने के लिए कहते हैं। where ऑपरेटर के साथ सिंटैक्स बहुत महत्वपूर्ण है। अगर हम अपना वही उदाहरण उपयोग करते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

यह पिछले 14 दिनों में हमारी SigninLogs तालिका में सटीक मिलानों की खोज करेगा, जहाँ हमारा UserPrincipalName [email protected] के बराबर है। KQL में == केस-सेंसिटिव है, इसलिए यदि आप [email protected] के लिए खोज करते हैं और उपयोगकर्ता नाम वास्तव में [email protected] है, तो आपको कोई परिणाम नहीं मिलेगा। गैर-केस-सेंसिटिव समकक्ष =~ है।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName =~ "[email protected]"

root@kitploit:~
यह केस संवेदनशीलता की परवाह किए बिना [email protected] के लिए कोई भी मिलान खोजेगा।

बराबर के बजाय, हम contains का भी उपयोग कर सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName contains "reprise_99"

यह उन सभी लॉग प्रविष्टियों को ढूंढेगा जहां UserPrincipalName में reprise_99 शामिल है, यदि आपके पास [email protected] और [email protected] डेटा है, तो यह दोनों को ढूंढ लेगा। contains ऑपरेटर केस-सेंसिटिव नहीं है, लेकिन आप इसे केस-सेंसिटिव बनाने के लिए contains_cs का उपयोग कर सकते हैं।

यदि आप विशेष पैटर्न खोज रहे हैं तो आप startswith या endswith का उपयोग कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName startswith "reprise_99"

SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName endswith "testdomain.com"

root@kitploit:~
startswith और endswith दोनों केस-सेंसिटिव नहीं हैं, लेकिन आप उन्हें केस-सेंसिटिव बनाने के लिए startswith_cs या endswith_cs का उपयोग कर सकते हैं।

यदि आप पूर्ण शब्दों (चार वर्णों से अधिक) की खोज कर रहे हैं, तो KQL में आप has ऑपरेटर का उपयोग कर सकते हैं। 'has' का उपयोग 'contains' की तुलना में अधिक कुशल है क्योंकि डेटा आपके लिए अनुक्रमित होता है।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has "Teams"

यह किसी भी SigninLogs को खोजेगा जहाँ एप्लिकेशन डिस्प्ले नाम में Teams शब्द हो, जिसमें "Microsoft Teams" और "Microsoft Teams Web Client" शामिल हो सकते हैं, दोनों क्वेरी को संतुष्ट करते हैं।

यदि आप कई शब्दों की खोज कर रहे हैं तो आप has_any या has_all का उपयोग कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where AppDisplayName has_any ("Teams","Outlook")

root@kitploit:~
यह उन परिणामों को लौटाएगा जहाँ एप्लिकेशन प्रदर्शन नाम में "Teams" या "Outlook" शामिल है```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has_all ("Teams","Outlook")

यह उन परिणामों को लौटाएगा जहाँ एप्लिकेशन के डिस्प्ले नाम में "Teams" और "Outlook" शामिल हैं।

यदि आप नहीं जानते कि किन फ़ील्ड्स में खोजना है, तो आप वाइल्डकार्ड का भी उपयोग कर सकते हैं। यह अक्षम है, लेकिन यह आपको वह खोजने के लिए सही रास्ते पर ले जा सकता है जो आप चाहते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where * contains "reprise_99"

root@kitploit:~
यह SigninLogs तालिका में किसी भी ऐसे फ़ील्ड की खोज करेगा जिसमें reprise_99 हो।

इनमें से कई विकल्प क्वेरी को उलटने और उन परिणामों को खोजने के लिए ! का उपयोग करने का समर्थन भी करते हैं जहाँ यह सत्य नहीं है।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName != "[email protected]"

यह क्वेरी उन सभी SigninLogs को ढूंढेगी जहाँ UserPrincipalName, [email protected] के बराबर नहीं है।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName !contains "reprise_99"

root@kitploit:~
यह क्वेरी उन सभी SigninLogs को ढूंढेगी जहाँ UserPrincipalName में reprise_99 शामिल नहीं है```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName !has "Teams"

यह क्वेरी उन SigninLogs को खोजेगी जहाँ एप्लिकेशन display name में "Teams" नहीं होता।

Project Basics

Project हमें यह चुनने की सुविधा देता है कि हमारी क्वेरी में कौन से columns लौटाए जाएँ और किस क्रम में।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

root@kitploit:~
यह क्वेरी पिछले 14 दिनों से SigninLogs डेटा खोजती है, जहाँ UserPrincipalname [email protected] के बराबर है, जहाँ ResultType 0 है, जहाँ एप्लिकेशन display name "Microsoft Teams" के बराबर है, फिर उस क्वेरी पर प्रत्येक मिलान के लिए यह TimeGenerated, Location, IPAddress और UserAgent लौटाता है।

हम उसी फ़ंक्शन के भाग के रूप में कॉलम का नाम बदल सकते हैं।```kql
| project LogTime=TimeGenerated, SigninLocation=Location, IP=IPAddress, Agent=UserAgent

यह समान डेटा लौटाता है, लेकिन कॉलमों का नाम बदलकर LogTime, SigninLocation, IP और Agent कर देता है। हम project operator के साथ आउटपुट को इनलाइन भी संशोधित कर सकते हैं।```kql | project LocalTime=TimeGenerated+5h, Location, IPAddress, UserAgent

root@kitploit:~
This returns the same data, but changes the TimeGenerated name to LocalTime and converts to a +5h time zone if you work in that time zone.

project-away is the opposite of project and will remove columns from your query.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| project-away UserAgent
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"

इस क्वेरी में हम UserAgent को हटाते हैं। याद रखें, यदि आप किसी कॉलम को हटाते हैं तो आप बाद में अपनी क्वेरी में उस तक नहीं पहुँच सकते।

Summarize की मूल बातें

Summarize आपकी क्वेरी की सामग्री को एकत्रित करने वाली एक तालिका तैयार करता है। Summarize के अंतर्निहित कई समुच्चयन (aggregation) फ़ंक्शन होते हैं। यदि हम फिर से अपनी उदाहरण क्वेरी लें, तो हम summarize का उपयोग करके परिणामों को विभिन्न तरीकों से बदल सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize count() by AppDisplayName

root@kitploit:~
यह क्वेरी पिछले 14 दिनों में SigninLogs तालिका में किसी भी ईवेंट को खोजेगी, [email protected] के किसी भी मिलान के लिए, जहाँ परिणाम सफल है (ResultType == 0) और फिर उन ईवेंट्स को एप्लिकेशन डिस्प्ले नाम द्वारा सारांशित करेगी।

आप वैकल्पिक रूप से परिणाम कॉलम को नाम दे सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppCount=count() by AppDisplayName

यह समान डेटा लौटाता है लेकिन लौटाए गए कॉलम का नाम अपडेट करके AppCount कर देता है।

कुल गणना के बजाय, आप एक distinct गणना का सारांश भी प्रस्तुत कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize DistinctAppCount=dcount(AppDisplayName) by AppDisplayName

root@kitploit:~
This will return a single record for each distinct application [email protected] signed into.

You can use the arg_max and arg_min functions to return either the newest or oldest record that matches your query.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize arg_max(TimeGenerated, *) by UserPrincipalName

यह क्वेरी पिछले 14 दिनों के सभी साइन-इन लॉग को खोजती है, जिनमें UserPrincipalname के रूप में [email protected] है, जो सफल हैं और फिर नवीनतम रिकॉर्ड लौटाती है।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize arg_min(TimeGenerated, *) by UserPrincipalName

root@kitploit:~
यह समान है लेकिन सबसे पुराना रिकॉर्ड लौटाता है।

आप अपने योगों को तर्क प्रदान करने के लिए countif का उपयोग कर सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize TeamsLogons=countif(AppDisplayName has "Teams"), SharePointLogons=countif(AppDisplayName has "SharePoint")

यह डेटा को दो नए कॉलमों में सारांशित करता है, TeamsLogons जहाँ एप्लिकेशन डिस्प्ले नाम में "Teams" होता है और SharePointLogons जहाँ एप्लिकेशन डिस्प्ले नाम में "SharePoint" होता है।

आप KQL को अपने डेटा को time 'bins' में रखने के लिए कहकर अपने डेटा को और अधिक हेरफेर कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppCount=count() by AppDisplayName, bin(TimeGenerated, 1d)

root@kitploit:~
यह हमारे पहले summarize उदाहरण के समान डेटा लौटाता है और फिर उस डेटा को 1d bins में समूहित करता है।

आप इन फ़ंक्शनों को जहाँ उपयोगी हो, एक साथ जोड़ सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize TeamsLogons=countif(AppDisplayName has "Teams"), SharePointLogons=countif(AppDisplayName has "SharePoint") by bin(TimeGenerated, 1d)

यह हमारे countif और bin फ़ंक्शनों का संयोजन है, जहाँ हम अपने एप्लिकेशन डिस्प्ले नाम के आधार पर सारांश प्रस्तुत करते हैं और परिणामों को 1d bins में भी रखते हैं।

आप किसी क्वेरी के भीतर आइटमों का एक सेट बना सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppList=make_set(AppDisplayName) by UserPrincipalName

root@kitploit:~
यह उन अनुप्रयोगों की एक सूची आउटपुट करेगा जिनमें [email protected] ने साइन इन किया है, जिसे AppList नामक सूची में संग्रहीत किया जाएगा।

आप इसे हमारे time bin के साथ जोड़ सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppList=make_set(AppDisplayName) by UserPrincipalName, bin(TimeGenerated, 1d)

यह उन अनुप्रयोगों की एक सूची बनाएगा जिनमें [email protected] ने साइन इन किया है, जिसे प्रति दिन एक सूची में विभाजित किया गया है।

Render की मूल बातें

render ऑपरेटर KQL को डेटा को विभिन्न प्रारूपों में विज़ुअलाइज़ करने की अनुमति देता है, जैसे piecharts, time या areacharts, और column तथा bar charts।

यदि हम अपने Signinlogs टेबल से उसी उदाहरण का उपयोग करते हैं, तो हम देख सकते हैं कि हम डेटा को विभिन्न तरीकों से विज़ुअलाइज़ कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppCount=count()by AppDisplayName | render piechart

root@kitploit:~
यह क्वेरी पिछले 14 दिनों में [email protected] द्वारा साइन-इन किए गए सभी अनुप्रयोगों का सारांश प्रस्तुत करती है, फिर आउटपुट को पाई चार्ट के रूप में दिखाती है।

![KQL Piechart](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-piechart.png?raw=true)

आप इसे कॉलम चार्ट के रूप में भी प्रस्तुत कर सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppCount=count()by AppDisplayName
| render columnchart

KQL स्तंभ चार्ट

या एक बार चार्ट।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppCount=count()by AppDisplayName | render barchart

root@kitploit:~
![KQL बार चार्ट](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-barchart.png?raw=true)

समय डेटा के लिए, आप पहले अपने डेटा को समय 'बिन्स' में सारांशित करते हैं जैसा कि summarize अनुभाग में बताया गया है, और फिर आप अपने डेटा को एक समय अवधि में विज़ुअलाइज़ कर सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by bin(TimeGenerated, 1d)
| render timechart

यह पिछले 14 दिनों में [email protected] द्वारा प्रति दिन सभी साइन-इन को विज़ुअलाइज़ करता है और इसे timechart के रूप में प्रदर्शित करता है।

KQL Timechart

आप render का उपयोग areachart के रूप में भी कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize SigninCount=count() by bin(TimeGenerated, 1d) | render areachart

root@kitploit:~
![KQL Areachart](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-areachart.png?raw=true)

स्तंभ चार्ट और बार चार्ट का उपयोग समय डेटा के साथ भी किया जा सकता है। आपको अपनी बड़ी समय अवधि में प्रत्येक समय 'bin' के लिए एक स्तंभ या बार मिलेगा।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by bin(TimeGenerated, 1d)
| render columnchart

यह हमारे timechart के समान ही query है, लेकिन इसे प्रति दिन एक कॉलम के साथ कॉलम चार्ट के रूप में प्रस्तुत किया गया है।

KQL समय कॉलम चार्ट```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize SigninCount=count() by bin(TimeGenerated, 1d) | render barchart

root@kitploit:~
और एक बार चार्ट।

![KQL टाइम बार चार्ट](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-timebarchart.png?raw=true)

कॉलम या बार चार्ट के साथ आप उन्हें एक साथ स्टैक्ड कर सकते हैं (जो डिफ़ॉल्ट है)।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by AppDisplayName, bin(TimeGenerated, 1d)
| render columnchart

यह क्वेरी हमारे खाते के लिए सभी साइन-इन ढूंढती है, प्रति एप्लिकेशन साइन-इन की गिनती करती है, फिर प्रत्येक दिन के लिए एक एकल कॉलम बनाती है।

KQL समय स्तंभ चार्ट स्टैक्ड

यदि आप चाहते हैं कि प्रत्येक एप्लिकेशन का अपना कॉलम हो, तो आप इसे अनस्टैक्ड पर सेट कर सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize SigninCount=count() by bin(TimeGenerated, 1d) | render columnchart with (kind=unstacked)

root@kitploit:~
![KQL Time Column Chart Unstacked](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-timecolumnchartunstacked.png?raw=true)

आप KQL के अनुरूप अपने चार्ट के अक्ष और शीर्षक का नाम भी बदल सकते हैं।```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by AppDisplayName, bin(TimeGenerated, 1d)
| render columnchart with (kind=unstacked, ytitle="Total Sign Ins", xtitle="Day", title="Application Signins Per Day")

KQL समय स्तंभ चार्ट Unstacked नाम बदला गया

आप अपने summarize क्रियाओं में तर्क जोड़कर अपने render ऑपरेटर के लिए गतिशील सामग्री बना सकते हैं।```kql SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "0" | summarize TeamsCount=countif(AppDisplayName has "Teams"), OneDrive=countif(AppDisplayName has "OneDrive"), SharePointCount=countif(AppDisplayName has "SharePoint") by bin(TimeGenerated, 1d) | render columnchart with (kind=unstacked, ytitle="Sign In Count", xtitle="Day", title="Teams vs OneDrive vs SharePoint Sign Ins Per Day")

root@kitploit:~
यह क्वेरी आपके टेनेंट में सभी साइन-इन खोजती है, फिर तीन समूहों की गणना करती है — एक जहाँ एप्लिकेशन डिस्प्ले नाम में "Teams" है, एक जहाँ एप्लिकेशन डिस्प्ले नाम में "OneDrive" है और एक जहाँ एप्लिकेशन डिस्प्ले नाम में "SharePoint" है, पिछले 14 दिनों के प्रत्येक दिन के लिए, फिर इसे एक अनस्टैक्ड कॉलम चार्ट के रूप में प्रस्तुत करती है।

![KQL Time Column Chart Outlook, OneDrive, SharePoint](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-timecolumn-outlookonedrivesharepoint.png?raw=true)

### Parse और Split की मूल बातें

Parse और split डेटा की एक स्ट्रिंग को मैचों के आधार पर कई कॉलमों में विस्तारित करने के दो अलग-अलग तरीके हैं। Microsoft Sentinel में इंजेस्ट किए गए बहुत सारे लॉग एक लंबी स्ट्रिंग के रूप में आ सकते हैं (जैसे sysmon), parse और split आपको उन्हें पठनीय डेटा में बदलने की अनुमति देते हैं।

इन उदाहरणों के लिए, हम निम्नलिखित परीक्षण डेटा का उपयोग करेंगे```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account'
];

यह डेटा केवल एक स्ट्रिंग है जो इस प्रकार दिखता है।

Parse

हम निम्नलिखित के साथ विशिष्ट डेटा मैचों को पार्स कर सकते हैं```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account' ]; ExampleText | parse TestData with * 'Name=' DisplayName ',' * | project DisplayName

root@kitploit:~
यह Name= और , के बीच के सभी डेटा को 'DisplayName' नामक एक नए कॉलम में पार्स करेगा।

![Parse 1](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/parse1.png?raw=true)

आप उसी कमांड में स्ट्रिंग के साथ मिलान करके कई कॉलम पार्स कर सकते हैं।```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account'
];
ExampleText
| parse TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' *
| project DisplayName, DomainSuffix, AzureADTenantId

यह तीन नए कॉलम पार्स करता है - DisplayName, DomainSuffix और AzureADTenantId

Parse 2

यह याद रखते हुए कि KQL अपने ऑपरेशन क्रमिक रूप से चलाता है, एक बार पार्स करने के बाद हम नए बनाए गए कॉलम पर फिर से पार्स कर सकते हैं।```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account', ]; ExampleText | parse TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' * | project DisplayName, DomainSuffix, AzureADTenantId | parse DomainSuffix with * '.' TopLevelDomain | project DisplayName, DomainSuffix, TopLevelDomain, AzureADTenantId

root@kitploit:~
यह हमारे डोमेन को आगे parse करके top level domain खोजता है, इस मामले में एक .com

![Parse 3](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/parse3.png?raw=true)

जब आप parse operator का उपयोग करते हैं, तो KQL आपके सभी डेटा की पंक्तियों से गुज़रता है और उन परिणामों को भी लौटाता है जहाँ कोई मेल नहीं होता है। इसलिए आपके डेटा संरचना के आधार पर आपके पास खाली डेटा की कई पंक्तियाँ आ सकती हैं। यदि हम अपने उदाहरण डेटा में अलग-अलग नामों के साथ एक और पंक्ति जोड़ते हैं और वही query चलाते हैं, तो आपको खाली परिणाम दिखाई देंगे।```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account',
'Display=Reprise99,UPN=testdomain.com,AadDirectoryId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadObjectId=cf6f2df6-b754-48dc-b7bc-c8339caf211,Name=Test User,AccountType=account'
]
;
ExampleText
| parse TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' *
| project DisplayName, DomainSuffix, AzureADTenantId
| parse DomainSuffix with * '.' TopLevelDomain
| project DisplayName, DomainSuffix, TopLevelDomain, AzureADTenantId

Parse 4

इसका मुकाबला करने के लिए आप 'parse-where' ऑपरेटर का उपयोग कर सकते हैं, जो केवल उन्हीं परिणामों को लौटाता है जहाँ आपकी क्वेरी से मेल होते हैं।```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account', 'Display=Reprise99,UPN=testdomain.com,AadDirectoryId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadObjectId=cf6f2df6-b754-48dc-b7bc-c8339caf211,Name=Test User,AccountType=account' ] ; ExampleText | parse-where TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' * | project DisplayName, DomainSuffix, AzureADTenantId | parse DomainSuffix with * '.' TopLevelDomain | project DisplayName, DomainSuffix, TopLevelDomain, AzureADTenantId

root@kitploit:~
हम देख सकते हैं कि हम फिर से एक एकल परिणाम पर लौट आए हैं जहाँ हमें अपने parse पर मैच मिला था।

![Parse 5](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/parse5.png?raw=true)

Split एक string of text को delimiter के आधार पर एक array में विभाजित करता है। यदि हम अपने मूल test data पर वापस जाएँ, तो हम कॉमा चिह्न के आधार पर split कर सकते हैं।```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account',
]
;
ExampleText
| extend SplitData = split(TestData,',')
| project SplitData

We will be returned an array with our string split out.

Split 1

Split is index aware so if your data is in the same order, you can split directly into new columns.```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account', ] ; ExampleText | extend Name = split(TestData,',')[0] | extend DomainSuffix = split(TestData,',')[1] | extend AzureADTenantId = split(TestData,',')[2] | extend AzureADUserId = split(TestData,',')[3] | extend DisplayName = split(TestData,',')[4] | extend AccountType = split(TestData,',')[5] | project Name, DomainSuffix, AzureADTenantId, AzureADUserId, DisplayName, AccountType

root@kitploit:~
यदि हमें स्ट्रिंग के भीतर अपने डेटा का स्थान पता है, तो हम इसे सीधे नामित कॉलम में विभाजित कर सकते हैं।

![Split 2](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/split2.png?raw=true)

एक बार जब हम अपने डेटा को विभाजित कर लेते हैं, तो हम उसे ऐसे क्वेरी कर सकते हैं जैसे कि वह शुरू से ही संरचित था। इसलिए यदि हम अपने डेटा में दूसरा रिकॉर्ड जोड़ते हैं, फिर विशिष्ट मिलान पर क्वेरी करते हैं, तो हमें वही मिलेगा जो हम खोज रहे हैं।```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account',
'Name=Reprise103,UPNSuffix=testdomain.com,AadTenantId=331c1234-a841-43e5-1d31-12220a5bcee1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User 2,Type=account'
]
;
ExampleText
| extend Name = split(TestData,',')[0]
| extend DomainSuffix = split(TestData,',')[1]
| extend AzureADTenantId = split(TestData,',')[2]
| extend AzureADUserId = split(TestData,',')[3]
| extend DisplayName = split(TestData,',')[4]
| extend AccountType = split(TestData,',')[5]
| project Name, DomainSuffix, AzureADTenantId, AzureADUserId, DisplayName, AccountType
| where Name contains "Reprise99"

हमें केवल एक हिट मिलती है, जहाँ Name में "Reprise99" शामिल है, हमारा दूसरा रिकॉर्ड जहाँ Name में "Reprise103" शामिल है, नहीं मिल पाता।

Split 3

टूल डाउनलोड करें