Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update Semperis DSP solution #11656

Merged
merged 10 commits into from
Feb 3, 2025
Merged
Next Next commit
update semperis DSP solution
lilacham committed Jan 13, 2025
commit f6240730eeea74cb8c0a7b29b1eb7220435d6ed6
Original file line number Diff line number Diff line change
@@ -20,15 +20,8 @@ query: |
dsp_parser
| where EventID == 9212
| where SecurityIndicatorName == "Evidence of Mimikatz DCShadow attack"
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: LoginUser
- identifier: NTDomain
columnName: NTDomain
- entityType: Host
fieldMappings:
- identifier: HostName
Original file line number Diff line number Diff line change
@@ -20,15 +20,8 @@ query: |
dsp_parser
| where EventID == 9212
| where SecurityIndicatorName == "Kerberos krbtgt account with old password"
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: LoginUser
- identifier: NTDomain
columnName: NTDomain
- entityType: Host
fieldMappings:
- identifier: HostName
Original file line number Diff line number Diff line change
@@ -21,15 +21,8 @@ query: |
dsp_parser
| where EventID == 9212
| where SecurityIndicatorName == "Recent sIDHistory changes on objects"
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: LoginUser
- identifier: NTDomain
columnName: NTDomain
- entityType: Host
fieldMappings:
- identifier: HostName
Original file line number Diff line number Diff line change
@@ -21,15 +21,8 @@ query: |
dsp_parser
| where EventID == 9212
| where SecurityIndicatorName == "Well-known privileged SIDs in sIDHistory"
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: LoginUser
- identifier: NTDomain
columnName: NTDomain
- entityType: Host
fieldMappings:
- identifier: HostName
Original file line number Diff line number Diff line change
@@ -20,15 +20,8 @@ query: |
dsp_parser
| where EventID == 9212
| where SecurityIndicatorName == "Zerologon vulnerability"
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: LoginUser
- identifier: NTDomain
columnName: NTDomain
- entityType: Host
fieldMappings:
- identifier: HostName
Original file line number Diff line number Diff line change
@@ -19,14 +19,20 @@ relevantTechniques:
triggerOperator: gt
triggerThreshold: 0
query: |
Event
| where Source == 'Semperis-Operation-Log' and EventID == 20002
SecurityEvent
| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20002
| sort by TimeGenerated desc
| parse RenderedDescription with "Operation: " Operation "Access Granted:" AccessGranted "Result: " Result "Details: " * "Trustee Name: " TrusteeName " Correlation ID: " * " Source: " HostIP "WebSite Target" *
| extend p1Xml = parse_xml(EventData).EventData.Data
| mv-expand bagexpansion=array p1Xml
| evaluate bag_unpack(p1Xml)
| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')
| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)
| extend det = column_ifexists('details', '')
| parse det with * "Trustee Name: " TrusteeName " Correlation ID: " * " Source: " HostIP "WebSite Target" *
| extend host = tostring(HostIP)
| extend HostIP = trim_end(":", HostIP)
| project TimeGenerated, UserName, HostIP, _ResourceId
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), Name = tostring(split(UserName, '\\', 1)[0])
| project TimeGenerated, TrusteeName, HostIP, _ResourceId
| extend NTDomain = tostring(split(TrusteeName, '\\', 0)[0]), Name = tostring(split(TrusteeName, '\\', 1)[0])
entityMappings:
- entityType: IP
fieldMappings:
Original file line number Diff line number Diff line change
@@ -21,15 +21,16 @@ relevantTechniques:
- T1110
- T1584
query: |
Event
| where Source == 'Semperis-DSP-Notifications' and EventID == 30001
| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data
SecurityEvent
| where EventSourceName == 'Semperis-DSP-Notifications' and EventID == 30001
| extend p1Xml = parse_xml(EventData).EventData.Data
| mv-expand bagexpansion=array p1Xml
| evaluate bag_unpack(p1Xml)
| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')
| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)
| parse column_ifexists('objectDN', '') with * "CN=" cnName "," *
| where "Critical" == column_ifexists('severity', "")
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend NTDomain = tostring(split(changedBy, '\\', 0)[0]), LoginUser = tostring(split(changedBy, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
Original file line number Diff line number Diff line change
@@ -19,13 +19,14 @@ relevantTechniques:
- T1548
- T1098
query: |
Event
| where Source == 'Semperis-Operation-Log' and EventID == 20012
SecurityEvent
| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20012
| order by TimeGenerated desc
| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data
| mv-expand bagexpansion=array p1Xml
| evaluate bag_unpack(p1Xml)
| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')
| evaluate pivot(Name, any(Value), TimeGenerated, Computer, Level, EventLevelName, EventID, Type, _ResourceId)
| extend det = column_ifexists('details', '')
| parse det with "Occured at (UTC): " OccurredAt "Session ID: " SessionID "Trustee Name: " TrusteeName "Correlation ID: " CorrelationID "Source: " Source "WebSite Target: " WebSiteTarget "Product: " Product "Component: " Component "AD Information: " ADInformation "Object GUID: " ObjectGUID "Attribute: " Attribute "Distinguished Name: " DistinguishedName "Additional Information: "AdditionalInformation "Operation Detail: " OperationDetail "operationName: " operationName "trustee: " trustee "personas: " personas "Status: " status "Granted: " Granted "Result: " Result
| extend _AccessGranted = iif(operationName contains "CreateRbacIdentity", "Added", "Removed")
@@ -36,7 +37,7 @@ query: |
| extend grid_personas = iif(operationName contains "CreateRbacIdentity", add_personas, remove_personas)
| extend date_to_sort = format_datetime(TimeGenerated, "yyyy-mm-dd HH:mm:ss")
| order by date_to_sort desc
| extend NTDomain = tostring(split(UserName, '\\', 0)[0]), LoginUser = tostring(split(UserName, '\\', 1)[0])
| extend NTDomain = tostring(split(TrusteeName, '\\', 0)[0]), LoginUser = tostring(split(TrusteeName, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
- entityType: Account
Original file line number Diff line number Diff line change
@@ -87,12 +87,16 @@
]
},
{
"title": "1. Configure Semperis DSP Management Server to send Windows event logs to your Microsoft Sentinel Workspace",
"description": "On your **Semperis DSP Management Server** install the Microsoft agent for Windows."
"title": "**Configure Windows Security Events via AMA connector**",
"description": "Collect Windows security events logs from your **Semperis DSP Management Server** ."
},
{
"title": "2. Install and onboard the Microsoft agent for Windows",
"description": "You can skip this step if you have already installed the Microsoft agent for Windows",
"title": "1. Install the Azure Monitor Agent (AMA)",
"description": "On your **Semperis DSP Management Server** install the AMA on the DSP machine that will act as the event log forwarder.\nYou can skip this step if you have already installed the Microsoft agent for Windows"
},
{
"title": "2. Create a Data Collection Rule (DCR)",
"description": "Start collecting logs from the **Semperis DSP Management Server** .\n\n1. In the Azure portal, navigate to your **Log Analytics workspace**.\n2. In the left pane, click on **Configuration** and then **Data connectors**.\n3. Find and install the **the Windows Security Events via AMA** connector.\n4. Click on **Open connector** and then on **Create data collection rule**.\n5. Configure the DCR with the necessary details, such as the log sources and the destination workspace.",
"instructions": [
{
"parameters": {
@@ -117,20 +121,46 @@
]
},
{
"title": "3. Configure the Semperis DSP Windows event logs to be collected by the agent",
"description": "Configure the agent to collect the logs.\n\n1. Under workspace advanced settings **Configuration**, select **Data** and then **Windows Event Logs**.\n2. Select **Go to Agents configuration** and click **Add Windows event log**.\n3. Enter **Semperis-DSP-Security/Operational** as the log name to be collected and click **Apply**",
"title": "**Configure Common Event Format via AMA connector**",
"description": "Collect syslog messages send from your **Semperis DSP Management Server** ."
},
{
"title": "1. Install the Azure Monitor Agent (AMA)",
"description": "Install the AMA on the Linux machine that will act as the log forwarder. This machine will collect and forward CEF logs to Microsoft Sentinel.\nYou can skip this step if you have already installed the Microsoft agent for Linux"
},
{
"title": "2. Create a Data Collection Rule (DCR)",
"description": "Start collecting logs from the **Semperis DSP Management Server** .\n\n1. In the Azure portal, navigate to your **Log Analytics workspace**.\n2. In the left pane, click on **Configuration** and then **Data connectors**.\n3. Find and install the **the Common Event Format via AMA** connector.\n4. Click on **Open connector** and then on **Create data collection rule**.\n5. Configure the DCR with the necessary details, such as the log sources and the destination workspace.",
"instructions": [
{
"parameters": {
"linkType": "OpenAdvancedWorkspaceSettings"
"title": "Choose where to install the agent:",
"instructionSteps": [
{
"title": "Install agent on Semperis DSP Management Server",
"description": "Download the agent on the relevant machine and follow the instructions.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnNonAzure"
},
"type": "InstallAgent"
}
]
}
]
},
"type": "InstallAgent"
"type": "InstructionStepsGroup"
}
]
},
{
"title": "3. Configure sending CEF logs on your Semperis DSP Management Server",
"description": "Configure your **Semperis DSP Management Server** to send CEF logs to the Linux machine where the AMA is installed. This involves setting the destination IP address and port for the CEF logs"
},
{
"title": "",
"description": "> You should now be able to receive logs in the *Windows event log* table, log data can be parsed using the **dsp_parser()** function, used by all query samples, workbooks and analytic templates."
"description": "> You should now be able to receive logs in the *Windows event log* table and *common log* table, log data can be parsed using the **dsp_parser()** function, used by all query samples, workbooks and analytic templates."
}
],
"metadata": {
Original file line number Diff line number Diff line change
@@ -2,41 +2,39 @@ id: 5ea4c8c2-a6e9-4321-8402-39635ffcfbe4
Function:
Title: Parser for dsp_parser
Version: '1.0.0'
LastUpdated: '2023-08-23'
LastUpdated: '2024-12-25'
Category: Microsoft Sentinel Parser
FunctionName: dsp_parser
FunctionAlias: dsp_parser
FunctionQuery: |
Event
| where Source == "Semperis-DSP-Security"
| where EventID in ("9211","9212","9208")
SecurityEvent
| where EventSourceName == "Semperis-DSP-Security"
| where EventID in ("9211", "9212", "9208")
| parse EventData with
'<DataItem type="' EventDataType
'" time="' EventDataTime
'" sourceHealthServiceId="' EventDataSourceHealthServiceId
'"><EventData ' * '>' DSPData '</EventData></DataItem>'
'<EventData ' * '>' DSPData '</EventData>'
| parse DSPData with
*
'<Data Name="firstFound">' FirstFound '</Data>'
*
| parse DSPData with
'<Data Name="generationTime">' GenerationTime '</Data>'
'<Data Name="securityIndicatorName">' SecurityIndicatorName '</Data>'
'<Data Name="result">' Result '</Data>'
*
'<Data Name="score">' Score '</Data>'
'<Data Name="forestName">' ForestName '</Data>'
'<Data Name="domains">' Domains '</Data>'
'<Data Name="severity">' Severity '</Data>'
'<Data Name="weight">' Weight '</Data>'
'<Data Name="securityFrameworkTags">' SecurityFrameworkTags '</Data>'
'<Data Name="securityIndicatorDescription">' SecurityIndicatorDescription '</Data>'
'<Data Name="likelihoodOfCompromise">' LikelihoodOfCompromise '</Data>'
'<Data Name="resultMessage">' ResultMessage '</Data>'
'<Data Name="numberOfResults">' NumberOfResults '</Data>'
'<Data Name="remediation">' Remediation '</Data>'
'<Data Name="schedule">' Schedule '</Data>'
*
'<Data Name="generationTime">' GenerationTime '</Data>' *
'<Data Name="securityIndicatorName">' SecurityIndicatorName '</Data>' *
'<Data Name="result">' Result '</Data>' *
'<Data Name="score">' Score '</Data>' *
'<Data Name="forestName">' ForestName '</Data>' *
'<Data Name="domains">' Domains '</Data>' *
'<Data Name="severity">' Severity '</Data>' *
'<Data Name="weight">' Weight '</Data>' *
'<Data Name="securityFrameworkTags">' SecurityFrameworkTags '</Data>' *
'<Data Name="securityIndicatorDescription">' SecurityIndicatorDescription '</Data>' *
'<Data Name="likelihoodOfCompromise">' LikelihoodOfCompromise '</Data>' *
'<Data Name="resultMessage">' ResultMessage '</Data>' *
'<Data Name="numberOfResults">' NumberOfResults '</Data>' *
'<Data Name="remediation">' Remediation '</Data>' *
'<Data Name="schedule">' Schedule '</Data>'
*
| extend SecurityFrameworkTagsCsv = replace(@' Mitre:', @'', tostring(SecurityFrameworkTags))
| extend SecurityFrameworkTagsCsv = replace(@'Mitre:', @'', tostring(SecurityFrameworkTagsCsv))
| extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))
| extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))
| extend GenerationTimeTags = tostring(DSPData)

Large diffs are not rendered by default.