Sentinel Workspace Function for 'sudo' commands
Today's post is going to be basic, but hopefully you will get the idea of how you can incorporate using Workspace Functions in your every-day workflows. The primary reason of having Worksapce Functions is that they allow you build queries and then save them in a manner that can easily be re-called in the KQL editor. This can be great for logs which require complex parsing or queries to make them more useful.
Today we are going to work with a Syslog feed to demonstrate how this can be used. Many people know Syslog is a powerful method of ingesting multiple log sources and can come in various formats. Specifically, today will focus on the 'authpriv' log within Linux which logs when somebody uses 'sudo' to run an elevated command:
The syslog message above gives useful insight, providing information in what looks to be a key=value format. However, in its current form, it's inefficient to query against, as none of those values are columns we can reference in our query.
That's fine, because we can fix this with the KQL 'parse' function. We do this by telling it our delimiters for each field:
| parse SyslogMessage with Username" : "LAZY"PWD="WorkingDirectory" USER="DestinationUser" COMMAND="ElevatedCommand
Note: I only use the phrase 'LAZY' to capture everything after the username and before the phrase 'PWD='. The irony of doing this is that I can lazily parse the whole syslog line, without writing multiple 'parse' statements below.
By parsing these fields, we can see they now return their own dedicate columns:
Using 'parse' means we have direct columns which can be referenced, as we build up more complex queries. For now, lets look at the complete query of how we're getting this data:
Syslog
| where Facility == "authpriv"
| where SyslogMessage contains "COMMAND=" // filtering to ensure returned log is parseable
| parse SyslogMessage with Username" : "LAZY"PWD="WorkingDirectory" USER="DestinationUser" COMMAND="ElevatedCommand
Although the above is a fairly basic example, you can see that if we were doing any more parsing (such as for a more complex log file) having to add these lines before we can query against our newly-created columns would be tiresome. It naturally adds complexity and room for copy / paste errors. Instead, we can turn it into a function so that anybody who has access to this Sentinel Workspace can use it!
To do this, we'll paste the query in the editor and in the top control button, hit 'save'. From there, we have the option to 'save as function' which gives us this editor:
This is a very basic example for the time being, but the eagle eyed may have noticed that custom functions can take parameters as you build more complex examples. For now, we just select the save option.
And just like that, our function can now be directly called upon within the KQL editor:
Having something simple like this can be really helpful for streamlining repetitive query logic, such as our log parsing. It also enables query creators to build further off this; one example may be using the new function to look for users with sudo privileges disabling system services:
ElevatedSudo
| where TimeGenerated > ago(30d)
| where ElevatedCommand contains "systemctl disable"
There are many complex applications for using Workspace Functions, but hopefully this post has inspired you to think about how you could use them for more efficient workflows.
Senior SOC Analyst
4 个月Very interesting and useful Nate. I wasn't aware you could use 'parse' which, as mentioned, is great for syslog - It would have come in useful multiple times in the past