CodeCommitsIssuesPull requestsActionsInsightsSecurity
master

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

Detections/SigninLogs/Brute Force Attack against GitHub Account.yaml

56lines · modepreview

id: 97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06
name: Brute Force Attack against GitHub Account
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 Azure Active Directory, 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.'
severity: Medium
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - SigninLogs
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADNonInteractiveUserSignInLogs
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CredentialAccess
relevantTechniques:
  - T1110
query: |
  let LearningPeriod = 7d; 
  let BinTime = 1h; 
  let RunTime = 1h; 
  let StartTime = 1h; 
  let NumberOfStds = 3; 
  let MinThreshold = 10.0; 
  let EndRunTime = StartTime - RunTime; 
  let EndLearningTime = StartTime + LearningPeriod;
  let aadFunc = (tableName:string){
  let GitHubFailedSSOLogins = (table(tableName)  
  | where AppDisplayName == "GitHub.com" 
  | where ResultType != 0); 
  GitHubFailedSSOLogins 
  | where TimeGenerated between (ago(EndLearningTime) .. ago(StartTime)) 
  | summarize FailedLoginsCountInBinTime = count() by  UserPrincipalName, bin(TimeGenerated, BinTime), Type
  | summarize AvgOfFailedLoginsInLearning = avg(FailedLoginsCountInBinTime), StdOfFailedLoginsInLearning = stdev(FailedLoginsCountInBinTime) by UserPrincipalName, Type
  | extend LearningThreshold = max_of(AvgOfFailedLoginsInLearning + StdOfFailedLoginsInLearning * NumberOfStds, MinThreshold)  
  | join kind=innerunique ( 
    GitHubFailedSSOLogins 
    | where TimeGenerated between (ago(StartTime) .. ago(EndRunTime)) 
    | summarize FailedLoginsCountInRunTime = count() by User = Identity, UserPrincipalName, bin(TimeGenerated, BinTime), Type
  ) on UserPrincipalName 
  | where FailedLoginsCountInRunTime > LearningThreshold
  | extend AccountCustomEntity = UserPrincipalName , timestamp = TimeGenerated
  };
  let aadSignin = aadFunc("SigninLogs");
  let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs");
  union isfuzzy=true aadSignin, aadNonInt
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountCustomEntity
version: 1.0.0
kind: Scheduled