Kehittyneet metsästyskyselyn parhaat käytännöt
Koskee seuraavia:
- Microsoft Defender XDR
Käytä näitä suosituksia saadaksesi tulokset nopeammin ja välttääksesi aikakatkaisut monimutkaisten kyselyiden suorittamisen aikana. Saat lisätietoja kyselyjen suorituskyvyn parantamisesta lukemalla kusto-kyselyn parhaat käytännöt.
Tietoja suorittimen resurssikiintiöistä
Sen koosta riippuen kullakin vuokraajalla on käyttöoikeus määritettyyn määrään suoritinresursseja, jotka on varattu kehittyneiden metsästyskyselyiden suorittamiseen. Lisätietoja erilaisista käyttöparametreista on artikkelissa Kehittyneet metsästyskiintiöt ja käyttöparametrit.
Kyselyn suorittamisen jälkeen näet suoritusajan ja sen resurssien käytön (pieni, normaali, suuri). Suuri ilmaisee, että kyselyn suorittaminen vaati enemmän resursseja, ja sitä voidaan parantaa tulosten palauttamiseksi tehokkaammin.
Asiakkaiden, jotka suorittavat useita kyselyitä säännöllisesti, tulee seurata kulutusta ja noudattaa tämän artikkelin optimointiohjeita kiintiöiden ylittämisestä tai käyttöparametrien ylittämisestä aiheutuvien häiriöiden minimoimiseksi.
Katso KQL-kyselyiden optimointi , niin näet yleisimpiä tapoja parantaa kyselyitäsi.
Yleisiä optimointivinkkejä
Määritä uudet kyselyt – Jos epäilet kyselyn palauttavan suuren tulosjoukon, arvioi se ensin käyttämällä count-operaattoria. Käytä rajoitusta tai sen synonyymiä
take
suurten tulosjoukkojen välttämiseksi.Ota suodattimet käyttöön aikasuodattimet ja muut suodattimet tietojoukon pienentämiseksi, erityisesti ennen muunnos- ja jäsennysfunktioiden käyttämistä, kuten substring(), replace(), trim(), toupper()tai parse_json(). Alla olevassa esimerkissä jäsennysfunktiota extractjson() käytetään sen jälkeen, kun suodatusoperaattorit ovat vähentäneet tietueiden määrää.
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "UsbDriveMount" | where DeviceName == "user-desktop.domain.com" | extend DriveLetter = extractjson("$.DriveLetter", AdditionalFields)
Sisältää lyöntiä – Jos haluat välttää alimerkkijonon etsimisen sanojen sisällä tarpeettomasti, käytä operaattoria -operaattorin
has
contains
sijaan. Lisätietoja merkkijono-operaattoreistaKatso tietyistä sarakkeista: etsi tiettyä saraketta sen sijaan, että suoritat koko tekstin hakuja kaikista sarakkeista. Käytä
*
tätä kaikkien sarakkeiden tarkistamiseen.Kirjainkoko on merkitsevä nopeuden kannalta – kirjainkoko on merkitsevä, joten haut ovat tarkempia ja yleensä suorituskykyisempiä. Kirjainkokoa merkitsevien merkkijono-operaattoreiden nimet, kuten
has_cs
jacontains_cs
, päättyvät yleensä merkkijonoon_cs
. Voit myös käyttää kirjainkoon huomioon ottavaa yhtä suuri kuin -operaattoria -operaattorin==
=~
sijaan.Jäsennä, älä poimi – Käytä jäsennysoperaattoria tai jäsennysfunktiota, kuten parse_json(). Vältä merkkijono-operaattoria
matches regex
tai extract()-funktiota, jotka molemmat käyttävät säännöllistä lauseketta. Varaa säännönmukaisen lausekkeen käyttö monimutkaisempia skenaarioita varten. Lue lisää funktioiden jäsentämisestäSuodata taulukot eivät lausekkeita – Älä suodata laskettua saraketta, jos voit suodattaa taulukon sarakkeen mukaan.
Ei kolmikirjaimisia termejä – Vältä ehtojen vertaamista tai suodatusta käyttämällä termejä, joissa on enintään kolme merkkiä. Näitä termejä ei indeksoida, ja niiden vastaavuus edellyttää enemmän resursseja.
Projekti valikoivasti– Tee tuloksista helpommin ymmärrettäviä projisoimalla vain tarvitsemasi sarakkeet. Tiettyjen sarakkeiden projisoiminen ennen liitoksen tai vastaavien toimintojen suorittamista auttaa myös parantamaan suorituskykyä.
join
Optimoi operaattori
Liitosoperaattori yhdistää rivit kahdesta taulukosta täsmäämällä määritettyjen sarakkeiden arvot. Näiden vinkkien avulla voit optimoida tätä operaattoria käyttäviä kyselyitä.
Pienempi taulukko vasemmalla – Operaattori
join
vastaa liitoslausekkeen vasemmalla puolella olevan taulukon tietueita oikealla oleviin tietueisiin. Jos vasemmalla on pienempi taulukko, vastaavia tietueita on oltava vähemmän, mikä nopeuttaa kyselyä.Alla olevassa taulukossa pienennämme vasemman taulukon
DeviceLogonEvents
kattamaan vain kolme tiettyä laitetta, ennen kuin liitymme siihen tilin SID-tunnuksillaIdentityLogonEvents
.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
Käytä sisäliitosmakua– Oletusliitosmaku tai innerunique-join lisää vasemman taulukon rivit liitosavaimella, ennen kuin palautat rivin kullekin ottelulle oikeaan taulukkoon. Jos vasemmassa taulukossa on useita rivejä, joilla on sama arvo avaimelle
join
, kyseiset rivit monistetaan niin, että kullekin yksilölliselle arvolle jätetään yksi satunnaisrivi.Tämä oletustoiminta voi jättää pois tärkeitä tietoja vasemmasta taulukosta, jotka voivat tarjota hyödyllisiä merkityksellisiä tietoja. Esimerkiksi alla olevassa kyselyssä näytetään vain yksi tietty liite, vaikka sama liite lähetettiin usealla sähköpostiviestillä:
EmailAttachmentInfo | where Timestamp > ago(1h) | where Subject == "Document Attachment" and FileName == "Document.pdf" | join (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256
Tämän rajoituksen ratkaisemiseksi käytämme sisäliitosmakua
kind=inner
määrittämällä, että vasemman taulukon kaikki rivit näytetään vastaavilla arvoilla oikealla:EmailAttachmentInfo | where Timestamp > ago(1h) | where Subject == "Document Attachment" and FileName == "Document.pdf" | join kind=inner (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256
Liitä tietueita aikaikkunasta – Suojaustapahtumia tutkiessaan analyytikot etsivät toisiinsa liittyviä tapahtumia, jotka tapahtuvat suunnilleen samalla ajanjaksolla. Saman lähestymistavan käyttäminen käytettäessä
join
hyödyttää myös suorituskykyä vähentämällä tarkastettavien tietueiden määrää.Alla oleva kysely tarkistaa kirjautumistapahtumat 30 minuutin kuluessa vahingollisen tiedoston vastaanottamisesta:
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)
Käytä aikasuodattimia molemmin puolin – vaikka et tutkisi tiettyä aikaikkunaa, aikasuodattimien lisääminen sekä vasemman että oikeanpuoleisiin taulukoihin voi vähentää tietueiden määrää suorituskyvyn tarkistamiseksi ja parantamiseksi
join
. Alla oleva kysely koskeeTimestamp > ago(1h)
molempia taulukoita niin, että se liittää vain edellisen tunnin tietueet:EmailAttachmentInfo | where Timestamp > ago(1h) | where Subject == "Document Attachment" and FileName == "Document.pdf" | join kind=inner (DeviceFileEvents | where Timestamp > ago(1h)) on SHA256
Käytä suorituskykyvihjeitä – Ohjaa taustaa jakamaan kuormitus resurssiin intensiivisten toimintojen suorittamisen aikana käyttämällä operaattorin
join
kanssa annettuja vihjeitä. Lisätietoja liittymisvihjeistäEsimerkiksi sekoitusvihje auttaa parantamaan kyselyn suorituskykyä liitettäessä taulukoita käyttämällä avainta, jonka kardinaliteetti on suuri – avain, jolla on useita yksilöllisiä arvoja – kuten
AccountObjectId
alla olevassa kyselyssä:IdentityInfo | where JobTitle == "CONSULTANT" | join hint.shufflekey = AccountObjectId (IdentityDirectoryEvents | where Application == "Active Directory" | where ActionType == "Private data retrieval") on AccountObjectId
Yleislähetysvihje auttaa, kun vasen taulukko on pieni (enintään 100 000 tietuetta) ja oikea taulukko on erittäin suuri. Alla olevassa kyselyssä yritetään esimerkiksi liittää sähköpostiviestejä, joissa on tiettyjä aiheita ja joissa on kaikki viestit, jotka sisältävät linkkejä
EmailUrlInfo
taulukossa:EmailEvents | where Subject in ("Warning: Update your credentials now", "Action required: Update your credentials now") | join hint.strategy = broadcast EmailUrlInfo on NetworkMessageId
summarize
Optimoi operaattori
Yhteenveto-operaattori koostaa taulukon sisällön. Näiden vinkkien avulla voit optimoida tätä operaattoria käyttäviä kyselyitä.
Etsi erillisiä arvoja – yleensä käytä
summarize
tätä toistuvien erillisten arvojen etsimiseen. Sen käyttäminen voi olla tarpeetonta niiden sarakkeiden koostamiseen, joissa ei ole toistuvia arvoja.Vaikka yksittäinen sähköpostiviesti voi olla osa useita tapahtumia, alla oleva esimerkki ei ole tehokas käyttö, koska yksittäisen sähköpostiviestin verkkoviestin tunnuksella on aina yksilöllinen lähettäjän
summarize
osoite.EmailEvents | where Timestamp > ago(1h) | summarize by NetworkMessageId, SenderFromAddress
Operaattori
summarize
voidaan helposti korvata kohteellaproject
, joka tuottaa mahdollisesti samat tulokset ja kuluttaa vähemmän resursseja:EmailEvents | where Timestamp > ago(1h) | project NetworkMessageId, SenderFromAddress
Seuraava esimerkki on tehokkaampi käyttö,
summarize
koska lähettäjän osoitteessa voi olla useita erillisiä esiintymiä, jotka lähettävät sähköpostia samaan vastaanottajan osoitteeseen. Tällaiset yhdistelmät ovat vähemmän erillisiä, ja niillä on todennäköisesti kaksoiskappaleita.EmailEvents | where Timestamp > ago(1h) | summarize by SenderFromAddress, RecipientEmailAddress
Kyselyn sekoittaminen – Vaikka
summarize
sitä kannattaa käyttää toistuvia arvoja sisältävissä sarakkeissa, samoilla sarakkeilla voi myös olla suuri kardinaliteetti tai suuri määrä yksilöllisiä arvoja.join
Kuten -operaattori, voit myös käyttää shuffle-vihjettä funktiollasummarize
prosessointikuormituksen jakamiseksi ja mahdollisesti suorituskyvyn parantamiseksi käytettäessä sarakkeita, joiden kardinaliteetti on suuri.Alla olevassa
summarize
kyselyssä lasketaan erillisten vastaanottajien sähköpostiosoite, joka voidaan suorittaa sadoissa tuhansissa suurissa organisaatioissa. Suorituskyvyn parantamiseksi se sisältäähint.shufflekey
:EmailEvents | where Timestamp > ago(1h) | summarize hint.shufflekey = RecipientEmailAddress count() by Subject, RecipientEmailAddress
Kyselyskenaariot
Yksilöllisten prosessien tunnistaminen prosessitunnuksia käyttämällä
Prosessitunnukset (PID) kierrätetään Windowsissa ja niitä käytetään uudelleen uusia prosesseja varten. He eivät voi toimia yksilöllisiä tunnisteita tietyille prosesseille.
Jos haluat saada prosessin yksilöivän tunnisteen tietyssä tietokoneessa, käytä prosessin tunnusta yhdessä prosessin luontiajan kanssa. Kun liität tietoja prosessien ympärille tai teet niistä yhteenvedon, sisällytä koneen tunnisteen sarakkeet (joko DeviceId
tai DeviceName
), prosessitunnus (ProcessId
tai InitiatingProcessId
), ja prosessin luontiaika (ProcessCreationTime
tai InitiatingProcessCreationTime
)
Seuraava esimerkkikysely etsii prosesseja, jotka käyttävät yli 10 IP-osoitetta portin 445 (SMB) kautta ja mahdollisesti skannaavat jaettuja tiedostoja.
Esimerkkikysely:
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
Kysely tekee yhteenvedon molempien InitiatingProcessId
mukaan siten InitiatingProcessCreationTime
, että se tarkastelee yhtä prosessia sekoittamatta useita prosesseja, joilla on sama prosessitunnus.
Kyselyn komentorivit
Tehtävän suorittamiseen voi luoda komentorivin usealla eri tavalla. Hyökkääjä voi esimerkiksi viitata kuvatiedostoon ilman polkua, ilman tiedostotunnistetta, käyttämällä ympäristömuuttujia tai lainausmerkkejä. Hyökkääjä voi myös muuttaa parametrien järjestystä tai lisätä useita lainausmerkkejä ja välilyöntejä.
Jos haluat luoda kestävämpiä kyselyitä komentorivien ympärille, noudata seuraavia käytäntöjä:
- Tunnista tunnetut prosessit (kuten net.exe tai psexec.exe) vastaamalla tiedostonimen kenttiin sen sijaan, että suodatat itse komentorivillä.
- Jäsennä komentorivin osia käyttämällä parse_command_line()-funktiota
- Kun kyselet komentoriviargumentteja, älä etsi tarkkaa vastaavuutta useille liittymättömille argumenteille tietyssä järjestyksessä. Käytä sen sijaan säännönmukaisia lausekkeita tai useita erillisiä sisältää-operaattoreita.
- Käytä kirjainkoolla ei-merkitseviä vastaavuuksia. Käytä esimerkiksi -
=~
, -in~
, - jacontains
-parametrin==
sijaan ,in
jacontains_cs
. - Jos haluat lieventää komentorivin obfusaatiotekniikoita, harkitse lainausmerkkien poistamista, pilkkujen korvaamista välilyönneillä ja useiden peräkkäisten välilyönnien korvaamista yhdellä välilyönnillä. On olemassa monimutkaisempia obfuscation-tekniikoita, jotka vaativat muita lähestymistapoja, mutta nämä säädöt voivat auttaa käsittelemään yleisiä.
Seuraavissa esimerkeissä näytetään eri tapoja muodostaa kysely, joka etsii tiedostoa net.exe palomuuripalvelun "MpsSvc" pysäyttämiseksi:
// 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"
Ulkoisten lähteiden tietojen käyttö
Jos haluat sisällyttää kyselyyn pitkiä luetteloita tai suuria taulukoita, käytä ulkoista tieto-operaattoria tietojen sisäänottoon määritetystä URI-tunnuksen avulla. Voit hakea tietoja tiedostoista TXT-, CSV-, JSON- tai muissa muodoissa. Alla olevassa esimerkissä näytetään, miten voit käyttää MalwareBazaarin (abuse.ch) tarjoamaa haittaohjelma SHA-256-hajautusarvojen laajaa luetteloa sähköpostien liitteiden tarkistamiseen:
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
Jäsennä merkkijonot
Käytettävissä on useita funktioita, joiden avulla voit tehokkaasti käsitellä merkkijonoja, jotka on jäsennettävä tai muunnettava.
Merkkijono | Funktio | Käyttöesimerkki |
---|---|---|
Komentorivit | parse_command_line() | Poimi komento ja kaikki argumentit. |
Polkuja | parse_path() | Pura tiedoston tai kansion polun osat. |
Versionumerot | parse_version() | Pura versionumero, jossa on enintään neljä osaa ja enintään kahdeksan merkkiä osaa kohden. Vertaile version ikää jäsennystietojen avulla. |
IPv4-osoitteet | parse_ipv4() | Muunna IPv4-osoite pitkäksi kokonaisluvuksi. Jos haluat verrata IPv4-osoitteita muuntamatta niitä, käytä ipv4_compare(). |
IPv6-osoitteet | parse_ipv6() | Muunna IPv4- tai IPv6-osoite kanoniseen IPv6-merkintätapaan. Jos haluat vertailla IPv6-osoitteita, käytä ipv6_compare(). |
Lisätietoja kaikista tuetuista jäsennysfunktioista on artikkelissa Kusto-merkkijonofunktiot.
Huomautus
Jotkin tämän artikkelin taulukot eivät ehkä ole käytettävissä Microsoft Defender for Endpoint. Ota Microsoft Defender XDR käyttöön uhkien etsimiseksi käyttämällä enemmän tietolähteitä. Voit siirtää kehittyneet metsästystyönkulut Microsoft Defender for Endpoint Microsoft Defender XDR noudattamalla kohdassa Kehittyneiden metsästyskyselyjen siirtäminen Microsoft Defender for Endpoint ohjeita.
Aiheeseen liittyvät artikkelit
- Kusto-kyselykielen dokumentaatio
- Kiintiöt ja käyttöparametrit
- Edistyneiden metsästysvirheiden käsitteleminen
- Tarkennetun etsinnän yleiskatsaus
- Opi kyselyn kieli
Vihje
Haluatko tietää lisää? Ota yhteyttä Microsoft Security -yhteisöön Tech Community -yhteisössä: Microsoft Defender XDR Tech Community.