Merge pull request #1525 from Azure/MultiplemachineMultipleAccount_Solorigate
New Proposed Hunting Query related to Solorigate
This commit is contained in:
Коммит
9651c32b16
|
@ -0,0 +1,61 @@
|
|||
id: 9e3fab4b-94dd-4cf9-b2aa-063d0fd25513
|
||||
name: Connections to multiple machines using multiple explicit credentials
|
||||
description: |
|
||||
'Based on recent investigations related to Solorigate, adversaries were seen to obtain and abuse credentials of multiple accounts
|
||||
to connect to multiple machines. This query uses Security Event 4648 (A logon was attempted using explicit credentials)
|
||||
to find machines in an environment, from where different accounts were used to connect to multiple hosts. Scoring is done based on
|
||||
protocols seen in Solorigate. While this mentions Solorigate, this hunting query can be used to identify this type of pattern for
|
||||
any attacker.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: SecurityEvents
|
||||
dataTypes:
|
||||
- SecurityEvent
|
||||
tactics:
|
||||
- Discovery
|
||||
- LateralMovement
|
||||
relevantTechniques:
|
||||
- T1078
|
||||
query: |
|
||||
|
||||
let WellKnownLocalSIDs = "S-1-5-[0-9][0-9]$";
|
||||
let protocols = dynamic(['cifs', 'ldap', 'RPCSS', 'host' , 'HTTP', 'RestrictedKrbHost', 'TERMSRV', 'msomsdksvc', 'mssqlsvc']);
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where EventID == 4648
|
||||
| where SubjectUserSid != 'S-1-0-0' // this is the Nobody SID which really means No security principal was included.
|
||||
| where not(SubjectUserSid matches regex WellKnownLocalSIDs) //excluding system account/service account as this is generally normal
|
||||
| where TargetInfo has '/' //looking for only items that indicate an interesting protocol is included
|
||||
| where Computer !has tostring(split(TargetServerName,'$')[0])
|
||||
| where TargetAccount !~ tostring(split(SubjectAccount,'$')[0])
|
||||
| extend TargetInfoProtocol = tolower(split(TargetInfo, '/')[0]), TargetInfoMachine = toupper(split(TargetInfo, '/')[1])
|
||||
| extend TargetAccount = tolower(TargetAccount), SubjectAccount = tolower(SubjectAccount)
|
||||
| extend UncommonProtocol = case(not(TargetInfoProtocol has_any (protocols)), TargetInfoProtocol, 'NotApplicable')
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), AccountsUsedCount = dcount(TargetAccount), AccountsUsed = make_set(TargetAccount), TargetMachineCount = dcount(TargetInfoMachine),
|
||||
TargetMachines = make_set(TargetInfoMachine), TargetProtocols = dcount(TargetInfoProtocol), Protocols = make_set(TargetInfoProtocol), Processes = make_set(Process) by Computer, SubjectAccount, UncommonProtocol
|
||||
| where TargetMachineCount > 1 or UncommonProtocol != 'NotApplicable'
|
||||
| extend ProtocolCount = array_length(Protocols)
|
||||
| extend ProtocolScore = case(
|
||||
Protocols has 'rpcss' and Protocols has 'host' and Protocols has 'cifs', 10, //observed in Solorigate and depending on which are used together the higher the score
|
||||
Protocols has 'rpcss' and Protocols has 'host', 5,
|
||||
Protocols has 'rpcss' and Protocols has 'cifs', 5,
|
||||
Protocols has 'host' and Protocols has 'cifs', 5,
|
||||
Protocols has 'ldap' or Protocols has 'rpcss' or Protocols has 'host' or Protocols has 'cifs', 1, //ldap is more commonly seen in general, this was also seen with Solorigate but not usually to the same machines as the others above
|
||||
UncommonProtocol != 'NotApplicable', 3,
|
||||
0 //other protocols may be of interest, but in relation to observations for enumeration/execution in Solorigate they receive 0
|
||||
)
|
||||
| extend Score = ProtocolScore + ProtocolCount + AccountsUsedCount
|
||||
| where Score >= 9 or (UncommonProtocol != 'NotApplicable' and Score >= 4) // Score must be 9 or better as this will include 5 points for atleast 2 of the interesting protocols + the count of protocols (min 2) + the number of accounts used for execution (min 2) = min of 9 OR score must be 4 or greater for an uncommon protocol
|
||||
| extend TimePeriod = EndTime - StartTime //This identifies the time between start and finish for the use of the explicit credentials, shorter time period may indicate scripted executions
|
||||
| project-away UncommonProtocol
|
||||
| extend timestamp = StartTime, AccountCustomEntity = SubjectAccount, HostCustomEntity = Computer
|
||||
| order by Score desc
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: Host
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: HostCustomEntity
|
Загрузка…
Ссылка в новой задаче