Microsoft Sentinel : Using KQL to detect failed login on Linux
Tags: security, azure, sentinel, microsoftsentinel
Published: 2024-01-07 12:06:52

Blog link at [https://aniket18292.wixsite.com/cyber-art/post/detect-failed-logins-on-a-linux-machine-in-azure-using-microsoft-sentinel](url)

This article will explain how to generate alerts and incidents for failed logins on Linux machines. This can be particularly useful to the SOC Team during a brute force attack.


**Pre-Requisites**

1. AMA/OmsAgent (Legacy) needs to be installed on the machine.

2. If using AMA, Data Collection Rule should be created to collect auth facility logs.

3. If using Legacy agent, you can navigate to Log Analytics Workspace -> legacy Agents Management -> Syslog and make sure "auth" facility has been selected here.


Along with this, we can setup automations as well to get notified or take action on the attacker IP address whenever a failed login is detected and try to enrich the IP to aid investigation but for now let us create the rule and have a look at how the incident looks like.


To create an analytic rule, navigate to Microsoft Sentinel -> Analytic Rules and from the top click on create NRT (Near-Realtime) Query rule. I am using NRT as failed login is a critical event and I would like to be notified as soon as possible. Usually with NRT, it takes around 2 minutes for an incident to be generated.


You can give a name of your choice, following is my configuration.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jb6yn6zwxvecy5gmjowp.png)

You can now click on Next and use the following query.
 
`Syslog
| where Facility == 'auth' and SyslogMessage has 'failed password'
| extend Account = tostring(extract("Failed password for (.*) from", 1, SyslogMessage))
| extend PortNumber = tostring(extract("port (\\d+)", 1, SyslogMessage))
| extend IpAddress = tostring(extract("from (\\d+\\.\\d+\\.\\d+\\.\\d+)", 1, SyslogMessage))
| extend Protocol = tostring(extract("port \\d+ (.*)$", 1, SyslogMessage))
| extend Description = iff(Account has "invalid","Failed Login from Invalid Account [Indicates brute force]", " Failed Login from Valid Account [Consider Password Change] [Could be legitimate attempt]")
| project
    IpAddress,
    HostIP,
    Account,
    PortNumber,
    Protocol,
    HostName,
    Computer,
    ProcessID,
    ProcessName,
    Description`
 

I will try to explain the KQL query here.


Firstly we filter syslog data to include only entries where the Facility is 'auth' and where SyslogMessage contains the string 'failed password'

Next, we use use the extract function to pull specific information from the SyslogMessage field. Each extend statement creates a new column with extracted information.

The Description column is created based on the content of the Account column. If the Account contains "invalid," it suggests a potential brute force attempt; otherwise, it implies a failed login from a valid account.

Finally, the project statement selects specific columns to display in the output. This will be useful for entity mapping.

 
Following are the entities mapped. Remember, it is very important to map entities in any analytic rule or else you wont be able to conduct any investigation.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f142x1ksu1bj745lk79f.png)

Rest of the columns, I have mapped to Custom Details as there were no relevant fields for them in Entity Mapping.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/462ztx45wvt7cdys3hnz.png)
 
For Event Grouping section, I have decided to trigger an alert for each event.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftiznz5ej09514pwkffy.png)

Click Next and make sure that enable incidents is enabled. It is upto you whether you would like to group the alerts. Ideally, it is a good practice to do so.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1u2kl4nvf3j3eta7zqw.png)

For automated response, I am using a playbook to enrich the IP address and block the attacker IP automatically at NSG level which I will cover in another article.

Once done, you can hit the review and create button.
 
Now, you can generated a failed login event on your linux machine and have an incident generated.

I had exposed my VM to the public internet and there were lots of incidents generated. 

Following is one such incident

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pe8pyuxq4ph4tk0vqrpx.png)

A sneak peek into the automation that I am using

Incident description has been updated with relevant details of playbook actions and severity has been lowered as playbook has returned success state.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z421poho2ejviqnal3f8.png)

Let's go and check out the task now, shall we?

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2n53j638f1ye8p945zc.png)

An email has also been triggered for the same as we can see below 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vsrm879m8iovfpdb08f1.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tyxu2wods7alibss0zn0.png)

I will release an article later on detailing the playbook and on how to fetch threat intel details.

Cheers, and thanks for reading!