This commit is contained in:
Pete Bryan 2022-02-07 15:31:00 -08:00
Родитель ed5ba8cd4b
Коммит f2c58f181f
15 изменённых файлов: 654 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,37 @@
id: 0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b
name: NRT Login to AWS Management Console without MFA
description: |
'Multi-Factor Authentication (MFA) helps you to prevent credential compromise. This alert identifies logins to the AWS Management Console without MFA.
You can limit this detection to trigger for adminsitrative accounts if you do not have MFA enabled on all accounts.
This is done by looking at the eventName ConsoleLogin and if the AdditionalEventData field indicates MFA was NOT used
and the ResponseElements field indicates NOT a Failure. Thereby indicating that a non-MFA login was successful.'
severity: Low
requiredDataConnectors:
- connectorId: AWS
dataTypes:
- AWSCloudTrail
tactics:
- DefenseEvasion
- PrivilegeEscalation
- Persistence
- InitialAccess
relevantTechniques:
- T1078
query: |
AWSCloudTrail
| where EventName =~ "ConsoleLogin"
| extend MFAUsed = tostring(parse_json(AdditionalEventData).MFAUsed), LoginResult = tostring(parse_json(ResponseElements).ConsoleLogin)
| where MFAUsed !~ "Yes" and LoginResult !~ "Failure"
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by EventName, EventTypeName, LoginResult, MFAUsed, UserIdentityAccountId, UserIdentityPrincipalid, UserAgent,
UserIdentityUserName, SessionMfaAuthenticated, SourceIpAddress, AWSRegion
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserIdentityUserName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIpAddress
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,42 @@
id: 8540c842-5bbc-4a24-9fb2-a836c0e55a51
name: NRT Modified domain federation trust settings
description: |
'This will alert when a user or application modifies the federation settings on the domain or Update domain authentication from Managed to Federated.
For example, this alert will trigger when a new Active Directory Federated Service (ADFS) TrustedRealm object, such as a signing certificate, is added to the domain.
Modification to domain federation settings should be rare. Confirm the added or modified target domain/URL is legitimate administrator behavior.
To understand why an authorized user may update settings for a federated domain in Office 365, Azure, or Intune, see: https://docs.microsoft.com/office365/troubleshoot/active-directory/update-federated-domain-office-365.
For details on security realms that accept security tokens, see the ADFS Proxy Protocol (MS-ADFSPP) specification: https://docs.microsoft.com/openspecs/windows_protocols/ms-adfspp/e7b9ea73-1980-4318-96a6-da559486664b.
For further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities.'
severity: High
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
tactics:
- CredentialAccess
query: |
AuditLogs
| where OperationName =~ "Set federation settings on domain" or OperationName =~ "Set domain authentication"
//| where Result =~ "success" // commenting out, as it may be interesting to capture failed attempts
| mv-expand TargetResources
| extend modifiedProperties = parse_json(TargetResources).modifiedProperties
| mv-expand modifiedProperties
| extend targetDisplayName = tostring(parse_json(modifiedProperties).displayName), NewDomainValue=tostring(parse_json(modifiedProperties).newValue)
| extend Federated = iif(OperationName =~ "Set domain authentication", iif(NewDomainValue has "Federated", True, False), True)
| where Federated == True
| mv-expand AdditionalDetails
| extend UserAgent = iff(AdditionalDetails.key == "User-Agent",tostring(AdditionalDetails.value),"")
| extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
| extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
| project-reorder TimeGenerated, OperationName, InitiatingUserOrApp, AADOperationType, targetDisplayName, Result, InitiatingIpAddress, UserAgent, CorrelationId, TenantId, AADTenantId
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: InitiatingUserOrApp
- entityType: IP
fieldMappings:
- identifier: Address
columnName: InitiatingIpAddress
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,56 @@
id: e42e889a-caaf-4dbb-aec6-371b37d64298
name: NRT New access credential added to Application or Service Principal
description: |
'This will alert when an admin or app owner account adds a new credential to an Application or Service Principal where a verify KeyCredential was already present for the app.
If a threat actor obtains access to an account with sufficient privileges and adds the alternate authentication material triggering this event, the threat actor can now authenticate as the Application or Service Principal using this credential.
Additional information on OAuth Credential Grants can be found in RFC 6749 Section 4.4 or https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
For further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities.'
severity: Medium
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
tactics:
- DefenseEvasion
relevantTechniques:
- T1550.001
tags:
- Solorigate
- NOBELIUM
query: |
AuditLogs
| where OperationName has_any ("Add service principal", "Certificates and secrets management")
| where Result =~ "success"
| mv-expand target = TargetResources
| where tostring(InitiatedBy.user.userPrincipalName) has "@" or tostring(InitiatedBy.app.displayName) has "@"
| extend targetDisplayName = tostring(TargetResources[0].displayName)
| extend targetId = tostring(TargetResources[0].id)
| extend targetType = tostring(TargetResources[0].type)
| extend keyEvents = TargetResources[0].modifiedProperties
| mv-expand keyEvents
| where keyEvents.displayName =~ "KeyDescription"
| extend new_value_set = parse_json(tostring(keyEvents.newValue))
| extend old_value_set = parse_json(tostring(keyEvents.oldValue))
| where old_value_set != "[]"
| extend diff = set_difference(new_value_set, old_value_set)
| where isnotempty(diff)
| parse diff with * "KeyIdentifier=" keyIdentifier:string ",KeyType=" keyType:string ",KeyUsage=" keyUsage:string ",DisplayName=" keyDisplayName:string "]" *
| where keyUsage == "Verify" or keyUsage == ""
| extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent",tostring(AdditionalDetails[0].value),"")
| extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
| extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
// The below line is currently commented out but Microsoft Sentinel users can modify this query to show only Application or only Service Principal events in their environment
//| where targetType =~ "Application" // or targetType =~ "ServicePrincipal"
| project-away diff, new_value_set, old_value_set
| project-reorder TimeGenerated, OperationName, InitiatingUserOrApp, InitiatingIpAddress, UserAgent, targetDisplayName, targetId, targetType, keyDisplayName, keyType, keyUsage, keyIdentifier, CorrelationId, TenantId
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: InitiatingUserOrApp
- entityType: IP
fieldMappings:
- identifier: Address
columnName: InitiatingIpAddress
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,40 @@
id: 5db427b2-f406-4274-b413-e9fcb29412f8
name: NRT PIM Elevation Request Rejected
description: |
'Identifies when a user is rejected for a privileged role elevation via PIM. Monitor rejections for indicators of attacker compromise of the requesting account.
Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-privileged-identity-management'
severity: High
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
tactics:
- Persistence
relevantTechniques:
- T1078.004
tags:
- AADSecOpsGuide
query: |
AuditLogs
| where ActivityDisplayName =~'Add member to role completed (PIM activation)'
| where Result == "failure"
| extend Role = tostring(TargetResources[3].displayName)
| extend User = tostring(TargetResources[2].displayName)
| project-reorder TimeGenerated, User, Role, OperationName, Result, ResultDescription
| extend InitiatingUser = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend IPCustomEntity = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: InitiatingUser
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: User
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,58 @@
id: 70fc7201-f28e-4ba7-b9ea-c04b96701f13
name: NRT User added to Azure Active Directory Privileged Groups
description: |
'This will alert when a user is added to any of the Privileged Groups.
For further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities.
For Administrator role permissions in Azure Active Directory please see https://docs.microsoft.com/azure/active-directory/users-groups-roles/directory-assign-admin-roles'
severity: Medium
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
tactics:
- Persistence
- PrivilegeEscalation
relevantTechniques:
- T1098
- T1078
query: |
let OperationList = dynamic(["Add member to role","Add member to role in PIM requested (permanent)"]);
let PrivilegedGroups = dynamic(["UserAccountAdmins","PrivilegedRoleAdmins","TenantAdmins"]);
AuditLogs
//| where LoggedByService =~ "Core Directory"
| where Category =~ "RoleManagement"
| where OperationName in~ (OperationList)
| mv-expand TargetResources
| extend modProps = parse_json(TargetResources).modifiedProperties
| mv-expand bagexpansion=array modProps
| evaluate bag_unpack(modProps)
| extend displayName = column_ifexists("displayName", "NotAvailable"), newValue = column_ifexists("newValue", "NotAvailable")
| where displayName =~ "Role.WellKnownObjectName"
| extend DisplayName = displayName, GroupName = replace('"','',newValue)
| extend initByApp = parse_json(InitiatedBy).app, initByUser = parse_json(InitiatedBy).user
| extend AppId = initByApp.appId,
InitiatedByDisplayName = case(isnotempty(initByApp.displayName), initByApp.displayName, isnotempty(initByUser.displayName), initByUser.displayName, "not available"),
ServicePrincipalId = tostring(initByApp.servicePrincipalId),
ServicePrincipalName = tostring(initByApp.servicePrincipalName),
UserId = initByUser.id,
UserIPAddress = initByUser.ipAddress,
UserRoles = initByUser.roles,
UserPrincipalName = tostring(initByUser.userPrincipalName),
TargetUserPrincipalName = tostring(TargetResources.userPrincipalName)
| where GroupName in~ (PrivilegedGroups)
// If you don't want to alert for operations from PIM, remove below filtering for MS-PIM.
//| where InitiatedByDisplayName != "MS-PIM"
| project TimeGenerated, AADOperationType, Category, OperationName, AADTenantId, AppId, InitiatedByDisplayName, ServicePrincipalId, ServicePrincipalName, DisplayName, GroupName, UserId, UserIPAddress, UserRoles, UserPrincipalName, TargetUserPrincipalName
| extend AccountCustomEntity = case(isnotempty(ServicePrincipalName), ServicePrincipalName, isnotempty(ServicePrincipalId), ServicePrincipalId, isnotempty(UserPrincipalName), UserPrincipalName, "not available")
entityMappings:
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: TargetUserPrincipalName
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,38 @@
id: ec491363-5fe7-4eff-b68e-f42dcb76fcf6
name: NRT Azure Active Directory Hybrid Health AD FS New Server
description: |
'This detection uses AzureActivity logs (Administrative category) to identify the creation or update of a server instance in an Azure AD Hybrid health AD FS service.
A threat actor can create a new AD Health ADFS service and create a fake server instance to spoof AD FS signing logs. There is no need to compromise an on-prem AD FS server.
This can be done programmatically via HTTP requests to Azure. More information in this blog: https://o365blog.com/post/hybridhealthagent/'
severity: Medium
requiredDataConnectors:
- connectorId: AzureActivity
dataTypes:
- AzureActivity
tactics:
- DefenseEvasion
relevantTechniques:
- T1578
tags:
- SimuLand
query: |
AzureActivity
| where CategoryValue == 'Administrative'
| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'
| where _ResourceId contains 'AdFederationService'
| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/servicemembers/action'
| extend claimsJson = parse_json(Claims)
| extend AppId = tostring(claimsJson.appid)
| extend AccountName = tostring(claimsJson.name)
| project-away claimsJson
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Caller
- entityType: IP
fieldMappings:
- identifier: Address
columnName: CallerIpAddress
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,41 @@
id: 884ead54-cb3f-4676-a1eb-b26532d6cbfd
name: NRT Sensitive Azure Key Vault operations
description: |
'Identifies when sensitive Azure Key Vault operations are used. This includes: VaultDelete, KeyDelete, SecretDelete, SecretPurge, KeyPurge, SecretBackup, KeyBackup.
Any Backup operations should match with expected scheduled backup activity.'
severity: Low
requiredDataConnectors:
- connectorId: AzureKeyVault
dataTypes:
- KeyVaultData
tactics:
- Impact
relevantTechniques:
- T1485
query: |
let SensitiveOperationList = dynamic(
["VaultDelete", "KeyDelete", "SecretDelete", "SecretPurge", "KeyPurge", "SecretBackup", "KeyBackup"]);
AzureDiagnostics
| extend ResultType = columnifexists("ResultType", "NoResultType")
| extend requestUri_s = columnifexists("requestUri_s", "None"), identity_claim_http_schemas_microsoft_com_identity_claims_objectidentifier_g = columnifexists("identity_claim_http_schemas_microsoft_com_identity_claims_objectidentifier_g", "None")
| extend id_s = columnifexists("id_s", "None"), CallerIPAddress = columnifexists("CallerIPAddress", "None"), clientInfo_s = columnifexists("clientInfo_s", "None")
| where ResultType !~ "None" and isnotempty(ResultType)
| where identity_claim_http_schemas_microsoft_com_identity_claims_objectidentifier_g !~ "None" and isnotempty(identity_claim_http_schemas_microsoft_com_identity_claims_objectidentifier_g)
| where id_s !~ "None" and isnotempty(id_s)
| where CallerIPAddress !~ "None" and isnotempty(CallerIPAddress)
| where clientInfo_s !~ "None" and isnotempty(clientInfo_s)
| where requestUri_s !~ "None" and isnotempty(requestUri_s)
| where ResourceType =~ "VAULTS" and ResultType =~ "Success"
| where OperationName in~ (SensitiveOperationList)
| summarize EventCount=count(), StartTimeUtc=min(TimeGenerated), EndTimeUtc=max(TimeGenerated), TimeTriggered=makelist(TimeGenerated),OperationNameList=make_set(OperationName), RequestURLList=make_set(requestUri_s), CallerIPList = make_set(CallerIPAddress), CallerIPMax= arg_max(CallerIPAddress,*) by ResourceType, ResultType, Resource, id_s, identity_claim_http_schemas_microsoft_com_identity_claims_objectidentifier_g, clientInfo_s
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: identity_claim_http_schemas_microsoft_com_identity_claims_objectidentifier_g
- entityType: IP
fieldMappings:
- identifier: Address
columnName: CallerIPMax
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,36 @@
id: d5b32cd4-2328-43da-ab47-cd289c1f5efc
name: NRT DNS events related to mining pools
description: |
'Identifies IP addresses that may be performing DNS lookups associated with common currency mining pools.'
severity: Low
requiredDataConnectors:
- connectorId: DNS
dataTypes:
- DnsEvents
tactics:
- Impact
relevantTechniques:
- T1496
query: |
DnsEvents
| where Name contains "."
| where Name has_any ("monerohash.com", "do-dear.com", "xmrminerpro.com", "secumine.net", "xmrpool.com", "minexmr.org", "hashanywhere.com",
"xmrget.com", "mininglottery.eu", "minergate.com", "moriaxmr.com", "multipooler.com", "moneropools.com", "xmrpool.eu", "coolmining.club",
"supportxmr.com", "minexmr.com", "hashvault.pro", "xmrpool.net", "crypto-pool.fr", "xmr.pt", "miner.rocks", "walpool.com", "herominers.com",
"gntl.co.uk", "semipool.com", "coinfoundry.org", "cryptoknight.cc", "fairhash.org", "baikalmine.com", "tubepool.xyz", "fairpool.xyz", "asiapool.io",
"coinpoolit.webhop.me", "nanopool.org", "moneropool.com", "miner.center", "prohash.net", "poolto.be", "cryptoescrow.eu", "monerominers.net", "cryptonotepool.org",
"extrmepool.org", "webcoin.me", "kippo.eu", "hashinvest.ws", "monero.farm", "supportxmr.com", "xmrpool.eu", "linux-repository-updates.com", "1gh.com",
"dwarfpool.com", "hash-to-coins.com", "hashvault.pro", "pool-proxy.com", "hashfor.cash", "fairpool.cloud", "litecoinpool.org", "mineshaft.ml", "abcxyz.stream",
"moneropool.ru", "cryptonotepool.org.uk", "extremepool.org", "extremehash.com", "hashinvest.net", "unipool.pro", "crypto-pools.org", "monero.net",
"backup-pool.com", "mooo.com", "freeyy.me", "cryptonight.net", "shscrypto.net")
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: Computer
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIP
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,48 @@
id: b79f6190-d104-4691-b7db-823e05980895
name: NRT Malicious Inbox Rule
description: |
'Often times after the initial compromise the attackers create inbox rules to delete emails that contain certain keywords.
This is done so as to limit ability to warn compromised users that they've been compromised. Below is a sample query that tries to detect this.
Reference: https://www.reddit.com/r/sysadmin/comments/7kyp0a/recent_phishing_attempts_my_experience_and_what/'
severity: Medium
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- OfficeActivity
tactics:
- Persistence
- DefenseEvasion
relevantTechniques:
- T1098
- T1078
query: |
let Keywords = dynamic(["helpdesk", " alert", " suspicious", "fake", "malicious", "phishing", "spam", "do not click", "do not open", "hijacked", "Fatal"]);
OfficeActivity
| where Operation =~ "New-InboxRule"
| where Parameters has "Deleted Items" or Parameters has "Junk Email" or Parameters has "DeleteMessage"
| extend Events=todynamic(Parameters)
| parse Events with * "SubjectContainsWords" SubjectContainsWords '}'*
| parse Events with * "BodyContainsWords" BodyContainsWords '}'*
| parse Events with * "SubjectOrBodyContainsWords" SubjectOrBodyContainsWords '}'*
| where SubjectContainsWords has_any (Keywords)
or BodyContainsWords has_any (Keywords)
or SubjectOrBodyContainsWords has_any (Keywords)
| extend ClientIPAddress = case( ClientIP has ".", tostring(split(ClientIP,":")[0]), ClientIP has "[", tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))), ClientIP )
| extend Keyword = iff(isnotempty(SubjectContainsWords), SubjectContainsWords, (iff(isnotempty(BodyContainsWords),BodyContainsWords,SubjectOrBodyContainsWords )))
| extend RuleDetail = case(OfficeObjectId contains '/' , tostring(split(OfficeObjectId, '/')[-1]) , tostring(split(OfficeObjectId, '\\')[-1]))
| summarize count(), StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by Operation, UserId, ClientIPAddress, ResultStatus, Keyword, OriginatingServer, OfficeObjectId, RuleDetail
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserId
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: OriginatingServer
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIPAddress
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,69 @@
id: 3b05727d-a8d1-477d-bbdd-d957da96ac7b
name: NRT Multiple users email forwarded to same destination
description: |
'Identifies when multiple (more than one) users mailboxes are configured to forward to the same destination.
This could be an attacker-controlled destination mailbox configured to collect mail from multiple compromised user accounts.'
severity: Medium
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- OfficeActivity
tactics:
- Collection
- Exfiltration
relevantTechniques:
- T1114
- T1020
query: |
OfficeActivity
| where Operation =~ "Set-Mailbox"
| where Parameters has "ForwardingSmtpAddress"
| extend parsed = parse_json(Parameters)
| mv-expand parsed
| where parsed.Name == "ForwardingSmtpAddress"
| extend parameterName = tostring(parsed.Name), fwdingDestination = tostring(parsed.Value)
| where isnotempty(fwdingDestination)
| extend ClientIPOnly = case(
ClientIP has "." and ClientIP has ':', tostring(split(ClientIP,":")[0]),
ClientIP has "." and ClientIP has '-', tostring(split(ClientIP,"-")[0]),
ClientIP has ']-', tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))),
ClientIP has ']:', tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))),
isempty(ClientIP) and ClientIP_ has "." and ClientIP_ has ':', tostring(split(ClientIP_,":")[0]),
isempty(ClientIP) and ClientIP_ has "." and ClientIP_ has '-', tostring(split(ClientIP_,"-")[0]),
isempty(ClientIP) and ClientIP_ has ']-', tostring(trim_start(@'[[]',tostring(split(ClientIP_,"]")[0]))),
isempty(ClientIP) and ClientIP_ has ']:', tostring(trim_start(@'[[]',tostring(split(ClientIP_,"]")[0]))),
isnotempty(ClientIP), ClientIP,
isnotempty(ClientIP_), ClientIP_,
"IP Not Available"
)
| extend Port = case(
ClientIP has "." and ClientIP has ':', tostring(split(ClientIP,":")[1]),
ClientIP has "." and ClientIP has '-', tostring(split(ClientIP,"-")[1]),
ClientIP has ']-', tostring(split(ClientIP,"]-")[1]),
ClientIP has ']:', tostring(split(ClientIP,"]:")[1]),
isempty(ClientIP) and ClientIP_ has "." and ClientIP_ has ':', tostring(split(ClientIP_,":")[1]),
isempty(ClientIP) and ClientIP_ has "." and ClientIP_ has '-', tostring(split(ClientIP_,"-")[1]),
isempty(ClientIP) and ClientIP_ has ']-', tostring(split(ClientIP_,"]-")[1]),
isempty(ClientIP) and ClientIP_ has ']:', tostring(split(ClientIP_,"]:")[1]),
isnotempty(ClientIP), ClientIP,
isnotempty(ClientIP_), ClientIP_,
"IP Not Available"
)
| extend UserId = iff(isempty(UserId), UserId_, UserId)
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), DistinctUserCount = dcount(UserId), UserId = make_set(UserId),
Ports = make_set(Port), EventCount = count() by fwdingDestination, ClientIP = ClientIPOnly
| where DistinctUserCount > 1
| mv-expand UserId
| extend UserId = tostring(UserId), Ports = tostring(Ports)
| distinct StartTimeUtc, EndTimeUtc, UserId, DistinctUserCount, ClientIP, Ports, fwdingDestination, EventCount
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIP
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,32 @@
id: 508cef41-2cd8-4d40-a519-b04826a9085f
name: NRT Security Event log cleared
description: |
'Checks for event id 1102 which indicates the security event log was cleared.
It uses Event Source Name "Microsoft-Windows-Eventlog" to avoid generating false positives from other sources, like AD FS servers for instance.'
severity: Medium
requiredDataConnectors:
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsSecurityEvents
dataTypes:
- SecurityEvent
tactics:
- DefenseEvasion
relevantTechniques:
- T1070
query: |
SecurityEvent
| where EventID == 1102 and EventSourceName == "Microsoft-Windows-Eventlog"
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), EventCount = count() by Computer, Account, EventID, Activity
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Account
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: Computer
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,32 @@
id: c3e5dbaa-a540-408c-8b36-68bdfb3df088
name: NRT Base64 encoded Windows process command-lines
description: |
'Identifies instances of a base64 encoded PE file header seen in the process command line parameter.'
severity: Medium
requiredDataConnectors:
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
tactics:
- Execution
- DefenseEvasion
relevantTechniques:
- T1059
- T1027
- T1140
query: |
SecurityEvent
| where EventID==4688
| where isnotempty(CommandLine)
| where CommandLine contains "TVqQAAMAAAAEAAA"
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Account
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: Computer
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,39 @@
id: 7ad4c32b-d0d2-411c-a0e8-b557afa12fce
name: NRT Process executed from binary hidden in Base64 encoded file
description: |
'Encoding malicious software is a technique used to obfuscate files from detection.
The first CommandLine component is looking for Python decoding base64.
The second CommandLine component is looking for Bash/sh command line base64 decoding.
The third one is looking for Ruby decoding base64.'
severity: Medium
requiredDataConnectors:
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
tactics:
- Execution
- DefenseEvasion
relevantTechniques:
- T1059
- T1027
- T1140
query: |
SecurityEvent
| where EventID==4688
| where isnotempty(CommandLine)
| project TimeGenerated, Computer, Account = SubjectUserName, AccountDomain = SubjectDomainName, FileName = Process, CommandLine, ParentProcessName;
ProcessCreationEvents
| where CommandLine contains ".decode('base64')"
or CommandLine contains "base64 --decode"
or CommandLine contains ".decode64("
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Account
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: Computer
version: 1.0.0
kind: NRT

Просмотреть файл

@ -0,0 +1,32 @@
id: 3617d76d-b15e-4c6f-985e-a1dac73c592d
name: NRT MFA Rejected by User
description: |
'Identifies accurances where a user has rejected an MFA prompt. This could be an indicator that a threat actor has compromised the username and password of this user account and is using it to try and log into the account.
Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user-accounts#monitoring-for-failed-unusual-sign-ins'
severity: Medium
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
tactics:
- InitialAccess
relevantTechniques:
- T1078.004
tags:
- AADSecOpsGuide
query: |
SigninLogs
| where ResultType == 500121
| extend additionalDetails_ = tostring(Status.additionalDetails)
| where additionalDetails_ =~ "MFA denied; user declined the authentication"
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserPrincipalName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
version: 1.0.1
kind: NRT

Просмотреть файл

@ -0,0 +1,54 @@
id: dd03057e-4347-4853-bf1e-2b2d21eb4e59
name: NRT Squid proxy events related to mining pools
description: |
'Checks for Squid proxy events in Syslog associated with common mining pools .This query presumes the default Squid log format is being used.
http://www.squid-cache.org/Doc/config/access_log/'
severity: Low
requiredDataConnectors:
- connectorId: Syslog
dataTypes:
- Syslog
tactics:
- CommandAndControl
relevantTechniques:
- T1102
query: |
let DomainList = dynamic(["monerohash.com", "do-dear.com", "xmrminerpro.com", "secumine.net", "xmrpool.com", "minexmr.org", "hashanywhere.com", "xmrget.com",
"mininglottery.eu", "minergate.com", "moriaxmr.com", "multipooler.com", "moneropools.com", "xmrpool.eu", "coolmining.club", "supportxmr.com",
"minexmr.com", "hashvault.pro", "xmrpool.net", "crypto-pool.fr", "xmr.pt", "miner.rocks", "walpool.com", "herominers.com", "gntl.co.uk", "semipool.com",
"coinfoundry.org", "cryptoknight.cc", "fairhash.org", "baikalmine.com", "tubepool.xyz", "fairpool.xyz", "asiapool.io", "coinpoolit.webhop.me", "nanopool.org",
"moneropool.com", "miner.center", "prohash.net", "poolto.be", "cryptoescrow.eu", "monerominers.net", "cryptonotepool.org", "extrmepool.org", "webcoin.me",
"kippo.eu", "hashinvest.ws", "monero.farm", "supportxmr.com", "xmrpool.eu", "linux-repository-updates.com", "1gh.com", "dwarfpool.com", "hash-to-coins.com",
"hashvault.pro", "pool-proxy.com", "hashfor.cash", "fairpool.cloud", "litecoinpool.org", "mineshaft.ml", "abcxyz.stream", "moneropool.ru", "cryptonotepool.org.uk",
"extremepool.org", "extremehash.com", "hashinvest.net", "unipool.pro", "crypto-pools.org", "monero.net", "backup-pool.com", "mooo.com", "freeyy.me", "cryptonight.net",
"shscrypto.net"]);
Syslog
| where ProcessName contains "squid"
| extend URL = extract("(([A-Z]+ [a-z]{4,5}:\\/\\/)|[A-Z]+ )([^ :]*)",3,SyslogMessage),
SourceIP = extract("([0-9]+ )(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}))",2,SyslogMessage),
Status = extract("(TCP_(([A-Z]+)(_[A-Z]+)*)|UDP_(([A-Z]+)(_[A-Z]+)*))",1,SyslogMessage),
HTTP_Status_Code = extract("(TCP_(([A-Z]+)(_[A-Z]+)*)|UDP_(([A-Z]+)(_[A-Z]+)*))/([0-9]{3})",8,SyslogMessage),
User = extract("(CONNECT |GET )([^ ]* )([^ ]+)",3,SyslogMessage),
RemotePort = extract("(CONNECT |GET )([^ ]*)(:)([0-9]*)",4,SyslogMessage),
Domain = extract("(([A-Z]+ [a-z]{4,5}:\\/\\/)|[A-Z]+ )([^ :\\/]*)",3,SyslogMessage),
Bytes = toint(extract("([A-Z]+\\/[0-9]{3} )([0-9]+)",2,SyslogMessage)),
contentType = extract("([a-z/]+$)",1,SyslogMessage)
| extend TLD = extract("\\.[a-z]*$",0,Domain)
| where HTTP_Status_Code == '200'
| where Domain contains "."
| where Domain has_any (DomainList)
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: User
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIP
- entityType: URL
fieldMappings:
- identifier: Url
columnName: URL
version: 1.0.0
kind: NRT