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

Brute Force Attack against GitHub Account

Back
Id97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06
RulenameBrute Force Attack against GitHub Account
DescriptionAttackers who are trying to guess your users’ passwords or use brute-force methods to get in. If your organization is using SSO with Microsoft Entra ID, authentication logs to GitHub.com will be generated. Using the following query can help you identify a sudden increase in failed logon attempt of users.
SeverityMedium
TacticsCredentialAccess
TechniquesT1110
Required data connectorsAzureActiveDirectory
KindScheduled
Query frequency1h
Query period7d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/Brute Force Attack against GitHub Account.yaml
Version2.0.2
Arm template97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06.json
Deploy To Azure
let LearningPeriod = 7d;
let BinTime = 1h;
let RunTime = 1h;
let StartTime = 1h;  
let sensitivity = 2.5;
let EndRunTime = StartTime - RunTime;
let EndLearningTime = StartTime + LearningPeriod;
let aadFunc = (tableName:string){
table(tableName)  
| where TimeGenerated between (ago(EndLearningTime) .. ago(EndRunTime))
| where AppDisplayName =~ "GitHub.com"
| where ResultType != 0
| make-series FailedLogins = count() on TimeGenerated from ago(LearningPeriod) to ago(EndRunTime) step BinTime by UserPrincipalName, Type
| extend (Anomalies, Score, Baseline) = series_decompose_anomalies(FailedLogins, sensitivity, -1, 'linefit')
| mv-expand FailedLogins to typeof(double), TimeGenerated to typeof(datetime), Anomalies to typeof(double), Score to typeof(double), Baseline to typeof(long)  
| where TimeGenerated >= ago(RunTime)
| where Anomalies > 0 and Baseline > 0
| join kind=inner (
          table(tableName)  
          | where TimeGenerated between (ago(StartTime) .. ago(EndRunTime))
          | where AppDisplayName =~ "GitHub.com"
          | where ResultType != 0
          | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), IPAddresses = make_set(IPAddress,100), Locations = make_set(LocationDetails,20), Devices = make_set(DeviceDetail,20) by UserPrincipalName, UserId, AppDisplayName
      ) on UserPrincipalName
| project-away UserPrincipalName1
| extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0])
| extend IPAddressFirst = tostring(IPAddresses[0])
};
let aadSignin = aadFunc("SigninLogs");
let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs");
union isfuzzy=true aadSignin, aadNonInt
relevantTechniques:
- T1110
name: Brute Force Attack against GitHub Account
requiredDataConnectors:
- dataTypes:
  - SigninLogs
  connectorId: AzureActiveDirectory
- dataTypes:
  - AADNonInteractiveUserSignInLogs
  connectorId: AzureActiveDirectory
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: UserPrincipalName
  - identifier: Name
    columnName: Name
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: AadUserId
    columnName: UserId
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: IPAddressFirst
  entityType: IP
triggerThreshold: 0
id: 97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06
tactics:
- CredentialAccess
version: 2.0.2
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/Brute Force Attack against GitHub Account.yaml
queryPeriod: 7d
kind: Scheduled
queryFrequency: 1h
severity: Medium
status: Available
description: |
    'Attackers who are trying to guess your users' passwords or use brute-force methods to get in. If your organization is using SSO with Microsoft Entra ID, authentication logs to GitHub.com will be generated. Using the following query can help you identify a sudden increase in failed logon attempt of users.'
query: |
  let LearningPeriod = 7d;
  let BinTime = 1h;
  let RunTime = 1h;
  let StartTime = 1h;  
  let sensitivity = 2.5;
  let EndRunTime = StartTime - RunTime;
  let EndLearningTime = StartTime + LearningPeriod;
  let aadFunc = (tableName:string){
  table(tableName)  
  | where TimeGenerated between (ago(EndLearningTime) .. ago(EndRunTime))
  | where AppDisplayName =~ "GitHub.com"
  | where ResultType != 0
  | make-series FailedLogins = count() on TimeGenerated from ago(LearningPeriod) to ago(EndRunTime) step BinTime by UserPrincipalName, Type
  | extend (Anomalies, Score, Baseline) = series_decompose_anomalies(FailedLogins, sensitivity, -1, 'linefit')
  | mv-expand FailedLogins to typeof(double), TimeGenerated to typeof(datetime), Anomalies to typeof(double), Score to typeof(double), Baseline to typeof(long)  
  | where TimeGenerated >= ago(RunTime)
  | where Anomalies > 0 and Baseline > 0
  | join kind=inner (
            table(tableName)  
            | where TimeGenerated between (ago(StartTime) .. ago(EndRunTime))
            | where AppDisplayName =~ "GitHub.com"
            | where ResultType != 0
            | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), IPAddresses = make_set(IPAddress,100), Locations = make_set(LocationDetails,20), Devices = make_set(DeviceDetail,20) by UserPrincipalName, UserId, AppDisplayName
        ) on UserPrincipalName
  | project-away UserPrincipalName1
  | extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0])
  | extend IPAddressFirst = tostring(IPAddresses[0])
  };
  let aadSignin = aadFunc("SigninLogs");
  let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs");
  union isfuzzy=true aadSignin, aadNonInt  
triggerOperator: gt
{
  "$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/97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06')]",
      "properties": {
        "alertRuleTemplateName": "97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06",
        "customDetails": null,
        "description": "'Attackers who are trying to guess your users' passwords or use brute-force methods to get in. If your organization is using SSO with Microsoft Entra ID, authentication logs to GitHub.com will be generated. Using the following query can help you identify a sudden increase in failed logon attempt of users.'\n",
        "displayName": "Brute Force Attack against GitHub Account",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserPrincipalName",
                "identifier": "FullName"
              },
              {
                "columnName": "Name",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserId",
                "identifier": "AadUserId"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPAddressFirst",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/Brute Force Attack against GitHub Account.yaml",
        "query": "let LearningPeriod = 7d;\nlet BinTime = 1h;\nlet RunTime = 1h;\nlet StartTime = 1h;  \nlet sensitivity = 2.5;\nlet EndRunTime = StartTime - RunTime;\nlet EndLearningTime = StartTime + LearningPeriod;\nlet aadFunc = (tableName:string){\ntable(tableName)  \n| where TimeGenerated between (ago(EndLearningTime) .. ago(EndRunTime))\n| where AppDisplayName =~ \"GitHub.com\"\n| where ResultType != 0\n| make-series FailedLogins = count() on TimeGenerated from ago(LearningPeriod) to ago(EndRunTime) step BinTime by UserPrincipalName, Type\n| extend (Anomalies, Score, Baseline) = series_decompose_anomalies(FailedLogins, sensitivity, -1, 'linefit')\n| mv-expand FailedLogins to typeof(double), TimeGenerated to typeof(datetime), Anomalies to typeof(double), Score to typeof(double), Baseline to typeof(long)  \n| where TimeGenerated >= ago(RunTime)\n| where Anomalies > 0 and Baseline > 0\n| join kind=inner (\n          table(tableName)  \n          | where TimeGenerated between (ago(StartTime) .. ago(EndRunTime))\n          | where AppDisplayName =~ \"GitHub.com\"\n          | where ResultType != 0\n          | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), IPAddresses = make_set(IPAddress,100), Locations = make_set(LocationDetails,20), Devices = make_set(DeviceDetail,20) by UserPrincipalName, UserId, AppDisplayName\n      ) on UserPrincipalName\n| project-away UserPrincipalName1\n| extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0])\n| extend IPAddressFirst = tostring(IPAddresses[0])\n};\nlet aadSignin = aadFunc(\"SigninLogs\");\nlet aadNonInt = aadFunc(\"AADNonInteractiveUserSignInLogs\");\nunion isfuzzy=true aadSignin, aadNonInt\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P7D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess"
        ],
        "techniques": [
          "T1110"
        ],
        "templateVersion": "2.0.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}