Detection rules › Kusto

Chia_Crypto_Mining IOC - June 2021

Status
available
Severity
low
Time window
6h
Source
github.com/Azure/Azure-Sentinel

Identifies a match across IOC's related to Chia cryptocurrency farming/plotting activity

MITRE ATT&CK coverage

TacticTechniques
ImpactT1496 Resource Hijacking

Event coverage

Rule body kusto

id: 4d173248-439b-4741-8b37-f63ad0c896ae
name: Chia_Crypto_Mining IOC - June 2021
description: | 
  'Identifies a match across IOC's related to Chia cryptocurrency farming/plotting activity'
severity: Low
status: Available 
requiredDataConnectors: 
  - connectorId: WindowsForwardedEvents
    dataTypes: 
      - WindowsEvent 
queryFrequency: 6h 
queryPeriod: 6h 
triggerOperator: gt 
triggerThreshold: 0 
tactics: 
  - Impact
relevantTechniques:
  - T1496
tags:
  - Chia 
  - ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/ChiaCryptoMining.yaml
    version: 1.1.0
query:  |  
  let iocs = externaldata(DateAdded:string,IoC:string,Type:string,TLP:string) [@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/ChiaCryptoIOC.csv"] with (format="csv", ignoreFirstRecord=True);
  let process = (iocs | where Type =~ "process" | project IoC);
  //This query uses sysmon data, sections that have - | where Source == "Microsoft-Windows-Sysmon" - may need to be updated with latest
  WindowsEvent
  | where EventID == '4688' and EventData has_any (process)
  | extend NewProcessName = tostring(EventData.NewProcessName)
  | where NewProcessName  has_any (process)
  | extend ParentProcessName = tostring(EventData.ParentProcessName)
    , Account =  strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
    , NewProcessId = tostring(EventData.NewProcessId)
  | extend Computer, Account, File = tostring(split(NewProcessName, '\\', -1)[-1]), AlertDetail = 'Chia crypto IOC detected'
  | extend FilePath = replace_string(NewProcessName, File, '')
  | project TimeGenerated, File, AlertDetail, FilePath,Computer, NewProcessName, ParentProcessName, Account, NewProcessId, Type
  | extend AccountName = tostring(split(Account, @'\')[1]), AccountNTDomain = tostring(split(Account, @'\')[0])
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Account
      - identifier: Name
        columnName: AccountName
      - identifier: NTDomain
        columnName: AccountNTDomain
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
  - entityType: File
    fieldMappings:
      - identifier: Name
        columnName: File
      - identifier: Directory
        columnName: FilePath
version: 1.0.4
kind: Scheduled

Stages and Predicates

Let binding: iocs

let iocs = externaldata(DateAdded:string,IoC:string,Type:string,TLP:string) [@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/ChiaCryptoIOC.csv"] with (format="csv", ignoreFirstRecord=True);

Let binding: process

let process = (iocs | where Type =~ "process" | project IoC);

Derived from iocs.

Stage 1: source

WindowsEvent

Stage 2: where

| where EventID == '4688' and EventData has_any (process)

References process (defined above).

Stage 3: extend

| extend NewProcessName = tostring(EventData.NewProcessName)

Stage 4: where

| where NewProcessName  has_any (process)

References process (defined above).

Stage 5: extend (3 consecutive steps)

| extend ParentProcessName = tostring(EventData.ParentProcessName)
  , Account =  strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
  , NewProcessId = tostring(EventData.NewProcessId)
| extend Computer, Account, File = tostring(split(NewProcessName, '\\', -1)[-1]), AlertDetail = 'Chia crypto IOC detected'
| extend FilePath = replace_string(NewProcessName, File, '')

Stage 6: project

| project TimeGenerated, File, AlertDetail, FilePath,Computer, NewProcessName, ParentProcessName, Account, NewProcessId, Type

Stage 7: extend (3 consecutive steps)

| extend AccountName = tostring(split(Account, @'\')[1]), AccountNTDomain = tostring(split(Account, @'\')[0])
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
EventDatamatch
  • process
EventIDeq
  • 4688 transforms: cased corpus 313 (splunk 283, kusto 30)
NewProcessNamematch
  • process

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
Accountproject
AlertDetailproject
Computerproject
Fileproject
FilePathproject
NewProcessIdproject
NewProcessNameproject
ParentProcessNameproject
TimeGeneratedproject
Typeproject
AccountNTDomainextend
AccountNameextend
DomainIndexextend
HostNameextend
HostNameDomainextend