Родитель
834ad9521d
Коммит
99a32a83f2
|
@ -0,0 +1,39 @@
|
|||
id: f041e01d-840d-43da-95c8-4188f6cef546
|
||||
name: GitHub Activites from a New Country
|
||||
description: |
|
||||
'Detect activities from a location that was not recently or was never visited by the user or by any user in your organization.'
|
||||
severity: Medium
|
||||
requiredDataConnectors: []
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 7d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- InitialAccess
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
let LearningPeriod = 7d;
|
||||
let RunTime = 1h;
|
||||
let StartTime = 1h;
|
||||
let EndRunTime = StartTime - RunTime;
|
||||
let EndLearningTime = StartTime + LearningPeriod;
|
||||
let GitHubCountryCodeLogs = (GitHubAuditData
|
||||
| where Country != "");
|
||||
GitHubCountryCodeLogs
|
||||
| where TimeGenerated between (ago(EndLearningTime) .. ago(StartTime))
|
||||
| summarize makeset(Country) by Actor
|
||||
| join kind=innerunique (
|
||||
GitHubCountryCodeLogs
|
||||
| where TimeGenerated between (ago(StartTime) .. ago(EndRunTime))
|
||||
| distinct Country, Actor, TimeGenerated
|
||||
) on Actor
|
||||
| where set_Country !contains Country
|
||||
| extend AccountCustomEntity = Actor , timestamp = TimeGenerated
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.0
|
||||
kind: Scheduled
|
|
@ -0,0 +1,27 @@
|
|||
id: 3ff0fffb-d963-40c0-b235-3404f915add7
|
||||
name: GitHub Two Factor Auth Disable
|
||||
description: |
|
||||
'Two-factor authentication is a process where a user is prompted during the sign-in process for an additional form of identification, such as to enter a code on their cellphone or to provide a fingerprint scan. Two factor authentication reduces the risk of account takeover. Attacker will want to disable such security tools in order to go undetected. '
|
||||
severity: Medium
|
||||
requiredDataConnectors: []
|
||||
queryFrequency: 1d
|
||||
queryPeriod: 1d
|
||||
triggerOperator: gt
|
||||
triggerThreshold: 0
|
||||
tactics:
|
||||
- DefenseEvasion
|
||||
relevantTechniques:
|
||||
- T1562
|
||||
query: |
|
||||
|
||||
GitHubAuditData
|
||||
| where Action == "org.disable_two_factor_requirement"
|
||||
| project TimeGenerated, Action, Actor, Country, Repository
|
||||
| extend AccountCustomEntity = Actor
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
version: 1.0.0
|
||||
kind: Scheduled
|
|
@ -0,0 +1,25 @@
|
|||
id: c3237d88-fdc4-4dee-8b90-118ded2c507c
|
||||
name: GitHub First Time Invite Member and Add Member to Repo
|
||||
description: |
|
||||
'This hunting query identifies a user that add/invite a member to the organization for the first time. This technique can be leveraged by attackers to add stealth account access to the organization.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Persistence
|
||||
relevantTechniques:
|
||||
- T1136
|
||||
query: |
|
||||
|
||||
let starttime = todatetime('{{StartTimeISO}}');
|
||||
let endtime = todatetime('{{EndTimeISO}}');
|
||||
let LearningPeriod = 7d;
|
||||
let EndLearningTime = starttime - LearningPeriod;
|
||||
let GitHubOrgMemberLogs = (GitHubAuditData
|
||||
| where Action == "org.invite_member" or Action == "org.update_member" or Action == "org.add_member" or Action == "repo.add_member" or Action == "team.add_member");
|
||||
GitHubOrgMemberLogs
|
||||
| where TimeGenerated between (EndLearningTime..starttime)
|
||||
| distinct Actor
|
||||
| join kind=rightanti (
|
||||
GitHubOrgMemberLogs
|
||||
| where TimeGenerated between (starttime..endtime)
|
||||
| distinct Actor
|
||||
) on Actor
|
|
@ -0,0 +1,45 @@
|
|||
id: b8508e24-47a6-4f8e-9066-3cc937197e7f
|
||||
name: GitHub Inactive or New Account Access or Usage
|
||||
description: |
|
||||
'This hunting query identifies Accounts that are new or inactive and have accessed or used GitHub that may be a sign of compromise.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Persistence
|
||||
relevantTechniques:
|
||||
- T1136
|
||||
query: |
|
||||
|
||||
let starttime = todatetime('{{StartTimeISO}}');
|
||||
let endtime = todatetime('{{EndTimeISO}}');
|
||||
let LearningPeriod = 7d;
|
||||
let EndLearningTime = starttime - LearningPeriod;
|
||||
let GitHubActorLogin = (GitHubAuditData
|
||||
| where Actor != "");
|
||||
let GitHubUser = (GitHubAuditData
|
||||
| where ImpactedUser != "");
|
||||
let GitHubNewActorLogin = (GitHubActorLogin
|
||||
| where TimeGenerated between (EndLearningTime .. starttime)
|
||||
| summarize makeset(Actor)
|
||||
| extend Dummy = 1
|
||||
| join kind=innerunique (
|
||||
GitHubActorLogin
|
||||
| where TimeGenerated between (starttime .. endtime)
|
||||
| distinct Actor
|
||||
| extend Dummy = 1
|
||||
) on Dummy
|
||||
| project-away Dummy
|
||||
| where set_Actor !contains Actor);
|
||||
let GitHubNewUser = ( GitHubUser
|
||||
| where TimeGenerated between (EndLearningTime .. starttime)
|
||||
| summarize makeset(ImpactedUser)
|
||||
| extend Dummy = 1
|
||||
| join kind=innerunique (
|
||||
GitHubUser
|
||||
| where TimeGenerated between (starttime .. endtime)
|
||||
| distinct ImpactedUser
|
||||
| extend Dummy = 1
|
||||
) on Dummy
|
||||
| project-away Dummy
|
||||
| where set_ImpactedUser !contains ImpactedUser);
|
||||
union GitHubNewActorLogin, GitHubNewUser
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
id: 67da5c4e-49f2-476d-96ff-2dbe4b855a48
|
||||
name: GitHub Mass Deletion of repos or projects
|
||||
description: |
|
||||
'This hunting query identifies GitHub activites where there are a large number of deletions that may be a sign of compromise.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Impact
|
||||
relevantTechniques:
|
||||
- T1485
|
||||
query: |
|
||||
|
||||
let starttime = todatetime('{{StartTimeISO}}');
|
||||
let endtime = todatetime('{{EndTimeISO}}');
|
||||
let LearningPeriod = 7d;
|
||||
let BinTime = 1h;
|
||||
let EndLearningTime = starttime - LearningPeriod;
|
||||
let NumberOfStds = 3;
|
||||
let MinThreshold = 10.0;
|
||||
let GitHubRepositoryDestroyEvents = (GitHubAuditData
|
||||
| where Action == "repo.destroy");
|
||||
GitHubRepositoryDestroyEvents
|
||||
| where TimeGenerated between (EndLearningTime .. starttime)
|
||||
| summarize count() by bin(TimeGenerated, BinTime)
|
||||
| summarize AvgInLearning = avg(count_), StdInLearning = stdev(count_)
|
||||
| extend LearningThreshold = max_of(AvgInLearning + StdInLearning * NumberOfStds, MinThreshold)
|
||||
| extend Dummy = 1
|
||||
| join kind=innerunique (
|
||||
GitHubRepositoryDestroyEvents
|
||||
| where TimeGenerated between (starttime..endtime)
|
||||
| summarize CountInRunTime = count() by bin(TimeGenerated, BinTime)
|
||||
| extend Dummy = 1
|
||||
) on Dummy
|
||||
| project-away Dummy
|
||||
| where CountInRunTime > LearningThreshold
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
id: 667e6a70-adc9-49b7-9cf3-f21927c71959
|
||||
name: GitHub OAuth App Restrictions Disabled
|
||||
description: |
|
||||
'This hunting query identifies GitHub OAuth Apps that have restrictions disabled that may be a sign of compromise. Attacker will want to disable such security tools in order to go undetected. '
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Persistence
|
||||
- DefenseEvasion
|
||||
relevantTechniques:
|
||||
- T1505
|
||||
- T1562
|
||||
query: |
|
||||
|
||||
GitHubAuditData
|
||||
| where Action == "org.disable_oauth_app_restrictions"
|
||||
| project TimeGenerated, Action, Actor, Country
|
|
@ -0,0 +1,16 @@
|
|||
id: ec986fb7-34ed-4528-a5f3-a496e61d8860
|
||||
name: GitHub Update Permissions
|
||||
description: |
|
||||
'This hunting query identifies GitHub activites where permissions are updated that may be a sign of compromise.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Persistence
|
||||
- DefenseEvasion
|
||||
relevantTechniques:
|
||||
- T1098
|
||||
- T1562
|
||||
query: |
|
||||
|
||||
GitHubAuditData
|
||||
| where Action == "org.update_default_repository_permission"
|
||||
| project TimeGenerated, Action, Actor, Country, Repository, PreviousPermission, CurrentPermission
|
|
@ -0,0 +1,15 @@
|
|||
id: a6e2afd3-559c-4e88-a693-39c1f6789ef1
|
||||
name: GitHub Repo switched from private to public
|
||||
description: |
|
||||
'This hunting query identifies GitHub activites where a repo was changed from private to public that may be a sign of compromise.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Collection
|
||||
relevantTechniques:
|
||||
- T1213
|
||||
query: |
|
||||
|
||||
GitHubAuditData
|
||||
| where Action == "repo.access"
|
||||
| where Visibility == "public" and PreviousVisibility in ("internal", "private")
|
||||
| project TimeGenerated, Action, Actor, Country, Repository, Visibility
|
|
@ -0,0 +1,25 @@
|
|||
id: c3237d88-fdc4-4dee-8b90-118ded2c507c
|
||||
name: GitHub First Time Repo Delete
|
||||
description: |
|
||||
'This hunting query identifies GitHub activites its the first time a user deleted a repo that may be a sign of compromise.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Impact
|
||||
relevantTechniques:
|
||||
- T1485
|
||||
query: |
|
||||
|
||||
let starttime = todatetime('{{StartTimeISO}}');
|
||||
let endtime = todatetime('{{EndTimeISO}}');
|
||||
let LearningPeriod = 7d;
|
||||
let EndLearningTime = starttime - LearningPeriod;
|
||||
let GitHubRepositoryDestroyEvents = (GitHubAuditData
|
||||
| where Action == "repo.destroy");
|
||||
GitHubRepositoryDestroyEvents
|
||||
| where TimeGenerated between (EndLearningTime .. starttime)
|
||||
| distinct Actor
|
||||
| join kind=rightanti (
|
||||
GitHubRepositoryDestroyEvents
|
||||
| where TimeGenerated between (starttime .. endtime)
|
||||
| distinct Actor
|
||||
) on Actor
|
|
@ -0,0 +1,26 @@
|
|||
id: f18c4dfb-4fa6-4a9d-9bd3-f7569d1d685a
|
||||
name: GitHub User Grants Access and Other User Grants Access
|
||||
description: |
|
||||
'This hunting query identifies Accounts in GitHub that have granted access to another account which then grants access to yet another account that may be a sign of compromise.'
|
||||
requiredDataConnectors: []
|
||||
tactics:
|
||||
- Persistence
|
||||
- PrivilegeEscalation
|
||||
relevantTechniques:
|
||||
- T1098
|
||||
- T1078
|
||||
query: |
|
||||
|
||||
GitHubAuditData
|
||||
| where ImpactedUser != ""
|
||||
| where Action == "org.invite_member" or Action == "org.add_member" or Action == "team.add_member" or Action == "repo.add_member"
|
||||
| distinct ImpactedUser, TimeGenerated, Actor
|
||||
| project-rename firstUserAdded = ImpactedUser, firstEventTime = TimeGenerated, firstAdderUser = Actor
|
||||
| join kind= innerunique (
|
||||
GitHubAuditData
|
||||
| where ImpactedUser != ""
|
||||
| where Action == "org.invite_member" or Action == "org.add_member" or Action == "team.add_member" or Action == "repo.add_member"
|
||||
| distinct ImpactedUser, TimeGenerated, Actor
|
||||
| project-rename secondUserAdded = ImpactedUser, secondEventTime = TimeGenerated, secondAdderUser = Actor
|
||||
) on $right.secondAdderUser == $left.firstUserAdded
|
||||
| where secondEventTime between (firstEventTime .. (firstEventTime + 1h))
|
|
@ -0,0 +1,27 @@
|
|||
// GitHub Enterprise Audit Entry Data Parser
|
||||
// Last Updated Date: Feb 16, 2022
|
||||
//
|
||||
//This parser parses GitHub Enterprise Audit and extract the infromation from their various components. It is assumed that you are using officially supported Github connector (installed from Content hub)
|
||||
//
|
||||
// Parser Notes:
|
||||
// 1. This parser assumes logs are collected into a custom log table entitled GitHubAuditLogPolling_CL
|
||||
|
||||
|
||||
GitHubAuditLogPolling_CL
|
||||
| project TimeGenerated=unixtime_milliseconds_todatetime(created_at_d),
|
||||
Organization=columnifexists('org_s', ""),
|
||||
Action=action_s,
|
||||
Repository=columnifexists('repo_s',""),
|
||||
Actor=columnifexists('actor_s', ""),
|
||||
Country=columnifexists('actor_location_country_code_s', ""),
|
||||
ImpactedUser=columnifexists('user_s', ""),
|
||||
InvitedUserPermission=columnifexists('permission_s', ""),
|
||||
Visibility=columnifexists('visibility_s', ""),
|
||||
PreviousVisibility=columnifexists('previous_visibility_s', ""),
|
||||
CurrentPermission=columnifexists('permission_s', ""),
|
||||
PreviousPermission=columnifexists('old_permission_s', ""),
|
||||
TeamName=columnifexists('team_s', ""),
|
||||
BlockedUser=columnifexists('blocked_user_s', "")
|
||||
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче