All countries has an ISO code, described in ISO 3166 is an international standard. These codes are used throughout the IT industry by computer systems and software to make it easier to identify a country.
It has multiple formats and they country codes are presented in the following formats: Alpha-2 (2 characters), Alpha-3 (3 characters) and Numeric (3 digits).
In the data from some logs like SigninLogs and IdentityLogonEvents the country is presented as Alpha-2. We realized pretty quick is that some 2-characters country codes are difficult to remember. As in below, picture it could be difficult to know all these countries.
We have been using this for a long time and thought it might be something others can use as well.
So to solve this I created a csv file and placed on github:
Earlier this month, the Kusto team announced graph semantics feature in Kusto.
This Kusto extension makes it possible to contextualize data in graphs which consists of Nodes and Edges that can be connected. These connections can visualize the relationships between the Nodes.
To describe graph semantics in a none-tech scenario, the best way is to look at social connections where people have connections, one to many, many to many and many to one
let Users = datatable (UserId:string , name:string)[
"1","Mattias",
"2","XboxController",
"3","Stefan",
"4","XBOX"
]; // nodes
let Knows = datatable (FirstUser:string , SecondUser:string)[
"1","2",//Mattias knows xbox controller
"2","4",//Xbox controller knows xbox
"1","3"//Mattias knows Stefan
]; // edges
Knows
| make-graph FirstUser --> SecondUser with Users on UserId
| graph-match (user)-->(middle_man)-->(friendOfAFriend)
project SecLabs_person = user.name, middle_man = middle_man.name, kusto_friend_of_friend = friendOfAFriend.name
What can it use it for?
Many-to-many relations
Hierarchical data
Networked relationships
Social Networks
Recommendation systems
Connected assets
Knowledge graphs
From a hunting perspective, we can connect systems in a unspecified amounts of times. Since we can’t to recursive join, we can use graph to connect unknown number of systems.
Time-aware
In a scenario where we have lateral movement, we could connect all devices involved and at what time (of course depending on the data source, but if we have data from Microsoft Defender XDR data with network data from the endpoint sensor and know about activities involving certain ports, 3389 for example) we could draw all show how and when the threat actor moved laterally.
Establishing a Proactive Hunting program is something which is useful and necessary today.
From working with proactive threat hunting for a long time, from when data was not available at your fingertips, things has become a lot easier in the era of SIEM and over the last years, EDR and XDR.
The technical part is the easy one. The process of establishing your hunting and connect it with existing processes is usually what’s difficult.
What is proactive Hunting?
First, what is threat hunting?
To dive in to this topic I want to point out activities that are somewhat related
The custom detections or scheduled rules is pretty clear what it is. but Tasks is something which sits in between Proactive Threat Hunting and Custom Detections. Tasks are things discovered in Hunting, and data of interest but cannot be set as a custom detection as of yet.
The reasons could be many, but for example to noisy data and no good correlation values or near-time events that can be used to reduce False-Positives. Even though we have finalized our hypothesis from threat hunting we might want to follow-up on the events, maybe on a daily basis, but we cant have it scheduled since it will give an incident fatigue.
To summarize tasks, it’s queries that might make it to a detection but for now we run it automatically or manual and do manual review on the result on a daily schedule.
To iterate back to threat hunting before we take a look at the hunts feature in Sentinel
Threat Hunting can be divided into 2 main pillars; Proactive and Reactive hunting
Proactive Threat Hunting is when you don’t know something is going on, like playing hide-n-seek, except for that you don’t know anyone is playing with you
Reactive Threat Hunting is post breach/post incident and you use threat hunting to find the outer boundaries of the incident, which could be other devices communicating with a specific IP, list all process communicating, find the same processes on other devices, and then which IP’s they are communicating with.
In the EDR era or now, the XDR era, threat hunting becomes easier on a technical level. The data collection happens automatically for many workloads and not only collected, it’s streamed.
With the power of Kusto Query Language, you can do advanced aggregations, anomaly calculations and visualizations to truly crunch and bend your data.
In Proactive Threat hunting, you will start your assignment by defining your Hypothesis, which could be something like “I would like to see if any local users have been added outside the process”
Then you check what ever data you need to discover such activities (DeviceEvents/DeviceProcessEvents hint hint) and you continue to develop the query for is and document your result.
Here is what makes Hunts feature so great. It actually allows for process integration, like we have in Microsoft 365 Defender where we can create incidents based on the results and have it handled by the incident process.
Hunts in Sentinel
Common use cases:
Proactively hunt based on specific MITRE techniques, potentially malicious activity, recent threats, or your own custom hypothesis.
Use security-researcher-generated hunting queries or custom hunting queries to investigate malicious behavior.
Conduct your hunts using multiple persisted-query tabs that enable you to keep context over time.
Collect evidence, investigate UEBA sources, and annotate your findings using hunt specific bookmarks.
Collaborate and document your findings with comments.
Act on results by creating new analytic rules, new incidents, new threat indicators, and running playbooks.
Keep track of your new, active, and closed hunts in one place.
View metrics based on validated hypotheses and tangible results.
In Sentinel go to Hunting and Hunts
Here is the list of previous hunts.
If you select New Hunt we can create a new
You can add the Hypothesis and choose if it’s Validated or not (which can be set later in the process by another Threat hunter)
When we have our new Hunting campaign, we can add queries
Adding Tactics and techniques and map entities
It’s possible to create incidents from the results to map to the incident process, and we can also start automated playbooks (entity-based) from the entity pane.
Summary
There are so many details on this feature and it has some many capabilities. The best part is that it has the process of hunting as its core. Now it’s easier to deliver threat hunting, as a service, as a consultant or if you work internally for an organization.
This post will be a part of a multiple posts to cover data parsing in Microsoft Sentinel.
Intro
Kusto is a powerfull query language and easy to adopt.
Even if Kusto is very powerfull, working with custom log sources is, sometimes, a mess. Some parsers requires more effort and some are very simple.
In general, when it’s possible to use operators like “parse” (link) function or “parse-kv” (link) it’s very welcome. However, the reality has a different challenge for us.
In this post we want to share a quick pro tip to solve the mystic of hidden whitespaces
The challenge of whitespaces
Whitespaces ” ” exists everywhere, the challenge is how it’s presented in log analytics.
Log analytics does a lot for the user in terms of nicely present data. It actually removes duplicate whitespaces, as well as leading and trailing whitespace.
This could result in problems like failing parsers, regex and string operators like “==”, “startswith”, “endswith” etc will fail. Especially if it’s not consistent.
Marking the string in the output view does not show the extra whitespaces
Copying the text and paste into a text-editor will not show it either like in below example where we copied the output into VS Code (we can only see one dot to show one whitespace between foo and bar)
However, the double whitespaces are interpreted during execution, and it’s only in the presentation view the extra is removed. As in below example, we used split on ” ” to show the existence of the double whitespace.
When working with multiple log sources you don’t want to search and see if they exist (which may change during the log source life cycle), you rather want a way to always make the log to look good in your parser.
Solution
To properly address this (if there aren’t any good ways to change the audit settings of the system sending the logs)
To handle the duplicate white spaces we use the replace_regex function (link here) and use the whitespace “\s” with the quantifier “+” which means one or multiple times and replace it with a space ” “.
This will search for spaces (one or more) and replace it with a single, because we don’t want to remove single spaces. And by using the same column name “SyslogMessage” we will actually reuse the same column for our clean output.
Please note that this will not change the message in the database, only during execution.
Doing this gives us the following output.
The next step is that we want to remove the leading and trailing whitespaces. If we for instance expect the first character to be a value, the leading whitespace could make our parser to fail or an analytic rule.
We have seen occasions where this happens from time to time and not all messages in a log source.
To fix the leading and trailing whitespaces we use another regex to look for start of string and end of string. But this time we want to replace with “nothing/null” which is why we can’t use this regex in the first cleaning.
In the second run we use the same column name again to cleanup the SyslogMessage. There is a best practice to always keep the original message, however, this is to solve an error from the log source and not to alter the SyslogMessage.
The regex starts with an anchor “^” to define the start of the string and followed by a whitespace “\s” since we cleaned all double whitespaces we don’t need to use the quantifier. To handle the trailing whitespace we use the OR operand “|” and check for a whitespace “\s” followed by the anchor “$” to determine the end of the string. If we get any hits it will be replaced with null and we have a clean string.
By adding these 2 lines of code to the parser, we will avoid running into strange issues which could take some time to troubleshoot.
Automated attack disruption of Ransomware and BEC (Business email compromise uses high-confidence Extended Detection and Response (XDR) signals across all workloads; endpoints, identities, email, and SaaS apps, to contain the threat quickly and effectively, to stop further impact.
These 2 scenarios are common attacks and it’s really great that they are supported by the feature in Microsoft 365 Defender.
Business Email Compromise, BEC
Threat actors are impersonating executives to trick, for example, Economic department to transfer money by impersonating the CFO or the CEO.
Automatic attack disruption can help to detect these attacks and remove the access to the accounts by disabling the compromised account, limiting their ability to send fraudulent email
Human-operated ransomware, HumOR
This attack, commonly used today, is devastating for an organization. The threat actors has full control of the environment and have usually controlled the environment for some time.
The challenge from a SecOps perspective is to be fast enough to respond to the incidents and mitigate accounts and the devices fast enough.
When the threat actors has gained privileged access, things move very quick and automatic attack disruption will contain the spreader device and disable the compromised user account
Automatic attack disruption operates in 3 key stages
Detect malicious activity and establish high confidence
Classification of scenarios and identification of assets controlled by the attacker
Trigger automatic response actions using the Microsoft 365 Defender protection stack to contain the active attack
First the detection will happen, which is achieved by AI, research-information etc.., to establish a high level of confidence in accurately detecting ransomware spread and encryption activity. The XDR-level capability correlates insights across endpoints, identities, email and SaaS apps to establish high-fidelity alerts.
A second stage will aggregate automatic analyze the activities like tampering, backup deletion, credential theft, mass lateral movement and many more to flag the assets included in the chain and trace the activities back to the remote execution TTP
Distrupting the attack
Response actions against the entities which are identified as compromised and in the public preview these two are the main actions:
If you want to find threats earlier it is now possible to use NRT rules in Defender.
Before this, we had the options to use 24h, 12h, 3h, and 1h as the schedule. This gives Defenders the possibility to detect and respond to threat much earlier.
Tables that support Continuous (NRT) frequency
AlertEvidence
DeviceEvents
DeviceFileCertificateInfo
DeviceFileEvents
DeviceImageLoadEvents
DeviceLogonEvents
DeviceNetworkEvents
DeviceNetworkInfo
DeviceInfo
DeviceProcessEvents
DeviceRegistryEvents
EmailAttachmentInfo
EmailEvents
EmailPostDeliveryEvents
EmailUrlInfo
UrlClickEvents
The NRT rules does not support externaldata operator and you can only query one table
Configuring NRT (Continuous) Rule
From the Advanced Hunting, develop your query and click and configure the Alert Details
Click Next and select impacted entities (in this case we are using an email table and therefore the impacted entities will be mailbox)Click Next and configure the actions. It’s important to think about what the actions means and make sure your query will detect exactly what you want.
Be cautious with the Isolate device when querying Device tables. If you have an error in your detection you may isolate all machines by mistake
It’s now completed!
Don’t forget that you can use the hunting if you want to take response actions on multiple entities very quickly.
From the Result of your hunting query, select the rows where you want to take action and click Take Actions
This brings your the Actions pane and you can choose which actions you need.
Depending on your query (which tables and output) you get different options for your actions. ‘
One thing that threat actors commonly do when getting a foothold on a device, is to try to disable Defender services and adding exclusions for their tools which they plan to execute.
For the Defender services, we have had Tamper Protection for some time, but that did not cover exclusions.
Tamper Protection configuration via Intune
Requirements
For Tamper Protection to cover exclusions, the following requirements must be met:
Devices are running Windows Defender platform 4.18.2211.5 or later
The registry value TPExclusions which is in the HKLM\SOFTWARE\Microsoft\Windows Defender\Features key shows a value of 1 if protected and 0 if not protected. Please note that you cannot change the registry value to protect the exclusions, it’s for information and not configuration
While we talk about Antivirus policies…
We would like to share this as well since it’s something we see when we do Defender assessments, it’s unfortunately very common that these settings are wrong
Cloud block level (high is recommended minimum) and Cloud Extended Timeout check must be set to 50 (seconds)
Sample submission is required for Cloud protection
The response action of blocking a compromised account is important to have available. Regardless of solution one must be able to quick and easy be able to block an account. In MDI (part of Microsoft 365 Defender) it is possible since some time ago to configure an MDI Action Account, lately the option to run with the system account of the Domain Controller has been added to this feature and therefor you don’t have to configure the gMSA account.
Using system or a custom gMSA account
The choice is made based on organizational structure, Tiering/RBAC, MSSP partner. Basically, if you are required to delegate the permissions to only allow actions on accounts in certain OU’s, then you must use a custom gMSA accounts.
For example, if you have a MSSP partner monitoring your security and take actions to discovered threats, a so called MDR (Managed Detection and Response), you have an option to control to which accounts the MSSP can take actions.
The available actions are:
Disable user in Active Directory: This will temporarily prevent a user from logging in to the on-premises network. This can help prevent compromised users from moving laterally and attempting to exfiltrate data or further compromise the network.
Suspend user in Azure Active Directory: This will temporarily prevent a user from logging in to Azure Active Directory. This can help prevent compromised users from attempting to exfiltrate data and minimizes the time between Disable user in Active Directory and the sync of this status to the cloud.
Reset user password – This will prompt the user to change their password on the next logon, ensuring that this account can’t be used for further impersonation attempts.
From an MSSP perspective, this feature is very useful since there wouldn’t require customer access (VPN or other kind of access) to respond to threats. Even though this feature is very popular for MSSPs, you will still want to have this option if you have your internal security operations to be able to respond from the portal you are currently working in.
Even though this feature is very popular for MSSPs
This can also be checked on the logon event (this will trigger 4625, logon failed)
Verify that the AccountType is “Machine”
Successful sign-in:
Account is not allowed to logon as a service
If the gMSA Account is setup and configured correctly and there is still event 4625 being logged.
Check the Status property of the login event
0xc000015b indicates that the account is not allowed to login0xC000015B
STATUS_LOGON_TYPE_NOT_GRANTED, A user has requested a type of logon (for example, interactive or network) that has not been granted. An administrator has control over who can logon interactively and through the network.
More information about the Status property can be found here:
Successful events effecting the user you try to take action on
The following query will find events of enabling and disabling a user
SecurityEvent
| where EventID in(4738,4725,4722)
| where Account contains "gMSA-mdi-action$"
| where TargetAccount contains "test" //the user you want to take action on
You see 4738 “A user account was changed” at the same timestamp as the 4725 and 4722 and the 4738 event show the UAC 0x10: Account Enabled and 0x11: Account Disabled
For a long time we have been able to isolate onboarded devices in Microsoft Defender for Endpoint. But if a device is not onboarded we could not take any response actions to an eventual threat.
Microsoft has released a feature called Contain device which basically makes the opposite, instead of isolating the compromised device, we can tell all managed devices that they cannot communicate with the specific unmanaged device.
If a contained device changes IP address, the blocking will be updated and changed to the new IP address and the old will be “released” from block.
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept”, you consent to the use of ALL the cookies.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.