Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

GitLab - Brute-force Attempts

Back
Id2238d13a-cf05-4973-a83f-d12a25dbb153
RulenameGitLab - Brute-force Attempts
DescriptionThis query relies on GitLab Application Logs to get failed logins to highlight brute-force attempts from different IP addresses in a short space of time.
SeverityMedium
TacticsCredentialAccess
TechniquesT1110
Required data connectorsSyslog
KindScheduled
Query frequency1h
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/GitLab/Analytic Rules/GitLab_BruteForce.yaml
Version1.0.0
Arm template2238d13a-cf05-4973-a83f-d12a25dbb153.json
Deploy To Azure
let LearningPeriod = 7d; 
let EndLearningTime = now();
let BinTime = 1h; 
let RunTime = 1h; 
let MinThreshold = 3.0; 
let GitLabFailedLogins = (GitLabApp
| where FailedLogin == 1
| parse kind=regex Message with "Failed Login: username=" User "ip=" IpAddress 
| project TimeGenerated, EventTime, Computer, User, HostName, HostIP, IpAddress);
GitLabFailedLogins 
| where EventTime between (ago(LearningPeriod) .. EndLearningTime) 
| summarize FailedLoginsCountInBinTime = count() by User, bin(EventTime, BinTime) 
| summarize AvgOfFailedLoginsInLearning = avg(FailedLoginsCountInBinTime), StdOfFailedLoginsInLearning = stdev(FailedLoginsCountInBinTime) by User 
| extend LearningThreshold = max_of(AvgOfFailedLoginsInLearning, MinThreshold) 
| join kind=innerunique ( GitLabFailedLogins 
| summarize FailedLoginsCountInRunTime = count() by User, IpAddress, EventTime = bin(EventTime, BinTime) ) on User 
| where FailedLoginsCountInRunTime >= LearningThreshold
| project User, IpAddress, EventTime, FailedLoginsCountInRunTime, LearningThreshold
id: 2238d13a-cf05-4973-a83f-d12a25dbb153
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/GitLab/Analytic Rules/GitLab_BruteForce.yaml
requiredDataConnectors:
- dataTypes:
  - Syslog
  connectorId: Syslog
description: |
    'This query relies on GitLab Application Logs to get failed logins to highlight brute-force attempts from different IP addresses in a short space of time.'
severity: Medium
queryPeriod: 1d
kind: Scheduled
tactics:
- CredentialAccess
queryFrequency: 1h
query: |
  let LearningPeriod = 7d; 
  let EndLearningTime = now();
  let BinTime = 1h; 
  let RunTime = 1h; 
  let MinThreshold = 3.0; 
  let GitLabFailedLogins = (GitLabApp
  | where FailedLogin == 1
  | parse kind=regex Message with "Failed Login: username=" User "ip=" IpAddress 
  | project TimeGenerated, EventTime, Computer, User, HostName, HostIP, IpAddress);
  GitLabFailedLogins 
  | where EventTime between (ago(LearningPeriod) .. EndLearningTime) 
  | summarize FailedLoginsCountInBinTime = count() by User, bin(EventTime, BinTime) 
  | summarize AvgOfFailedLoginsInLearning = avg(FailedLoginsCountInBinTime), StdOfFailedLoginsInLearning = stdev(FailedLoginsCountInBinTime) by User 
  | extend LearningThreshold = max_of(AvgOfFailedLoginsInLearning, MinThreshold) 
  | join kind=innerunique ( GitLabFailedLogins 
  | summarize FailedLoginsCountInRunTime = count() by User, IpAddress, EventTime = bin(EventTime, BinTime) ) on User 
  | where FailedLoginsCountInRunTime >= LearningThreshold
  | project User, IpAddress, EventTime, FailedLoginsCountInRunTime, LearningThreshold  
version: 1.0.0
triggerThreshold: 0
name: GitLab - Brute-force Attempts
entityMappings:
- entityType: IP
  fieldMappings:
  - columnName: IPAddress
    identifier: Address
- entityType: Account
  fieldMappings:
  - columnName: User
    identifier: FullName
status: Available
relevantTechniques:
- T1110
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/2238d13a-cf05-4973-a83f-d12a25dbb153')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/2238d13a-cf05-4973-a83f-d12a25dbb153')]",
      "properties": {
        "alertRuleTemplateName": "2238d13a-cf05-4973-a83f-d12a25dbb153",
        "customDetails": null,
        "description": "'This query relies on GitLab Application Logs to get failed logins to highlight brute-force attempts from different IP addresses in a short space of time.'\n",
        "displayName": "GitLab - Brute-force Attempts",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPAddress",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "User",
                "identifier": "FullName"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/GitLab/Analytic Rules/GitLab_BruteForce.yaml",
        "query": "let LearningPeriod = 7d; \nlet EndLearningTime = now();\nlet BinTime = 1h; \nlet RunTime = 1h; \nlet MinThreshold = 3.0; \nlet GitLabFailedLogins = (GitLabApp\n| where FailedLogin == 1\n| parse kind=regex Message with \"Failed Login: username=\" User \"ip=\" IpAddress \n| project TimeGenerated, EventTime, Computer, User, HostName, HostIP, IpAddress);\nGitLabFailedLogins \n| where EventTime between (ago(LearningPeriod) .. EndLearningTime) \n| summarize FailedLoginsCountInBinTime = count() by User, bin(EventTime, BinTime) \n| summarize AvgOfFailedLoginsInLearning = avg(FailedLoginsCountInBinTime), StdOfFailedLoginsInLearning = stdev(FailedLoginsCountInBinTime) by User \n| extend LearningThreshold = max_of(AvgOfFailedLoginsInLearning, MinThreshold) \n| join kind=innerunique ( GitLabFailedLogins \n| summarize FailedLoginsCountInRunTime = count() by User, IpAddress, EventTime = bin(EventTime, BinTime) ) on User \n| where FailedLoginsCountInRunTime >= LearningThreshold\n| project User, IpAddress, EventTime, FailedLoginsCountInRunTime, LearningThreshold\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess"
        ],
        "techniques": [
          "T1110"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}