diff --git a/.github/workflows/solutionIntegration.yaml b/.github/workflows/solutionIntegration.yaml
new file mode 100644
index 00000000000..a93e455cfae
--- /dev/null
+++ b/.github/workflows/solutionIntegration.yaml
@@ -0,0 +1,120 @@
+name: Solution Integration Testing
+run-name: Running Solution Integration Testing on ${{ github.ref_name }}
+
+on:
+ pull_request_target:
+ types: [opened, edited, reopened, synchronize]
+ branches:
+ - master
+ paths:
+ - 'Solutions/**/Package/mainTemplate.json'
+
+permissions:
+ id-token: write
+ contents: read
+ pull-requests: write
+
+jobs:
+ Run-solutionIntegration-Testimio:
+ name: Solution Integration Testing - Testim.io
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout pull request branch
+ uses: actions/checkout@v3
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+ repository: ${{ github.event.pull_request.head.repo.full_name }}
+ # persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
+ fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
+
+ - name: Setup git config
+ run: |
+ git config --local user.name "github-actions[bot]"
+ git config --local user.email "<>"
+
+ - name: Azure Login to Dev Account
+ uses: azure/login@a65d910e8af852a8061c627c456678983e180302
+ with:
+ client-id: ${{ secrets.AZURE_SOLUTIONTESTING_DEV_CLIENT_ID }}
+ tenant-id: ${{ secrets.AZURE_SOLUTIONTESTING_DEV_TENANT_ID }}
+ allow-no-subscriptions: true
+
+ - name: Whitelist Runner IP
+ run: |
+ agentIP=$(curl -s https://api.ipify.org/)
+ az keyvault network-rule add --name e2e-solIntegTesting-KV --ip-address $agentIP --query properties.networkAcls.ipRules
+
+ - name: Delete Scripts from branch
+ run: |
+ if [ -f "./evaluateAndExtractTemplate.py" ]; then rm ./evaluateAndExtractTemplate.py; fi
+ if [ -f "./runUITests.py" ]; then rm ./runUITests.py; fi
+ if [ -f "./requirements.txt" ]; then rm ./requirements.txt; fi
+ if [ -f "./config.json" ]; then rm ./config.json; fi
+
+ - name: Download files from ADO
+ run: |
+ curl -u :$(az account get-access-token -o tsv --query accessToken) \
+ -o evaluateAndExtractTemplate.py \
+ "https://dev.azure.com/msazure/One/_apis/git/repositories/Sentinel-CATUtilities/items?path=/SolutionIntegrationTesting/.scripts/evaluateAndExtractTemplate.py&api-version=6.0" \
+ -o runUITests.py \
+ "https://dev.azure.com/msazure/One/_apis/git/repositories/Sentinel-CATUtilities/items?path=/SolutionIntegrationTesting/.scripts/runUITests.py&api-version=6.0" \
+ -o requirements.txt \
+ "https://dev.azure.com/msazure/One/_apis/git/repositories/Sentinel-CATUtilities/items?path=/SolutionIntegrationTesting/requirements.txt&api-version=6.0" \
+ -o config.json \
+ "https://dev.azure.com/msazure/One/_apis/git/repositories/Sentinel-CATUtilities/items?path=/SolutionIntegrationTesting/config.json&api-version=6.0"
+
+ - name: Setup Python Environment
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.x'
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+
+ - name: Get Test Tenant Client ID and Tenant ID
+ run: |
+ echo "AZURE_TEST_CLIENT_ID=$(az keyvault secret show --name ClientId-Test --vault-name e2e-solIntegTesting-KV --query value -o tsv)" >> $GITHUB_ENV
+ echo "AZURE_TEST_TENANT_ID=$(az keyvault secret show --name TenantId-Test --vault-name e2e-solIntegTesting-KV --query value -o tsv)" >> $GITHUB_ENV
+
+ - name: Azure Login to Test Tenant Account
+ uses: azure/login@a65d910e8af852a8061c627c456678983e180302
+ with:
+ client-id: ${{ env.AZURE_TEST_CLIENT_ID }}
+ tenant-id: ${{ env.AZURE_TEST_TENANT_ID }}
+ allow-no-subscriptions: true
+
+ - name: Get Test Tenant Subscription
+ run: |
+ echo "TEST_TENANT_SUBSCRIPTION_ID=$(az account show --query id -o tsv)" >> $GITHUB_ENV
+
+ - name: Deploy Solution to Workspace, Evaluate and Extract Template Files
+ continue-on-error: true # Continues even after failing so as to not block the PR
+ run: |
+ filePath="evaluateAndExtractTemplate.py"
+ python $filePath
+
+ - name: Azure Login to Dev Account
+ uses: azure/login@a65d910e8af852a8061c627c456678983e180302
+ if: '!cancelled()'
+ with:
+ client-id: ${{ secrets.AZURE_SOLUTIONTESTING_DEV_CLIENT_ID }}
+ tenant-id: ${{ secrets.AZURE_SOLUTIONTESTING_DEV_TENANT_ID }}
+ allow-no-subscriptions: true
+
+ - name: Execute Tests on Testim
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ continue-on-error: true # Continues even after failing so as to not block the PR
+ run: |
+ filePath="runUITests.py"
+ python $filePath
+
+ - name: Delist Runner IP
+ if: '!cancelled()'
+ run: |
+ agentIP=$(curl -s https://api.ipify.org/)
+ az keyvault network-rule remove --name e2e-solIntegTesting-KV --ip-address $agentIP --query properties.networkAcls.ipRules
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/IllumioSyslogAuditEvents.json b/.script/tests/KqlvalidationsTests/CustomTables/IllumioSyslogAuditEvents.json
new file mode 100644
index 00000000000..31d8c7c0af0
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/IllumioSyslogAuditEvents.json
@@ -0,0 +1,53 @@
+{
+ "name": "IllumioSyslogAuditEvents",
+ "Properties": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "Name": "href",
+ "Type": "String"
+ },
+ {
+ "Name": "pce_fqdn",
+ "Type": "String"
+ },
+ {
+ "Name": "created_by",
+ "Type": "dynamic"
+ },
+ {
+ "Name": "event_type",
+ "Type": "String"
+ },
+ {
+ "Name": "status",
+ "Type": "String"
+ },
+ {
+ "Name": "severity",
+ "Type": "String"
+ },
+ {
+ "Name": "action",
+ "Type": "dynamic"
+ },
+ {
+ "Name": "resource_changes",
+ "Type": "dynamic"
+ },
+ {
+ "Name": "notifications",
+ "Type": "dynamic"
+ },
+ {
+ "Name": "version",
+ "Type": "Int"
+ },
+ {
+ "Name": "Type",
+ "Type": "String"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/IllumioSyslogNetworkTrafficEvents.json b/.script/tests/KqlvalidationsTests/CustomTables/IllumioSyslogNetworkTrafficEvents.json
new file mode 100644
index 00000000000..d668e3ecd2d
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/IllumioSyslogNetworkTrafficEvents.json
@@ -0,0 +1,117 @@
+{
+ "name": "IllumioSyslogNetworkTrafficEvents",
+ "Properties": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "tdms",
+ "type": "int"
+ },
+ {
+ "name": "ddms",
+ "type": "int"
+ },
+ {
+ "name": "pn",
+ "type": "string"
+ },
+ {
+ "name": "un",
+ "type": "string"
+ },
+ {
+ "name": "sn",
+ "type": "string"
+ },
+ {
+ "name": "src_ip",
+ "type": "string"
+ },
+ {
+ "name": "dst_ip",
+ "type": "string"
+ },
+ {
+ "name": "class",
+ "type": "string"
+ },
+ {
+ "name": "proto",
+ "type": "int"
+ },
+ {
+ "name": "dst_port",
+ "type": "int"
+ },
+ {
+ "name": "flow_count",
+ "type": "int"
+ },
+ {
+ "name": "dir",
+ "type": "string"
+ },
+ {
+ "name": "org_id",
+ "type": "int"
+ },
+ {
+ "name": "state",
+ "type": "string"
+ },
+ {
+ "name": "pd_qualifier",
+ "type": "int"
+ },
+ {
+ "name": "pd",
+ "type": "int"
+ },
+ {
+ "name": "src_hostname",
+ "type": "string"
+ },
+ {
+ "name": "src_href",
+ "type": "string"
+ },
+ {
+ "name": "dst_hostname",
+ "type": "string"
+ },
+ {
+ "name": "dst_href",
+ "type": "string"
+ },
+ {
+ "name": "network",
+ "type": "string"
+ },
+ {
+ "name": "src_labels",
+ "type": "dynamic"
+ },
+ {
+ "name": "dst_labels",
+ "type": "dynamic"
+ },
+ {
+ "name": "interval_sec",
+ "type": "int"
+ },
+ {
+ "name": "pce_fqdn",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "int"
+ },
+ {
+ "Name": "Type",
+ "Type": "String"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_ASN_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_ASN_CL.json
new file mode 100644
index 00000000000..62a2c1a5cce
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_ASN_CL.json
@@ -0,0 +1,33 @@
+{
+ "Name": "Ipinfo_ASN_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "asn",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "domain",
+ "Type": "String"
+ },
+ {
+ "Name": "route",
+ "Type": "String"
+ },
+ {
+ "Name": "asn_type",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Abuse_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Abuse_CL.json
new file mode 100644
index 00000000000..96c6b8c402c
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Abuse_CL.json
@@ -0,0 +1,37 @@
+{
+ "Name": "Ipinfo_Abuse_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "email",
+ "Type": "String"
+ },
+ {
+ "Name": "address",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "phone",
+ "Type": "String"
+ },
+ {
+ "Name": "network",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Carrier_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Carrier_CL.json
new file mode 100644
index 00000000000..f418168a591
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Carrier_CL.json
@@ -0,0 +1,33 @@
+{
+ "Name": "Ipinfo_Carrier_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "carrier",
+ "Type": "String"
+ },
+ {
+ "Name": "mcc",
+ "Type": "String"
+ },
+ {
+ "Name": "mnc",
+ "Type": "String"
+ },
+ {
+ "Name": "cc",
+ "Type": "String"
+ },
+ {
+ "Name": "network",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Country_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Country_CL.json
new file mode 100644
index 00000000000..2c1b1d0883b
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Country_CL.json
@@ -0,0 +1,41 @@
+{
+ "Name": "Ipinfo_Country_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "as_domain",
+ "Type": "String"
+ },
+ {
+ "Name": "as_name",
+ "Type": "String"
+ },
+ {
+ "Name": "asn",
+ "Type": "String"
+ },
+ {
+ "Name": "continent",
+ "Type": "String"
+ },
+ {
+ "Name": "continent_name",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "country_name",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Domain_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Domain_CL.json
new file mode 100644
index 00000000000..49a2e0b2a37
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Domain_CL.json
@@ -0,0 +1,21 @@
+{
+ "Name": "Ipinfo_Domain_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "domains",
+ "Type": "String"
+ },
+ {
+ "Name": "total",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Location_extended_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Location_extended_CL.json
new file mode 100644
index 00000000000..5a69511ecf6
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Location_extended_CL.json
@@ -0,0 +1,57 @@
+{
+ "Name": "Ipinfo_Location_extended_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "city",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "country_name",
+ "Type": "String"
+ },
+ {
+ "Name": "latitude",
+ "Type": "String"
+ },
+ {
+ "Name": "longitude",
+ "Type": "String"
+ },
+ {
+ "Name": "postal_code",
+ "Type": "String"
+ },
+ {
+ "Name": "radius",
+ "Type": "String"
+ },
+ {
+ "Name": "region_name",
+ "Type": "String"
+ },
+ {
+ "Name": "region",
+ "Type": "String"
+ },
+ {
+ "Name": "timezone",
+ "Type": "String"
+ },
+ {
+ "Name": "geoname_id",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Privacy_extended_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Privacy_extended_CL.json
new file mode 100644
index 00000000000..e27f26b0dbc
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_Privacy_extended_CL.json
@@ -0,0 +1,65 @@
+{
+ "Name": "Ipinfo_Privacy_extended_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "anycast",
+ "Type": "String"
+ },
+ {
+ "Name": "census",
+ "Type": "String"
+ },
+ {
+ "Name": "census_port",
+ "Type": "String"
+ },
+ {
+ "Name": "device_activity",
+ "Type": "String"
+ },
+ {
+ "Name": "hosting",
+ "Type": "String"
+ },
+ {
+ "Name": "network",
+ "Type": "String"
+ },
+ {
+ "Name": "proxy",
+ "Type": "String"
+ },
+ {
+ "Name": "relay",
+ "Type": "String"
+ },
+ {
+ "Name": "tor",
+ "Type": "String"
+ },
+ {
+ "Name": "vpn",
+ "Type": "String"
+ },
+ {
+ "Name": "vpn_config",
+ "Type": "String"
+ },
+ {
+ "Name": "vpn_name",
+ "Type": "String"
+ },
+ {
+ "Name": "whois",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_RIRWHOIS_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_RIRWHOIS_CL.json
new file mode 100644
index 00000000000..2f5587e4a07
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_RIRWHOIS_CL.json
@@ -0,0 +1,89 @@
+{
+ "Name": "Ipinfo_RIRWHOIS_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "status",
+ "Type": "String"
+ },
+ {
+ "Name": "tech",
+ "Type": "String"
+ },
+ {
+ "Name": "maintainer",
+ "Type": "String"
+ },
+ {
+ "Name": "admin",
+ "Type": "String"
+ },
+ {
+ "Name": "source",
+ "Type": "String"
+ },
+ {
+ "Name": "whois_domain",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "org",
+ "Type": "String"
+ },
+ {
+ "Name": "rdns_domain",
+ "Type": "String"
+ },
+ {
+ "Name": "domain",
+ "Type": "String"
+ },
+ {
+ "Name": "geoloc",
+ "Type": "String"
+ },
+ {
+ "Name": "org_address",
+ "Type": "String"
+ },
+ {
+ "Name": "asn",
+ "Type": "String"
+ },
+ {
+ "Name": "as_name",
+ "Type": "String"
+ },
+ {
+ "Name": "as_domain",
+ "Type": "String"
+ },
+ {
+ "Name": "as_type",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_RWHOIS_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_RWHOIS_CL.json
new file mode 100644
index 00000000000..e4cfc750677
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_RWHOIS_CL.json
@@ -0,0 +1,65 @@
+{
+ "Name": "Ipinfo_RWHOIS_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "whois_desc",
+ "Type": "String"
+ },
+ {
+ "Name": "host",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "email",
+ "Type": "String"
+ },
+ {
+ "Name": "abuse",
+ "Type": "String"
+ },
+ {
+ "Name": "domain",
+ "Type": "String"
+ },
+ {
+ "Name": "city",
+ "Type": "String"
+ },
+ {
+ "Name": "street",
+ "Type": "String"
+ },
+ {
+ "Name": "postal",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "imported",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_ASN_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_ASN_CL.json
new file mode 100644
index 00000000000..2a91a5861ce
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_ASN_CL.json
@@ -0,0 +1,37 @@
+{
+ "Name": "Ipinfo_WHOIS_ASN_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "org_id",
+ "Type": "String"
+ },
+ {
+ "Name": "created",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "source",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_MNT_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_MNT_CL.json
new file mode 100644
index 00000000000..df86c921768
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_MNT_CL.json
@@ -0,0 +1,41 @@
+{
+ "Name": "Ipinfo_WHOIS_MNT_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "admin_id",
+ "Type": "String"
+ },
+ {
+ "Name": "tech_id",
+ "Type": "String"
+ },
+ {
+ "Name": "org_id",
+ "Type": "String"
+ },
+ {
+ "Name": "created",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "source",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_NET_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_NET_CL.json
new file mode 100644
index 00000000000..aacdb181c20
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_NET_CL.json
@@ -0,0 +1,65 @@
+{
+ "Name": "Ipinfo_WHOIS_NET_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "domain",
+ "Type": "String"
+ },
+ {
+ "Name": "org_id",
+ "Type": "String"
+ },
+ {
+ "Name": "status",
+ "Type": "String"
+ },
+ {
+ "Name": "tech_id",
+ "Type": "String"
+ },
+ {
+ "Name": "mnt_id",
+ "Type": "String"
+ },
+ {
+ "Name": "admin_id",
+ "Type": "String"
+ },
+ {
+ "Name": "abuse_id",
+ "Type": "String"
+ },
+ {
+ "Name": "created",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "source",
+ "Type": "String"
+ },
+ {
+ "Name": "range",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_ORG_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_ORG_CL.json
new file mode 100644
index 00000000000..ce2440a8214
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_ORG_CL.json
@@ -0,0 +1,77 @@
+{
+ "Name": "Ipinfo_WHOIS_ORG_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "address",
+ "Type": "String"
+ },
+ {
+ "Name": "street",
+ "Type": "String"
+ },
+ {
+ "Name": "city",
+ "Type": "String"
+ },
+ {
+ "Name": "state",
+ "Type": "String"
+ },
+ {
+ "Name": "postalcode",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "admin_id",
+ "Type": "String"
+ },
+ {
+ "Name": "tech_id",
+ "Type": "String"
+ },
+ {
+ "Name": "abuse_id",
+ "Type": "String"
+ },
+ {
+ "Name": "mnt_id",
+ "Type": "String"
+ },
+ {
+ "Name": "email",
+ "Type": "String"
+ },
+ {
+ "Name": "domain",
+ "Type": "String"
+ },
+ {
+ "Name": "created",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "source",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_POC_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_POC_CL.json
new file mode 100644
index 00000000000..1df0b7e0279
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/Ipinfo_WHOIS_POC_CL.json
@@ -0,0 +1,57 @@
+{
+ "Name": "Ipinfo_WHOIS_POC_CL",
+ "Properties": [
+ {
+ "Name": "TimeGenerated",
+ "Type": "datetime"
+ },
+ {
+ "Name": "whois_id",
+ "Type": "String"
+ },
+ {
+ "Name": "name",
+ "Type": "String"
+ },
+ {
+ "Name": "mobilephone",
+ "Type": "String"
+ },
+ {
+ "Name": "officephone",
+ "Type": "String"
+ },
+ {
+ "Name": "fax",
+ "Type": "String"
+ },
+ {
+ "Name": "address",
+ "Type": "String"
+ },
+ {
+ "Name": "country",
+ "Type": "String"
+ },
+ {
+ "Name": "email",
+ "Type": "String"
+ },
+ {
+ "Name": "abuse_email",
+ "Type": "String"
+ },
+ {
+ "Name": "created",
+ "Type": "String"
+ },
+ {
+ "Name": "updated",
+ "Type": "String"
+ },
+ {
+ "Name": "source",
+ "Type": "String"
+ }
+ ]
+}
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/ProofPointTAPClicksPermitted_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/ProofPointTAPClicksPermitted_CL.json
index 9278720faf4..0d76d7971f6 100644
--- a/.script/tests/KqlvalidationsTests/CustomTables/ProofPointTAPClicksPermitted_CL.json
+++ b/.script/tests/KqlvalidationsTests/CustomTables/ProofPointTAPClicksPermitted_CL.json
@@ -40,6 +40,10 @@
{
"Name": "classification_s",
"Type": "String"
+ },
+ {
+ "Name": "threatStatus_s",
+ "Type": "String"
}
]
}
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/jamfprotectalerts_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotectalerts_CL.json
new file mode 100644
index 00000000000..409256edf73
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotectalerts_CL.json
@@ -0,0 +1,225 @@
+{
+ "Name": "jamfprotectalerts_CL",
+ "Properties": [
+ {
+ "name": "input",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventVendor",
+ "type": "string"
+ },
+ {
+ "name": "EventProduct",
+ "type": "string"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "EventResult",
+ "type": "string"
+ },
+ {
+ "name": "EventMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventResultMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventSubType",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessName",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessId",
+ "type": "real"
+ },
+ {
+ "name": "ActingProcessGuid",
+ "type": "string"
+ },
+ {
+ "name": "ParentProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessId",
+ "type": "real"
+ },
+ {
+ "name": "ParentProcessGuid",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessSHA1",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessSHA256",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCurrentDirectory",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessStatusCode",
+ "type": "real"
+ },
+ {
+ "name": "TargetFilePath",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSHA1",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSize",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSigningInfoMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetFileSigningTeamID",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileIsDownload",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsAppBundle",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsDirectory",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsScreenshot",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileExtendedAttributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinaryFilePath",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA1",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySigningInfoMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetbinarySignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningTeamID",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySigningAppID",
+ "type": "dynamic"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/jamfprotecttelemetryv1_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotecttelemetryv1_CL.json
new file mode 100644
index 00000000000..f2aa2dfdbf2
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotecttelemetryv1_CL.json
@@ -0,0 +1,253 @@
+{
+ "Name": "jamfprotecttelemetryv1_CL",
+ "Properties": [
+ {
+ "name": "architecture",
+ "type": "string"
+ },
+ {
+ "name": "arguments",
+ "type": "dynamic"
+ },
+ {
+ "name": "attributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "bios_firmware_versions",
+ "type": "dynamic"
+ },
+ {
+ "name": "contents",
+ "type": "string"
+ },
+ {
+ "name": "exec_args",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_child",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_parent",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_env",
+ "type": "dynamic"
+ },
+ {
+ "name": "exit",
+ "type": "dynamic"
+ },
+ {
+ "name": "file",
+ "type": "dynamic"
+ },
+ {
+ "name": "header",
+ "type": "dynamic"
+ },
+ {
+ "name": "host_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "identity",
+ "type": "dynamic"
+ },
+ {
+ "name": "key",
+ "type": "string"
+ },
+ {
+ "name": "metrics",
+ "type": "dynamic"
+ },
+ {
+ "name": "page_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "path",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "rateLimitingSeconds",
+ "type": "int"
+ },
+ {
+ "name": "return",
+ "type": "dynamic"
+ },
+ {
+ "name": "socket_inet",
+ "type": "dynamic"
+ },
+ {
+ "name": "subject",
+ "type": "dynamic"
+ },
+ {
+ "name": "texts",
+ "type": "string"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventVendor",
+ "type": "string"
+ },
+ {
+ "name": "EventProduct",
+ "type": "string"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "TargetModel",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActingProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessSHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetUserId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetUsername",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActorUsername",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActorUserId",
+ "type": "dynamic"
+ },
+ {
+ "name": "GroupName",
+ "type": "dynamic"
+ },
+ {
+ "name": "GroupID",
+ "type": "dynamic"
+ },
+ {
+ "name": "EffectiveGroupName",
+ "type": "dynamic"
+ },
+ {
+ "name": "EffectiveGroupID",
+ "type": "dynamic"
+ },
+ {
+ "name": "DstIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DstPortNumber",
+ "type": "dynamic"
+ },
+ {
+ "name": "NetworkProtocolVersion",
+ "type": "string"
+ },
+ {
+ "name": "SrcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetbinarySignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningTeamID",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningAppID",
+ "type": "string"
+ },
+ {
+ "name": "TargetFilePath",
+ "type": "dynamic"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/jamfprotecttelemetryv2_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotecttelemetryv2_CL.json
new file mode 100644
index 00000000000..322d9f8b7e6
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotecttelemetryv2_CL.json
@@ -0,0 +1,89 @@
+{
+ "Name": "jamfprotecttelemetryv2_CL",
+ "Properties": [
+ {
+ "name": "action",
+ "type": "dynamic"
+ },
+ {
+ "name": "event",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "int"
+ },
+ {
+ "name": "EventCount",
+ "type": "int"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "thread",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "string"
+ },
+ {
+ "name": "EventVendor",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventProduct",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSchemaVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.script/tests/KqlvalidationsTests/CustomTables/jamfprotectunifiedlogs_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotectunifiedlogs_CL.json
new file mode 100644
index 00000000000..3b9caf4f0bd
--- /dev/null
+++ b/.script/tests/KqlvalidationsTests/CustomTables/jamfprotectunifiedlogs_CL.json
@@ -0,0 +1,105 @@
+{
+ "Name": "jamfprotectunifiedlogs_CL",
+ "Properties": [
+ {
+ "name": "input",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "EventResult",
+ "type": "string"
+ },
+ {
+ "name": "EventMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventResultMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventSubType",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCurrentDirectory",
+ "type": "dynamic"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/DataConnectors/Syslog/Forwarder_AMA_installer.py b/DataConnectors/Syslog/Forwarder_AMA_installer.py
index b45ff646bd2..3d615077383 100644
--- a/DataConnectors/Syslog/Forwarder_AMA_installer.py
+++ b/DataConnectors/Syslog/Forwarder_AMA_installer.py
@@ -23,7 +23,7 @@
rsyslog_old_config_tcp_content = "# provides TCP syslog reception\n$ModLoad imtcp\n$InputTCPServerRun " + daemon_default_incoming_port + "\n"
syslog_ng_documantation_path = "https://www.syslog-ng.com/technical-documents/doc/syslog-ng-open-source-edition/3.26/administration-guide/34#TOPIC-1431029"
rsyslog_documantation_path = "https://www.rsyslog.com/doc/master/configuration/actions.html"
-temp_file_path = "/tmp/rsyslog_temp_config.txt"
+temp_file_path = "/tmp/syslog_temp_config.txt"
def print_error(input_str):
@@ -266,7 +266,7 @@ def set_syslog_ng_configuration():
comment_line = False
# write line correctly
fout.write(line if not comment_line else ("#" + line))
- command_tokens = ["sudo", "cp", temp_file_path, rsyslog_conf_path]
+ command_tokens = ["sudo", "cp", temp_file_path, syslog_ng_conf_path]
write_new_content = subprocess.Popen(command_tokens, stdout=subprocess.PIPE)
time.sleep(3)
o, e = write_new_content.communicate()
@@ -325,4 +325,4 @@ def main():
-main()
\ No newline at end of file
+main()
diff --git a/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-base64-encoded-registry-keys.yaml b/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-base64-encoded-registry-keys.yaml
new file mode 100644
index 00000000000..66573bc60da
--- /dev/null
+++ b/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-base64-encoded-registry-keys.yaml
@@ -0,0 +1,26 @@
+id: 4751319e-6d20-4c26-893d-baaad90f0747
+name: suspicious-base64-encoded-registry-keys
+description: |
+ Looks for suspicious base64 encoded registry keys being created.
+ Author: Jouni Mikkola
+ References:
+ https://threathunt.blog/registry-hunts/
+requiredDataConnectors:
+- connectorId: MicrosoftThreatProtection
+ dataTypes:
+ - DeviceRegistryEvents
+tactics:
+- Defense evasion
+relevantTechniques:
+ - T1112
+query: |
+ DeviceRegistryEvents
+ | where Timestamp > ago(30d)
+ | where ActionType has_any ('RegistryValueSet','RegistryKeyCreated')
+ | where isnotempty(RegistryValueData)
+ | where RegistryValueData matches regex @'\s+([A-Za-z0-9+/]{4,}(?:[A-Za-z0-9+/]{2}[=]{2}|[A-Za-z0-9+/]{3}=)?)\s+' or RegistryValueData matches regex @'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$'
+ | extend ExtractedB64 = trim(" ",extract(@'(?:\s+)[A-Za-z0-9+\/=]+(?:\s+)',0,RegistryValueData))
+ | extend DecodedCommand = replace(@'\x00','', base64_decode_tostring(RegistryValueData))
+ | extend ExtractedDecodedCommand = base64_decode_tostring(ExtractedB64)
+ | where isnotempty(DecodedCommand) or isnotempty(ExtractedDecodedCommand)
+ | project Timestamp, DeviceName, DecodedCommand, ExtractedDecodedCommand, RegistryValueData, RegistryKey, RegistryValueName, RegistryValueType, PreviousRegistryValueData, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName
\ No newline at end of file
diff --git a/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-command-interpreters-added-to-registry.yaml b/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-command-interpreters-added-to-registry.yaml
new file mode 100644
index 00000000000..196d59f4d02
--- /dev/null
+++ b/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-command-interpreters-added-to-registry.yaml
@@ -0,0 +1,27 @@
+id: 74dd8aa9-996b-44b1-bf36-9ac9ef6d2c02
+name: suspicious-command-interpreters-added-to-registry
+description: |
+ Looks for suspicious addition of command interpreters to windows registry.
+ Author: Jouni Mikkola
+ References:
+ https://threathunt.blog/registry-hunts/
+requiredDataConnectors:
+- connectorId: MicrosoftThreatProtection
+ dataTypes:
+ - DeviceRegistryEvents
+tactics:
+- Defense evasion
+relevantTechniques:
+ - T1112
+query: |
+ DeviceRegistryEvents
+ // Filter out events initiated by OneDriveSetup.exe to reduce noise
+ | where InitiatingProcessVersionInfoInternalFileName != @"OneDriveSetup.exe"
+ // Look at events from the last 30 days
+ | where Timestamp > ago(30d)
+ // Consider only key set and key created actions
+ | where ActionType has_any ('RegistryValueSet','RegistryKeyCreated')
+ // Search for registry values containing 'powershell' or 'cmd'
+ | where RegistryValueData has_any('powershell','cmd')
+ // Project relevant fields for analysis
+ | project Timestamp, DeviceName, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName
\ No newline at end of file
diff --git a/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-keywords-in-registry.yaml b/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-keywords-in-registry.yaml
new file mode 100644
index 00000000000..52d5dfcd4dc
--- /dev/null
+++ b/Hunting Queries/Microsoft 365 Defender/Defense evasion/suspicious-keywords-in-registry.yaml
@@ -0,0 +1,21 @@
+id: 749f313e-08b4-48f6-9f9d-ba57c1abbf55
+name: suspicious-keywords-in-registry
+description: |
+ Looks for suspicious keyword additions to windows registry.
+ Author: Jouni Mikkola
+ References:
+ https://threathunt.blog/registry-hunts/
+requiredDataConnectors:
+- connectorId: MicrosoftThreatProtection
+ dataTypes:
+ - DeviceRegistryEvents
+tactics:
+- Defense evasion
+relevantTechniques:
+ - T1112
+query: |
+ DeviceRegistryEvents
+ | where Timestamp > ago(30d)
+ | where ActionType has_any ('RegistryValueSet','RegistryKeyCreated')
+ | where RegistryValueData has_any('xor','new-item','invoke-expression','iex','sleep','invoke-','System.Net.HttpWebRequest','webclient','iwr','curl') // Look for common obfuscation techniques or commands used in malicious scripts
+ | project Timestamp, DeviceName, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName // Project relevant fields for analysis
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_ASN_CL.json b/Sample Data/Custom/Ipinfo_ASN_CL.json
new file mode 100644
index 00000000000..f4c65498c9a
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_ASN_CL.json
@@ -0,0 +1,62 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "asn":"AS13335",
+ "domain":"cloudflare.com",
+ "name":"Cloudflare, Inc.",
+ "range":"1.0.0.0/24",
+ "route":"1.0.0.0/24",
+ "asn_type":"hosting",
+ "Type": "Ipinfo_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.341 PM",
+ "asn":"AS206617",
+ "domain":"neomedia.it",
+ "name":"Neomedia S.r.l.",
+ "range":"1.0.1.0/24",
+ "route":"1.0.1.0/24",
+ "asn_type":"business",
+ "Type": "Ipinfo_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.342 PM",
+ "asn":"AS206617",
+ "domain":"neomedia.it",
+ "name":"Neomedia S.r.l.",
+ "range":"1.0.2.0/24",
+ "route":"1.0.2.0/24",
+ "asn_type":"business",
+ "Type": "Ipinfo_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.343 PM",
+ "asn":"AS38803",
+ "domain":"gtelecom.com.au",
+ "name":"Wirefreebroadband Pty Ltd",
+ "range":"1.0.4.0/24",
+ "route":"1.0.4.0/22",
+ "asn_type":"isp",
+ "Type": "Ipinfo_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.344 PM",
+ "asn":"AS38803",
+ "domain":"gtelecom.com.au",
+ "name":"Wirefreebroadband Pty Ltd",
+ "range":"1.0.5.0/24",
+ "route":"1.0.5.0/24",
+ "asn_type":"isp",
+ "Type": "Ipinfo_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.345 PM",
+ "asn":"AS38803",
+ "domain":"gtelecom.com.au",
+ "name":"Wirefreebroadband Pty Ltd",
+ "range":"1.0.6.0/23",
+ "route":"1.0.4.0/22",
+ "asn_type":"isp",
+ "Type": "Ipinfo_ASN_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_Abuse_CL.json b/Sample Data/Custom/Ipinfo_Abuse_CL.json
new file mode 100644
index 00000000000..8e18da21046
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_Abuse_CL.json
@@ -0,0 +1,68 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "name":"ABUSE APNICRANDNETAU",
+ "email":"sanitized@sanitized.com",
+ "address":"PO Box 3646, South Brisbane, QLD 4101, Australia",
+ "country":"AU",
+ "phone":"+000000000",
+ "network":"1.0.0.0/24",
+ "range":"1.0.0.0/24",
+ "Type": "Ipinfo_Abuse_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.341 PM",
+ "address":"No.31 ,jingrong street,beijing, 100032",
+ "country":"CN",
+ "email":"sanitized@sanitized.com",
+ "name":"ABUSE CHINANETCN",
+ "network":"1.0.1.0/24",
+ "phone":"+000000000",
+ "range":"1.0.1.0/24",
+ "Type": "Ipinfo_Abuse_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.342 PM",
+ "address":"No.31 ,jingrong street,beijing, 100032",
+ "country":"CN",
+ "email":"sanitized@sanitized.com",
+ "name":"ABUSE CHINANETCN",
+ "network":"1.0.2.0/23",
+ "phone":"+000000000",
+ "range":"1.0.2.0/23",
+ "Type": "Ipinfo_Abuse_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.343 PM",
+ "address":"1/18 Deblin drive, Narre warren, vic 3805, Melbourne victoria 3805",
+ "country":"AU",
+ "email":"sanitized@sanitized.com",
+ "name":"ABUSE WPLAU",
+ "network":"1.0.4.0/24",
+ "phone":"+000000000",
+ "range":"1.0.4.0/24",
+ "Type": "Ipinfo_Abuse_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.344 PM",
+ "address":"1/18 Deblin drive, Narre warren, vic 3805, Melbourne victoria 3805",
+ "country":"AU",
+ "email":"sanitized@sanitized.com",
+ "name":"ABUSE WPLAU",
+ "network":"1.0.5.0/24",
+ "phone":"+000000000",
+ "range":"1.0.5.0/24",
+ "Type": "Ipinfo_Abuse_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.345 PM",
+ "address":"1/18 Deblin drive, Narre warren, vic 3805, Melbourne victoria 3805",
+ "country":"AU",
+ "email":"sanitized@sanitized.com",
+ "name":"ABUSE WPLAU",
+ "network":"1.0.6.0/24",
+ "phone":"+000000000",
+ "range":"1.0.6.0/24",
+ "Type": "Ipinfo_Abuse_CL"
+ }
+]
diff --git a/Sample Data/Custom/Ipinfo_Carrier_CL.json b/Sample Data/Custom/Ipinfo_Carrier_CL.json
new file mode 100644
index 00000000000..0ac663759b3
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_Carrier_CL.json
@@ -0,0 +1,62 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "carrier":"dtac-T",
+ "cc":"TH",
+ "mcc":"520",
+ "mnc":"47",
+ "network":"1.0.178.0-1.0.178.255",
+ "range":"1.0.178.0/24",
+ "Type": "Ipinfo_Carrier_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.341 PM",
+ "carrier":"NTT docomo",
+ "cc":"JP",
+ "mcc":"440",
+ "mnc":"10",
+ "network":"1.1.125.0-1.1.125.255",
+ "range":"1.1.125.0/24",
+ "Type": "Ipinfo_Carrier_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.342 PM",
+ "carrier":"dtac-T",
+ "cc":"TH",
+ "mcc":"520",
+ "mnc":"47",
+ "network":"1.1.240.0-1.1.240.255",
+ "range":"1.1.240.0/24",
+ "Type": "Ipinfo_Carrier_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.343 PM",
+ "carrier":"AIS",
+ "cc":"TH",
+ "mcc":"520",
+ "mnc":"01",
+ "network":"1.2.164.0-1.2.164.255",
+ "range":"1.2.164.0/24",
+ "Type": "Ipinfo_Carrier_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.344 PM",
+ "carrier":"AIS",
+ "cc":"TH",
+ "mcc":"520",
+ "mnc":"01",
+ "network":"1.2.177.0-1.2.177.255",
+ "range":"1.2.177.0/24",
+ "Type": "Ipinfo_Carrier_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.345 PM",
+ "carrier":"dtac-T",
+ "cc":"TH",
+ "mcc":"520",
+ "mnc":"47",
+ "network":"1.2.238.0-1.2.238.255",
+ "range":"1.2.238.0/24",
+ "Type": "Ipinfo_Carrier_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_Country_CL.json b/Sample Data/Custom/Ipinfo_Country_CL.json
new file mode 100644
index 00000000000..ff8c0615829
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_Country_CL.json
@@ -0,0 +1,73 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:07:33.199 PM",
+ "as_domain":"cloudflare.com",
+ "as_name":"Cloudflare, Inc.",
+ "asn":"AS13335",
+ "continent":"OC",
+ "continent_name":"Oceania",
+ "country":"AU",
+ "country_name":"Australia",
+ "ip_range":"1.0.0.0/25",
+ "Type": "Ipinfo_Country_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:07:33.199 PM",
+ "as_domain":"cloudflare.com",
+ "as_name":"Cloudflare, Inc.",
+ "asn":"AS13335","continent":"OC",
+ "continent_name":"Oceania",
+ "country":"AU",
+ "country_name":"Australia",
+ "ip_range":"1.0.0.128/26",
+ "Type": "Ipinfo_Country_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:07:33.199 PM",
+ "as_domain":"cloudflare.com",
+ "as_name":"Cloudflare, Inc.",
+ "asn":"AS13335",
+ "continent":"OC",
+ "continent_name":"Oceania",
+ "country":"AU",
+ "country_name":"Australia",
+ "ip_range":"1.0.0.192/27",
+ "Type": "Ipinfo_Country_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:07:33.199 PM",
+ "as_domain":"cloudflare.com",
+ "as_name":"Cloudflare, Inc.",
+ "asn":"AS13335",
+ "continent":"OC",
+ "continent_name":"Oceania",
+ "country":"AU",
+ "country_name":"Australia",
+ "ip_range":"1.0.0.224/28",
+ "Type": "Ipinfo_Country_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:07:33.199 PM",
+ "as_domain":"cloudflare.com",
+ "as_name":"Cloudflare, Inc.",
+ "asn":"AS13335",
+ "continent":"OC",
+ "continent_name":"Oceania",
+ "country":"AU",
+ "country_name":"Australia",
+ "ip_range":"1.0.0.240/29",
+ "Type": "Ipinfo_Country_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:07:33.199 PM",
+ "as_domain":"cloudflare.com",
+ "as_name":"Cloudflare, Inc.",
+ "asn":"AS13335",
+ "continent":"OC",
+ "continent_name":"Oceania",
+ "country":"AU",
+ "country_name":"Australia",
+ "ip_range":"1.0.0.248/30",
+ "Type": "Ipinfo_Country_CL"
+ }
+]
diff --git a/Sample Data/Custom/Ipinfo_Domain_CL.json b/Sample Data/Custom/Ipinfo_Domain_CL.json
new file mode 100644
index 00000000000..63b49305cd3
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_Domain_CL.json
@@ -0,0 +1,44 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "domains":"xn--uhr444azd877g.cn,xn--ugr712atyak08d.cn",
+ "range":"1.0.0.4/32",
+ "total":"2",
+ "Type": "Ipinfo_Domain_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.341 PM",
+ "domains":"zfdnf.com,xn--ugr712atyak08d.cn,xn--uhr444azd877g.cn",
+ "range":"1.0.0.5/32",
+ "total":"3",
+ "Type": "Ipinfo_Domain_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.342 PM",
+ "domains":"xn--uhr444azd877g.cn,xn--ugr712atyak08d.cn",
+ "range":"1.0.0.6/32",
+ "total":"2",
+ "Type": "Ipinfo_Domain_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.343 PM",
+ "domains":"xn--uhr444azd877g.cn,xn--ugr712atyak08d.cn,tcm-database.cf",
+ "range":"1.0.0.7/32",
+ "total":"3",
+ "Type": "Ipinfo_Domain_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.344 PM",
+ "domains":"xn--uhr444azd877g.cn,dimeji.com,xn--ugr712atyak08d.cn",
+ "range":"1.0.0.8/32",
+ "total":"3",
+ "Type": "Ipinfo_Domain_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.345 PM",
+ "domains":"xn--ugr712atyak08d.cn,xn--uhr444azd877g.cn",
+ "range":"1.0.0.9/32",
+ "total":"2",
+ "Type": "Ipinfo_Domain_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_Location_extended_CL.json b/Sample Data/Custom/Ipinfo_Location_extended_CL.json
new file mode 100644
index 00000000000..9095ee0bb0c
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_Location_extended_CL.json
@@ -0,0 +1,98 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "city":"Parepare",
+ "country":"ID",
+ "country_name":"Indonesia",
+ "geoname_id":"1632353",
+ "latitude":"-4.0135",
+ "longitude":"119.6255",
+ "postal_code":"",
+ "radius":"20",
+ "range":"1.0.0.255/32",
+ "region":"SN",
+ "region_name":"South Sulawesi",
+ "timezone":"Asia/Makassar",
+ "Type": "Ipinfo_Location_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.341 PM",
+ "city":"Xiamen",
+ "country":"CN",
+ "country_name":"China",
+ "geoname_id":"1790645",
+ "latitude":"24.47979",
+ "longitude":"118.08187",
+ "postal_code":"",
+ "radius":"1000",
+ "range":"1.0.1.0/24",
+ "region":"FJ",
+ "region_name":"Fujian",
+ "timezone":"Asia/Shanghai",
+ "Type": "Ipinfo_Location_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.342 PM",
+ "city":"Xiamen",
+ "country":"CN",
+ "country_name":"China",
+ "geoname_id":"1790645",
+ "latitude":"24.47979",
+ "longitude":"118.08187",
+ "postal_code":"",
+ "radius":"1000",
+ "range":"1.0.2.0/23",
+ "region":"FJ",
+ "region_name":"Fujian",
+ "timezone":"Asia/Shanghai",
+ "Type": "Ipinfo_Location_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.343 PM",
+ "city":"Frankston East",
+ "country":"AU",
+ "country_name":"Australia",
+ "geoname_id":"2166143",
+ "latitude":"-38.03357",
+ "longitude":"145.305",
+ "postal_code":"3805",
+ "radius":"1000",
+ "range":"1.0.4.0/22",
+ "region":"VIC",
+ "region_name":"Victoria",
+ "timezone":"Australia/Melbourne",
+ "Type": "Ipinfo_Location_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.344 PM",
+ "city":"Shenzhen",
+ "country":"CN",
+ "country_name":"China",
+ "geoname_id":"1795565",
+ "latitude":"22.54554",
+ "longitude":"114.0683",
+ "postal_code":"",
+ "radius":"1000",
+ "range":"1.0.8.0/21",
+ "region":"GD",
+ "region_name":"Guangdong",
+ "timezone":"Asia/Shanghai",
+ "Type": "Ipinfo_Location_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.345 PM",
+ "city":"Tokyo",
+ "country":"JP",
+ "country_name":"Japan",
+ "geoname_id":"1850147",
+ "latitude":"35.6895",
+ "longitude":"139.69171",
+ "postal_code":"101-8656",
+ "radius":"5000",
+ "range":"1.0.16.0/29",
+ "region":"13",
+ "region_name":"Tokyo",
+ "timezone":"Asia/Tokyo",
+ "Type": "Ipinfo_Location_extended_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_Privacy_extended_CL.json b/Sample Data/Custom/Ipinfo_Privacy_extended_CL.json
new file mode 100644
index 00000000000..07653a5a34b
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_Privacy_extended_CL.json
@@ -0,0 +1,110 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "anycast":"true",
+ "census":"false",
+ "census_port":"",
+ "device_activity":"true",
+ "hosting":"true",
+ "network":"1.0.0.0-1.0.0.0",
+ "proxy":"",
+ "range":"1.0.0.0/32",
+ "relay":"",
+ "tor":"",
+ "vpn":"",
+ "vpn_config":"false",
+ "vpn_name":"",
+ "whois":"false",
+ "Type": "Ipinfo_Privacy_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.341 PM",
+ "anycast":"true",
+ "census":"true",
+ "census_port":"500",
+ "device_activity":"true",
+ "hosting":"true",
+ "network":"1.0.0.1-1.0.0.2",
+ "proxy":"",
+ "range":"1.0.0.1/32",
+ "relay":"",
+ "tor":"",
+ "vpn":"true",
+ "vpn_config":"false",
+ "vpn_name":"",
+ "whois":"false",
+ "Type": "Ipinfo_Privacy_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.342 PM",
+ "anycast":"true",
+ "census":"true",
+ "census_port":"500",
+ "device_activity":"true",
+ "hosting":"true",
+ "network":"1.0.0.1-1.0.0.2",
+ "proxy":"",
+ "range":"1.0.0.2/32",
+ "relay":"",
+ "tor":"",
+ "vpn":"true",
+ "vpn_config":"false",
+ "vpn_name":"",
+ "whois":"false",
+ "Type": "Ipinfo_Privacy_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.343 PM",
+ "anycast":"true",
+ "census":"false",
+ "census_port":"",
+ "device_activity":"true",
+ "hosting":"true",
+ "network":"1.0.0.3-1.0.0.255",
+ "proxy":"",
+ "range":"1.0.0.3/32",
+ "relay":"",
+ "tor":"",
+ "vpn":"",
+ "vpn_config":"false",
+ "vpn_name":"",
+ "whois":"false",
+ "Type": "Ipinfo_Privacy_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.344 PM",
+ "anycast":"true",
+ "census":"false",
+ "census_port":"",
+ "device_activity":"true",
+ "hosting":"true",
+ "network":"1.0.0.3-1.0.0.255",
+ "proxy":"",
+ "range":"1.0.0.4/30",
+ "relay":"",
+ "tor":"",
+ "vpn":"",
+ "vpn_config":"false",
+ "vpn_name":"",
+ "whois":"false",
+ "Type": "Ipinfo_Privacy_extended_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.345 PM",
+ "anycast":"true",
+ "census":"false",
+ "census_port":"",
+ "device_activity":"true",
+ "hosting":"true",
+ "network":"1.0.0.3-1.0.0.255",
+ "proxy":"",
+ "range":"1.0.0.8/29",
+ "relay":"",
+ "tor":"",
+ "vpn":"",
+ "vpn_config":"false",
+ "vpn_name":"",
+ "whois":"false",
+ "Type": "Ipinfo_Privacy_extended_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_RIRWHOIS_CL.json b/Sample Data/Custom/Ipinfo_RIRWHOIS_CL.json
new file mode 100644
index 00000000000..0bb34a2cef3
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_RIRWHOIS_CL.json
@@ -0,0 +1,146 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "177.101.205.240/30",
+ "whois_id": "PAC154",
+ "name": "THIAGO GARCIA CARO FORNECEDOR DE ACESSO A INTERNET",
+ "country": "BR",
+ "status": "REALLOCATED",
+ "tech": "GLBRA31",
+ "maintainer": "",
+ "admin": "",
+ "source": "lacnic",
+ "whois_domain": "vogeltelecom.com",
+ "updated": "2019-08-23",
+ "org": "",
+ "rdns_domain": "",
+ "domain": "vogeltelecom.com",
+ "geoloc": "",
+ "org_address": "",
+ "asn": "AS25933",
+ "as_name": "Vogel Solu\u00e7\u00f5es em Telecom e Inform\u00e1tica S/A",
+ "as_domain": "vogeltelecom.com",
+ "as_type": "isp",
+ "Type": "Ipinfo_RIRWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "141.95.214.108/30",
+ "whois_id": "OVH_408693513",
+ "name": "OVH HOSTING OY",
+ "country": "FI",
+ "status": "ASSIGNED PA",
+ "tech": "OTC15-RIPE",
+ "maintainer": "OVH-MNT",
+ "admin": "OTC15-RIPE",
+ "source": "ripe",
+ "whois_domain": "ovh.net",
+ "updated": "2022-03-14",
+ "org": "ORG-OH6-RIPE",
+ "rdns_domain": "",
+ "domain": "ovh.net",
+ "geoloc": "",
+ "org_address": "Malminkatu 28\\n00100 Helsinki\\nFinland",
+ "asn": "AS16276",
+ "as_name": "OVH SAS",
+ "as_domain": "ovhcloud.com",
+ "as_type": "hosting",
+ "Type": "Ipinfo_RIRWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "31.147.223.128/29",
+ "whois_id": "CARNET-XVIIIGIMZG",
+ "name": "XVIII. GIMNAZIJA ZAGREB",
+ "country": "HR",
+ "status": "ASSIGNED PA",
+ "tech": "CIA22-RIPE",
+ "maintainer": "RIPE-NCC-HM-MNT\\NAS2108-MNT",
+ "admin": "CIA22-RIPE",
+ "source": "ripe",
+ "whois_domain": "carnet.hr",
+ "updated": "2021-03-11",
+ "org": "ORG-CAAR1-RIPE",
+ "rdns_domain": "",
+ "domain": "carnet.hr",
+ "geoloc": "",
+ "org_address": "Josipa Marohnica 5\\n10000\\nZagreb\\nCROATIA",
+ "asn": "AS2108",
+ "as_name": "Croatian Academic and Research Network",
+ "as_domain": "carnet.hr",
+ "as_type": "education",
+ "Type": "Ipinfo_RIRWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "79.187.91.160/30",
+ "whois_id": "CUSTOMER-IDSL-207981",
+ "name": "static IP",
+ "country": "PL",
+ "status": "ASSIGNED PA",
+ "tech": "TPHT",
+ "maintainer": "RIPE-NCC-HM-MNT\\NTPNET",
+ "admin": "TPHT",
+ "source": "ripe",
+ "whois_domain": "tpnet.pl",
+ "updated": "2010-09-25",
+ "org": "ORG-PT1-RIPE",
+ "rdns_domain": "",
+ "domain": "tpnet.pl",
+ "geoloc": "",
+ "org_address": "Al. Jerozolimskie 160\\n02-326\\nWarszawa\\nPOLAND",
+ "asn": "AS5617",
+ "as_name": "Orange Polska Spolka Akcyjna",
+ "as_domain": "orange.pl",
+ "as_type": "isp",
+ "Type": "Ipinfo_RIRWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "77.60.231.232/29",
+ "whois_id": "OTS136779",
+ "name": "Blok Textiel",
+ "country": "NL",
+ "status": "ASSIGNED PA",
+ "tech": "BB3481-RIPE",
+ "maintainer": "RIPE-NCC-HM-MNT\\NKPN-MNT",
+ "admin": "BB3481-RIPE",
+ "source": "ripe",
+ "whois_domain": "wxs.nl",
+ "updated": "2007-04-20",
+ "org": "ORG-KOVN1-RIPE",
+ "rdns_domain": "",
+ "domain": "wxs.nl",
+ "geoloc": "",
+ "org_address": "Wilhelminakade 123\\n3072AP\\nRotterdam\\nNETHERLANDS",
+ "asn": "AS1136",
+ "as_name": "KPN B.V.",
+ "as_domain": "idstrategy.com.ua",
+ "as_type": "isp",
+ "Type": "Ipinfo_RIRWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "209.121.11.128/26",
+ "whois_id": "TELUS-HSIA-PTCMBC2",
+ "name": "TELUS-HSIA-PTCMBC02",
+ "country": "CA",
+ "status": "REASSIGNMENT",
+ "tech": "",
+ "maintainer": "",
+ "admin": "",
+ "source": "arin",
+ "whois_domain": "",
+ "updated": "2021-10-20",
+ "org": "C08072763",
+ "rdns_domain": "telus.net",
+ "domain": "telus.net",
+ "geoloc": "",
+ "org_address": "2990 Gordon Ave, Port Coquitlam, BC, CA",
+ "asn": "AS852",
+ "as_name": "TELUS Communications Inc.",
+ "as_domain": "telus.com",
+ "as_type": "isp",
+ "Type": "Ipinfo_RIRWHOIS_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_RWHOIS_CL.json b/Sample Data/Custom/Ipinfo_RWHOIS_CL.json
new file mode 100644
index 00000000000..88d2fd76a6e
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_RWHOIS_CL.json
@@ -0,0 +1,110 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "172.17.68.238",
+ "whois_id": "NET-154835.172.17.68.238",
+ "name": "Web-hosting.com",
+ "whois_desc": "NC-PH-3045 (IPMI)",
+ "host": "whois.namecheaphosting.com:4321",
+ "country": "US",
+ "email": "sanitized@sanitized.com",
+ "abuse": "",
+ "domain": "",
+ "city": "Phoenix",
+ "street": "3402 East University Drive",
+ "postal": "85034",
+ "updated": "2020-12-24",
+ "imported": "2024-08-01",
+ "Type": "Ipinfo_RWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "50.120.213.8/30",
+ "whois_id": "NET-50-120-213-8-30",
+ "name": "Wyalusing Hotel",
+ "whois_desc": "50-120-213-8-30",
+ "host": "rwhois.frontiernet.net:4321",
+ "country": "US",
+ "email": "sanitized@sanitized.com",
+ "abuse": "",
+ "domain": "wyalusinghotel.com",
+ "city": "Wyalusing",
+ "street": "54 Main Street",
+ "postal": "18853",
+ "updated": "2012-05-16",
+ "imported": "2024-07-24",
+ "Type": "Ipinfo_RWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "208.72.23.225",
+ "whois_id": "WEBLINE4 208.72.20.0/22",
+ "name": "Justin Apperson",
+ "whois_desc": "Justin Apperson-208.72.23.225",
+ "host": "rwhois.webline-services.com:4321",
+ "country": "",
+ "email": "sanitized@sanitized.com",
+ "abuse": "",
+ "domain": "",
+ "city": "",
+ "street": "8535 Baymeadows Rd",
+ "postal": "",
+ "updated": "2017-03-15",
+ "imported": "2024-08-01",
+ "Type": "Ipinfo_RWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "206.130.64.200/29",
+ "whois_id": "NETBLK-VIANET.206.130.64.0/24",
+ "name": "Vianet Internet Solutions",
+ "whois_desc": "VIANET-206.130.64.200/29",
+ "host": "rwhois.vianet.ca:4321",
+ "country": "CA",
+ "email": "sanitized@sanitized.com",
+ "abuse": "",
+ "domain": "vianet.ca",
+ "city": "Sudbury",
+ "street": "128 Larch St.",
+ "postal": "P3E 5J8",
+ "updated": "2012-01-11",
+ "imported": "2024-08-01",
+ "Type": "Ipinfo_RWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "67.223.118.149",
+ "whois_id": "NET-227820.67.223.118.149",
+ "name": "Web-hosting.com",
+ "whois_desc": "premium100.web-hosting.com",
+ "host": "whois.namecheaphosting.com:4321",
+ "country": "US",
+ "email": "sanitized@sanitized.com",
+ "abuse": "",
+ "domain": "",
+ "city": "Phoenix",
+ "street": "3402 East University Drive",
+ "postal": "85034",
+ "updated": "2022-04-17",
+ "imported": "2024-08-01",
+ "Type": "Ipinfo_RWHOIS_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "108.179.233.202",
+ "whois_id": "NETBLK-BO.108.179.233.202/32",
+ "name": "structuresgo3d.com",
+ "whois_desc": "BO-108.179.233.202/32",
+ "host": "rwhois.websitewelcome.com:4321",
+ "country": "US",
+ "email": "sanitized@sanitized.com",
+ "abuse": "",
+ "domain": "",
+ "city": "",
+ "street": "",
+ "postal": "",
+ "updated": "2013-07-17",
+ "imported": "2024-08-01",
+ "Type": "Ipinfo_RWHOIS_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_WHOIS_ASN_CL.json b/Sample Data/Custom/Ipinfo_WHOIS_ASN_CL.json
new file mode 100644
index 00000000000..ba625c1af10
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_WHOIS_ASN_CL.json
@@ -0,0 +1,68 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AS133315",
+ "name": "Icontechnext",
+ "country": "IN",
+ "org_id": "",
+ "created": "",
+ "updated": "2017-03-06",
+ "source": "apnic",
+ "Type": "Ipinfo_WHOIS_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AS60413",
+ "name": "Innovative solutions Ltd.",
+ "country": "RU",
+ "org_id": "ORG-ISL54-RIPE",
+ "created": "2013-07-23",
+ "updated": "2019-06-05",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AS61670",
+ "name": "New Net Informatica e Telecomunica\u00e7\u00f5es",
+ "country": "BR",
+ "org_id": "",
+ "created": "2014-09-03",
+ "updated": "2016-08-24",
+ "source": "lacnic",
+ "Type": "Ipinfo_WHOIS_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AS209758",
+ "name": "CryptoCentre LLC",
+ "country": "RU",
+ "org_id": "ORG-CL530-RIPE",
+ "created": "2018-12-10",
+ "updated": "2021-05-19",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AS141236",
+ "name": "Mandalay City Development Committee",
+ "country": "MM",
+ "org_id": "",
+ "created": "2020-10-06",
+ "updated": "2020-10-06",
+ "source": "apnic",
+ "Type": "Ipinfo_WHOIS_ASN_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AS205501",
+ "name": "Telus Comunicaciones S.L.",
+ "country": "ES",
+ "org_id": "ORG-TCS31-RIPE",
+ "created": "2017-08-03",
+ "updated": "2018-09-04",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_ASN_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_WHOIS_MNT_CL.json b/Sample Data/Custom/Ipinfo_WHOIS_MNT_CL.json
new file mode 100644
index 00000000000..f022a4aaa0d
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_WHOIS_MNT_CL.json
@@ -0,0 +1,74 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "LIR-RU-REDBYTES-1-MNT",
+ "name": "",
+ "admin_id": "DUMY-RIPE",
+ "tech_id": "",
+ "org_id": "",
+ "created": "2022-02-16",
+ "updated": "2023-02-21",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_MNT_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "LIR-RS-RTS-SERBIA-1-MNT",
+ "name": "",
+ "admin_id": "DUMY-RIPE",
+ "tech_id": "",
+ "org_id": "",
+ "created": "2021-04-19",
+ "updated": "2021-04-19",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_MNT_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "IR-FOURSE-1-MNT",
+ "name": "Startup maintainer",
+ "admin_id": "TS36964-RIPE",
+ "tech_id": "TS36964-RIPE",
+ "org_id": "",
+ "created": "2016-01-26",
+ "updated": "2016-01-31",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_MNT_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "DE-KIS2-1-MNT",
+ "name": "Startup maintainer",
+ "admin_id": "WK2587-RIPE",
+ "tech_id": "WK2587-RIPE",
+ "org_id": "",
+ "created": "2018-06-08",
+ "updated": "2018-06-08",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_MNT_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "MNT-DK-IT-FORSYNINGEN-1",
+ "name": "Startup maintainer",
+ "admin_id": "AD14826-RIPE",
+ "tech_id": "AD14826-RIPE",
+ "org_id": "",
+ "created": "2018-11-09",
+ "updated": "2018-11-09",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_MNT_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "GENERATED-FXRUAVLTJUMFE2GLJSHZB7C9FLFCVYHX-MNT",
+ "name": "Auto-generated maintainer",
+ "admin_id": "AGMT2310-AFRINIC",
+ "tech_id": "",
+ "org_id": "",
+ "created": "",
+ "updated": "",
+ "source": "afrinic",
+ "Type": "Ipinfo_WHOIS_MNT_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_WHOIS_NET_CL.json b/Sample Data/Custom/Ipinfo_WHOIS_NET_CL.json
new file mode 100644
index 00000000000..b985b576836
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_WHOIS_NET_CL.json
@@ -0,0 +1,110 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "195.99.253.56/29",
+ "whois_id": "BTNET-CUSTOMER",
+ "name": "FTIP003328088 IP MASTER",
+ "country": "GB",
+ "domain": "bt.net",
+ "org_id": "ORG-BPIS1-RIPE",
+ "status": "ASSIGNED PA",
+ "tech_id": "BY73-RIPE",
+ "mnt_id": "BTNET-MNT",
+ "admin_id": "BY73-RIPE",
+ "abuse_id": "AR13878-RIPE",
+ "created": "2013-11-11",
+ "updated": "2023-12-15",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_NET_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "76.202.106.56/29",
+ "whois_id": "SBC-76-202-106-56-29-0704022956",
+ "name": "JEFFERSON BANK TRUST-070402182948",
+ "country": "US",
+ "domain": "",
+ "org_id": "C01608463",
+ "status": "REASSIGNMENT",
+ "tech_id": "",
+ "mnt_id": "",
+ "admin_id": "",
+ "abuse_id": "",
+ "created": "2007-04-02",
+ "updated": "2018-01-10",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_NET_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "201.144.11.0/24",
+ "whois_id": "DCA",
+ "name": "Gesti\u00f3n de direccionamiento UniNet",
+ "country": "MX",
+ "domain": "uninet.net.mx",
+ "org_id": "",
+ "status": "REASSIGNED",
+ "tech_id": "DCA",
+ "mnt_id": "",
+ "admin_id": "",
+ "abuse_id": "SRU",
+ "created": "2007-09-15",
+ "updated": "2012-09-01",
+ "source": "lacnic",
+ "Type": "Ipinfo_WHOIS_NET_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "62.207.162.64/29",
+ "whois_id": "OTS582089",
+ "name": "Zeeuws Landgoed",
+ "country": "NL",
+ "domain": "zeeuwslandgoed.nl",
+ "org_id": "ORG-KOVN1-RIPE",
+ "status": "ASSIGNED PA",
+ "tech_id": "AVO78-RIPE",
+ "mnt_id": "AS286-MNT",
+ "admin_id": "AVO78-RIPE",
+ "abuse_id": "KPN-RIPE",
+ "created": "2011-12-14",
+ "updated": "2011-12-14",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_NET_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "173.166.203.128/29",
+ "whois_id": "HILTONGARDENINN",
+ "name": "HILTON GARDEN INN",
+ "country": "US",
+ "domain": "hilton.com",
+ "org_id": "C04858711",
+ "status": "REASSIGNMENT",
+ "tech_id": "",
+ "mnt_id": "",
+ "admin_id": "",
+ "abuse_id": "",
+ "created": "2014-01-24",
+ "updated": "2014-01-24",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_NET_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "range": "83.13.228.104/30",
+ "whois_id": "CUSTOMER-IDSL-143791",
+ "name": "static IP",
+ "country": "PL",
+ "domain": "tpnet.pl",
+ "org_id": "ORG-PT1-RIPE",
+ "status": "ASSIGNED PA",
+ "tech_id": "TPHT",
+ "mnt_id": "TPNET",
+ "admin_id": "TPHT",
+ "abuse_id": "OPHT",
+ "created": "2010-09-25",
+ "updated": "2010-09-25",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_NET_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_WHOIS_ORG_CL.json b/Sample Data/Custom/Ipinfo_WHOIS_ORG_CL.json
new file mode 100644
index 00000000000..c3fc8a36e36
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_WHOIS_ORG_CL.json
@@ -0,0 +1,128 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "C06122127",
+ "name": "TWINING",
+ "address": "",
+ "street": "1572 SANTA ANA AVE\\nFL 1st",
+ "city": "SACRAMENTO",
+ "state": "CA",
+ "postalcode": "95838",
+ "country": "US",
+ "admin_id": "",
+ "tech_id": "",
+ "abuse_id": "",
+ "mnt_id": "",
+ "email": "sanitized@sanitized.com",
+ "domain": "",
+ "created": "2016-05-10",
+ "updated": "2016-05-10",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_ORG_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "C08143236",
+ "name": "KIMBERLY CLARK",
+ "address": "",
+ "street": "58 PICKETT DISTRICT RD",
+ "city": "NEW MILFORD",
+ "state": "CT",
+ "postalcode": "06776",
+ "country": "US",
+ "admin_id": "",
+ "tech_id": "",
+ "abuse_id": "",
+ "mnt_id": "",
+ "email": "sanitized@sanitized.com",
+ "domain": "kimberly-clark.com",
+ "created": "2021-12-22",
+ "updated": "2021-12-22",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_ORG_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "C02003329",
+ "name": "1 Up Software",
+ "address": "",
+ "street": "701 Congressional Boulevard\\nSuite 100",
+ "city": "Carmel",
+ "state": "IN",
+ "postalcode": "46032",
+ "country": "US",
+ "admin_id": "",
+ "tech_id": "",
+ "abuse_id": "",
+ "mnt_id": "",
+ "email": "sanitized@sanitized.com",
+ "domain": "",
+ "created": "2008-07-31",
+ "updated": "2011-03-19",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_ORG_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "C07074935",
+ "name": "Private Customer - AT&T Internet Services",
+ "address": "",
+ "street": "Private Residence",
+ "city": "Richardson",
+ "state": "TX",
+ "postalcode": "75082",
+ "country": "US",
+ "admin_id": "",
+ "tech_id": "",
+ "abuse_id": "",
+ "mnt_id": "",
+ "email": "sanitized@sanitized.com",
+ "domain": "",
+ "created": "2018-10-03",
+ "updated": "2018-10-03",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_ORG_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "HSS-116",
+ "name": "HostFlyte Server Solutions",
+ "address": "",
+ "street": "PO Box 32",
+ "city": "Dingwall",
+ "state": "NS",
+ "postalcode": "B0C 1G0",
+ "country": "CA",
+ "admin_id": "ADMIN6928-ARIN",
+ "tech_id": "ADMIN6928-ARIN",
+ "abuse_id": "ABUSE7319-ARIN",
+ "mnt_id": "ADMIN6928-ARIN",
+ "email": "sanitized@sanitized.com",
+ "domain": "hostflyte.com",
+ "created": "2018-12-13",
+ "updated": "2019-05-30",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_ORG_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "C04673155",
+ "name": "Scott Kostler08162013121202551",
+ "address": "",
+ "street": "2701 N. Central Expwy",
+ "city": "Richardson",
+ "state": "TX",
+ "postalcode": "75080",
+ "country": "US",
+ "admin_id": "",
+ "tech_id": "",
+ "abuse_id": "",
+ "mnt_id": "",
+ "email": "sanitized@sanitized.com",
+ "domain": "",
+ "created": "2013-08-16",
+ "updated": "2018-07-19",
+ "source": "arin",
+ "Type": "Ipinfo_WHOIS_ORG_CL"
+ }
+]
\ No newline at end of file
diff --git a/Sample Data/Custom/Ipinfo_WHOIS_POC_CL.json b/Sample Data/Custom/Ipinfo_WHOIS_POC_CL.json
new file mode 100644
index 00000000000..799c114116c
--- /dev/null
+++ b/Sample Data/Custom/Ipinfo_WHOIS_POC_CL.json
@@ -0,0 +1,98 @@
+[
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "DD768-RIPE",
+ "name": "Domenico D'alessandro",
+ "mobilephone": "",
+ "officephone": "+39 040365722",
+ "fax": "+39 040365722",
+ "address": "NORDSPEDIZIONIERI DUE SRL\\nVIA MALASPINA 34\\n34100 TRIESTE\\nItaly",
+ "country": "IT",
+ "email": "sanitized@sanitized.com",
+ "abuse_email": "sanitized@sanitized.com",
+ "created": "2003-08-01",
+ "updated": "2020-06-03",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_POC_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "LC15352-RIPE",
+ "name": "Luc Chamourin",
+ "mobilephone": "",
+ "officephone": "+33 326540758",
+ "fax": "",
+ "address": "8 RUE DU PRE BREDA 51530 MARDEUIL FRA",
+ "country": "FR",
+ "email": "sanitized@sanitized.com",
+ "abuse_email": "sanitized@sanitized.com",
+ "created": "2022-03-21",
+ "updated": "2022-03-21",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_POC_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "FS5029-RIPE",
+ "name": "FEDERICA SABA",
+ "mobilephone": "",
+ "officephone": "+39356689950",
+ "fax": "+39356689950",
+ "address": "SABA FEDERICA\\nVIA DANIMARCA 14\\n09100 CAGLIARI\\nItaly",
+ "country": "IT",
+ "email": "sanitized@sanitized.com",
+ "abuse_email": "sanitized@sanitized.com",
+ "created": "2007-02-08",
+ "updated": "2020-06-03",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_POC_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "AN33089-RIPE",
+ "name": "ADRIANO NUZZO",
+ "mobilephone": "",
+ "officephone": "+39789598399",
+ "fax": "+39789598399",
+ "address": "A.L. SRL\\nVIA COREA 10\\n07026 OLBIA\\nItaly",
+ "country": "IT",
+ "email": "sanitized@sanitized.com",
+ "abuse_email": "sanitized@sanitized.com",
+ "created": "2023-01-09",
+ "updated": "2023-01-09",
+ "source": "ripe",
+ "Type": "Ipinfo_WHOIS_POC_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "CCMFR7",
+ "name": "Caio C\u00e9sar Martins Fraporti",
+ "mobilephone": "",
+ "officephone": "",
+ "fax": "",
+ "address": "",
+ "country": "",
+ "email": "sanitized@sanitized.com",
+ "abuse_email": "sanitized@sanitized.com",
+ "created": "2016-07-05",
+ "updated": "2016-07-05",
+ "source": "lacnic",
+ "Type": "Ipinfo_WHOIS_POC_CL"
+ },
+ {
+ "TimeGenerated": "4/30/2024, 4:01:17.340 PM",
+ "whois_id": "WYH19-TW",
+ "name": "Ming Her Wu",
+ "mobilephone": "",
+ "officephone": "",
+ "fax": "",
+ "address": "Jeng Sheng Lee\\nNo.91, Fu Shing Rd., Yunlin\\nYunlin Taiwan",
+ "country": "TW",
+ "email": "sanitized@sanitized.com",
+ "abuse_email": "sanitized@sanitized.com",
+ "created": "2001-08-07",
+ "updated": "2001-08-07",
+ "source": "twnic",
+ "Type": "Ipinfo_WHOIS_POC_CL"
+ }
+]
\ No newline at end of file
diff --git a/Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_DataConnectorDefination.json b/Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_DataConnectorDefinition.json
similarity index 100%
rename from Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_DataConnectorDefination.json
rename to Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_DataConnectorDefinition.json
diff --git a/Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_PollingConfig.json b/Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_PollingConfig.json
index 0642946194c..2cd6b05bafd 100644
--- a/Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_PollingConfig.json
+++ b/Solutions/Amazon Web Services/Data Connectors/AWS_WAF_CCP/AwsS3_WAF_PollingConfig.json
@@ -17,7 +17,7 @@
"dataCollectionEndpoint": "{{dataCollectionEndpoint}}",
"dataCollectionRuleImmutableId": "{{dataCollectionRuleImmutableId}}"
},
- "destinationTable": "",
+ "destinationTable": "AWSWAF",
"dataFormat": {
"Format": "Json",
"IsCompressed": true,
diff --git a/Solutions/Amazon Web Services/Data/Solution_AmazonWebServices.json b/Solutions/Amazon Web Services/Data/Solution_AmazonWebServices.json
index ca9e0746a88..2e0c3846bd1 100644
--- a/Solutions/Amazon Web Services/Data/Solution_AmazonWebServices.json
+++ b/Solutions/Amazon Web Services/Data/Solution_AmazonWebServices.json
@@ -6,7 +6,7 @@
"Data Connectors": [
"Data Connectors/template_AWS.JSON",
"Data Connectors/template_AwsS3.JSON",
- "Data Connectors/AWS_WAF_CCP/AwsS3_WAF_DataConnectorDefination.json"
+ "Data Connectors/AWS_WAF_CCP/AwsS3_WAF_DataConnectorDefinition.json"
],
"Workbooks": [
"Workbooks/AmazonWebServicesNetworkActivities.json",
@@ -110,7 +110,7 @@
"Hunting Queries/AWS_STStoLambda.yaml"
],
"BasePath": "C:\\One\\Azure\\Azure-Sentinel\\Solutions\\Amazon Web Services",
- "Version": "3.0.3",
+ "Version": "3.0.5",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"StaticDataConnectorIds": [
diff --git a/Solutions/Amazon Web Services/Package/3.0.5.zip b/Solutions/Amazon Web Services/Package/3.0.5.zip
new file mode 100644
index 00000000000..d0ce70213e4
Binary files /dev/null and b/Solutions/Amazon Web Services/Package/3.0.5.zip differ
diff --git a/Solutions/Amazon Web Services/Package/createUiDefinition.json b/Solutions/Amazon Web Services/Package/createUiDefinition.json
index 903cb374749..e84a0630745 100644
--- a/Solutions/Amazon Web Services/Package/createUiDefinition.json
+++ b/Solutions/Amazon Web Services/Package/createUiDefinition.json
@@ -64,7 +64,7 @@
}
},
{
- "name": "dataconnectors-link2",
+ "name": "dataconnectors-link3",
"type": "Microsoft.Common.TextBlock",
"options": {
"link": {
diff --git a/Solutions/Amazon Web Services/Package/mainTemplate.json b/Solutions/Amazon Web Services/Package/mainTemplate.json
index 853ec2d0ac8..e36f6f45ef1 100644
--- a/Solutions/Amazon Web Services/Package/mainTemplate.json
+++ b/Solutions/Amazon Web Services/Package/mainTemplate.json
@@ -61,7 +61,7 @@
},
"variables": {
"_solutionName": "Amazon Web Services",
- "_solutionVersion": "3.0.4",
+ "_solutionVersion": "3.0.5",
"solutionId": "azuresentinel.azure-sentinel-solution-amazonwebservices",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "AWS",
@@ -693,7 +693,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Amazon Web Services data connector with template version 3.0.4",
+ "description": "Amazon Web Services data connector with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -850,7 +850,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Amazon Web Services data connector with template version 3.0.4",
+ "description": "Amazon Web Services data connector with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion2')]",
@@ -862,13 +862,14 @@
"apiVersion": "2021-03-01-preview",
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
"location": "[parameters('workspace-location')]",
- "kind": "StaticUI",
+ "kind": "GenericUI",
"properties": {
"connectorUiConfig": {
"id": "[variables('_uiConfigId2')]",
"title": "Amazon Web Services S3",
"publisher": "Amazon",
"descriptionMarkdown": "This connector allows you to ingest AWS service logs, collected in AWS S3 buckets, to Microsoft Sentinel. The currently supported data types are: \n* AWS CloudTrail\n* VPC Flow Logs\n* AWS GuardDuty\n* AWSCloudWatch\n\nFor more information, see the [Microsoft Sentinel documentation](https://go.microsoft.com/fwlink/p/?linkid=2218883&wt.mc_id=sentinel_dataconnectordocs_content_cnl_csasci).",
+ "logo": "Aws.svg",
"graphQueries": [
{
"metricName": "Total data received",
@@ -930,6 +931,98 @@
"name": "AWSCloudWatch",
"lastDataReceivedQuery": "AWSCloudWatch\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
}
+ ],
+ "availability": {
+ "status": 2,
+ "featureFlag": {
+ "feature": "AWSS3Connector",
+ "featureStates": {
+ "Dogfood": "GA",
+ "MPAC": "GA",
+ "Prod": "GA",
+ "Fairfax": "GA",
+ "Mooncake": "PrivatePreview",
+ "USSec": "PrivatePreview",
+ "USNat": "PrivatePreview"
+ }
+ },
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "write permission.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "delete": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Environment",
+ "description": "you must have the following AWS resources defined and configured: S3, Simple Queue Service (SQS), IAM roles and permissions policies, and the AWS services whose logs you want to collect."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": "There are two options for setting up your AWS environment to send logs from an S3 bucket to your Log Analytics Workspace:",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Setup with PowerShell script (recommended)",
+ "instructions": [
+ {
+ "parameters": {
+ "govScript": "Download and extract the files from the following link: [AWS S3 Setup Script](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/AWS-S3/ConfigAwsS3DataConnectorScriptsGov.zip).\n\n> 1. Make sure that you have PowerShell on your machine: [Installation instructions for PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-7.2).\n\n> 2. Make sure that you have the AWS CLI on your machine: [Installation instructions for the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html).\n\nBefore running the script, run the aws configure command from your PowerShell command line, and enter the relevant information as prompted. See [AWS Command Line Interface | Configuration basics](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) for details.",
+ "prodScript": "Download and extract the files from the following link: [AWS S3 Setup Script](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/AWS-S3/ConfigAwsS3DataConnectorScripts.zip).\n\n> 1. Make sure that you have PowerShell on your machine: [Installation instructions for PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-7.2).\n\n> 2. Make sure that you have the AWS CLI on your machine: [Installation instructions for the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html).\n\nBefore running the script, run the aws configure command from your PowerShell command line, and enter the relevant information as prompted. See [AWS Command Line Interface | Configuration basics](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) for details."
+ },
+ "type": "MarkdownControlEnvBased"
+ },
+ {
+ "parameters": {
+ "label": "Run script to set up the environment",
+ "value": "./ConfigAwsConnector.ps1"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "fillWith": [
+ "WorkspaceId"
+ ],
+ "label": "External ID (Workspace ID)"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ },
+ {
+ "title": "Manual Setup",
+ "description": "Follow the instruction in the following link to set up the environment: [Connect AWS S3 to Microsoft Sentinel](https://aka.ms/AWSS3Connector)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Set up your AWS environment"
+ },
+ {
+ "instructions": [
+ {
+ "parameters": {},
+ "type": "AwsS3"
+ }
+ ],
+ "title": "2. Add connection"
+ }
]
}
}
@@ -1008,7 +1101,7 @@
"apiVersion": "2021-03-01-preview",
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
"location": "[parameters('workspace-location')]",
- "kind": "StaticUI",
+ "kind": "GenericUI",
"properties": {
"connectorUiConfig": {
"title": "Amazon Web Services S3",
@@ -1062,6 +1155,112 @@
]
}
],
+ "sampleQueries": [
+ {
+ "description": "High severity findings summarized by activity type",
+ "query": "AWSGuardDuty\n | where Severity > 7\n | summarize count() by ActivityType"
+ },
+ {
+ "description": "Top 10 rejected actions of type IPv4",
+ "query": "AWSVPCFlow\n | where Action == \"REJECT\"\n | where Type == \"IPv4\"\n | take 10"
+ },
+ {
+ "description": "User creation events summarized by region",
+ "query": "AWSCloudTrail\n | where EventName == \"CreateUser\"\n | summarize count() by AWSRegion"
+ }
+ ],
+ "availability": {
+ "status": 2,
+ "featureFlag": {
+ "feature": "AWSS3Connector",
+ "featureStates": {
+ "Dogfood": "GA",
+ "MPAC": "GA",
+ "Prod": "GA",
+ "Fairfax": "GA",
+ "Mooncake": "PrivatePreview",
+ "USSec": "PrivatePreview",
+ "USNat": "PrivatePreview"
+ }
+ },
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "write permission.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "delete": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Environment",
+ "description": "you must have the following AWS resources defined and configured: S3, Simple Queue Service (SQS), IAM roles and permissions policies, and the AWS services whose logs you want to collect."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": "There are two options for setting up your AWS environment to send logs from an S3 bucket to your Log Analytics Workspace:",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Setup with PowerShell script (recommended)",
+ "instructions": [
+ {
+ "parameters": {
+ "govScript": "Download and extract the files from the following link: [AWS S3 Setup Script](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/AWS-S3/ConfigAwsS3DataConnectorScriptsGov.zip).\n\n> 1. Make sure that you have PowerShell on your machine: [Installation instructions for PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-7.2).\n\n> 2. Make sure that you have the AWS CLI on your machine: [Installation instructions for the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html).\n\nBefore running the script, run the aws configure command from your PowerShell command line, and enter the relevant information as prompted. See [AWS Command Line Interface | Configuration basics](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) for details.",
+ "prodScript": "Download and extract the files from the following link: [AWS S3 Setup Script](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/AWS-S3/ConfigAwsS3DataConnectorScripts.zip).\n\n> 1. Make sure that you have PowerShell on your machine: [Installation instructions for PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-7.2).\n\n> 2. Make sure that you have the AWS CLI on your machine: [Installation instructions for the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html).\n\nBefore running the script, run the aws configure command from your PowerShell command line, and enter the relevant information as prompted. See [AWS Command Line Interface | Configuration basics](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) for details."
+ },
+ "type": "MarkdownControlEnvBased"
+ },
+ {
+ "parameters": {
+ "label": "Run script to set up the environment",
+ "value": "./ConfigAwsConnector.ps1"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "fillWith": [
+ "WorkspaceId"
+ ],
+ "label": "External ID (Workspace ID)"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ },
+ {
+ "title": "Manual Setup",
+ "description": "Follow the instruction in the following link to set up the environment: [Connect AWS S3 to Microsoft Sentinel](https://aka.ms/AWSS3Connector)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Set up your AWS environment"
+ },
+ {
+ "instructions": [
+ {
+ "parameters": {},
+ "type": "AwsS3"
+ }
+ ],
+ "title": "2. Add connection"
+ }
+ ],
"id": "[variables('_uiConfigId2')]"
}
}
@@ -1545,15 +1744,13 @@
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorCCPVersion')]",
"parameters": {
- "apikey": {
- "defaultValue": "-NA-",
- "type": "securestring",
- "minLength": 1
+ "guidValue": {
+ "defaultValue": "[[newGuid()]",
+ "type": "string"
},
- "baseUrl": {
- "defaultValue": "Enter baseUrl value",
- "type": "string",
- "minLength": 1
+ "innerWorkspace": {
+ "defaultValue": "[parameters('workspace')]",
+ "type": "string"
},
"connectorDefinitionName": {
"defaultValue": "Amazon Web Services S3 WAF",
@@ -1612,7 +1809,7 @@
}
},
{
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', 'AwsS3 WAF Pollinf Config')]",
+ "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'AwsS3 WAF Pollinf Config', parameters('guidValue'))]",
"apiVersion": "2023-02-01-preview",
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
"location": "[parameters('workspace-location')]",
@@ -1629,7 +1826,7 @@
"dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]",
"dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]"
},
- "destinationTable": "",
+ "destinationTable": "AWSWAF",
"dataFormat": {
"Format": "Json",
"IsCompressed": true,
@@ -1661,7 +1858,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AmazonWebServicesNetworkActivities Workbook with template version 3.0.4",
+ "description": "AmazonWebServicesNetworkActivities Workbook with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -1748,7 +1945,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AmazonWebServicesUserActivities Workbook with template version 3.0.4",
+ "description": "AmazonWebServicesUserActivities Workbook with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -1835,7 +2032,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ChangeToRDSDatabase_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ChangeToRDSDatabase_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -1961,7 +2158,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ChangeToVPC_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ChangeToVPC_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -2089,7 +2286,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ClearStopChangeTrailLogs_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ClearStopChangeTrailLogs_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -2215,7 +2412,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ConfigServiceResourceDeletion_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ConfigServiceResourceDeletion_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -2345,7 +2542,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ConsoleLogonWithoutMFA_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ConsoleLogonWithoutMFA_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -2474,7 +2671,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CredentialHijack_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CredentialHijack_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -2600,7 +2797,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_FullAdminPolicyAttachedToRolesUsersGroups_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_FullAdminPolicyAttachedToRolesUsersGroups_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -2727,7 +2924,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_IngressEgressSecurityGroupChange_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_IngressEgressSecurityGroupChange_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -2853,7 +3050,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_LoadBalancerSecGroupChange_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_LoadBalancerSecGroupChange_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -2979,7 +3176,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "NRT_AWS_ConsoleLogonWithoutMFA_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "NRT_AWS_ConsoleLogonWithoutMFA_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]",
@@ -3104,7 +3301,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_GuardDuty_template_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_GuardDuty_template_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject11').analyticRuleVersion11]",
@@ -3185,17 +3382,17 @@
}
],
"customDetails": {
- "ThreatFamilyName": "ThreatFamilyName",
- "DetectionMechanism": "DetectionMechanism",
"ResourceTypeAffected": "ResourceTypeAffected",
"ThreatPurpose": "ThreatPurpose",
- "Artifact": "Artifact"
+ "Artifact": "Artifact",
+ "ThreatFamilyName": "ThreatFamilyName",
+ "DetectionMechanism": "DetectionMechanism"
},
"alertDetailsOverride": {
+ "alertSeverityColumnName": "Severity",
"alertTacticsColumnName": "ThreatPurpose",
"alertDisplayNameFormat": "{{Title}}",
- "alertDescriptionFormat": "{{Description}}",
- "alertSeverityColumnName": "Severity"
+ "alertDescriptionFormat": "{{Description}}"
}
}
},
@@ -3249,7 +3446,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ECRContainerHigh_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ECRContainerHigh_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject12').analyticRuleVersion12]",
@@ -3369,7 +3566,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_SuspiciousCommandEC2_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_SuspiciousCommandEC2_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject13').analyticRuleVersion13]",
@@ -3489,7 +3686,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_APIfromTor_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_APIfromTor_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject14').analyticRuleVersion14]",
@@ -3609,7 +3806,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_GuardDutyDisabled_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_GuardDutyDisabled_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject15').analyticRuleVersion15]",
@@ -3729,7 +3926,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedCloudFormationPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedCloudFormationPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject16').analyticRuleVersion16]",
@@ -3849,7 +4046,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedCRUDDyanmoDBPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedCRUDDyanmoDBPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject17').analyticRuleVersion17]",
@@ -3969,7 +4166,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedCRUDIAMtoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedCRUDIAMtoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject18').analyticRuleVersion18]",
@@ -4089,7 +4286,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedCRUDKMSPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedCRUDKMSPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject19').analyticRuleVersion19]",
@@ -4209,7 +4406,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedCRUDS3PolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedCRUDS3PolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject20').analyticRuleVersion20]",
@@ -4329,7 +4526,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedCURDLambdaPolicytoPrivilegEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedCURDLambdaPolicytoPrivilegEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject21').analyticRuleVersion21]",
@@ -4449,7 +4646,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedDataPipelinePolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedDataPipelinePolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject22').analyticRuleVersion22]",
@@ -4569,7 +4766,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedEC2PolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedEC2PolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject23').analyticRuleVersion23]",
@@ -4689,7 +4886,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedGluePolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedGluePolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject24').analyticRuleVersion24]",
@@ -4809,7 +5006,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedLambdaPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedLambdaPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject25').analyticRuleVersion25]",
@@ -4929,7 +5126,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreatedSSMPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreatedSSMPolicytoPrivilegeEscalation_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject26').analyticRuleVersion26]",
@@ -5049,7 +5246,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreationofEncryptKeysWithoutMFA_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_CreationofEncryptKeysWithoutMFA_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject27').analyticRuleVersion27]",
@@ -5169,7 +5366,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ECRImageScanningDisabled_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_ECRImageScanningDisabled_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject28').analyticRuleVersion28]",
@@ -5289,7 +5486,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_LogTampering_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_LogTampering_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject29').analyticRuleVersion29]",
@@ -5409,7 +5606,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_NetworkACLOpenToAllPorts_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_NetworkACLOpenToAllPorts_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject30').analyticRuleVersion30]",
@@ -5529,7 +5726,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_OverlyPermessiveKMS_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_OverlyPermessiveKMS_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject31').analyticRuleVersion31]",
@@ -5649,7 +5846,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationAdministratorAccessManagedPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationAdministratorAccessManagedPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject32').analyticRuleVersion32]",
@@ -5769,7 +5966,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationAdminManagedPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationAdminManagedPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject33').analyticRuleVersion33]",
@@ -5889,7 +6086,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationFullAccessManagedPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationFullAccessManagedPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject34').analyticRuleVersion34]",
@@ -6009,7 +6206,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaCloudFormationPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaCloudFormationPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject35').analyticRuleVersion35]",
@@ -6129,7 +6326,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationviaCRUDDynamoDB_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationviaCRUDDynamoDB_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject36').analyticRuleVersion36]",
@@ -6249,7 +6446,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaCRUDIAMPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaCRUDIAMPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject37').analyticRuleVersion37]",
@@ -6369,7 +6566,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaCRUDKMSPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaCRUDKMSPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject38').analyticRuleVersion38]",
@@ -6489,7 +6686,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaCRUDLambdaPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaCRUDLambdaPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject39').analyticRuleVersion39]",
@@ -6609,7 +6806,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaCRUDS3Policy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaCRUDS3Policy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject40').analyticRuleVersion40]",
@@ -6729,7 +6926,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaDataPipeline_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaDataPipeline_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject41').analyticRuleVersion41]",
@@ -6849,7 +7046,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaEC2Policy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaEC2Policy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject42').analyticRuleVersion42]",
@@ -6969,7 +7166,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaGluePolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaGluePolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject43').analyticRuleVersion43]",
@@ -7089,7 +7286,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaLambdaPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaLambdaPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject44').analyticRuleVersion44]",
@@ -7209,7 +7406,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegeEscalationViaSSM_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_PrivilegeEscalationViaSSM_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject45').analyticRuleVersion45]",
@@ -7329,7 +7526,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_RDSInstancePubliclyExposed_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_RDSInstancePubliclyExposed_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject46').analyticRuleVersion46]",
@@ -7449,7 +7646,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3BruteForce_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_S3BruteForce_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject47').analyticRuleVersion47]",
@@ -7569,7 +7766,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3BucketAccessPointExposed_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_S3BucketAccessPointExposed_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject48').analyticRuleVersion48]",
@@ -7689,7 +7886,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3BucketExposedviaACL_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_S3BucketExposedviaACL_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject49').analyticRuleVersion49]",
@@ -7809,7 +8006,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3BucketExposedviaPolicy_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_S3BucketExposedviaPolicy_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject50').analyticRuleVersion50]",
@@ -7929,7 +8126,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3ObjectPubliclyExposed_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_S3ObjectPubliclyExposed_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject51').analyticRuleVersion51]",
@@ -8049,7 +8246,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3Ransomware_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_S3Ransomware_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject52').analyticRuleVersion52]",
@@ -8169,7 +8366,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_SAMLUpdateIdentity_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_SAMLUpdateIdentity_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject53').analyticRuleVersion53]",
@@ -8289,7 +8486,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_SetDefaulyPolicyVersion_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_SetDefaulyPolicyVersion_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject54').analyticRuleVersion54]",
@@ -8409,7 +8606,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_SSMPubliclyExposed_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "AWS_SSMPubliclyExposed_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject55').analyticRuleVersion55]",
@@ -8529,7 +8726,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SuspiciousAWSCLICommandExecution_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "SuspiciousAWSCLICommandExecution_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject56').analyticRuleVersion56]",
@@ -8656,7 +8853,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SuspiciousAWSEC2ComputeResourceDeployments_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "SuspiciousAWSEC2ComputeResourceDeployments_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject57').analyticRuleVersion57]",
@@ -8725,9 +8922,9 @@
}
],
"customDetails": {
+ "UserAgent": "UserAgent",
"SourceIpAddress": "SourceIpAddress",
- "AWSUser": "UserIdentityArn",
- "UserAgent": "UserAgent"
+ "AWSUser": "UserIdentityArn"
}
}
},
@@ -8781,7 +8978,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_IAM_PolicyChange_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_IAM_PolicyChange_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
@@ -8865,7 +9062,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_IAM_PrivilegeEscalationbyAttachment_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_IAM_PrivilegeEscalationbyAttachment_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
@@ -8949,7 +9146,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PrivilegedRoleAttachedToInstance_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_PrivilegedRoleAttachedToInstance_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
@@ -9033,7 +9230,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_SuspiciousCredentialTokenAccessOfValid_IAM_Roles_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_SuspiciousCredentialTokenAccessOfValid_IAM_Roles_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
@@ -9117,7 +9314,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_Unused_UnsupportedCloudRegions_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_Unused_UnsupportedCloudRegions_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
@@ -9201,7 +9398,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_EC2_WithoutKeyPair_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_EC2_WithoutKeyPair_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
@@ -9285,7 +9482,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_AssumeRoleBruteForce_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_AssumeRoleBruteForce_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
@@ -9369,7 +9566,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_BucketVersioningSuspended_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_BucketVersioningSuspended_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]",
@@ -9453,7 +9650,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreateAccessKey_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_CreateAccessKey_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]",
@@ -9537,7 +9734,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_CreateLoginProfile_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_CreateLoginProfile_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]",
@@ -9621,7 +9818,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ECRContainerLow_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_ECRContainerLow_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject11').huntingQueryVersion11]",
@@ -9705,7 +9902,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ECRContainerMedium_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_ECRContainerMedium_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject12').huntingQueryVersion12]",
@@ -9789,7 +9986,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ExcessiveExecutionofDiscoveryEvents_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_ExcessiveExecutionofDiscoveryEvents_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject13').huntingQueryVersion13]",
@@ -9873,7 +10070,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_FailedBruteForceS3Bucket_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_FailedBruteForceS3Bucket_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject14').huntingQueryVersion14]",
@@ -9957,7 +10154,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_FailedBruteForceWithoutMFA_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_FailedBruteForceWithoutMFA_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject15').huntingQueryVersion15]",
@@ -10041,7 +10238,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_IAMAccsesDeniedDiscoveryEvents_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_IAMAccsesDeniedDiscoveryEvents_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject16').huntingQueryVersion16]",
@@ -10125,7 +10322,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_IAMUserGroupChanges_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_IAMUserGroupChanges_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject17').huntingQueryVersion17]",
@@ -10209,7 +10406,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_LambdaFunctionThrottled_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_LambdaFunctionThrottled_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject18').huntingQueryVersion18]",
@@ -10293,7 +10490,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_LambdaLayerImportedExternalAccount_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_LambdaLayerImportedExternalAccount_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject19').huntingQueryVersion19]",
@@ -10377,7 +10574,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_LambdaUpdateFunctionCode_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_LambdaUpdateFunctionCode_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject20').huntingQueryVersion20]",
@@ -10461,7 +10658,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_LoginProfileUpdated_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_LoginProfileUpdated_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject21').huntingQueryVersion21]",
@@ -10545,7 +10742,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ModificationofRouteTableAttributes_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_ModificationofRouteTableAttributes_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject22').huntingQueryVersion22]",
@@ -10629,7 +10826,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ModificationofSubnetAttributes_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_ModificationofSubnetAttributes_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject23').huntingQueryVersion23]",
@@ -10713,7 +10910,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_ModificationofVPCAttributes_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_ModificationofVPCAttributes_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject24').huntingQueryVersion24]",
@@ -10797,7 +10994,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_NetworkACLDeleted_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_NetworkACLDeleted_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject25').huntingQueryVersion25]",
@@ -10881,7 +11078,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_NewRootAccessKey_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_NewRootAccessKey_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject26').huntingQueryVersion26]",
@@ -10965,7 +11162,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_PolicywithExcessivePermissions_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_PolicywithExcessivePermissions_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject27').huntingQueryVersion27]",
@@ -11049,7 +11246,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_RDSMasterPasswordChanged_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_RDSMasterPasswordChanged_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject28').huntingQueryVersion28]",
@@ -11133,7 +11330,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_RiskyRoleName_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_RiskyRoleName_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject29').huntingQueryVersion29]",
@@ -11217,7 +11414,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3BucketDeleted_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_S3BucketDeleted_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject30').huntingQueryVersion30]",
@@ -11301,7 +11498,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_S3BucketEncryptionModified_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_S3BucketEncryptionModified_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject31').huntingQueryVersion31]",
@@ -11385,7 +11582,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_STStoEC2_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_STStoEC2_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject32').huntingQueryVersion32]",
@@ -11469,7 +11666,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_STStoECS_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_STStoECS_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject33').huntingQueryVersion33]",
@@ -11553,7 +11750,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_STStoGlue_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_STStoGlue_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject34').huntingQueryVersion34]",
@@ -11637,7 +11834,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_STStoKWN_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_STStoKWN_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject35').huntingQueryVersion35]",
@@ -11721,7 +11918,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AWS_STStoLambda_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AWS_STStoLambda_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject36').huntingQueryVersion36]",
@@ -11801,7 +11998,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.4",
+ "version": "3.0.5",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Amazon Web Services",
diff --git a/Solutions/Amazon Web Services/ReleaseNotes.md b/Solutions/Amazon Web Services/ReleaseNotes.md
index d6062253d20..4ec7da7ce9f 100644
--- a/Solutions/Amazon Web Services/ReleaseNotes.md
+++ b/Solutions/Amazon Web Services/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.0.5 | 10-02-2025 | Repackaged to fix ccp grid showing only 1 record and rename of file |
| 3.0.4 | 13-12-2024 | Updated title of **Analytic Rule** - AWS_LogTampering.yaml |
| 3.0.3 | 27-05-2024 | Updated **Hunting Query** AWS_FailedBruteForceS3Bucket.yaml and **Analytic Rules** for missing TTP |
| 3.0.2 | 05-04-2024 | Updated awsS3 **Data connector**, added new Data Type CloudWatch |
diff --git a/Solutions/Auth0/Data Connectors/Auth0_CCP/DataConnectorDefinition.json b/Solutions/Auth0/Data Connectors/Auth0_CCP/DataConnectorDefinition.json
index 84fc49b93b8..25d12da3894 100644
--- a/Solutions/Auth0/Data Connectors/Auth0_CCP/DataConnectorDefinition.json
+++ b/Solutions/Auth0/Data Connectors/Auth0_CCP/DataConnectorDefinition.json
@@ -7,7 +7,7 @@
"properties": {
"connectorUiConfig": {
"id": "Auth0ConnectorCCPDefinition",
- "title": "Auth0 Logs (Preview)",
+ "title": "Auth0 Logs",
"publisher": "Microsoft",
"descriptionMarkdown": "The [Auth0](https://auth0.com/docs/api/management/v2/logs/get-logs) data connector allows ingesting logs from Auth0 API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses Auth0 API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
diff --git a/Solutions/Auth0/Data Connectors/Auth0_FunctionApp.json b/Solutions/Auth0/Data Connectors/Auth0_FunctionApp.json
index dbcc4cbf8ea..a58e338517c 100644
--- a/Solutions/Auth0/Data Connectors/Auth0_FunctionApp.json
+++ b/Solutions/Auth0/Data Connectors/Auth0_FunctionApp.json
@@ -1,6 +1,6 @@
{
"id": "Auth0",
- "title": "Auth0 Access Management(using Azure Function)",
+ "title": "Auth0 Access Management",
"publisher": "Auth0",
"descriptionMarkdown": "The [Auth0 Access Management](https://auth0.com/access-management) data connector provides the capability to ingest [Auth0 log events](https://auth0.com/docs/api/management/v2/#!/Logs/get_logs) into Microsoft Sentinel",
"additionalRequirementBanner": "These queries are dependent on a parser based on a Kusto Function deployed as part of the solution.",
diff --git a/Solutions/Auth0/Package/3.1.2.zip b/Solutions/Auth0/Package/3.1.2.zip
new file mode 100644
index 00000000000..c355e46b3f7
Binary files /dev/null and b/Solutions/Auth0/Package/3.1.2.zip differ
diff --git a/Solutions/Auth0/Package/mainTemplate.json b/Solutions/Auth0/Package/mainTemplate.json
index a8e6dde87fa..c060c531f18 100644
--- a/Solutions/Auth0/Package/mainTemplate.json
+++ b/Solutions/Auth0/Package/mainTemplate.json
@@ -47,7 +47,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Auth0",
- "_solutionVersion": "3.1.1",
+ "_solutionVersion": "3.1.2",
"solutionId": "azuresentinel.azure-sentinel-solution-auth0",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "Auth0",
@@ -92,7 +92,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Auth0 data connector with template version 3.1.1",
+ "description": "Auth0 data connector with template version 3.1.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -108,7 +108,7 @@
"properties": {
"connectorUiConfig": {
"id": "[variables('_uiConfigId1')]",
- "title": "Auth0 Access Management(using Azure Function) (using Azure Functions)",
+ "title": "Auth0 Access Management (using Azure Functions)",
"publisher": "Auth0",
"descriptionMarkdown": "The [Auth0 Access Management](https://auth0.com/access-management) data connector provides the capability to ingest [Auth0 log events](https://auth0.com/docs/api/management/v2/#!/Logs/get_logs) into Microsoft Sentinel",
"additionalRequirementBanner": "These queries are dependent on a parser based on a Kusto Function deployed as part of the solution.",
@@ -279,7 +279,7 @@
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_dataConnectorContentId1')]",
"contentKind": "DataConnector",
- "displayName": "Auth0 Access Management(using Azure Function) (using Azure Functions)",
+ "displayName": "Auth0 Access Management (using Azure Functions)",
"contentProductId": "[variables('_dataConnectorcontentProductId1')]",
"id": "[variables('_dataConnectorcontentProductId1')]",
"version": "[variables('dataConnectorVersion1')]"
@@ -323,7 +323,7 @@
"kind": "GenericUI",
"properties": {
"connectorUiConfig": {
- "title": "Auth0 Access Management(using Azure Function) (using Azure Functions)",
+ "title": "Auth0 Access Management (using Azure Functions)",
"publisher": "Auth0",
"descriptionMarkdown": "The [Auth0 Access Management](https://auth0.com/access-management) data connector provides the capability to ingest [Auth0 log events](https://auth0.com/docs/api/management/v2/#!/Logs/get_logs) into Microsoft Sentinel",
"graphQueries": [
@@ -454,7 +454,7 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]",
- "displayName": "Auth0 Logs (Preview)",
+ "displayName": "Auth0 Logs",
"contentKind": "DataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -471,7 +471,7 @@
"properties": {
"connectorUiConfig": {
"id": "Auth0ConnectorCCPDefinition",
- "title": "Auth0 Logs (Preview)",
+ "title": "Auth0 Logs",
"publisher": "Microsoft",
"descriptionMarkdown": "The [Auth0](https://auth0.com/docs/api/management/v2/logs/get-logs) data connector allows ingesting logs from Auth0 API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses Auth0 API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
@@ -852,7 +852,7 @@
"properties": {
"connectorUiConfig": {
"id": "Auth0ConnectorCCPDefinition",
- "title": "Auth0 Logs (Preview)",
+ "title": "Auth0 Logs",
"publisher": "Microsoft",
"descriptionMarkdown": "The [Auth0](https://auth0.com/docs/api/management/v2/logs/get-logs) data connector allows ingesting logs from Auth0 API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses Auth0 API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
@@ -1001,14 +1001,24 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnections2')]",
- "displayName": "Auth0 Logs (Preview)",
+ "displayName": "Auth0 Logs",
"contentKind": "ResourcesDataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorCCPVersion')]",
"parameters": {
+ "ClientId": {
+ "defaultValue": "-NA-",
+ "type": "securestring",
+ "minLength": 4
+ },
+ "ClientSecret": {
+ "defaultValue": "-NA-",
+ "type": "securestring",
+ "minLength": 4
+ },
"connectorDefinitionName": {
- "defaultValue": "Auth0 Logs (Preview)",
+ "defaultValue": "Auth0 Logs",
"type": "string",
"minLength": 1
},
@@ -1027,16 +1037,6 @@
"defaultValue": "Domain",
"type": "string",
"minLength": 1
- },
- "ClientId": {
- "defaultValue": "ClientId",
- "type": "string",
- "minLength": 1
- },
- "ClientSecret": {
- "defaultValue": "ClientSecret",
- "type": "securestring",
- "minLength": 1
}
},
"variables": {
@@ -1136,7 +1136,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Auth0AM Data Parser with template version 3.1.1",
+ "description": "Auth0AM Data Parser with template version 3.1.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -1268,7 +1268,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Auth0 Data Parser with template version 3.1.1",
+ "description": "Auth0 Data Parser with template version 3.1.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject2').parserVersion2]",
@@ -1396,7 +1396,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.1.1",
+ "version": "3.1.2",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Auth0",
diff --git a/Solutions/Auth0/ReleaseNotes.md b/Solutions/Auth0/ReleaseNotes.md
index a6ca0d78599..99a5ff5d443 100644
--- a/Solutions/Auth0/ReleaseNotes.md
+++ b/Solutions/Auth0/ReleaseNotes.md
@@ -1,7 +1,8 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------|
-| 3.1.1 | 22-01-2025 | Added Preview tag to CCP **Data Connector**|
-| 3.1.0 | 13-12-2024 | Added new CCP **Data Connector** to the Solution |
+| 3.1.2 | 10-02-2025 | Advancing CCP **Data Connector** from Public preview to Global Availability. |
+| 3.1.1 | 22-01-2025 | Added Preview tag to CCP **Data Connector** |
+| 3.1.0 | 13-12-2024 | Added new CCP **Data Connector** to the Solution |
| 3.0.0 | 24-08-2024 | Updated the **Data Connector** Function app python runtime version to 3.11 |
-| | 11-12-2023 | Added new **Parser** (Auth0AM) |
+| | 11-12-2023 | Added new **Parser** (Auth0AM) |
diff --git a/Solutions/Azure Activity/Data/Solution_AzureActivity.json b/Solutions/Azure Activity/Data/Solution_AzureActivity.json
index c778d63e6fb..66156b1f9e8 100644
--- a/Solutions/Azure Activity/Data/Solution_AzureActivity.json
+++ b/Solutions/Azure Activity/Data/Solution_AzureActivity.json
@@ -20,7 +20,8 @@
"Hunting Queries/Creating_Anomalous_Number_Of_Resources.yaml",
"Hunting Queries/Granting_Permissions_to_Account.yaml",
"Hunting Queries/PortOpenedForAzureResource.yaml",
- "Hunting Queries/Rare_Custom_Script_Extension.yaml"
+ "Hunting Queries/Rare_Custom_Script_Extension.yaml",
+ "Hunting Queries/Machine_Learning_Creation.yaml"
],
"Analytic Rules": [
"Analytic Rules/AADHybridHealthADFSNewServer.yaml",
@@ -43,7 +44,7 @@
"Workbooks/AzureServiceHealthWorkbook.json"
],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity",
- "Version": "3.0.0",
+ "Version": "3.0.3",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"StaticDataConnectorIds": [
diff --git a/Solutions/Azure Activity/Hunting Queries/Machine_Learning_Creation.yaml b/Solutions/Azure Activity/Hunting Queries/Machine_Learning_Creation.yaml
new file mode 100644
index 00000000000..ab8a4765784
--- /dev/null
+++ b/Solutions/Azure Activity/Hunting Queries/Machine_Learning_Creation.yaml
@@ -0,0 +1,46 @@
+id: 26d116bd-324b-4bb8-b102-d4a282607ad7
+name: Azure Machine Learning Write Operations
+description: |
+ 'Shows the most prevalent users who perform write operations on Azure Machine Learning resources. List the common source IP address for each of those accounts. If an operation is not from those IP addresses, it may be worthy of investigation.'
+requiredDataConnectors:
+ - connectorId: AzureActivity
+ dataTypes:
+ - AzureActivity
+tactics:
+ - InitialAccess
+ - Execution
+ - Impact
+relevantTechniques:
+ - T1078
+ - T1059
+ - T1496
+query: |
+ AzureActivity
+ | where ResourceProviderValue == "MICROSOFT.MACHINELEARNINGSERVICES" // Filter activities related to Microsoft Machine Learning Services
+ | extend SCOPE = tostring(parse_json(Authorization).scope) // Parse Authorization scope as string
+ | extend subname = split(Hierarchy, "/") // Split Hierarchy to extract Subscription Name and ID
+ | extend ['Subscription Name'] = subname[-2], ['Subscription ID'] = subname[-1] // Extract Subscription Name and ID
+ | extend Properties = parse_json(Properties) // Parse Properties as JSON
+ | extend Properties_entity = tostring(Properties.entity) // Cast Properties.entity to string
+ | where isnotempty(Properties_entity) // Filter activities where Properties.entity is not empty
+ // | where Properties_entity contains "deepseek" // Filter activities where Properties.entity contains "deepseek"
+ | where OperationNameValue contains "write" // Filter activities where OperationNameValue contains "write"
+ | where OperationNameValue !contains "MICROSOFT.AUTHORIZATION/ROLEASSIGNMENTS/WRITE" // Exclude role assignments
+ | extend LLM = tostring(split(Properties_entity, "/")[-1]) // Extract the last segment of Properties_entity and cast it to string
+ | distinct TimeGenerated, tostring(['Subscription Name']), ResourceGroup, tostring(['Subscription ID']), Caller, CallerIpAddress, OperationNameValue, LLM, _ResourceId // Select distinct relevant fields for output
+
+entityMappings:
+ - entityType: Account
+ fieldMappings:
+ - identifier: Name
+ columnName: Caller
+ - entityType: IP
+ fieldMappings:
+ - identifier: Address
+ columnName: CallerIpAddress
+ - entityType: Azure Resource
+ fieldMappings:
+ - identifier: ResourceId
+ columnName: _ResourceId
+
+version: 1.0
diff --git a/Solutions/Azure Activity/Package/3.0.3.zip b/Solutions/Azure Activity/Package/3.0.3.zip
index 4b73e379972..01b2c49492b 100644
Binary files a/Solutions/Azure Activity/Package/3.0.3.zip and b/Solutions/Azure Activity/Package/3.0.3.zip differ
diff --git a/Solutions/Azure Activity/Package/createUiDefinition.json b/Solutions/Azure Activity/Package/createUiDefinition.json
index d0abf6cd829..df21571a6ad 100644
--- a/Solutions/Azure Activity/Package/createUiDefinition.json
+++ b/Solutions/Azure Activity/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Azure%20Activity/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.\n\n**Data Connectors:** 1, **Workbooks:** 2, **Analytic Rules:** 13, **Hunting Queries:** 14\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Azure%20Activity/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.\n\n**Data Connectors:** 1, **Workbooks:** 2, **Analytic Rules:** 13, **Hunting Queries:** 15\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
@@ -558,6 +558,20 @@
}
}
]
+ },
+ {
+ "name": "huntingquery15",
+ "type": "Microsoft.Common.Section",
+ "label": "Azure Machine Learning Write Operations",
+ "elements": [
+ {
+ "name": "huntingquery15-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Shows the most prevalent users who perform write operations on Azure Machine Learning resources. List the common source IP address for each of those accounts. If an operation is not from those IP addresses, it may be worthy of investigation. This hunting query depends on AzureActivity data connector (AzureActivity Parser or Table)"
+ }
+ }
+ ]
}
]
}
diff --git a/Solutions/Azure Activity/Package/mainTemplate.json b/Solutions/Azure Activity/Package/mainTemplate.json
index 0c319dbeeb6..0eb9a577166 100644
--- a/Solutions/Azure Activity/Package/mainTemplate.json
+++ b/Solutions/Azure Activity/Package/mainTemplate.json
@@ -62,7 +62,7 @@
"dataConnectorVersion1": "2.0.0",
"_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
"huntingQueryObject1": {
- "huntingQueryVersion1": "2.0.1",
+ "huntingQueryVersion1": "2.0.2",
"_huntingQuerycontentId1": "ef7ef44e-6129-4d8e-94fe-b5530415d8e5",
"huntingQueryTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('ef7ef44e-6129-4d8e-94fe-b5530415d8e5')))]"
},
@@ -131,6 +131,11 @@
"_huntingQuerycontentId14": "81fd68a2-9ad6-4a1c-7bd7-18efe5c99081",
"huntingQueryTemplateSpecName14": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('81fd68a2-9ad6-4a1c-7bd7-18efe5c99081')))]"
},
+ "huntingQueryObject15": {
+ "huntingQueryVersion15": "1",
+ "_huntingQuerycontentId15": "26d116bd-324b-4bb8-b102-d4a282607ad7",
+ "huntingQueryTemplateSpecName15": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('26d116bd-324b-4bb8-b102-d4a282607ad7')))]"
+ },
"analyticRuleObject1": {
"analyticRuleVersion1": "2.0.3",
"_analyticRulecontentId1": "88f453ff-7b9e-45bb-8c12-4058ca5e44ee",
@@ -422,7 +427,7 @@
"eTag": "*",
"displayName": "Microsoft Sentinel Analytics Rules Administrative Operations",
"category": "Hunting Queries",
- "query": "let opValues = dynamic([\"Microsoft.SecurityInsights/alertRules/write\", \"Microsoft.SecurityInsights/alertRules/delete\"]);\n// Microsoft Sentinel Analytics - Rule Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n",
+ "query": "let opValues = dynamic([\"Microsoft.SecurityInsights/alertRules/write\", \"Microsoft.SecurityInsights/alertRules/delete\"]);\n// Microsoft Sentinel Analytics - Rule Create / Update / Delete\nAzureActivity\n| where CategoryValue =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n",
"version": 2,
"tags": [
{
@@ -477,9 +482,9 @@
"contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
"contentKind": "HuntingQuery",
"displayName": "Microsoft Sentinel Analytics Rules Administrative Operations",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '2.0.1')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '2.0.1')))]",
- "version": "2.0.1"
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '2.0.2')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '2.0.2')))]",
+ "version": "2.0.2"
}
},
{
@@ -1587,6 +1592,91 @@
"version": "2.0.1"
}
},
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject15').huntingQueryTemplateSpecName15]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Machine_Learning_Creation_HuntingQueries Hunting Query with template version 3.0.3",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject15').huntingQueryVersion15]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Azure_Activity_Hunting_Query_15",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Azure Machine Learning Write Operations",
+ "category": "Hunting Queries",
+ "query": "AzureActivity\n| where ResourceProviderValue == \"MICROSOFT.MACHINELEARNINGSERVICES\" // Filter activities related to Microsoft Machine Learning Services\n| extend SCOPE = tostring(parse_json(Authorization).scope) // Parse Authorization scope as string\n| extend subname = split(Hierarchy, \"/\") // Split Hierarchy to extract Subscription Name and ID\n| extend ['Subscription Name'] = subname[-2], ['Subscription ID'] = subname[-1] // Extract Subscription Name and ID\n| extend Properties = parse_json(Properties) // Parse Properties as JSON\n| extend Properties_entity = tostring(Properties.entity) // Cast Properties.entity to string\n| where isnotempty(Properties_entity) // Filter activities where Properties.entity is not empty\n// | where Properties_entity contains \"deepseek\" // Filter activities where Properties.entity contains \"deepseek\"\n| where OperationNameValue contains \"write\" // Filter activities where OperationNameValue contains \"write\"\n| where OperationNameValue !contains \"MICROSOFT.AUTHORIZATION/ROLEASSIGNMENTS/WRITE\" // Exclude role assignments\n| extend LLM = tostring(split(Properties_entity, \"/\")[-1]) // Extract the last segment of Properties_entity and cast it to string\n| distinct TimeGenerated, tostring(['Subscription Name']), ResourceGroup, tostring(['Subscription ID']), Caller, CallerIpAddress, OperationNameValue, LLM, _ResourceId // Select distinct relevant fields for output\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Shows the most prevalent users who perform write operations on Azure Machine Learning resources. List the common source IP address for each of those accounts. If an operation is not from those IP addresses, it may be worthy of investigation."
+ },
+ {
+ "name": "tactics",
+ "value": "InitialAccess,Execution,Impact"
+ },
+ {
+ "name": "techniques",
+ "value": "T1078,T1059,T1496"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject15')._huntingQuerycontentId15),'/'))))]",
+ "properties": {
+ "description": "Azure Activity Hunting Query 15",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject15')._huntingQuerycontentId15)]",
+ "contentId": "[variables('huntingQueryObject15')._huntingQuerycontentId15]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject15').huntingQueryVersion15]",
+ "source": {
+ "kind": "Solution",
+ "name": "Azure Activity",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "tier": "Microsoft",
+ "name": "Microsoft Corporation",
+ "email": "support@microsoft.com",
+ "link": "https://support.microsoft.com/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject15')._huntingQuerycontentId15]",
+ "contentKind": "HuntingQuery",
+ "displayName": "Azure Machine Learning Write Operations",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject15')._huntingQuerycontentId15,'-', '1')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject15')._huntingQuerycontentId15,'-', '1')))]",
+ "version": "1"
+ }
+ },
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
@@ -3167,8 +3257,8 @@
"SourceTenantId": "SourceTenantId"
},
"alertDetailsOverride": {
- "alertDisplayNameFormat": "Subscription {{SubscriptionId}} changed tenants\n",
- "alertDescriptionFormat": "The user {{Caller}} moved a subscription:\n\n{{Summary}}\n\nIf this was not expected, it may indicate a subscription hijacking event.\n"
+ "alertDescriptionFormat": "The user {{Caller}} moved a subscription:\n\n{{Summary}}\n\nIf this was not expected, it may indicate a subscription hijacking event.\n",
+ "alertDisplayNameFormat": "Subscription {{SubscriptionId}} changed tenants\n"
}
}
},
@@ -3400,7 +3490,7 @@
"contentSchemaVersion": "3.0.0",
"displayName": "Azure Activity",
"publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation",
- "descriptionHtml": "
Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Azure Activity solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health logs using Diagnostic Settings into Microsoft Sentinel.
\nData Connectors: 1, Workbooks: 2, Analytic Rules: 13, Hunting Queries: 14
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Azure Activity solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health logs using Diagnostic Settings into Microsoft Sentinel.
\nData Connectors: 1, Workbooks: 2, Analytic Rules: 13, Hunting Queries: 15
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
"id": "[variables('_solutioncontentProductId')]",
@@ -3500,6 +3590,11 @@
"contentId": "[variables('huntingQueryObject14')._huntingQuerycontentId14]",
"version": "[variables('huntingQueryObject14').huntingQueryVersion14]"
},
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject15')._huntingQuerycontentId15]",
+ "version": "[variables('huntingQueryObject15').huntingQueryVersion15]"
+ },
{
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
diff --git a/Solutions/Azure Activity/ReleaseNotes.md b/Solutions/Azure Activity/ReleaseNotes.md
index 0a5aa944bfb..4c10fa37a46 100644
--- a/Solutions/Azure Activity/ReleaseNotes.md
+++ b/Solutions/Azure Activity/ReleaseNotes.md
@@ -1,6 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|----------------------------------------------------------------------------|
-| 3.0.3 | 30-04-2024 | Added new **Workbook** Azure Service Health to the Solution |
+| 3.0.3 | 05-02-2025 | Added new **Workbook** Azure Service Health to the Solution and added new **Hunting query** Machine_Learning_Creation.yaml |
| 3.0.2 | 21-02-2024 | Modified Entity Mappings of **Analytic Rules** |
| 3.0.1 | 23-01-2024 | Added subTechniques in Template |
| 3.0.0 | 06-11-2023 | Modified text as there is rebranding from Azure Active Directory to Microsoft Entra ID.
Optimized the **Analytic Rule** query logic to achieve expected results |
diff --git a/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/3.0.2.zip b/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/3.0.2.zip
index 63bf1764b67..0c3196897b9 100644
Binary files a/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/3.0.2.zip and b/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/3.0.2.zip differ
diff --git a/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/createUiDefinition.json b/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/createUiDefinition.json
index c06a12fe49f..c81fd8f28e8 100644
--- a/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/createUiDefinition.json
+++ b/Solutions/Azure Cloud NGFW by Palo Alto Networks/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Azure%20Cloud%20NGFW%20By%20Palo%20Alto%20Networks/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Azure Cloud NGFW By Palo Alto Networks](https://docs.paloaltonetworks.com/cloud-ngfw/azure) Solution for Microsoft Sentinel allows you to easily connect your Cloud NGFW logs with Microsoft Sentinel, to view dashboards, create custom alerts, and improve investigation. This gives you more insight into your organization's network and improves your security operation capabilities. This solution also contains playbooks to help in automated remediation. \n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs: \n\na. [Agent-based log collection (CEF over Syslog)](https://docs.microsoft.com/azure/sentinel/connect-common-event-format)\n\n**Data Connectors:** 1, **Workbooks:** 2, **Analytic Rules:** 3, **Hunting Queries:** 2\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure%20Cloud%20NGFW%20by%20Palo%20Alto%20Networks/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Azure Cloud NGFW By Palo Alto Networks](https://docs.paloaltonetworks.com/cloud-ngfw/azure) Solution for Microsoft Sentinel allows you to easily connect your Cloud NGFW logs with Microsoft Sentinel, to view dashboards, create custom alerts, and improve investigation. This gives you more insight into your organization's network and improves your security operation capabilities. This solution also contains playbooks to help in automated remediation. \n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs: \n\na. [Agent-based log collection (CEF over Syslog)](https://docs.microsoft.com/azure/sentinel/connect-common-event-format)\n\n**Data Connectors:** 1, **Workbooks:** 2, **Analytic Rules:** 3, **Hunting Queries:** 2\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
diff --git a/Solutions/Azure Cloud NGFW by Palo Alto Networks/ReleaseNotes.md b/Solutions/Azure Cloud NGFW by Palo Alto Networks/ReleaseNotes.md
index 03a22cab8b3..d7e884e6fa8 100644
--- a/Solutions/Azure Cloud NGFW by Palo Alto Networks/ReleaseNotes.md
+++ b/Solutions/Azure Cloud NGFW by Palo Alto Networks/ReleaseNotes.md
@@ -1,5 +1,5 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------------------|
-| 3.0.2 | 09-01-2025 | Updated **Analytic RUles** and **Workbooks** |
+| 3.0.2 | 09-01-2025 | Updated query of **Analytic Rules** and fixed failing queries of **Workbooks** |
| 3.0.1 | 02-12-2024 | Updated **Data Connector** Ids for dependent content |
| 3.0.0 | 15-02-2024 | Initial Solution Release |
diff --git a/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-SQLiDetection.yaml b/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-SQLiDetection.yaml
index d87bfd22efe..e8845bb1c66 100644
--- a/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-SQLiDetection.yaml
+++ b/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-SQLiDetection.yaml
@@ -31,13 +31,16 @@ query: |
| where Category == "ApplicationGatewayFirewallLog"
| where action_s == "Matched"
| where Message has "SQL Injection"
- | project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message, details_message_s, details_data_s
+ | extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)
+ | extend hostname_s = tostring(parse_json(AdditionalFields).hostname_s)
+ | project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message
| join kind = inner(
AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
- | where action_s == "Blocked") on transactionId_g
+ | where action_s == "Blocked"
+ | extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)) on transactionId_g
| extend Uri = strcat(hostname_s,requestUri_s)
- | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Detail_Message = make_set(details_message_s,100), Detail_Data = make_set(details_data_s,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s
+ | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s
| where Total_TransactionId >= Threshold
# The Threshold value above can be changed as per your infrastructure's requirement
entityMappings:
@@ -49,5 +52,5 @@ entityMappings:
fieldMappings:
- identifier: Address
columnName: clientIp_s
-version: 1.0.0
+version: 1.0.1
kind: Scheduled
diff --git a/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-XSSDetection.yaml b/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-XSSDetection.yaml
index eb30bdac327..8dca6e11779 100644
--- a/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-XSSDetection.yaml
+++ b/Solutions/Azure Web Application Firewall (WAF)/Analytic Rules/App-GW-WAF-XSSDetection.yaml
@@ -28,13 +28,16 @@ query: |
| where Category == "ApplicationGatewayFirewallLog"
| where action_s == "Matched"
| where Message has "XSS"
- | project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message, details_message_s, details_data_s
+ | extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)
+ | extend hostname_s = tostring(parse_json(AdditionalFields).hostname_s)
+ | project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message
| join kind = inner(
AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
- | where action_s == "Blocked") on transactionId_g
+ | where action_s == "Blocked"
+ | extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)) on transactionId_g
| extend Uri = strcat(hostname_s,requestUri_s)
- | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Detail_Message = make_set(details_message_s,100), Detail_Data = make_set(details_data_s,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s
+ | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s
| where Total_TransactionId >= Threshold
# The Threshold value above can be changed as per your infrastructure's requirement
entityMappings:
@@ -46,5 +49,5 @@ entityMappings:
fieldMappings:
- identifier: Address
columnName: clientIp_s
-version: 1.0.0
+version: 1.0.1
kind: Scheduled
diff --git a/Solutions/Azure Web Application Firewall (WAF)/Package/3.0.2.zip b/Solutions/Azure Web Application Firewall (WAF)/Package/3.0.2.zip
new file mode 100644
index 00000000000..760d1a7f182
Binary files /dev/null and b/Solutions/Azure Web Application Firewall (WAF)/Package/3.0.2.zip differ
diff --git a/Solutions/Azure Web Application Firewall (WAF)/Package/createUiDefinition.json b/Solutions/Azure Web Application Firewall (WAF)/Package/createUiDefinition.json
index b893f102b8b..d3dcfeaa473 100644
--- a/Solutions/Azure Web Application Firewall (WAF)/Package/createUiDefinition.json
+++ b/Solutions/Azure Web Application Firewall (WAF)/Package/createUiDefinition.json
@@ -64,7 +64,7 @@
}
},
{
- "name": "dataconnectors-link2",
+ "name": "dataconnectors-link1",
"type": "Microsoft.Common.TextBlock",
"options": {
"link": {
diff --git a/Solutions/Azure Web Application Firewall (WAF)/Package/mainTemplate.json b/Solutions/Azure Web Application Firewall (WAF)/Package/mainTemplate.json
index 738f87afbd9..e3b208d2782 100644
--- a/Solutions/Azure Web Application Firewall (WAF)/Package/mainTemplate.json
+++ b/Solutions/Azure Web Application Firewall (WAF)/Package/mainTemplate.json
@@ -65,7 +65,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Azure Web Application Firewall (WAF)",
- "_solutionVersion": "3.0.1",
+ "_solutionVersion": "3.0.2",
"solutionId": "azuresentinel.azure-sentinel-solution-azurewebapplicationfirewal",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "WAF",
@@ -134,18 +134,18 @@
"_analyticRulecontentProductId8": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','9b8dd8fd-f192-42eb-84f6-541920400a7a','-', '1.0.2')))]"
},
"analyticRuleObject9": {
- "analyticRuleVersion9": "1.0.0",
+ "analyticRuleVersion9": "1.0.1",
"_analyticRulecontentId9": "bdb2cd63-99f2-472e-b1b9-acba473b6744",
"analyticRuleId9": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'bdb2cd63-99f2-472e-b1b9-acba473b6744')]",
"analyticRuleTemplateSpecName9": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('bdb2cd63-99f2-472e-b1b9-acba473b6744')))]",
- "_analyticRulecontentProductId9": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','bdb2cd63-99f2-472e-b1b9-acba473b6744','-', '1.0.0')))]"
+ "_analyticRulecontentProductId9": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','bdb2cd63-99f2-472e-b1b9-acba473b6744','-', '1.0.1')))]"
},
"analyticRuleObject10": {
- "analyticRuleVersion10": "1.0.0",
+ "analyticRuleVersion10": "1.0.1",
"_analyticRulecontentId10": "1c7ff502-2ad4-4970-9d29-9210c6753138",
"analyticRuleId10": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '1c7ff502-2ad4-4970-9d29-9210c6753138')]",
"analyticRuleTemplateSpecName10": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('1c7ff502-2ad4-4970-9d29-9210c6753138')))]",
- "_analyticRulecontentProductId10": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','1c7ff502-2ad4-4970-9d29-9210c6753138','-', '1.0.0')))]"
+ "_analyticRulecontentProductId10": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','1c7ff502-2ad4-4970-9d29-9210c6753138','-', '1.0.1')))]"
},
"workbookVersion1": "1.1.0",
"workbookContentId1": "WebApplicationFirewallFirewallEventsWorkbook",
@@ -184,7 +184,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Azure Web Application Firewall (WAF) data connector with template version 3.0.1",
+ "description": "Azure Web Application Firewall (WAF) data connector with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -383,7 +383,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MaliciousWAFSessions_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "MaliciousWAFSessions_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -487,7 +487,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AFD-Premium-WAF-SQLiDetection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "AFD-Premium-WAF-SQLiDetection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -606,7 +606,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AFD-Premium-WAF-XSSDetection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "AFD-Premium-WAF-XSSDetection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -722,7 +722,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AFD-WAF-Code-Injection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "AFD-WAF-Code-Injection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -840,7 +840,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AFD-WAF-Path-Traversal-Attack_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "AFD-WAF-Path-Traversal-Attack_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -960,7 +960,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "App-GW-WAF-Code-Injection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "App-GW-WAF-Code-Injection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -1078,7 +1078,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "App-GW-WAF-Path-Traversal-Attack_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "App-GW-WAF-Path-Traversal-Attack_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -1198,7 +1198,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "App-GW-WAF-Scanner-detection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "App-GW-WAF-Scanner-detection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -1319,7 +1319,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "App-GW-WAF-SQLiDetection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "App-GW-WAF-SQLiDetection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -1336,7 +1336,7 @@
"description": "Identifies a match for a SQL Injection attack in the App Gateway WAF logs. The threshold value in the query can be changed as per your infrastructure's requirements.\nReferences: https://owasp.org/Top10/A03_2021-Injection/",
"displayName": "App Gateway WAF - SQLi Detection",
"enabled": false,
- "query": "let Threshold = 3; \nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Matched\"\n| where Message has \"SQL Injection\"\n| project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message, details_message_s, details_data_s\n| join kind = inner(\nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Blocked\") on transactionId_g\n| extend Uri = strcat(hostname_s,requestUri_s)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Detail_Message = make_set(details_message_s,100), Detail_Data = make_set(details_data_s,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s\n| where Total_TransactionId >= Threshold\n",
+ "query": "let Threshold = 3; \nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Matched\"\n| where Message has \"SQL Injection\"\n| extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)\n| extend hostname_s = tostring(parse_json(AdditionalFields).hostname_s)\n| project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message\n| join kind = inner(\nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Blocked\"\n| extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)) on transactionId_g\n| extend Uri = strcat(hostname_s,requestUri_s)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s\n| where Total_TransactionId >= Threshold\n",
"queryFrequency": "PT6H",
"queryPeriod": "PT6H",
"severity": "High",
@@ -1438,7 +1438,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "App-GW-WAF-XSSDetection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "App-GW-WAF-XSSDetection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]",
@@ -1455,7 +1455,7 @@
"description": "Identifies a match for an XSS attack in the App Gateway WAF logs. The threshold value in the query can be changed as per your infrastructure's requirements.\n References: https://owasp.org/www-project-top-ten/2017/A7_2017-Cross-Site_Scripting_(XSS)",
"displayName": "App Gateway WAF - XSS Detection",
"enabled": false,
- "query": "let Threshold = 3; \nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Matched\"\n| where Message has \"XSS\"\n| project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message, details_message_s, details_data_s\n| join kind = inner(\nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Blocked\") on transactionId_g\n| extend Uri = strcat(hostname_s,requestUri_s)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Detail_Message = make_set(details_message_s,100), Detail_Data = make_set(details_data_s,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s\n| where Total_TransactionId >= Threshold\n",
+ "query": "let Threshold = 3; \nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Matched\"\n| where Message has \"XSS\"\n| extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)\n| extend hostname_s = tostring(parse_json(AdditionalFields).hostname_s)\n| project transactionId_g, hostname_s, requestUri_s, TimeGenerated, clientIp_s, Message\n| join kind = inner(\nAzureDiagnostics\n| where Category == \"ApplicationGatewayFirewallLog\"\n| where action_s == \"Blocked\"\n| extend transactionId_g = tostring(parse_json(AdditionalFields).transactionId_g)) on transactionId_g\n| extend Uri = strcat(hostname_s,requestUri_s)\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TransactionID = make_set(transactionId_g,100), Message = make_set(Message,100), Total_TransactionId = dcount(transactionId_g) by clientIp_s, Uri, action_s\n| where Total_TransactionId >= Threshold\n",
"queryFrequency": "PT6H",
"queryPeriod": "PT6H",
"severity": "High",
@@ -1554,7 +1554,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "WebApplicationFirewallFirewallEvents Workbook with template version 3.0.1",
+ "description": "WebApplicationFirewallFirewallEvents Workbook with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -1642,7 +1642,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "WebApplicationFirewallGatewayAccessEvents Workbook with template version 3.0.1",
+ "description": "WebApplicationFirewallGatewayAccessEvents Workbook with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -1730,7 +1730,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "WebApplicationFirewallOverview Workbook with template version 3.0.1",
+ "description": "WebApplicationFirewallOverview Workbook with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -1818,7 +1818,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "WebApplicationFirewallWAFTypeEvents Workbook with template version 3.0.1",
+ "description": "WebApplicationFirewallWAFTypeEvents Workbook with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion4')]",
@@ -1902,7 +1902,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.1",
+ "version": "3.0.2",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Azure Web Application Firewall (WAF)",
diff --git a/Solutions/Azure Web Application Firewall (WAF)/ReleaseNotes.md b/Solutions/Azure Web Application Firewall (WAF)/ReleaseNotes.md
index bc0bedbe672..d7122cf05c7 100644
--- a/Solutions/Azure Web Application Firewall (WAF)/ReleaseNotes.md
+++ b/Solutions/Azure Web Application Firewall (WAF)/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------------------------------------|
+| 3.0.2 | 06-02-2025 | Extracting transactionId_g and hostname_s from the AdditionalFields column using parse_json and Removing the now unavailable details_message_s and details_data_s fields from **Analytic Rules** App Gateway WAF - SQLi Detection and App Gateway WAF - XSS Detection.|
| 3.0.1 | 10-06-2024 | Added new **Analytic Rules** [App Gateway WAF - SQLi Detection and App Gateway WAF - XSS Detection] |
| 3.0.0 | 21-12-2023 | Added ResourceProvide condition as it is standard for Application Gateway WAF logs |
diff --git a/Solutions/BloodHound Enterprise/Data Connectors/AzureFunctionBloodHoundEnterprise/function.json b/Solutions/BloodHound Enterprise/Data Connectors/AzureFunctionBloodHoundEnterprise/function.json
index 10d7172e6a7..603069fd531 100644
--- a/Solutions/BloodHound Enterprise/Data Connectors/AzureFunctionBloodHoundEnterprise/function.json
+++ b/Solutions/BloodHound Enterprise/Data Connectors/AzureFunctionBloodHoundEnterprise/function.json
@@ -4,7 +4,7 @@
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
- "schedule": "0 0 1,13 * * *"
+ "schedule": "%Schedule%"
}
]
}
diff --git a/Solutions/BloodHound Enterprise/Data Connectors/BloodHoundEnterprise_API_FunctionApp.json b/Solutions/BloodHound Enterprise/Data Connectors/BloodHoundEnterprise_API_FunctionApp.json
index 0c0e4829550..09fd11f2647 100644
--- a/Solutions/BloodHound Enterprise/Data Connectors/BloodHoundEnterprise_API_FunctionApp.json
+++ b/Solutions/BloodHound Enterprise/Data Connectors/BloodHoundEnterprise_API_FunctionApp.json
@@ -79,18 +79,7 @@
},
{
"title": "",
- "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the BloodHound Enterprise connector, have the Workspace Name (can be copied from the following), as well as the BloodHound Enterprise API authorization key(s) or Token, readily available.",
- "instructions": [
- {
- "parameters": {
- "fillWith": [
- "workspaceName"
- ],
- "label": "Workspace Name"
- },
- "type": "CopyableLabel"
- }
- ]
+ "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the BloodHound Enterprise connector, have the Log Analytics Workspace Name, as well as the BloodHound Enterprise API authorization key(s) or Token, readily available."
},
{
"title": "",
diff --git a/Solutions/BloodHound Enterprise/Data Connectors/Makefile b/Solutions/BloodHound Enterprise/Data Connectors/Makefile
new file mode 100644
index 00000000000..63b22f6bf0b
--- /dev/null
+++ b/Solutions/BloodHound Enterprise/Data Connectors/Makefile
@@ -0,0 +1,30 @@
+.PHONY: build clean package
+
+# Packaging variables
+FUNCTION_NAME := function
+BINARY_NAME := function
+ZIP_NAME := bhe-funcapp.zip
+
+# Go build variables
+GOOS := linux
+GOARCH := amd64
+
+# Package the function app
+package: build
+ @echo "Packaging"
+ rm -f $(ZIP_NAME)
+ zip -r $(ZIP_NAME) AzureFunctionBloodHoundEnterprise/ AzureFunctionBloodHoundEnterprise/function.json function host.json
+ @echo "Packaging complete"
+
+# Build binary
+build: clean
+ @echo "Building $(BINARY_NAME)"
+ GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BINARY_NAME)
+
+# Clean up build artifacts
+clean:
+ @echo "Clean"
+ go clean
+ rm -f $(ZIP_NAME)
+
+
diff --git a/Solutions/BloodHound Enterprise/Data Connectors/azuredeploy_BloodHoundEnterprise_API_FunctionApp.json b/Solutions/BloodHound Enterprise/Data Connectors/azuredeploy_BloodHoundEnterprise_API_FunctionApp.json
index 0fd0875a632..027a0dccd13 100644
--- a/Solutions/BloodHound Enterprise/Data Connectors/azuredeploy_BloodHoundEnterprise_API_FunctionApp.json
+++ b/Solutions/BloodHound Enterprise/Data Connectors/azuredeploy_BloodHoundEnterprise_API_FunctionApp.json
@@ -34,6 +34,13 @@
"metadata": {
"description": "Token Key from the BloodHound Enterprise API"
}
+ },
+ "Schedule": {
+ "type": "string",
+ "defaultValue": "0 0 1,13 * * *",
+ "metadata": {
+ "description": "Please enter a valid Quartz cron schedule. The default runs at 1am and 1pm"
+ }
}
},
"variables": {
@@ -77,6 +84,9 @@
"workspaceID": {
"value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceName'))]"
},
+ "Schedule": {
+ "value": "[parameters('Schedule')]"
+ },
"BHEDomain": {
"value": "[parameters('BHEDomain')]"
},
diff --git a/Solutions/BloodHound Enterprise/Data Connectors/bhe-funcapp.zip b/Solutions/BloodHound Enterprise/Data Connectors/bhe-funcapp.zip
index 5a936903f14..1c285b0ba82 100644
Binary files a/Solutions/BloodHound Enterprise/Data Connectors/bhe-funcapp.zip and b/Solutions/BloodHound Enterprise/Data Connectors/bhe-funcapp.zip differ
diff --git a/Solutions/BloodHound Enterprise/Data Connectors/deployment/BloodHoundEnterprise_function_app.json b/Solutions/BloodHound Enterprise/Data Connectors/deployment/BloodHoundEnterprise_function_app.json
index b9e2afa7339..51b52b59310 100644
--- a/Solutions/BloodHound Enterprise/Data Connectors/deployment/BloodHoundEnterprise_function_app.json
+++ b/Solutions/BloodHound Enterprise/Data Connectors/deployment/BloodHoundEnterprise_function_app.json
@@ -46,6 +46,13 @@
"metadata": {
"description": " The immutable Id of the Data Collection Rule"
}
+ },
+ "Schedule": {
+ "type": "string",
+ "defaultValue": "0 0 1,13 * * *",
+ "metadata": {
+ "description": "Please enter a valid Quartz cron schedule. The default runs at 1am and 1pm"
+ }
}
},
"variables": {
@@ -55,6 +62,7 @@
"KeyVaultName": "[substring(variables('functionName'), 0, 22)]",
"BHETokenId": "BHETokenId",
"BHETokenKey": "BHETokenKey",
+ "Schedule": "[parameters('Schedule')]",
"keyVaultSecretReader": "[format('/subscriptions/){0}/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6', subscription().subscriptionId)]",
"metricsPublisher": "[format('/subscriptions/){0}/providers/Microsoft.Authorization/roleDefinitions/3913510d-42f4-4e42-8a64-420c390055eb', subscription().subscriptionId)]",
"uniqueRoleGuidMetricsPublisher": "[guid(resourceId('Microsoft.Storage/storageAccounts', variables('functionName')))]",
@@ -204,6 +212,7 @@
"logAnalyticsUri": "[variables('LogAnaltyicsUri')]",
"logsIngestionUrl": "[parameters('logsIngestionUrl')]",
"dcrImmutableId": "[parameters('dcrImmutableId')]",
+ "Schedule": "[variables('Schedule')]",
"WEBSITE_RUN_FROM_PACKAGE": "https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/BloodHound%20Enterprise/Data%20Connectors/bhe-funcapp.zip"
}
}
diff --git a/Solutions/BloodHound Enterprise/Package/3.1.1.zip b/Solutions/BloodHound Enterprise/Package/3.1.1.zip
index d66a1871200..cda96a0c6aa 100644
Binary files a/Solutions/BloodHound Enterprise/Package/3.1.1.zip and b/Solutions/BloodHound Enterprise/Package/3.1.1.zip differ
diff --git a/Solutions/BloodHound Enterprise/Package/createUiDefinition.json b/Solutions/BloodHound Enterprise/Package/createUiDefinition.json
index 1509aad02b2..42d2d7a09d3 100644
--- a/Solutions/BloodHound Enterprise/Package/createUiDefinition.json
+++ b/Solutions/BloodHound Enterprise/Package/createUiDefinition.json
@@ -1,253 +1,253 @@
-{
- "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
- "handler": "Microsoft.Azure.CreateUIDef",
- "version": "0.1.2-preview",
- "parameters": {
- "config": {
- "isWizard": false,
- "basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/BloodHound%20Enterprise/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe BloodHound Enterprise Microsoft Sentinel solution ingests your BloodHound Enterprise posture and attack paths into Microsoft Sentinel. Use the dashboards to track the Active Directory and Azure attack paths of your environment. Create alerts to detect when new attack paths emerge or new the exposure increases.\n\n**Data Connectors:** 1, **Workbooks:** 5, **Analytic Rules:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
- "subscription": {
- "resourceProviders": [
- "Microsoft.OperationsManagement/solutions",
- "Microsoft.OperationalInsights/workspaces/providers/alertRules",
- "Microsoft.Insights/workbooks",
- "Microsoft.Logic/workflows"
- ]
- },
- "location": {
- "metadata": {
- "hidden": "Hiding location, we get it from the log analytics workspace"
- },
- "visible": false
- },
- "resourceGroup": {
- "allowExisting": true
- }
- }
- },
- "basics": [
- {
- "name": "getLAWorkspace",
- "type": "Microsoft.Solutions.ArmApiControl",
- "toolTip": "This filters by workspaces that exist in the Resource Group selected",
- "condition": "[greater(length(resourceGroup().name),0)]",
- "request": {
- "method": "GET",
- "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]"
- }
- },
- {
- "name": "workspace",
- "type": "Microsoft.Common.DropDown",
- "label": "Workspace",
- "placeholder": "Select a workspace",
- "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected",
- "constraints": {
- "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]",
- "required": true
- },
- "visible": true
- }
- ],
- "steps": [
- {
- "name": "dataconnectors",
- "label": "Data Connectors",
- "bladeTitle": "Data Connectors",
- "elements": [
- {
- "name": "dataconnectors1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This Solution installs the data connector for BloodHound Enterprise. You can get BloodHound Enterprise custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
- }
- },
- {
- "name": "dataconnectors-link2",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more about connecting data sources",
- "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources"
- }
- }
- }
- ]
- },
- {
- "name": "workbooks",
- "label": "Workbooks",
- "subLabel": {
- "preValidation": "Configure the workbooks",
- "postValidation": "Done"
- },
- "bladeTitle": "Workbooks",
- "elements": [
- {
- "name": "workbooks-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This Microsoft Sentinel Solution installs workbooks. Workbooks provide a flexible canvas for data monitoring, analysis, and the creation of rich visual reports within the Azure portal. They allow you to tap into one or many data sources from Microsoft Sentinel and combine them into unified interactive experiences."
- }
- },
- {
- "name": "workbooks-link",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more",
- "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data"
- }
- }
- },
- {
- "name": "workbook1",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise Attack Path Details",
- "elements": [
- {
- "name": "workbook1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Gain insights into BloodHound Enterprise attack path details."
- }
- }
- ]
- },
- {
- "name": "workbook2",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise Attack Path Overview",
- "elements": [
- {
- "name": "workbook2-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Gain insights into BloodHound Enterprise attack path."
- }
- }
- ]
- },
- {
- "name": "workbook3",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise Audit Logs",
- "elements": [
- {
- "name": "workbook3-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Gain insights into BloodHound Enterprise audit logs."
- }
- }
- ]
- },
- {
- "name": "workbook4",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise Domain Posture",
- "elements": [
- {
- "name": "workbook4-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Gain insights into BloodHound Enterprise domain posture."
- }
- }
- ]
- },
- {
- "name": "workbook5",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise Tier Zero Search",
- "elements": [
- {
- "name": "workbook5-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Search BloodHound Enterprise Tier Zero data."
- }
- }
- ]
- }
- ]
- },
- {
- "name": "analytics",
- "label": "Analytics",
- "subLabel": {
- "preValidation": "Configure the analytics",
- "postValidation": "Done"
- },
- "bladeTitle": "Analytics",
- "elements": [
- {
- "name": "analytics-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view. "
- }
- },
- {
- "name": "analytics-link",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more",
- "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
- }
- }
- },
- {
- "name": "analytic1",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise - Number of critical attack paths increase",
- "elements": [
- {
- "name": "analytic1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "The number of critical attack paths has increased over the past 7 days."
- }
- }
- ]
- },
- {
- "name": "analytic2",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise - Exposure increase",
- "elements": [
- {
- "name": "analytic2-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "The exposure for a domain has increased by more than 5% over the past 7 days."
- }
- }
- ]
- },
- {
- "name": "analytic3",
- "type": "Microsoft.Common.Section",
- "label": "BloodHound Enterprise - Number of Tier Zero assets increase",
- "elements": [
- {
- "name": "analytic3-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "The number of Tier Zero assets has increased by more than 5% over the past 7 days."
- }
- }
- ]
- }
- ]
- }
- ],
- "outputs": {
- "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]",
- "location": "[location()]",
- "workspace": "[basics('workspace')]"
- }
- }
-}
+{
+ "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
+ "handler": "Microsoft.Azure.CreateUIDef",
+ "version": "0.1.2-preview",
+ "parameters": {
+ "config": {
+ "isWizard": false,
+ "basics": {
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/BloodHound%20Enterprise/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe BloodHound Enterprise Microsoft Sentinel solution ingests your BloodHound Enterprise posture and attack paths into Microsoft Sentinel. Use the dashboards to track the Active Directory and Azure attack paths of your environment. Create alerts to detect when new attack paths emerge or new the exposure increases.\n\n**Data Connectors:** 1, **Workbooks:** 5, **Analytic Rules:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "subscription": {
+ "resourceProviders": [
+ "Microsoft.OperationsManagement/solutions",
+ "Microsoft.OperationalInsights/workspaces/providers/alertRules",
+ "Microsoft.Insights/workbooks",
+ "Microsoft.Logic/workflows"
+ ]
+ },
+ "location": {
+ "metadata": {
+ "hidden": "Hiding location, we get it from the log analytics workspace"
+ },
+ "visible": false
+ },
+ "resourceGroup": {
+ "allowExisting": true
+ }
+ }
+ },
+ "basics": [
+ {
+ "name": "getLAWorkspace",
+ "type": "Microsoft.Solutions.ArmApiControl",
+ "toolTip": "This filters by workspaces that exist in the Resource Group selected",
+ "condition": "[greater(length(resourceGroup().name),0)]",
+ "request": {
+ "method": "GET",
+ "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]"
+ }
+ },
+ {
+ "name": "workspace",
+ "type": "Microsoft.Common.DropDown",
+ "label": "Workspace",
+ "placeholder": "Select a workspace",
+ "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected",
+ "constraints": {
+ "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]",
+ "required": true
+ },
+ "visible": true
+ }
+ ],
+ "steps": [
+ {
+ "name": "dataconnectors",
+ "label": "Data Connectors",
+ "bladeTitle": "Data Connectors",
+ "elements": [
+ {
+ "name": "dataconnectors1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for BloodHound Enterprise. You can get BloodHound Enterprise custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
+ },
+ {
+ "name": "dataconnectors-link2",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more about connecting data sources",
+ "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "name": "workbooks",
+ "label": "Workbooks",
+ "subLabel": {
+ "preValidation": "Configure the workbooks",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Workbooks",
+ "elements": [
+ {
+ "name": "workbooks-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Microsoft Sentinel Solution installs workbooks. Workbooks provide a flexible canvas for data monitoring, analysis, and the creation of rich visual reports within the Azure portal. They allow you to tap into one or many data sources from Microsoft Sentinel and combine them into unified interactive experiences."
+ }
+ },
+ {
+ "name": "workbooks-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data"
+ }
+ }
+ },
+ {
+ "name": "workbook1",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise Attack Path Details",
+ "elements": [
+ {
+ "name": "workbook1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Gain insights into BloodHound Enterprise attack path details."
+ }
+ }
+ ]
+ },
+ {
+ "name": "workbook2",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise Attack Path Overview",
+ "elements": [
+ {
+ "name": "workbook2-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Gain insights into BloodHound Enterprise attack path."
+ }
+ }
+ ]
+ },
+ {
+ "name": "workbook3",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise Audit Logs",
+ "elements": [
+ {
+ "name": "workbook3-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Gain insights into BloodHound Enterprise audit logs."
+ }
+ }
+ ]
+ },
+ {
+ "name": "workbook4",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise Domain Posture",
+ "elements": [
+ {
+ "name": "workbook4-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Gain insights into BloodHound Enterprise domain posture."
+ }
+ }
+ ]
+ },
+ {
+ "name": "workbook5",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise Tier Zero Search",
+ "elements": [
+ {
+ "name": "workbook5-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Search BloodHound Enterprise Tier Zero data."
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "analytics",
+ "label": "Analytics",
+ "subLabel": {
+ "preValidation": "Configure the analytics",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Analytics",
+ "elements": [
+ {
+ "name": "analytics-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view. "
+ }
+ },
+ {
+ "name": "analytics-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
+ }
+ }
+ },
+ {
+ "name": "analytic1",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise - Number of critical attack paths increase",
+ "elements": [
+ {
+ "name": "analytic1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "The number of critical attack paths has increased over the past 7 days."
+ }
+ }
+ ]
+ },
+ {
+ "name": "analytic2",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise - Exposure increase",
+ "elements": [
+ {
+ "name": "analytic2-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "The exposure for a domain has increased by more than 5% over the past 7 days."
+ }
+ }
+ ]
+ },
+ {
+ "name": "analytic3",
+ "type": "Microsoft.Common.Section",
+ "label": "BloodHound Enterprise - Number of Tier Zero assets increase",
+ "elements": [
+ {
+ "name": "analytic3-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "The number of Tier Zero assets has increased by more than 5% over the past 7 days."
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "outputs": {
+ "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]",
+ "location": "[location()]",
+ "workspace": "[basics('workspace')]"
+ }
+ }
+}
diff --git a/Solutions/BloodHound Enterprise/Package/mainTemplate.json b/Solutions/BloodHound Enterprise/Package/mainTemplate.json
index 696a648a69d..ad921297844 100644
--- a/Solutions/BloodHound Enterprise/Package/mainTemplate.json
+++ b/Solutions/BloodHound Enterprise/Package/mainTemplate.json
@@ -1,1293 +1,1271 @@
-{
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "author": "SpecterOps - support@specterops.io",
- "comments": "Solution template for BloodHound Enterprise"
- },
- "parameters": {
- "location": {
- "type": "string",
- "minLength": 1,
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
- }
- },
- "workspace-location": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
- }
- },
- "workspace": {
- "defaultValue": "",
- "type": "string",
- "metadata": {
- "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
- }
- },
- "workbook1-name": {
- "type": "string",
- "defaultValue": "BloodHound Enterprise Attack Path Details",
- "minLength": 1,
- "metadata": {
- "description": "Name for the workbook"
- }
- },
- "workbook2-name": {
- "type": "string",
- "defaultValue": "BloodHound Enterprise Attack Path Overview",
- "minLength": 1,
- "metadata": {
- "description": "Name for the workbook"
- }
- },
- "workbook3-name": {
- "type": "string",
- "defaultValue": "BloodHound Enterprise Audit Logs",
- "minLength": 1,
- "metadata": {
- "description": "Name for the workbook"
- }
- },
- "workbook4-name": {
- "type": "string",
- "defaultValue": "BloodHound Enterprise Domain Posture",
- "minLength": 1,
- "metadata": {
- "description": "Name for the workbook"
- }
- },
- "workbook5-name": {
- "type": "string",
- "defaultValue": "BloodHound Enterprise Tier Zero Search",
- "minLength": 1,
- "metadata": {
- "description": "Name for the workbook"
- }
- }
- },
- "variables": {
- "email": "support@specterops.io",
- "_email": "[variables('email')]",
- "_solutionName": "BloodHound Enterprise",
- "_solutionVersion": "3.1.1",
- "solutionId": "azurehoundenterprise.bloodhoundenterprise-azuresentinel",
- "_solutionId": "[variables('solutionId')]",
- "workbookVersion1": "2.0",
- "workbookContentId1": "BloodHoundEnterpriseAttackPathDetails",
- "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
- "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]",
- "_workbookContentId1": "[variables('workbookContentId1')]",
- "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
- "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
- "workbookVersion2": "2.0",
- "workbookContentId2": "BloodHoundEnterpriseAttackPathOverview",
- "workbookId2": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId2'))]",
- "workbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2'))))]",
- "_workbookContentId2": "[variables('workbookContentId2')]",
- "_workbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId2'),'-', variables('workbookVersion2'))))]",
- "workbookVersion3": "2.0",
- "workbookContentId3": "BloodHoundEnterpriseAuditLogs",
- "workbookId3": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId3'))]",
- "workbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3'))))]",
- "_workbookContentId3": "[variables('workbookContentId3')]",
- "_workbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId3'),'-', variables('workbookVersion3'))))]",
- "workbookVersion4": "2.0",
- "workbookContentId4": "BloodHoundEnterprisePosture",
- "workbookId4": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId4'))]",
- "workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]",
- "_workbookContentId4": "[variables('workbookContentId4')]",
- "_workbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId4'),'-', variables('workbookVersion4'))))]",
- "workbookVersion5": "1.0",
- "workbookContentId5": "BloodHoundEnterpriseTierZeroSearch",
- "workbookId5": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId5'))]",
- "workbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId5'))))]",
- "_workbookContentId5": "[variables('workbookContentId5')]",
- "_workbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId5'),'-', variables('workbookVersion5'))))]",
- "analyticRuleObject1": {
- "analyticRuleVersion1": "1.2.0",
- "_analyticRulecontentId1": "df292d06-f348-41ad-b780-0abb5acfe9ab",
- "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'df292d06-f348-41ad-b780-0abb5acfe9ab')]",
- "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('df292d06-f348-41ad-b780-0abb5acfe9ab')))]",
- "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','df292d06-f348-41ad-b780-0abb5acfe9ab','-', '1.2.0')))]"
- },
- "analyticRuleObject2": {
- "analyticRuleVersion2": "1.2.0",
- "_analyticRulecontentId2": "b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8",
- "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8')]",
- "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8')))]",
- "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8','-', '1.2.0')))]"
- },
- "analyticRuleObject3": {
- "analyticRuleVersion3": "1.2.0",
- "_analyticRulecontentId3": "13424be6-aed7-448b-afe5-c03d8b29b4fe",
- "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '13424be6-aed7-448b-afe5-c03d8b29b4fe')]",
- "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('13424be6-aed7-448b-afe5-c03d8b29b4fe')))]",
- "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','13424be6-aed7-448b-afe5-c03d8b29b4fe','-', '1.2.0')))]"
- },
- "uiConfigId1": "BloodHoundEnterprise",
- "_uiConfigId1": "[variables('uiConfigId1')]",
- "dataConnectorContentId1": "BloodHoundEnterprise",
- "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]",
- "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "_dataConnectorId1": "[variables('dataConnectorId1')]",
- "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
- "dataConnectorVersion1": "1.0.0",
- "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
- "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
- },
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseAttackPathDetails Workbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion1')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId1')]",
- "location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "Gain insights into BloodHound Enterprise attack path details."
- },
- "properties": {
- "displayName": "[parameters('workbook1-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Attack Path Details\\n--- \\n\"},\"name\":\"attack-path-details\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| extend Severity = case(\\n exposure < 40.0, 'low',\\n exposure >= 40.0 and exposure <= 79.0, 'medium',\\n exposure > 79.0 and exposure <= 94.0, 'high',\\n exposure > 94.0, 'critical',\\n 'unknown'\\n )\\n| summarize arg_max(updated_at, *) by domain_id, domain_name, path_type, path_title\\n| sort by round(exposure) desc\\n| project \\n ['Domain'] = domain_name,\\n ['Attack path'] = path_title,\\n Severity,\\n ['Exposure (%)'] = round(exposure, 2)\\n\\n\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"attack-path-details-query1\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
- "properties": {
- "description": "@{workbookKey=BloodHoundEnterpriseAttackPathDetails; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise attack path details.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Attack Path Details; templateRelativePath=BloodHoundEnterpriseAttackPathDetails.json; subtitle=Detailed View; provider=SpecterOps}.description",
- "parentId": "[variables('workbookId1')]",
- "contentId": "[variables('_workbookContentId1')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "BloodHoundLogs_CL",
- "kind": "DataType"
- },
- {
- "contentId": "BloodHoundEnterprise",
- "kind": "DataConnector"
- }
- ]
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId1')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook1-name')]",
- "contentProductId": "[variables('_workbookcontentProductId1')]",
- "id": "[variables('_workbookcontentProductId1')]",
- "version": "[variables('workbookVersion1')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName2')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseAttackPathOverview Workbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion2')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId2')]",
- "location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "Gain insights into BloodHound Enterprise attack path."
- },
- "properties": {
- "displayName": "[parameters('workbook2-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Attack Path Overview\"},\"name\":\"attack-path-overview\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f83ce0ef-a752-49c8-9e57-38e59621e984\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":2592000000},\"label\":\"Time Range\",\"value\":{\"durationMs\":31708800000,\"endTime\":\"2024-12-09T10:37:00Z\"}},{\"id\":\"39b26570-b884-4143-9b01-38a84d7f2663\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"domain_name\",\"label\":\"Domain Name\",\"type\":2,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL \\n| where data_type == \\\"posture_path\\\"\\n| extend domainNameLabel = strcat(domain_name, \\\" (\\\", domain_type, \\\")\\\")\\n| distinct domain_id, domainNameLabel\\n\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"7Y67V8G4-G4DD-6Y87-8764-8S23KJRE9834\"},{\"id\":\"afbf7d11-42d2-4e8c-8b1a-9628bc27ab96\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"attack_path\",\"label\":\"Attack path\",\"type\":2,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| distinct path_type, path_title\\n| order by path_title\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"AzureT0MGAddOwner\"},{\"id\":\"cde4481a-66a9-4c6e-b126-02fa1c4b1b87\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"relationship_type\",\"label\":\"Relation Type\",\"type\":1,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where domain_id == \\\"{domain_name}\\\"\\n| where data_type == \\\"posture_path\\\"\\n| where path_type == \\\"{attack_path}\\\"\\n| extend PathCase = case(\\n path_type hasprefix \\\"LargeDefault\\\", \\\"LargeDefaultRelational\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Relational\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Configuration\\\",\\n \\\"Unknown\\\"\\n)\\n| limit 1\\n| project PathCase\\n| distinct PathCase\",\"isHiddenWhenLocked\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where created_at {time_range}\\n| where path_type == \\\"{attack_path}\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| summarize arg_max(\\\"updated_at\\\", *) by non_tier_zero_principal, tier_zero_principal, principal\\n| extend PathType = path_type\\n| extend PathCase = case(\\n PathType hasprefix \\\"LargeDefault\\\", \\\"Case1\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Case2\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Case3\\\",\\n \\\"Unknown\\\"\\n)\\n// Create columns based on the PathCase\\n| extend [\\\"Group\\\"] = iff(PathCase == \\\"Case1\\\", non_tier_zero_principal, dynamic(null))\\n| extend [\\\"Principal\\\"] = iff(PathCase == \\\"Case1\\\", tier_zero_principal, dynamic(null))\\n| extend [\\\"Non-Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", non_tier_zero_principal, dynamic(null))\\n| extend [\\\"Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", tier_zero_principal, dynamic(null))\\n| extend [\\\"Principal (Tier Zero)\\\"] = iff(PathCase == \\\"Case3\\\", principal, dynamic(null))\\n| extend [\\\"Column Check Error\\\"] = iff(PathCase == \\\"Unknown\\\", tier_zero_principal, dynamic(null))\\n| extend [\\\"PATH_CASE\\\"] = PathCase\\n// Project the relevant columns\\n| project\\n [\\\"Non-Tier Zero Principal\\\"],\\n [\\\"Tier Zero Principal\\\"]\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"conditionalVisibility\":{\"parameterName\":\"relationship_type\",\"comparison\":\"isEqualTo\",\"value\":\"Relational\"},\"customWidth\":\"100\",\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where created_at {time_range} \\n| where path_type == \\\"{attack_path}\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| extend PathType = path_type\\n| extend PathCase = case(\\n PathType hasprefix \\\"LargeDefault\\\", \\\"Case1\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Case2\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Case3\\\",\\n \\\"Unknown\\\"\\n)\\n// Create columns based on the PathCase\\n| extend [\\\"Group\\\"] = iff(PathCase == \\\"Case1\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal\\\"] = iff(PathCase == \\\"Case1\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Non-Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal (Tier Zero)\\\"] = iff(PathCase == \\\"Case3\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Column Check Error\\\"] = iff(PathCase == \\\"Unknown\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"PATH_CASE\\\"] = PathCase\\n// Project the relevant columns\\n| project\\n [\\\"Principal (Tier Zero)\\\"]\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"conditionalVisibility\":{\"parameterName\":\"relationship_type\",\"comparison\":\"isEqualTo\",\"value\":\"Configuration\"},\"customWidth\":\"100\",\"name\":\"query - 3 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where created_at {time_range} \\n| where path_type == \\\"{attack_path}\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| extend PathType = path_type\\n| extend PathCase = case(\\n PathType hasprefix \\\"LargeDefault\\\", \\\"Case1\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Case2\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Case3\\\",\\n \\\"Unknown\\\"\\n)\\n// Create columns based on the PathCase\\n| extend [\\\"Group\\\"] = iff(PathCase == \\\"Case1\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal\\\"] = iff(PathCase == \\\"Case1\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Non-Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal (Tier Zero)\\\"] = iff(PathCase == \\\"Case3\\\", principal, \\\"\\\")\\n| extend [\\\"Column Check Error\\\"] = iff(PathCase == \\\"Unknown\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"PATH_CASE\\\"] = PathCase\\n// Project the relevant columns\\n| project\\n [\\\"Group\\\"],\\n [\\\"Principal\\\"]\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"conditionalVisibility\":{\"parameterName\":\"relationship_type\",\"comparison\":\"isEqualTo\",\"value\":\"LargeDefaultRelational\"},\"customWidth\":\"100\",\"name\":\"query - 3 - Copy - Copy\"},{\"type\":1,\"content\":{\"json\":\"# Exposure %\"},\"name\":\"text - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| where created_at {time_range}\\n| where domain_id == \\\"{domain_name}\\\"\\n| extend exposureAsPercent = exposure/100\\n| summarize max(exposureAsPercent) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xAxis\":\"created_at\",\"yAxis\":[\"max_exposureAsPercent\"],\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimeNoMsPattern\",\"showUtcTime\":false}},\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"percent\",\"useGrouping\":true},\"missingSparkDataOption\":\"Zero\"},\"min\":0,\"max\":1}}},\"name\":\"query - 5\"},{\"type\":1,\"content\":{\"json\":\"# Findings\\n## count\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| where created_at {time_range} \\n| where domain_id == \\\"{domain_name}\\\"\\n| summarize max(finding_count) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xAxis\":\"created_at\",\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimeNoMsPattern\",\"showUtcTime\":false}}}},\"name\":\"query - 8\"},{\"type\":1,\"content\":{\"json\":\"# Principals\\n## count\"},\"name\":\"text - 9\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| where created_at {time_range} \\n| where domain_id == \\\"{domain_name}\\\"\\n| where path_type == \\\"{attack_path}\\\"\\n| summarize max(domain_impact_value) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xAxis\":\"created_at\",\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimeNoMsPattern\",\"showUtcTime\":false}}}},\"name\":\"query - 10\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId2'),'/'))))]",
- "properties": {
- "description": "@{workbookKey=BloodHoundEnterpriseAttackPathOverview; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise attack path.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Attack Path Overview; templateRelativePath=BloodHoundEnterpriseAttackPathOverview.json; subtitle=Overview; provider=SpecterOps}.description",
- "parentId": "[variables('workbookId2')]",
- "contentId": "[variables('_workbookContentId2')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion2')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "BloodHoundLogs_CL",
- "kind": "DataType"
- },
- {
- "contentId": "BloodHoundEnterprise",
- "kind": "DataConnector"
- }
- ]
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId2')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook2-name')]",
- "contentProductId": "[variables('_workbookcontentProductId2')]",
- "id": "[variables('_workbookcontentProductId2')]",
- "version": "[variables('workbookVersion2')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName3')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseAuditLogs Workbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion3')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId3')]",
- "location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "Gain insights into BloodHound Enterprise audit logs."
- },
- "properties": {
- "displayName": "[parameters('workbook3-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Audit Logs\\n---\\n\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f20bb42b-e116-4bc5-9f3d-2fd42491a340\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_param\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":172800000}},{\"id\":\"44ebb9da-a987-4690-8fc5-f844a0c6daee\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"event_type_param\",\"label\":\"Type\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"audit_log\\\"\\n| distinct event_type\\n| project value = event_type\\n| sort by value asc\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"audit_log\\\"\\n| where created_at {time_param}\\n| where event_type in ({event_type_param})\\n| project [\\\"Time\\\"]=created_at, [\\\"Event\\\"]=event_details\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Event\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"90%\"}}]}},\"name\":\"query - 2\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId3'),'/'))))]",
- "properties": {
- "description": "@{workbookKey=BloodHoundEnterpriseAuditLogs; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise audit logs.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Audit Logs; templateRelativePath=BloodHoundEnterpriseAuditLogs.json; subtitle=; provider=SpecterOps}.description",
- "parentId": "[variables('workbookId3')]",
- "contentId": "[variables('_workbookContentId3')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion3')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "BloodHoundLogs_CL",
- "kind": "DataType"
- },
- {
- "contentId": "BloodHoundEnterprise",
- "kind": "DataConnector"
- }
- ]
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId3')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook3-name')]",
- "contentProductId": "[variables('_workbookcontentProductId3')]",
- "id": "[variables('_workbookcontentProductId3')]",
- "version": "[variables('workbookVersion3')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName4')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterprisePosture Workbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion4')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId4')]",
- "location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "Gain insights into BloodHound Enterprise domain posture."
- },
- "properties": {
- "displayName": "[parameters('workbook4-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Posture\"},\"name\":\"posture\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"868cc59a-f969-451f-9d87-e6c554cb54e3\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_range\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":7776000000}},{\"id\":\"586cb0f9-15b3-4887-bf7a-842121615cb0\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"domain_name\",\"label\":\"Domain\",\"type\":2,\"description\":\"Domain to display\",\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| extend domainNameType = strcat(domain_name, \\\" (\\\", domain_type, \\\")\\\")\\n| distinct domain_id, domainNameType\\n| order by domainNameType\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"S-1-5-21-3702535222-3822678775-2090119576\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":1,\"content\":{\"json\":\"## Domain Exposure %\"},\"name\":\"text - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| where created_at {time_range}\\n| where domain_id == '{domain_name}'\\n| summarize max(exposure_index/100) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimePattern\",\"showUtcTime\":true}},\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"percent\",\"useGrouping\":true}},\"min\":0,\"max\":1}}},\"name\":\"query - 2\"},{\"type\":1,\"content\":{\"json\":\"## Critical Attack Paths\"},\"name\":\"text - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| where created_at {time_range} \\n| where domain_id == '{domain_name}'\\n| summarize max(finding_count) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimePattern\",\"showUtcTime\":true}}}},\"name\":\"query - 4\"},{\"type\":1,\"content\":{\"json\":\"## Tier Zero Count\"},\"name\":\"text - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| where created_at {time_range} \\n| where domain_id == '{domain_name}'\\n| summarize max(tier_zero_count) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimePattern\",\"showUtcTime\":true}}}},\"name\":\"query - 7\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId4'),'/'))))]",
- "properties": {
- "description": "@{workbookKey=BloodHoundEnterprisePosture; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise domain posture.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Domain Posture; templateRelativePath=BloodHoundEnterprisePosture.json; subtitle=; provider=SpecterOps}.description",
- "parentId": "[variables('workbookId4')]",
- "contentId": "[variables('_workbookContentId4')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion4')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "BloodHoundLogs_CL",
- "kind": "DataType"
- },
- {
- "contentId": "BloodHoundEnterprise",
- "kind": "DataConnector"
- }
- ]
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId4')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook4-name')]",
- "contentProductId": "[variables('_workbookcontentProductId4')]",
- "id": "[variables('_workbookcontentProductId4')]",
- "version": "[variables('workbookVersion4')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName5')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseTierZeroSearch Workbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion5')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId5')]",
- "location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "Search BloodHound Enterprise Tier Zero data."
- },
- "properties": {
- "displayName": "[parameters('workbook5-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Tier Zero Search\\n---\\n\"},\"name\":\"tier_zero\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"6daab3de-20af-4001-b60c-f726da5e1a36\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"domain_name_param\",\"label\":\"Domain Name\",\"type\":2,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"t0_export\\\"\\n| extend domainNameType = strcat(domain_name, \\\" (\\\", domain_type, \\\")\\\")\\n| distinct domain_id, domainNameType\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"S-1-5-21-2697957641-2271029196-387917394\"},{\"id\":\"cd7af2df-a53e-46a2-bdea-ad99c3f2034f\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"type_param\",\"label\":\"Type\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BloodHoundLogs_CL\\n| where data_type ==\\\"t0_export\\\"\\n| distinct event_details\\n| sort by event_details asc\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type ==\\\"t0_export\\\"\\n| where domain_id == \\\"{domain_name_param}\\\"\\n| where event_details in ({type_param})\\n| summarize arg_max(\\\"updated_at\\\", *) by tier_zero_principal, domain_id, event_details\\n| project [\\\"Name\\\"]=tier_zero_principal, [\\\"Environment Name\\\"]=domain_name, [\\\"Type\\\"]=event_details, [\\\"Object ID\\\"]=finding_id\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Object ID\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Object ID\",\"sortOrder\":1}]},\"name\":\"query - 3\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId5'),'/'))))]",
- "properties": {
- "description": "@{workbookKey=BloodHoundEnterpriseTierZeroSearch; logoFileName=BHE_Logo.svg; description=Search BloodHound Enterprise Tier Zero data.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0; title=BloodHound Enterprise Tier Zero Search; templateRelativePath=BloodHoundEnterpriseTierZeroSearch.json; subtitle=; provider=SpecterOps}.description",
- "parentId": "[variables('workbookId5')]",
- "contentId": "[variables('_workbookContentId5')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion5')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "BloodHoundLogs_CL",
- "kind": "DataType"
- },
- {
- "contentId": "BloodHoundEnterprise",
- "kind": "DataConnector"
- }
- ]
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId5')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook5-name')]",
- "contentProductId": "[variables('_workbookcontentProductId5')]",
- "id": "[variables('_workbookcontentProductId5')]",
- "version": "[variables('workbookVersion5')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseCriticalAttackPaths_AnalyticalRules Analytics Rule with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "apiVersion": "2023-02-01-preview",
- "kind": "Scheduled",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "The number of critical attack paths has increased over the past 7 days.",
- "displayName": "BloodHound Enterprise - Number of critical attack paths increase",
- "enabled": false,
- "query": "BloodHoundLogs_CL\n| where data_type == \"finding_export\"\n| where created_at > ago (7d)\n| summarize min_critical_risk_count = min(finding_count), arg_max(created_at, current_critical_risk_count = finding_count, domain_name) by domain_name\n| extend difference = current_critical_risk_count - min_critical_risk_count\n| where difference > 0",
- "queryFrequency": "P7D",
- "queryPeriod": "P7D",
- "severity": "Medium",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "triggerOperator": "GreaterThan",
- "triggerThreshold": 0,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "connectorId": "BloodHoundEnterprise",
- "dataTypes": [
- "BloodHoundLogs_CL"
- ]
- }
- ],
- "entityMappings": [
- {
- "fieldMappings": [
- {
- "displayName": "domain_name",
- "identifier": "DomainName"
- }
- ],
- "entityType": "DNS"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]",
- "properties": {
- "description": "BloodHound Enterprise Analytics Rule 1",
- "parentId": "[variables('analyticRuleObject1').analyticRuleId1]",
- "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleObject1').analyticRuleVersion1]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "contentKind": "AnalyticsRule",
- "displayName": "BloodHound Enterprise - Number of critical attack paths increase",
- "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
- "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
- "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseExposure_AnalyticalRules Analytics Rule with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "apiVersion": "2023-02-01-preview",
- "kind": "Scheduled",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "The exposure for a domain has increased by more than 5% over the past 7 days.",
- "displayName": "BloodHound Enterprise - Exposure increase",
- "enabled": false,
- "query": "BloodHoundLogs_CL\n| where data_type == \"posture\"\n| where created_at > ago (7d)\n| summarize min(exposure_index), arg_max(created_at, exposure_index, domain_name) by domain_name\n| extend min_exposure = min_exposure_index * 100, latest_exposure = exposure_index * 100\n| where latest_exposure - min_exposure > 5",
- "queryFrequency": "P7D",
- "queryPeriod": "P7D",
- "severity": "High",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "triggerOperator": "GreaterThan",
- "triggerThreshold": 0,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "connectorId": "BloodHoundEnterprise",
- "dataTypes": [
- "BloodHoundLogs_CL"
- ]
- }
- ],
- "entityMappings": [
- {
- "fieldMappings": [
- {
- "displayName": "domain_name",
- "identifier": "DomainName"
- }
- ],
- "entityType": "DNS"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]",
- "properties": {
- "description": "BloodHound Enterprise Analytics Rule 2",
- "parentId": "[variables('analyticRuleObject2').analyticRuleId2]",
- "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleObject2').analyticRuleVersion2]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "contentKind": "AnalyticsRule",
- "displayName": "BloodHound Enterprise - Exposure increase",
- "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
- "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
- "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHoundEnterpriseTierZeroAssets_AnalyticalRules Analytics Rule with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "apiVersion": "2023-02-01-preview",
- "kind": "Scheduled",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "The number of Tier Zero assets has increased by more than 5% over the past 7 days.",
- "displayName": "BloodHound Enterprise - Number of Tier Zero assets increase",
- "enabled": false,
- "query": "BloodHoundLogs_CL\n| where data_type == \"posture\"\n| where created_at > ago (7d)\n| summarize min_tier_zero = min(tier_zero_count), max_tier_zero = arg_max(created_at, current_tier_zero = tier_zero_count, domain_name) by domain_name\n| extend percent_difference = ((current_tier_zero - min_tier_zero) / min_tier_zero) * 100\n| where percent_difference > 5",
- "queryFrequency": "P7D",
- "queryPeriod": "P7D",
- "severity": "Medium",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "triggerOperator": "GreaterThan",
- "triggerThreshold": 0,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "connectorId": "BloodHoundEnterprise",
- "dataTypes": [
- "BloodHoundLogs_CL"
- ]
- }
- ],
- "entityMappings": [
- {
- "fieldMappings": [
- {
- "displayName": "domain_name",
- "identifier": "DomainName"
- }
- ],
- "entityType": "DNS"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]",
- "properties": {
- "description": "BloodHound Enterprise Analytics Rule 3",
- "parentId": "[variables('analyticRuleObject3').analyticRuleId3]",
- "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleObject3').analyticRuleVersion3]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "contentKind": "AnalyticsRule",
- "displayName": "BloodHound Enterprise - Number of Tier Zero assets increase",
- "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
- "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
- "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('dataConnectorTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "BloodHound Enterprise data connector with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('dataConnectorVersion1')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
- "apiVersion": "2021-03-01-preview",
- "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
- "location": "[parameters('workspace-location')]",
- "kind": "GenericUI",
- "properties": {
- "connectorUiConfig": {
- "id": "[variables('_uiConfigId1')]",
- "title": "BloodHound Enterprise (using Azure Functions)",
- "publisher": "SpecterOps",
- "descriptionMarkdown": "The BloodHound Enterprise data connector provides the capability to ingest events from your BloodHound Enterprise instance.",
- "graphQueries": [
- {
- "metricName": "BloodHound Enterprise events",
- "legend": "BloodHoundLogs_CL",
- "baseQuery": "BloodHoundLogs_CL"
- }
- ],
- "sampleQueries": [
- {
- "description": "Data types from BloodHound Enterprise",
- "query": "BloodHoundLogs_CL\n | summarize count() by data_type"
- }
- ],
- "dataTypes": [
- {
- "name": "BloodHoundLogs_CL",
- "lastDataReceivedQuery": "BloodHoundLogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
- }
- ],
- "connectivityCriterias": [
- {
- "type": "IsConnectedQuery",
- "value": [
- "BloodHoundLogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
- ]
- }
- ],
- "availability": {
- "status": 1,
- "isPreview": false
- },
- "permissions": {
- "resourceProvider": [
- {
- "provider": "Microsoft.OperationalInsights/workspaces",
- "permissionsDisplayText": "read and write permissions on the workspace are required.",
- "providerDisplayName": "Workspace",
- "scope": "Workspace",
- "requiredPermissions": {
- "write": true,
- "read": true,
- "delete": true
- }
- },
- {
- "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
- "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
- "providerDisplayName": "Keys",
- "scope": "Workspace",
- "requiredPermissions": {
- "action": true
- }
- }
- ],
- "customs": [
- {
- "name": "Microsoft.Web/sites permissions",
- "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
- },
- {
- "name": "BloodHound Enterprise API key pair",
- "description": "A BloodHound Enterprise API key pair is requried. Refer to the documentation for more information: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
- }
- ]
- },
- "instructionSteps": [
- {
- "description": ">**NOTE:** This connector uses Azure Functions to connect to the BloodHound Enterprise instance to pull its logs into Azure Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
- },
- {
- "description": "**STEP 1 - Configuration steps for the BloodHound Enterprise API**\n\nRefer to the documentation for more information to retreive API keys for your instance: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
- },
- {
- "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the BloodHound Enterprise connector, have the Workspace Name (can be copied from the following), as well as the BloodHound Enterprise API authorization key(s) or Token, readily available.",
- "instructions": [
- {
- "parameters": {
- "fillWith": [
- "workspaceName"
- ],
- "label": "Workspace Name"
- },
- "type": "CopyableLabel"
- }
- ]
- },
- {
- "description": "**Option 1 - Azure Resource Manager (ARM) Template**\n\nUse this method for automated deployment of the BloodHound Enterprise connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Frefs%2Fheads%2Fmaster%2FSolutions%2FBloodHound%2520Enterprise%2FData%2520Connectors%2Fazuredeploy_BloodHoundEnterprise_API_FunctionApp.json)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceName**, **BHEDomain**, **BHETokenId**, **BHETokenKey**, and/or Other required fields.\n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
- },
- {
- "description": "**Option 2 - Manual Deployment of Azure Functions**\n\nUse the following step-by-step instructions to deploy the BloodHound Enterprise connector manually with Azure Functions."
- },
- {
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other#configure-your-environment) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/BloodHound%20Enterprise/Data%20Connectors/bhe-funcapp.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Build the function using the [following instructions](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other?tabs=go%2Cmacos#compile-the-custom-handler-for-azure) \n4. Select the top level folder from extracted files.\n5. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n6. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. bloodhoundenterpriseXX).\n\n\te. **Select a runtime:** Choose Custom.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n7. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n8. Go to Azure Portal for the Function App configuration."
- },
- {
- "description": "**2. Configure the Function App**\n\n 1. In the Function App, select the Function App Name and select **Settings**, then **Environment variables**.\n\n 2. In the **Environment variables** tab, add or modify each of the following variables individually, with their respective string values (case-sensitive): \n\t\t BHEDomain\n\t\t BHETokenId\n\t\t BHETokenKey\n\t\t workspaceID\n\t\t dcrImmutableId\n\t\t logsIngestionUrl\n\t\t logAnalyticsUri (optional)\n\n 3. Once all variables have been set, click **Apply**."
- }
- ],
- "metadata": {
- "version": "1.0.0",
- "kind": "dataConnector"
- }
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2023-04-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
- "properties": {
- "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "kind": "DataConnector",
- "version": "[variables('dataConnectorVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "contentKind": "DataConnector",
- "displayName": "BloodHound Enterprise (using Azure Functions)",
- "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
- "id": "[variables('_dataConnectorcontentProductId1')]",
- "version": "[variables('dataConnectorVersion1')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2023-04-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
- "dependsOn": [
- "[variables('_dataConnectorId1')]"
- ],
- "location": "[parameters('workspace-location')]",
- "properties": {
- "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "kind": "DataConnector",
- "version": "[variables('dataConnectorVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- }
- }
- },
- {
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
- "apiVersion": "2021-03-01-preview",
- "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
- "location": "[parameters('workspace-location')]",
- "kind": "GenericUI",
- "properties": {
- "connectorUiConfig": {
- "title": "BloodHound Enterprise (using Azure Functions)",
- "publisher": "SpecterOps",
- "descriptionMarkdown": "The BloodHound Enterprise data connector provides the capability to ingest events from your BloodHound Enterprise instance.",
- "graphQueries": [
- {
- "metricName": "BloodHound Enterprise events",
- "legend": "BloodHoundLogs_CL",
- "baseQuery": "BloodHoundLogs_CL"
- }
- ],
- "dataTypes": [
- {
- "name": "BloodHoundLogs_CL",
- "lastDataReceivedQuery": "BloodHoundLogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
- }
- ],
- "connectivityCriterias": [
- {
- "type": "IsConnectedQuery",
- "value": [
- "BloodHoundLogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
- ]
- }
- ],
- "sampleQueries": [
- {
- "description": "Data types from BloodHound Enterprise",
- "query": "BloodHoundLogs_CL\n | summarize count() by data_type"
- }
- ],
- "availability": {
- "status": 1,
- "isPreview": false
- },
- "permissions": {
- "resourceProvider": [
- {
- "provider": "Microsoft.OperationalInsights/workspaces",
- "permissionsDisplayText": "read and write permissions on the workspace are required.",
- "providerDisplayName": "Workspace",
- "scope": "Workspace",
- "requiredPermissions": {
- "write": true,
- "read": true,
- "delete": true
- }
- },
- {
- "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
- "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
- "providerDisplayName": "Keys",
- "scope": "Workspace",
- "requiredPermissions": {
- "action": true
- }
- }
- ],
- "customs": [
- {
- "name": "Microsoft.Web/sites permissions",
- "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
- },
- {
- "name": "BloodHound Enterprise API key pair",
- "description": "A BloodHound Enterprise API key pair is requried. Refer to the documentation for more information: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
- }
- ]
- },
- "instructionSteps": [
- {
- "description": ">**NOTE:** This connector uses Azure Functions to connect to the BloodHound Enterprise instance to pull its logs into Azure Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
- },
- {
- "description": "**STEP 1 - Configuration steps for the BloodHound Enterprise API**\n\nRefer to the documentation for more information to retreive API keys for your instance: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
- },
- {
- "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the BloodHound Enterprise connector, have the Workspace Name (can be copied from the following), as well as the BloodHound Enterprise API authorization key(s) or Token, readily available.",
- "instructions": [
- {
- "parameters": {
- "fillWith": [
- "workspaceName"
- ],
- "label": "Workspace Name"
- },
- "type": "CopyableLabel"
- }
- ]
- },
- {
- "description": "**Option 1 - Azure Resource Manager (ARM) Template**\n\nUse this method for automated deployment of the BloodHound Enterprise connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Frefs%2Fheads%2Fmaster%2FSolutions%2FBloodHound%2520Enterprise%2FData%2520Connectors%2Fazuredeploy_BloodHoundEnterprise_API_FunctionApp.json)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceName**, **BHEDomain**, **BHETokenId**, **BHETokenKey**, and/or Other required fields.\n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
- },
- {
- "description": "**Option 2 - Manual Deployment of Azure Functions**\n\nUse the following step-by-step instructions to deploy the BloodHound Enterprise connector manually with Azure Functions."
- },
- {
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other#configure-your-environment) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/BloodHound%20Enterprise/Data%20Connectors/bhe-funcapp.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Build the function using the [following instructions](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other?tabs=go%2Cmacos#compile-the-custom-handler-for-azure) \n4. Select the top level folder from extracted files.\n5. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n6. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. bloodhoundenterpriseXX).\n\n\te. **Select a runtime:** Choose Custom.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n7. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n8. Go to Azure Portal for the Function App configuration."
- },
- {
- "description": "**2. Configure the Function App**\n\n 1. In the Function App, select the Function App Name and select **Settings**, then **Environment variables**.\n\n 2. In the **Environment variables** tab, add or modify each of the following variables individually, with their respective string values (case-sensitive): \n\t\t BHEDomain\n\t\t BHETokenId\n\t\t BHETokenKey\n\t\t workspaceID\n\t\t dcrImmutableId\n\t\t logsIngestionUrl\n\t\t logAnalyticsUri (optional)\n\n 3. Once all variables have been set, click **Apply**."
- }
- ],
- "id": "[variables('_uiConfigId1')]"
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
- "apiVersion": "2023-04-01-preview",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "version": "3.1.1",
- "kind": "Solution",
- "contentSchemaVersion": "3.0.0",
- "displayName": "BloodHound Enterprise",
- "publisherDisplayName": "SpecterOps",
- "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe BloodHound Enterprise Microsoft Sentinel solution ingests your BloodHound Enterprise posture and attack paths into Microsoft Sentinel. Use the dashboards to track the Active Directory and Azure attack paths of your environment. Create alerts to detect when new attack paths emerge or new the exposure increases.
\nData Connectors: 1, Workbooks: 5, Analytic Rules: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
- "contentKind": "Solution",
- "contentProductId": "[variables('_solutioncontentProductId')]",
- "id": "[variables('_solutioncontentProductId')]",
- "icon": "
",
- "contentId": "[variables('_solutionId')]",
- "parentId": "[variables('_solutionId')]",
- "source": {
- "kind": "Solution",
- "name": "BloodHound Enterprise",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "SpecterOps",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "SpecterOps",
- "email": "support@specterops.io",
- "tier": "Partner",
- "link": "https://bloodhoundenterprise.io/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "kind": "Workbook",
- "contentId": "[variables('_workbookContentId1')]",
- "version": "[variables('workbookVersion1')]"
- },
- {
- "kind": "Workbook",
- "contentId": "[variables('_workbookContentId2')]",
- "version": "[variables('workbookVersion2')]"
- },
- {
- "kind": "Workbook",
- "contentId": "[variables('_workbookContentId3')]",
- "version": "[variables('workbookVersion3')]"
- },
- {
- "kind": "Workbook",
- "contentId": "[variables('_workbookContentId4')]",
- "version": "[variables('workbookVersion4')]"
- },
- {
- "kind": "Workbook",
- "contentId": "[variables('_workbookContentId5')]",
- "version": "[variables('workbookVersion5')]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
- },
- {
- "kind": "DataConnector",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "version": "[variables('dataConnectorVersion1')]"
- }
- ]
- },
- "firstPublishDate": "2023-05-04",
- "lastPublishDate": "2021-05-04",
- "providers": [
- "SpecterOps"
- ],
- "categories": {
- "domains": [
- "Security - Network"
- ]
- }
- },
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]"
- }
- ],
- "outputs": {}
-}
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "author": "SpecterOps - support@specterops.io",
+ "comments": "Solution template for BloodHound Enterprise"
+ },
+ "parameters": {
+ "location": {
+ "type": "string",
+ "minLength": 1,
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
+ }
+ },
+ "workspace-location": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
+ }
+ },
+ "workspace": {
+ "defaultValue": "",
+ "type": "string",
+ "metadata": {
+ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
+ }
+ },
+ "workbook1-name": {
+ "type": "string",
+ "defaultValue": "BloodHound Enterprise Attack Path Details",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook2-name": {
+ "type": "string",
+ "defaultValue": "BloodHound Enterprise Attack Path Overview",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook3-name": {
+ "type": "string",
+ "defaultValue": "BloodHound Enterprise Audit Logs",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook4-name": {
+ "type": "string",
+ "defaultValue": "BloodHound Enterprise Domain Posture",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook5-name": {
+ "type": "string",
+ "defaultValue": "BloodHound Enterprise Tier Zero Search",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ }
+ },
+ "variables": {
+ "email": "support@specterops.io",
+ "_email": "[variables('email')]",
+ "_solutionName": "BloodHound Enterprise",
+ "_solutionVersion": "3.1.1",
+ "solutionId": "azurehoundenterprise.bloodhoundenterprise-azuresentinel",
+ "_solutionId": "[variables('solutionId')]",
+ "workbookVersion1": "2.0",
+ "workbookContentId1": "BloodHoundEnterpriseAttackPathDetails",
+ "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
+ "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]",
+ "_workbookContentId1": "[variables('workbookContentId1')]",
+ "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
+ "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
+ "workbookVersion2": "2.0",
+ "workbookContentId2": "BloodHoundEnterpriseAttackPathOverview",
+ "workbookId2": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId2'))]",
+ "workbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2'))))]",
+ "_workbookContentId2": "[variables('workbookContentId2')]",
+ "_workbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId2'),'-', variables('workbookVersion2'))))]",
+ "workbookVersion3": "2.0",
+ "workbookContentId3": "BloodHoundEnterpriseAuditLogs",
+ "workbookId3": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId3'))]",
+ "workbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3'))))]",
+ "_workbookContentId3": "[variables('workbookContentId3')]",
+ "_workbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId3'),'-', variables('workbookVersion3'))))]",
+ "workbookVersion4": "2.0",
+ "workbookContentId4": "BloodHoundEnterprisePosture",
+ "workbookId4": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId4'))]",
+ "workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]",
+ "_workbookContentId4": "[variables('workbookContentId4')]",
+ "_workbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId4'),'-', variables('workbookVersion4'))))]",
+ "workbookVersion5": "1.0",
+ "workbookContentId5": "BloodHoundEnterpriseTierZeroSearch",
+ "workbookId5": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId5'))]",
+ "workbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId5'))))]",
+ "_workbookContentId5": "[variables('workbookContentId5')]",
+ "_workbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId5'),'-', variables('workbookVersion5'))))]",
+ "analyticRuleObject1": {
+ "analyticRuleVersion1": "1.2.0",
+ "_analyticRulecontentId1": "df292d06-f348-41ad-b780-0abb5acfe9ab",
+ "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'df292d06-f348-41ad-b780-0abb5acfe9ab')]",
+ "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('df292d06-f348-41ad-b780-0abb5acfe9ab')))]",
+ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','df292d06-f348-41ad-b780-0abb5acfe9ab','-', '1.2.0')))]"
+ },
+ "analyticRuleObject2": {
+ "analyticRuleVersion2": "1.2.0",
+ "_analyticRulecontentId2": "b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8",
+ "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8')]",
+ "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8')))]",
+ "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b1f6aed2-ebb9-4fe4-bd7c-6657d02a0cc8','-', '1.2.0')))]"
+ },
+ "analyticRuleObject3": {
+ "analyticRuleVersion3": "1.2.0",
+ "_analyticRulecontentId3": "13424be6-aed7-448b-afe5-c03d8b29b4fe",
+ "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '13424be6-aed7-448b-afe5-c03d8b29b4fe')]",
+ "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('13424be6-aed7-448b-afe5-c03d8b29b4fe')))]",
+ "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','13424be6-aed7-448b-afe5-c03d8b29b4fe','-', '1.2.0')))]"
+ },
+ "uiConfigId1": "BloodHoundEnterprise",
+ "_uiConfigId1": "[variables('uiConfigId1')]",
+ "dataConnectorContentId1": "BloodHoundEnterprise",
+ "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]",
+ "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "_dataConnectorId1": "[variables('dataConnectorId1')]",
+ "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
+ "dataConnectorVersion1": "1.0.0",
+ "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
+ "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName1')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseAttackPathDetails Workbook with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion1')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId1')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "Gain insights into BloodHound Enterprise attack path details."
+ },
+ "properties": {
+ "displayName": "[parameters('workbook1-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Attack Path Details\\n--- \\n\"},\"name\":\"attack-path-details\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| extend Severity = case(\\n exposure < 40.0, 'low',\\n exposure >= 40.0 and exposure <= 79.0, 'medium',\\n exposure > 79.0 and exposure <= 94.0, 'high',\\n exposure > 94.0, 'critical',\\n 'unknown'\\n )\\n| summarize arg_max(updated_at, *) by domain_id, domain_name, path_type, path_title\\n| sort by round(exposure) desc\\n| project \\n ['Domain'] = domain_name,\\n ['Attack path'] = path_title,\\n Severity,\\n ['Exposure (%)'] = round(exposure, 2)\\n\\n\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"attack-path-details-query1\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=BloodHoundEnterpriseAttackPathDetails; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise attack path details.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Attack Path Details; templateRelativePath=BloodHoundEnterpriseAttackPathDetails.json; subtitle=Detailed View; provider=SpecterOps}.description",
+ "parentId": "[variables('workbookId1')]",
+ "contentId": "[variables('_workbookContentId1')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "BloodHoundLogs_CL",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "BloodHoundEnterprise",
+ "kind": "DataConnector"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId1')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook1-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId1')]",
+ "id": "[variables('_workbookcontentProductId1')]",
+ "version": "[variables('workbookVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName2')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseAttackPathOverview Workbook with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion2')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId2')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "Gain insights into BloodHound Enterprise attack path."
+ },
+ "properties": {
+ "displayName": "[parameters('workbook2-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Attack Path Overview\"},\"name\":\"attack-path-overview\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f83ce0ef-a752-49c8-9e57-38e59621e984\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":2592000000},\"label\":\"Time Range\",\"value\":{\"durationMs\":31708800000,\"endTime\":\"2024-12-09T10:37:00Z\"}},{\"id\":\"39b26570-b884-4143-9b01-38a84d7f2663\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"domain_name\",\"label\":\"Domain Name\",\"type\":2,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL \\n| where data_type == \\\"posture_path\\\"\\n| extend domainNameLabel = strcat(domain_name, \\\" (\\\", domain_type, \\\")\\\")\\n| distinct domain_id, domainNameLabel\\n\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"7Y67V8G4-G4DD-6Y87-8764-8S23KJRE9834\"},{\"id\":\"afbf7d11-42d2-4e8c-8b1a-9628bc27ab96\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"attack_path\",\"label\":\"Attack path\",\"type\":2,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| distinct path_type, path_title\\n| order by path_title\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"AzureT0MGAddOwner\"},{\"id\":\"cde4481a-66a9-4c6e-b126-02fa1c4b1b87\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"relationship_type\",\"label\":\"Relation Type\",\"type\":1,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where domain_id == \\\"{domain_name}\\\"\\n| where data_type == \\\"posture_path\\\"\\n| where path_type == \\\"{attack_path}\\\"\\n| extend PathCase = case(\\n path_type hasprefix \\\"LargeDefault\\\", \\\"LargeDefaultRelational\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Relational\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Configuration\\\",\\n \\\"Unknown\\\"\\n)\\n| limit 1\\n| project PathCase\\n| distinct PathCase\",\"isHiddenWhenLocked\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where created_at {time_range}\\n| where path_type == \\\"{attack_path}\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| summarize arg_max(\\\"updated_at\\\", *) by non_tier_zero_principal, tier_zero_principal, principal\\n| extend PathType = path_type\\n| extend PathCase = case(\\n PathType hasprefix \\\"LargeDefault\\\", \\\"Case1\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Case2\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Case3\\\",\\n \\\"Unknown\\\"\\n)\\n// Create columns based on the PathCase\\n| extend [\\\"Group\\\"] = iff(PathCase == \\\"Case1\\\", non_tier_zero_principal, dynamic(null))\\n| extend [\\\"Principal\\\"] = iff(PathCase == \\\"Case1\\\", tier_zero_principal, dynamic(null))\\n| extend [\\\"Non-Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", non_tier_zero_principal, dynamic(null))\\n| extend [\\\"Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", tier_zero_principal, dynamic(null))\\n| extend [\\\"Principal (Tier Zero)\\\"] = iff(PathCase == \\\"Case3\\\", principal, dynamic(null))\\n| extend [\\\"Column Check Error\\\"] = iff(PathCase == \\\"Unknown\\\", tier_zero_principal, dynamic(null))\\n| extend [\\\"PATH_CASE\\\"] = PathCase\\n// Project the relevant columns\\n| project\\n [\\\"Non-Tier Zero Principal\\\"],\\n [\\\"Tier Zero Principal\\\"]\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"conditionalVisibility\":{\"parameterName\":\"relationship_type\",\"comparison\":\"isEqualTo\",\"value\":\"Relational\"},\"customWidth\":\"100\",\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where created_at {time_range} \\n| where path_type == \\\"{attack_path}\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| extend PathType = path_type\\n| extend PathCase = case(\\n PathType hasprefix \\\"LargeDefault\\\", \\\"Case1\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Case2\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Case3\\\",\\n \\\"Unknown\\\"\\n)\\n// Create columns based on the PathCase\\n| extend [\\\"Group\\\"] = iff(PathCase == \\\"Case1\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal\\\"] = iff(PathCase == \\\"Case1\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Non-Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal (Tier Zero)\\\"] = iff(PathCase == \\\"Case3\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Column Check Error\\\"] = iff(PathCase == \\\"Unknown\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"PATH_CASE\\\"] = PathCase\\n// Project the relevant columns\\n| project\\n [\\\"Principal (Tier Zero)\\\"]\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"conditionalVisibility\":{\"parameterName\":\"relationship_type\",\"comparison\":\"isEqualTo\",\"value\":\"Configuration\"},\"customWidth\":\"100\",\"name\":\"query - 3 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture_path\\\"\\n| where created_at {time_range} \\n| where path_type == \\\"{attack_path}\\\"\\n| where domain_id == \\\"{domain_name}\\\"\\n| extend PathType = path_type\\n| extend PathCase = case(\\n PathType hasprefix \\\"LargeDefault\\\", \\\"Case1\\\",\\n isnotempty(tier_zero_principal) and isnotempty(non_tier_zero_principal), \\\"Case2\\\",\\n isnotempty(tier_zero_principal) and isempty(non_tier_zero_principal), \\\"Case3\\\",\\n \\\"Unknown\\\"\\n)\\n// Create columns based on the PathCase\\n| extend [\\\"Group\\\"] = iff(PathCase == \\\"Case1\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal\\\"] = iff(PathCase == \\\"Case1\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Non-Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", non_tier_zero_principal, \\\"\\\")\\n| extend [\\\"Tier Zero Principal\\\"] = iff(PathCase == \\\"Case2\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"Principal (Tier Zero)\\\"] = iff(PathCase == \\\"Case3\\\", principal, \\\"\\\")\\n| extend [\\\"Column Check Error\\\"] = iff(PathCase == \\\"Unknown\\\", tier_zero_principal, \\\"\\\")\\n| extend [\\\"PATH_CASE\\\"] = PathCase\\n// Project the relevant columns\\n| project\\n [\\\"Group\\\"],\\n [\\\"Principal\\\"]\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"conditionalVisibility\":{\"parameterName\":\"relationship_type\",\"comparison\":\"isEqualTo\",\"value\":\"LargeDefaultRelational\"},\"customWidth\":\"100\",\"name\":\"query - 3 - Copy - Copy\"},{\"type\":1,\"content\":{\"json\":\"# Exposure %\"},\"name\":\"text - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| where created_at {time_range}\\n| where domain_id == \\\"{domain_name}\\\"\\n| extend exposureAsPercent = exposure/100\\n| summarize max(exposureAsPercent) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xAxis\":\"created_at\",\"yAxis\":[\"max_exposureAsPercent\"],\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimeNoMsPattern\",\"showUtcTime\":false}},\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"percent\",\"useGrouping\":true},\"missingSparkDataOption\":\"Zero\"},\"min\":0,\"max\":1}}},\"name\":\"query - 5\"},{\"type\":1,\"content\":{\"json\":\"# Findings\\n## count\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| where created_at {time_range} \\n| where domain_id == \\\"{domain_name}\\\"\\n| summarize max(finding_count) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xAxis\":\"created_at\",\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimeNoMsPattern\",\"showUtcTime\":false}}}},\"name\":\"query - 8\"},{\"type\":1,\"content\":{\"json\":\"# Principals\\n## count\"},\"name\":\"text - 9\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"finding_export\\\"\\n| where created_at {time_range} \\n| where domain_id == \\\"{domain_name}\\\"\\n| where path_type == \\\"{attack_path}\\\"\\n| summarize max(domain_impact_value) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xAxis\":\"created_at\",\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimeNoMsPattern\",\"showUtcTime\":false}}}},\"name\":\"query - 10\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId2'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=BloodHoundEnterpriseAttackPathOverview; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise attack path.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Attack Path Overview; templateRelativePath=BloodHoundEnterpriseAttackPathOverview.json; subtitle=Overview; provider=SpecterOps}.description",
+ "parentId": "[variables('workbookId2')]",
+ "contentId": "[variables('_workbookContentId2')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion2')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "BloodHoundLogs_CL",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "BloodHoundEnterprise",
+ "kind": "DataConnector"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId2')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook2-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId2')]",
+ "id": "[variables('_workbookcontentProductId2')]",
+ "version": "[variables('workbookVersion2')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName3')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseAuditLogs Workbook with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion3')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId3')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "Gain insights into BloodHound Enterprise audit logs."
+ },
+ "properties": {
+ "displayName": "[parameters('workbook3-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Audit Logs\\n---\\n\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f20bb42b-e116-4bc5-9f3d-2fd42491a340\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_param\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":172800000}},{\"id\":\"44ebb9da-a987-4690-8fc5-f844a0c6daee\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"event_type_param\",\"label\":\"Type\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"audit_log\\\"\\n| distinct event_type\\n| project value = event_type\\n| sort by value asc\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"audit_log\\\"\\n| where created_at {time_param}\\n| where event_type in ({event_type_param})\\n| project [\\\"Time\\\"]=created_at, [\\\"Event\\\"]=event_details\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Event\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"90%\"}}]}},\"name\":\"query - 2\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId3'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=BloodHoundEnterpriseAuditLogs; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise audit logs.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Audit Logs; templateRelativePath=BloodHoundEnterpriseAuditLogs.json; subtitle=; provider=SpecterOps}.description",
+ "parentId": "[variables('workbookId3')]",
+ "contentId": "[variables('_workbookContentId3')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion3')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "BloodHoundLogs_CL",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "BloodHoundEnterprise",
+ "kind": "DataConnector"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId3')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook3-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId3')]",
+ "id": "[variables('_workbookcontentProductId3')]",
+ "version": "[variables('workbookVersion3')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName4')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterprisePosture Workbook with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion4')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId4')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "Gain insights into BloodHound Enterprise domain posture."
+ },
+ "properties": {
+ "displayName": "[parameters('workbook4-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Posture\"},\"name\":\"posture\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"868cc59a-f969-451f-9d87-e6c554cb54e3\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_range\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":7776000000}},{\"id\":\"586cb0f9-15b3-4887-bf7a-842121615cb0\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"domain_name\",\"label\":\"Domain\",\"type\":2,\"description\":\"Domain to display\",\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| extend domainNameType = strcat(domain_name, \\\" (\\\", domain_type, \\\")\\\")\\n| distinct domain_id, domainNameType\\n| order by domainNameType\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"S-1-5-21-3702535222-3822678775-2090119576\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":1,\"content\":{\"json\":\"## Domain Exposure %\"},\"name\":\"text - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| where created_at {time_range}\\n| where domain_id == '{domain_name}'\\n| summarize max(exposure_index/100) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimePattern\",\"showUtcTime\":true}},\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"percent\",\"useGrouping\":true}},\"min\":0,\"max\":1}}},\"name\":\"query - 2\"},{\"type\":1,\"content\":{\"json\":\"## Critical Attack Paths\"},\"name\":\"text - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| where created_at {time_range} \\n| where domain_id == '{domain_name}'\\n| summarize max(finding_count) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimePattern\",\"showUtcTime\":true}}}},\"name\":\"query - 4\"},{\"type\":1,\"content\":{\"json\":\"## Tier Zero Count\"},\"name\":\"text - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"posture\\\"\\n| where created_at {time_range} \\n| where domain_id == '{domain_name}'\\n| summarize max(tier_zero_count) by bin(created_at, 1d), domain_name\",\"size\":0,\"aggregation\":5,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\",\"chartSettings\":{\"xSettings\":{\"dateFormatSettings\":{\"formatName\":\"shortDateTimePattern\",\"showUtcTime\":true}}}},\"name\":\"query - 7\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId4'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=BloodHoundEnterprisePosture; logoFileName=BHE_Logo.svg; description=Gain insights into BloodHound Enterprise domain posture.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0; title=BloodHound Enterprise Domain Posture; templateRelativePath=BloodHoundEnterprisePosture.json; subtitle=; provider=SpecterOps}.description",
+ "parentId": "[variables('workbookId4')]",
+ "contentId": "[variables('_workbookContentId4')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion4')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "BloodHoundLogs_CL",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "BloodHoundEnterprise",
+ "kind": "DataConnector"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId4')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook4-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId4')]",
+ "id": "[variables('_workbookcontentProductId4')]",
+ "version": "[variables('workbookVersion4')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName5')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseTierZeroSearch Workbook with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion5')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId5')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "Search BloodHound Enterprise Tier Zero data."
+ },
+ "properties": {
+ "displayName": "[parameters('workbook5-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Tier Zero Search\\n---\\n\"},\"name\":\"tier_zero\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"6daab3de-20af-4001-b60c-f726da5e1a36\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"domain_name_param\",\"label\":\"Domain Name\",\"type\":2,\"isRequired\":true,\"query\":\"BloodHoundLogs_CL\\n| where data_type == \\\"t0_export\\\"\\n| extend domainNameType = strcat(domain_name, \\\" (\\\", domain_type, \\\")\\\")\\n| distinct domain_id, domainNameType\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"S-1-5-21-2697957641-2271029196-387917394\"},{\"id\":\"cd7af2df-a53e-46a2-bdea-ad99c3f2034f\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"type_param\",\"label\":\"Type\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BloodHoundLogs_CL\\n| where data_type ==\\\"t0_export\\\"\\n| distinct event_details\\n| sort by event_details asc\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BloodHoundLogs_CL\\n| where data_type ==\\\"t0_export\\\"\\n| where domain_id == \\\"{domain_name_param}\\\"\\n| where event_details in ({type_param})\\n| summarize arg_max(\\\"updated_at\\\", *) by tier_zero_principal, domain_id, event_details\\n| project [\\\"Name\\\"]=tier_zero_principal, [\\\"Environment Name\\\"]=domain_name, [\\\"Type\\\"]=event_details, [\\\"Object ID\\\"]=finding_id\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Object ID\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Object ID\",\"sortOrder\":1}]},\"name\":\"query - 3\"}],\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId5'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=BloodHoundEnterpriseTierZeroSearch; logoFileName=BHE_Logo.svg; description=Search BloodHound Enterprise Tier Zero data.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0; title=BloodHound Enterprise Tier Zero Search; templateRelativePath=BloodHoundEnterpriseTierZeroSearch.json; subtitle=; provider=SpecterOps}.description",
+ "parentId": "[variables('workbookId5')]",
+ "contentId": "[variables('_workbookContentId5')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion5')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "BloodHoundLogs_CL",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "BloodHoundEnterprise",
+ "kind": "DataConnector"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId5')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook5-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId5')]",
+ "id": "[variables('_workbookcontentProductId5')]",
+ "version": "[variables('workbookVersion5')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseCriticalAttackPaths_AnalyticalRules Analytics Rule with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "Scheduled",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "The number of critical attack paths has increased over the past 7 days.",
+ "displayName": "BloodHound Enterprise - Number of critical attack paths increase",
+ "enabled": false,
+ "query": "BloodHoundLogs_CL\n| where data_type == \"finding_export\"\n| where created_at > ago (7d)\n| summarize min_critical_risk_count = min(finding_count), arg_max(created_at, current_critical_risk_count = finding_count, domain_name) by domain_name\n| extend difference = current_critical_risk_count - min_critical_risk_count\n| where difference > 0",
+ "queryFrequency": "P7D",
+ "queryPeriod": "P7D",
+ "severity": "Medium",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "triggerOperator": "GreaterThan",
+ "triggerThreshold": 0,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "BloodHoundLogs_CL"
+ ],
+ "connectorId": "BloodHoundEnterprise"
+ }
+ ],
+ "entityMappings": [
+ {
+ "entityType": "DNS",
+ "fieldMappings": [
+ {
+ "identifier": "DomainName",
+ "displayName": "domain_name"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]",
+ "properties": {
+ "description": "BloodHound Enterprise Analytics Rule 1",
+ "parentId": "[variables('analyticRuleObject1').analyticRuleId1]",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "BloodHound Enterprise - Number of critical attack paths increase",
+ "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseExposure_AnalyticalRules Analytics Rule with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "Scheduled",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "The exposure for a domain has increased by more than 5% over the past 7 days.",
+ "displayName": "BloodHound Enterprise - Exposure increase",
+ "enabled": false,
+ "query": "BloodHoundLogs_CL\n| where data_type == \"posture\"\n| where created_at > ago (7d)\n| summarize min(exposure_index), arg_max(created_at, exposure_index, domain_name) by domain_name\n| extend min_exposure = min_exposure_index * 100, latest_exposure = exposure_index * 100\n| where latest_exposure - min_exposure > 5",
+ "queryFrequency": "P7D",
+ "queryPeriod": "P7D",
+ "severity": "High",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "triggerOperator": "GreaterThan",
+ "triggerThreshold": 0,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "BloodHoundLogs_CL"
+ ],
+ "connectorId": "BloodHoundEnterprise"
+ }
+ ],
+ "entityMappings": [
+ {
+ "entityType": "DNS",
+ "fieldMappings": [
+ {
+ "identifier": "DomainName",
+ "displayName": "domain_name"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]",
+ "properties": {
+ "description": "BloodHound Enterprise Analytics Rule 2",
+ "parentId": "[variables('analyticRuleObject2').analyticRuleId2]",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "BloodHound Enterprise - Exposure increase",
+ "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHoundEnterpriseTierZeroAssets_AnalyticalRules Analytics Rule with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "Scheduled",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "The number of Tier Zero assets has increased by more than 5% over the past 7 days.",
+ "displayName": "BloodHound Enterprise - Number of Tier Zero assets increase",
+ "enabled": false,
+ "query": "BloodHoundLogs_CL\n| where data_type == \"posture\"\n| where created_at > ago (7d)\n| summarize min_tier_zero = min(tier_zero_count), max_tier_zero = arg_max(created_at, current_tier_zero = tier_zero_count, domain_name) by domain_name\n| extend percent_difference = ((current_tier_zero - min_tier_zero) / min_tier_zero) * 100\n| where percent_difference > 5",
+ "queryFrequency": "P7D",
+ "queryPeriod": "P7D",
+ "severity": "Medium",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "triggerOperator": "GreaterThan",
+ "triggerThreshold": 0,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "BloodHoundLogs_CL"
+ ],
+ "connectorId": "BloodHoundEnterprise"
+ }
+ ],
+ "entityMappings": [
+ {
+ "entityType": "DNS",
+ "fieldMappings": [
+ {
+ "identifier": "DomainName",
+ "displayName": "domain_name"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]",
+ "properties": {
+ "description": "BloodHound Enterprise Analytics Rule 3",
+ "parentId": "[variables('analyticRuleObject3').analyticRuleId3]",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "BloodHound Enterprise - Number of Tier Zero assets increase",
+ "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName1')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "BloodHound Enterprise data connector with template version 3.1.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion1')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId1')]",
+ "title": "BloodHound Enterprise (using Azure Functions)",
+ "publisher": "SpecterOps",
+ "descriptionMarkdown": "The BloodHound Enterprise data connector provides the capability to ingest events from your BloodHound Enterprise instance.",
+ "graphQueries": [
+ {
+ "metricName": "BloodHound Enterprise events",
+ "legend": "BloodHoundLogs_CL",
+ "baseQuery": "BloodHoundLogs_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Data types from BloodHound Enterprise",
+ "query": "BloodHoundLogs_CL\n | summarize count() by data_type"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "BloodHoundLogs_CL",
+ "lastDataReceivedQuery": "BloodHoundLogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "BloodHoundLogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "BloodHound Enterprise API key pair",
+ "description": "A BloodHound Enterprise API key pair is requried. Refer to the documentation for more information: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This connector uses Azure Functions to connect to the BloodHound Enterprise instance to pull its logs into Azure Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
+ },
+ {
+ "description": "**STEP 1 - Configuration steps for the BloodHound Enterprise API**\n\nRefer to the documentation for more information to retreive API keys for your instance: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
+ },
+ {
+ "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the BloodHound Enterprise connector, have the Log Analytics Workspace Name, as well as the BloodHound Enterprise API authorization key(s) or Token, readily available."
+ },
+ {
+ "description": "**Option 1 - Azure Resource Manager (ARM) Template**\n\nUse this method for automated deployment of the BloodHound Enterprise connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Frefs%2Fheads%2Fmaster%2FSolutions%2FBloodHound%2520Enterprise%2FData%2520Connectors%2Fazuredeploy_BloodHoundEnterprise_API_FunctionApp.json)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceName**, **BHEDomain**, **BHETokenId**, **BHETokenKey**, and/or Other required fields.\n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "description": "**Option 2 - Manual Deployment of Azure Functions**\n\nUse the following step-by-step instructions to deploy the BloodHound Enterprise connector manually with Azure Functions."
+ },
+ {
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other#configure-your-environment) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/BloodHound%20Enterprise/Data%20Connectors/bhe-funcapp.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Build the function using the [following instructions](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other?tabs=go%2Cmacos#compile-the-custom-handler-for-azure) \n4. Select the top level folder from extracted files.\n5. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n6. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. bloodhoundenterpriseXX).\n\n\te. **Select a runtime:** Choose Custom.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n7. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n8. Go to Azure Portal for the Function App configuration."
+ },
+ {
+ "description": "**2. Configure the Function App**\n\n 1. In the Function App, select the Function App Name and select **Settings**, then **Environment variables**.\n\n 2. In the **Environment variables** tab, add or modify each of the following variables individually, with their respective string values (case-sensitive): \n\t\t BHEDomain\n\t\t BHETokenId\n\t\t BHETokenKey\n\t\t workspaceID\n\t\t dcrImmutableId\n\t\t logsIngestionUrl\n\t\t logAnalyticsUri (optional)\n\n 3. Once all variables have been set, click **Apply**."
+ }
+ ],
+ "metadata": {
+ "version": "1.0.0",
+ "kind": "dataConnector"
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "contentKind": "DataConnector",
+ "displayName": "BloodHound Enterprise (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
+ "id": "[variables('_dataConnectorcontentProductId1')]",
+ "version": "[variables('dataConnectorVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId1')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "BloodHound Enterprise (using Azure Functions)",
+ "publisher": "SpecterOps",
+ "descriptionMarkdown": "The BloodHound Enterprise data connector provides the capability to ingest events from your BloodHound Enterprise instance.",
+ "graphQueries": [
+ {
+ "metricName": "BloodHound Enterprise events",
+ "legend": "BloodHoundLogs_CL",
+ "baseQuery": "BloodHoundLogs_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "BloodHoundLogs_CL",
+ "lastDataReceivedQuery": "BloodHoundLogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "BloodHoundLogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Data types from BloodHound Enterprise",
+ "query": "BloodHoundLogs_CL\n | summarize count() by data_type"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "BloodHound Enterprise API key pair",
+ "description": "A BloodHound Enterprise API key pair is requried. Refer to the documentation for more information: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This connector uses Azure Functions to connect to the BloodHound Enterprise instance to pull its logs into Azure Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
+ },
+ {
+ "description": "**STEP 1 - Configuration steps for the BloodHound Enterprise API**\n\nRefer to the documentation for more information to retreive API keys for your instance: [Working with the BloodHound Enterprise API](https://support.bloodhoundenterprise.io/hc/articles/11311053342619-Working-with-the-BloodHound-Enterprise-API)."
+ },
+ {
+ "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the BloodHound Enterprise connector, have the Log Analytics Workspace Name, as well as the BloodHound Enterprise API authorization key(s) or Token, readily available."
+ },
+ {
+ "description": "**Option 1 - Azure Resource Manager (ARM) Template**\n\nUse this method for automated deployment of the BloodHound Enterprise connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Frefs%2Fheads%2Fmaster%2FSolutions%2FBloodHound%2520Enterprise%2FData%2520Connectors%2Fazuredeploy_BloodHoundEnterprise_API_FunctionApp.json)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceName**, **BHEDomain**, **BHETokenId**, **BHETokenKey**, and/or Other required fields.\n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "description": "**Option 2 - Manual Deployment of Azure Functions**\n\nUse the following step-by-step instructions to deploy the BloodHound Enterprise connector manually with Azure Functions."
+ },
+ {
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other#configure-your-environment) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Solutions/BloodHound%20Enterprise/Data%20Connectors/bhe-funcapp.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Build the function using the [following instructions](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-other?tabs=go%2Cmacos#compile-the-custom-handler-for-azure) \n4. Select the top level folder from extracted files.\n5. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n6. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. bloodhoundenterpriseXX).\n\n\te. **Select a runtime:** Choose Custom.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n7. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n8. Go to Azure Portal for the Function App configuration."
+ },
+ {
+ "description": "**2. Configure the Function App**\n\n 1. In the Function App, select the Function App Name and select **Settings**, then **Environment variables**.\n\n 2. In the **Environment variables** tab, add or modify each of the following variables individually, with their respective string values (case-sensitive): \n\t\t BHEDomain\n\t\t BHETokenId\n\t\t BHETokenKey\n\t\t workspaceID\n\t\t dcrImmutableId\n\t\t logsIngestionUrl\n\t\t logAnalyticsUri (optional)\n\n 3. Once all variables have been set, click **Apply**."
+ }
+ ],
+ "id": "[variables('_uiConfigId1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
+ "apiVersion": "2023-04-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "version": "3.1.1",
+ "kind": "Solution",
+ "contentSchemaVersion": "3.0.0",
+ "displayName": "BloodHound Enterprise",
+ "publisherDisplayName": "SpecterOps",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe BloodHound Enterprise Microsoft Sentinel solution ingests your BloodHound Enterprise posture and attack paths into Microsoft Sentinel. Use the dashboards to track the Active Directory and Azure attack paths of your environment. Create alerts to detect when new attack paths emerge or new the exposure increases.
\nData Connectors: 1, Workbooks: 5, Analytic Rules: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "contentKind": "Solution",
+ "contentProductId": "[variables('_solutioncontentProductId')]",
+ "id": "[variables('_solutioncontentProductId')]",
+ "icon": "
",
+ "contentId": "[variables('_solutionId')]",
+ "parentId": "[variables('_solutionId')]",
+ "source": {
+ "kind": "Solution",
+ "name": "BloodHound Enterprise",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "SpecterOps",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "SpecterOps",
+ "email": "support@specterops.io",
+ "tier": "Partner",
+ "link": "https://bloodhoundenterprise.io/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId1')]",
+ "version": "[variables('workbookVersion1')]"
+ },
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId2')]",
+ "version": "[variables('workbookVersion2')]"
+ },
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId3')]",
+ "version": "[variables('workbookVersion3')]"
+ },
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId4')]",
+ "version": "[variables('workbookVersion4')]"
+ },
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId5')]",
+ "version": "[variables('workbookVersion5')]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
+ },
+ {
+ "kind": "DataConnector",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "version": "[variables('dataConnectorVersion1')]"
+ }
+ ]
+ },
+ "firstPublishDate": "2023-05-04",
+ "lastPublishDate": "2021-05-04",
+ "providers": [
+ "SpecterOps"
+ ],
+ "categories": {
+ "domains": [
+ "Security - Network"
+ ]
+ }
+ },
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]"
+ }
+ ],
+ "outputs": {}
+}
diff --git a/Solutions/BloodHound Enterprise/ReleaseNotes.md b/Solutions/BloodHound Enterprise/ReleaseNotes.md
index 94c4108f218..1f1b3e0f376 100644
--- a/Solutions/BloodHound Enterprise/ReleaseNotes.md
+++ b/Solutions/BloodHound Enterprise/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.1.1 | 03-01-2025 | Fixed compilation error in golang **Data Connector** function app. Removed non-working function app installation hint, the workspace name. |
+| | 17-12-2024 | Updated **Workbooks**- principals now shown properly, percentages calculated correctly, **Data Connector** function app mapping to custom table fixed |
+| 3.1.0 | 17-11-2024 | Updated Solution: table schema updated, new **Workbooks**, new golang **Data Connector** function app uses bloodhound-golang-sdk |
| 3.0.0 | 20-07-2023 | Initial Solution Release |
-| 3.1.0 | 17-11-2024 | Updated Solution: table schema updated, new workbooks, new golang function app uses bloodhound-golang-sdk |
-| 3.1.1 | 17-12-2024 | Updated workbooks- principals now shown properly, percentages calculated correctly, function app mapping to custom table fixed |
diff --git a/Solutions/Box/Data Connectors/BoxConn.zip b/Solutions/Box/Data Connectors/BoxConn.zip
index 9563010c0e4..894493319fc 100644
Binary files a/Solutions/Box/Data Connectors/BoxConn.zip and b/Solutions/Box/Data Connectors/BoxConn.zip differ
diff --git a/Solutions/Box/Data Connectors/BoxEvents_ccp/BoxEvents_DataConnectorDefinition.json b/Solutions/Box/Data Connectors/BoxEvents_ccp/BoxEvents_DataConnectorDefinition.json
index d3c6be1fb74..ba994dacc3c 100644
--- a/Solutions/Box/Data Connectors/BoxEvents_ccp/BoxEvents_DataConnectorDefinition.json
+++ b/Solutions/Box/Data Connectors/BoxEvents_ccp/BoxEvents_DataConnectorDefinition.json
@@ -8,7 +8,7 @@
"properties": {
"connectorUiConfig": {
"id": "BoxEventsCCPDefinition",
- "title": "Box Events (CCP) (Preview)",
+ "title": "Box Events (CCP)",
"publisher": "Microsoft",
"descriptionMarkdown": "The Box data connector provides the capability to ingest [Box enterprise's events](https://developer.box.com/guides/events/#admin-events) into Microsoft Sentinel using the Box REST API. Refer to [Box documentation](https://developer.box.com/guides/events/enterprise-events/for-enterprise/) for more information.",
"graphQueriesTableName": "BoxEventsV2_CL",
diff --git a/Solutions/Box/Data Connectors/requirements.txt b/Solutions/Box/Data Connectors/requirements.txt
index 2f32c7d842f..b1ba3e46bd5 100644
--- a/Solutions/Box/Data Connectors/requirements.txt
+++ b/Solutions/Box/Data Connectors/requirements.txt
@@ -5,7 +5,7 @@
azure-functions
pyjwt==2.4.0
-cryptography==43.0.1
+cryptography==44.0.1
boxsdk==3.3.0
azure-storage-file-share==12.7.0
python-dateutil==2.8.2
diff --git a/Solutions/Box/Package/3.1.1.zip b/Solutions/Box/Package/3.1.1.zip
new file mode 100644
index 00000000000..417adad6462
Binary files /dev/null and b/Solutions/Box/Package/3.1.1.zip differ
diff --git a/Solutions/Box/Package/mainTemplate.json b/Solutions/Box/Package/mainTemplate.json
index f275a635619..2a4495bf265 100644
--- a/Solutions/Box/Package/mainTemplate.json
+++ b/Solutions/Box/Package/mainTemplate.json
@@ -55,7 +55,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Box",
- "_solutionVersion": "3.1.0",
+ "_solutionVersion": "3.1.1",
"solutionId": "azuresentinel.azure-sentinel-solution-box",
"_solutionId": "[variables('solutionId')]",
"workbookVersion1": "1.0.0",
@@ -221,7 +221,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Box Workbook with template version 3.1.0",
+ "description": "Box Workbook with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -309,7 +309,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxEvents Data Parser with template version 3.1.0",
+ "description": "BoxEvents Data Parser with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -441,7 +441,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxAdminIpAddress_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxAdminIpAddress_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
@@ -526,7 +526,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxDeletedUsers_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxDeletedUsers_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
@@ -611,7 +611,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxInactiveAdmins_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxInactiveAdmins_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
@@ -696,7 +696,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxInactiveUsers_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxInactiveUsers_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
@@ -781,7 +781,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxNewUsers_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxNewUsers_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
@@ -866,7 +866,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxSuspiciousFiles_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxSuspiciousFiles_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
@@ -951,7 +951,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxUserDownloadsByVolume_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxUserDownloadsByVolume_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
@@ -1036,7 +1036,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxUserGroupChanges_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxUserGroupChanges_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]",
@@ -1121,7 +1121,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxUserUploadsByVolume_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxUserUploadsByVolume_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]",
@@ -1206,7 +1206,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxUsersWithOwnerPermissions_HuntingQueries Hunting Query with template version 3.1.0",
+ "description": "BoxUsersWithOwnerPermissions_HuntingQueries Hunting Query with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]",
@@ -1291,7 +1291,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Box data connector with template version 3.1.0",
+ "description": "Box data connector with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -1687,7 +1687,7 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]",
- "displayName": "Box Events (CCP) (Preview)",
+ "displayName": "Box Events (CCP)",
"contentKind": "DataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -1704,7 +1704,7 @@
"properties": {
"connectorUiConfig": {
"id": "BoxEventsCCPDefinition",
- "title": "Box Events (CCP) (Preview)",
+ "title": "Box Events (CCP)",
"publisher": "Microsoft",
"descriptionMarkdown": "The Box data connector provides the capability to ingest [Box enterprise's events](https://developer.box.com/guides/events/#admin-events) into Microsoft Sentinel using the Box REST API. Refer to [Box documentation](https://developer.box.com/guides/events/enterprise-events/for-enterprise/) for more information.",
"graphQueriesTableName": "BoxEventsV2_CL",
@@ -2099,7 +2099,7 @@
"properties": {
"connectorUiConfig": {
"id": "BoxEventsCCPDefinition",
- "title": "Box Events (CCP) (Preview)",
+ "title": "Box Events (CCP)",
"publisher": "Microsoft",
"descriptionMarkdown": "The Box data connector provides the capability to ingest [Box enterprise's events](https://developer.box.com/guides/events/#admin-events) into Microsoft Sentinel using the Box REST API. Refer to [Box documentation](https://developer.box.com/guides/events/enterprise-events/for-enterprise/) for more information.",
"graphQueriesTableName": "BoxEventsV2_CL",
@@ -2241,24 +2241,24 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnections2')]",
- "displayName": "Box Events (CCP) (Preview)",
+ "displayName": "Box Events (CCP)",
"contentKind": "ResourcesDataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorCCPVersion')]",
"parameters": {
- "ClientId": {
+ "clientId": {
"defaultValue": "-NA-",
"type": "securestring",
- "minLength": 1
+ "minLength": 4
},
- "ClientSecret": {
+ "clientSecret": {
"defaultValue": "-NA-",
"type": "securestring",
- "minLength": 1
+ "minLength": 4
},
"connectorDefinitionName": {
- "defaultValue": "Box Events (CCP) (Preview)",
+ "defaultValue": "Box Events (CCP)",
"type": "string",
"minLength": 1
},
@@ -2336,8 +2336,8 @@
},
"auth": {
"type": "OAuth2",
- "clientSecret": "[[parameters('ClientSecret')]",
- "clientId": "[[parameters('ClientId')]",
+ "clientSecret": "[[parameters('clientSecret')]",
+ "clientId": "[[parameters('clientId')]",
"grantType": "client_credentials",
"TokenEndpoint": "https://api.box.com/oauth2/token",
"TokenEndpointHeaders": {
@@ -2345,7 +2345,7 @@
},
"tokenEndpointQueryParameters": {
"box_subject_type": "enterprise",
- "box_subject_id": "[[parameters('boxEnterpriseId']]"
+ "box_subject_id": "[[parameters('boxEnterpriseId')]"
}
},
"request": {
@@ -2391,7 +2391,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxAbnormalUserActivity_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxAbnormalUserActivity_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -2495,7 +2495,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxBinaryFile_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxBinaryFile_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -2599,7 +2599,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxDownloadForbiddenFiles_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxDownloadForbiddenFiles_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -2712,7 +2712,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxInactiveUserLogin_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxInactiveUserLogin_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -2816,7 +2816,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxItemSharedToExternalUser_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxItemSharedToExternalUser_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -2920,7 +2920,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxMultipleItemsDeletedByUser_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxMultipleItemsDeletedByUser_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -3024,7 +3024,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxNewExternalUser_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxNewExternalUser_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -3138,7 +3138,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxSensitiveFile_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxSensitiveFile_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -3251,7 +3251,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxUserLoginAsAdmin_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxUserLoginAsAdmin_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -3364,7 +3364,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "BoxUserRoleChangedToOwner_AnalyticalRules Analytics Rule with template version 3.1.0",
+ "description": "BoxUserRoleChangedToOwner_AnalyticalRules Analytics Rule with template version 3.1.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]",
@@ -3464,7 +3464,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.1.0",
+ "version": "3.1.1",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Box",
diff --git a/Solutions/Box/ReleaseNotes.md b/Solutions/Box/ReleaseNotes.md
index 8c560b94fe9..29945246d61 100644
--- a/Solutions/Box/ReleaseNotes.md
+++ b/Solutions/Box/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------------------|
-| 3.1.0 | 06-12-2024 | Added new CCP **Data Connector** and modified **Parser** |
-| 3.0.1 | 18-08-2023 | Added text 'using Azure Functions' in **Data Connector** page |
-| 3.0.0 | 19-07-2023 | Manual deployment instructions updated for **Data Connector** |
\ No newline at end of file
+| 3.1.1 | 10-02-2025 | Advancing CCP **Data Connector** from Public preview to Global Availability.|
+| 3.1.0 | 06-12-2024 | Added new CCP **Data Connector** and modified **Parser**. |
+| 3.0.1 | 18-08-2023 | Added text 'using Azure Functions' in **Data Connector** page. |
+| 3.0.0 | 19-07-2023 | Manual deployment instructions updated for **Data Connector**. |
\ No newline at end of file
diff --git a/Solutions/CyberArkAudit/Data Connectors/azuredeploy_CyberArkAudit_MainTemplate.json b/Solutions/CyberArkAudit/Data Connectors/azuredeploy_CyberArkAudit_MainTemplate.json
index 149a8b77c10..a59e51d9b9d 100644
--- a/Solutions/CyberArkAudit/Data Connectors/azuredeploy_CyberArkAudit_MainTemplate.json
+++ b/Solutions/CyberArkAudit/Data Connectors/azuredeploy_CyberArkAudit_MainTemplate.json
@@ -238,7 +238,8 @@
"location": "[variables('location')]",
"kind": "web",
"properties": {
- "Application_Type": "web"
+ "Application_Type": "web",
+ "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/Workspaces', variables('loganalyticsworkspace'))]"
}
},
{
diff --git a/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/DataminrPulseAlerts.zip b/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/DataminrPulseAlerts.zip
index bb96f5a80c0..502646819cc 100644
Binary files a/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/DataminrPulseAlerts.zip and b/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/DataminrPulseAlerts.zip differ
diff --git a/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/requirements.txt b/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/requirements.txt
index e26a81f3f9a..ab23bbddf7a 100644
--- a/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/requirements.txt
+++ b/Solutions/Dataminr Pulse/Data Connectors/DataminrPulseAlerts/requirements.txt
@@ -8,7 +8,7 @@ requests
#Libraries for Log Analytics to Threat Intelligence Function.
azure-monitor-query
azure-identity
-cryptography==44.0.0
+cryptography==44.0.1
asyncio
aiohttp
azure-storage-file-share==12.10.1
diff --git a/Solutions/Dragos/Analytic Rules/DragosNotifiction.yaml b/Solutions/Dragos/Analytic Rules/DragosNotifiction.yaml
index 0198745ab8e..c309833f426 100644
--- a/Solutions/Dragos/Analytic Rules/DragosNotifiction.yaml
+++ b/Solutions/Dragos/Analytic Rules/DragosNotifiction.yaml
@@ -37,7 +37,7 @@ alertDetailsOverride:
- alertProperty: ProductName
value: AlertProductName
customDetails:
- DragosNotificationId: id
+ DragosIdentifier: id
DragosSeverity: severity
DragosDetectionQuads: detectionQuads
DragosCreatedAt: createdAt
@@ -60,6 +60,6 @@ incidentConfiguration:
lookbackDuration: PT1H
matchingMethod: Selected
groupByCustomDetails:
- - DragosNotificationId
-version: 1.0.0
+ - DragosIdentifier
+version: 1.0.1
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Dragos/Package/3.0.0.zip b/Solutions/Dragos/Package/3.0.0.zip
index 498ee7bfc50..0548619c22c 100644
Binary files a/Solutions/Dragos/Package/3.0.0.zip and b/Solutions/Dragos/Package/3.0.0.zip differ
diff --git a/Solutions/Dragos/Package/mainTemplate.json b/Solutions/Dragos/Package/mainTemplate.json
index f3c23494f63..7769ad5ed0d 100644
--- a/Solutions/Dragos/Package/mainTemplate.json
+++ b/Solutions/Dragos/Package/mainTemplate.json
@@ -48,7 +48,7 @@
"_email": "[variables('email')]",
"_solutionName": "Dragos",
"_solutionVersion": "3.0.0",
- "solutionId": "dragosinc1734451815609.azure-sentinel-solution-dragos",
+ "solutionId": "dragosinc1734451815609.microsoft-sentinel-solution-dragos",
"_solutionId": "[variables('solutionId')]",
"parserObject1": {
"_parserName1": "[concat(parameters('workspace'),'/','DragosNotificationsToSentinel')]",
@@ -87,11 +87,11 @@
"dataCollectionEndpointId": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]",
"blanks": "[replace('b', 'b', '')]",
"analyticRuleObject1": {
- "analyticRuleVersion1": "1.0.0",
+ "analyticRuleVersion1": "1.0.1",
"_analyticRulecontentId1": "9a74fe72-4c21-4ac5-80d9-37434e809721",
"analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '9a74fe72-4c21-4ac5-80d9-37434e809721')]",
"analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('9a74fe72-4c21-4ac5-80d9-37434e809721')))]",
- "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','9a74fe72-4c21-4ac5-80d9-37434e809721','-', '1.0.0')))]"
+ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','9a74fe72-4c21-4ac5-80d9-37434e809721','-', '1.0.1')))]"
},
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
@@ -122,7 +122,7 @@
"displayName": "Dragos Notifications Sentinel Incidents",
"category": "Microsoft Sentinel Parser",
"functionAlias": "DragosNotificationsToSentinel",
- "query": "let existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosNotificationId[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nunion isfuzzy=true DragosPushNotificationsToSentinel, DragosPullNotificationsToSentinel\n | join kind=leftouter (existingIncidents) on id\n | where isempty(SystemAlertId)\n | sort by severity desc\n",
+ "query": "let existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosIdentifier[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nunion isfuzzy=true DragosPushNotificationsToSentinel, DragosPullNotificationsToSentinel\n | join kind=leftouter (existingIncidents) on id\n | where isempty(SystemAlertId)\n | sort by severity desc\n",
"functionParameters": "",
"version": 2,
"tags": [
@@ -187,7 +187,7 @@
"displayName": "Dragos Notifications Sentinel Incidents",
"category": "Microsoft Sentinel Parser",
"functionAlias": "DragosNotificationsToSentinel",
- "query": "let existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosNotificationId[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nunion isfuzzy=true DragosPushNotificationsToSentinel, DragosPullNotificationsToSentinel\n | join kind=leftouter (existingIncidents) on id\n | where isempty(SystemAlertId)\n | sort by severity desc\n",
+ "query": "let existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosIdentifier[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nunion isfuzzy=true DragosPushNotificationsToSentinel, DragosPullNotificationsToSentinel\n | join kind=leftouter (existingIncidents) on id\n | where isempty(SystemAlertId)\n | sort by severity desc\n",
"functionParameters": "",
"version": 2,
"tags": [
@@ -254,7 +254,7 @@
"displayName": "Dragos Pull Notifications Sentinel Incidents",
"category": "Microsoft Sentinel Parser",
"functionAlias": "DragosPullNotificationsToSentinel",
- "query": "let Addresses = DragosAlerts_CL\n| mv-expand asset=assets\n| mv-expand address=asset.addresses\n| extend SentinelEntities=case(address.type == \"IP\",\n bag_pack(\"Type\", \"IP\", \"Address\", address.value, \"AddressScope\", address.networkId),\n address.type == \"HOSTNAME\",\n bag_pack(\"Type\", \"Host\", \"HostName\", address.value),\n address.type == \"DOMAIN\",\n bag_pack(\"Type\", \"Host\", \"HostName\", split(address.value, '.')[0], \"DnsDomain\", strcat_array(array_slice(split(address.value, '.'), 1, -1), '.')),\n dynamic(null))\n| extend MacAddresses = case(address.type == 'MAC', address.value, '')\n| extend IpAddresses = case(address.type == \"IP\", address.value, '');\nlet MitreThreatInfo = DragosAlerts_CL\n| mv-expand threat=threatInfo\n| extend MitreTactics=case(threat.framework == \"MITRE ATT&CK FOR ICS\" and threat.tactic.name != \"N/A\", replace_string(tostring(threat.tactic.name), \" \", \"\"), '')\n| extend MitreTechniques=case(threat.framework == \"MITRE ATT&CK FOR ICS\", threat.technique.id, '');\nlet existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosNotificationId[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nDragosAlerts_CL\n| extend detectionQuads=strcat_array(detectionQuads, \",\")\n| extend threatInfo=strcat_array(threatInfo, \",\")\n| join kind=leftouter Addresses on id\n| join kind=leftouter MitreThreatInfo on id\n| extend notification_id = id\n| summarize SentinelEntities=make_list(SentinelEntities, 250), MacAddresses=make_list(MacAddresses, 250), IpAddresses=make_list(IpAddresses, 250), MitreTactics=make_set_if(MitreTactics, strlen(MitreTactics) > 0), MitreTechniques=make_set_if(MitreTechniques, strlen(MitreTechniques) > 0) by id=notification_id, source, summary, content, severity, detectionQuads, createdAt, firstSeenAt, lastSeenAt, occurredAt, state, threatInfo\n| extend MacAddresses = set_difference(MacAddresses,dynamic([\"\"]))\n| extend IpAddresses = set_difference(IpAddresses,dynamic([\"\"]))\n| extend MitreTactics=strcat_array(MitreTactics, \",\")\n| extend AlertProductName=\"Dragos\"\n| extend DragosConnectorSource=\"DragosCcp\"\n| extend MSSentinelSeverity = DragosSeverityToSentinelSeverity(severity)\n| join kind=leftouter (existingIncidents) on id\n| where isempty(SystemAlertId)\n| summarize arg_max(createdAt, *) by id\n",
+ "query": "let Addresses = DragosAlerts_CL\n| mv-expand asset=assets\n| mv-expand address=asset.addresses\n| extend SentinelEntities=case(address.type == \"IP\",\n bag_pack(\"Type\", \"IP\", \"Address\", address.value, \"AddressScope\", address.networkId),\n address.type == \"HOSTNAME\",\n bag_pack(\"Type\", \"Host\", \"HostName\", address.value),\n address.type == \"DOMAIN\",\n bag_pack(\"Type\", \"Host\", \"HostName\", split(address.value, '.')[0], \"DnsDomain\", strcat_array(array_slice(split(address.value, '.'), 1, -1), '.')),\n dynamic(null))\n| extend MacAddresses = case(address.type == 'MAC', address.value, '')\n| extend IpAddresses = case(address.type == \"IP\", address.value, '');\nlet MitreThreatInfo = DragosAlerts_CL\n| mv-expand threat=threatInfo\n| extend MitreTactics=case(threat.framework == \"MITRE ATT&CK FOR ICS\" and threat.tactic.name != \"N/A\", replace_string(tostring(threat.tactic.name), \" \", \"\"), '')\n| extend MitreTechniques=case(threat.framework == \"MITRE ATT&CK FOR ICS\", threat.technique.id, '');\nlet existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosIdentifier[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nDragosAlerts_CL\n| extend detectionQuads=strcat_array(detectionQuads, \",\")\n| extend threatInfo=strcat_array(threatInfo, \",\")\n| join kind=leftouter Addresses on id\n| join kind=leftouter MitreThreatInfo on id\n| extend notification_id = id\n| summarize SentinelEntities=make_list(SentinelEntities, 250), MacAddresses=make_list(MacAddresses, 250), IpAddresses=make_list(IpAddresses, 250), MitreTactics=make_set_if(MitreTactics, strlen(MitreTactics) > 0), MitreTechniques=make_set_if(MitreTechniques, strlen(MitreTechniques) > 0) by id=notification_id, source, summary, content, severity, detectionQuads, createdAt, firstSeenAt, lastSeenAt, occurredAt, state, threatInfo\n| extend MacAddresses = set_difference(MacAddresses,dynamic([\"\"]))\n| extend IpAddresses = set_difference(IpAddresses,dynamic([\"\"]))\n| extend MitreTactics=strcat_array(MitreTactics, \",\")\n| extend AlertProductName=\"Dragos\"\n| extend DragosConnectorSource=\"DragosCcp\"\n| extend MSSentinelSeverity = DragosSeverityToSentinelSeverity(severity)\n| join kind=leftouter (existingIncidents) on id\n| where isempty(SystemAlertId)\n| summarize arg_max(createdAt, *) by id\n",
"functionParameters": "",
"version": 2,
"tags": [
@@ -319,7 +319,7 @@
"displayName": "Dragos Pull Notifications Sentinel Incidents",
"category": "Microsoft Sentinel Parser",
"functionAlias": "DragosPullNotificationsToSentinel",
- "query": "let Addresses = DragosAlerts_CL\n| mv-expand asset=assets\n| mv-expand address=asset.addresses\n| extend SentinelEntities=case(address.type == \"IP\",\n bag_pack(\"Type\", \"IP\", \"Address\", address.value, \"AddressScope\", address.networkId),\n address.type == \"HOSTNAME\",\n bag_pack(\"Type\", \"Host\", \"HostName\", address.value),\n address.type == \"DOMAIN\",\n bag_pack(\"Type\", \"Host\", \"HostName\", split(address.value, '.')[0], \"DnsDomain\", strcat_array(array_slice(split(address.value, '.'), 1, -1), '.')),\n dynamic(null))\n| extend MacAddresses = case(address.type == 'MAC', address.value, '')\n| extend IpAddresses = case(address.type == \"IP\", address.value, '');\nlet MitreThreatInfo = DragosAlerts_CL\n| mv-expand threat=threatInfo\n| extend MitreTactics=case(threat.framework == \"MITRE ATT&CK FOR ICS\" and threat.tactic.name != \"N/A\", replace_string(tostring(threat.tactic.name), \" \", \"\"), '')\n| extend MitreTechniques=case(threat.framework == \"MITRE ATT&CK FOR ICS\", threat.technique.id, '');\nlet existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosNotificationId[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nDragosAlerts_CL\n| extend detectionQuads=strcat_array(detectionQuads, \",\")\n| extend threatInfo=strcat_array(threatInfo, \",\")\n| join kind=leftouter Addresses on id\n| join kind=leftouter MitreThreatInfo on id\n| extend notification_id = id\n| summarize SentinelEntities=make_list(SentinelEntities, 250), MacAddresses=make_list(MacAddresses, 250), IpAddresses=make_list(IpAddresses, 250), MitreTactics=make_set_if(MitreTactics, strlen(MitreTactics) > 0), MitreTechniques=make_set_if(MitreTechniques, strlen(MitreTechniques) > 0) by id=notification_id, source, summary, content, severity, detectionQuads, createdAt, firstSeenAt, lastSeenAt, occurredAt, state, threatInfo\n| extend MacAddresses = set_difference(MacAddresses,dynamic([\"\"]))\n| extend IpAddresses = set_difference(IpAddresses,dynamic([\"\"]))\n| extend MitreTactics=strcat_array(MitreTactics, \",\")\n| extend AlertProductName=\"Dragos\"\n| extend DragosConnectorSource=\"DragosCcp\"\n| extend MSSentinelSeverity = DragosSeverityToSentinelSeverity(severity)\n| join kind=leftouter (existingIncidents) on id\n| where isempty(SystemAlertId)\n| summarize arg_max(createdAt, *) by id\n",
+ "query": "let Addresses = DragosAlerts_CL\n| mv-expand asset=assets\n| mv-expand address=asset.addresses\n| extend SentinelEntities=case(address.type == \"IP\",\n bag_pack(\"Type\", \"IP\", \"Address\", address.value, \"AddressScope\", address.networkId),\n address.type == \"HOSTNAME\",\n bag_pack(\"Type\", \"Host\", \"HostName\", address.value),\n address.type == \"DOMAIN\",\n bag_pack(\"Type\", \"Host\", \"HostName\", split(address.value, '.')[0], \"DnsDomain\", strcat_array(array_slice(split(address.value, '.'), 1, -1), '.')),\n dynamic(null))\n| extend MacAddresses = case(address.type == 'MAC', address.value, '')\n| extend IpAddresses = case(address.type == \"IP\", address.value, '');\nlet MitreThreatInfo = DragosAlerts_CL\n| mv-expand threat=threatInfo\n| extend MitreTactics=case(threat.framework == \"MITRE ATT&CK FOR ICS\" and threat.tactic.name != \"N/A\", replace_string(tostring(threat.tactic.name), \" \", \"\"), '')\n| extend MitreTechniques=case(threat.framework == \"MITRE ATT&CK FOR ICS\", threat.technique.id, '');\nlet existingIncidents = SecurityAlert\n | where ProductName == \"Dragos\"\n | extend CustomDetails=tostring(parse_json(ExtendedProperties)[\"Custom Details\"])\n | extend id = toint(extract_json(\"$.DragosIdentifier[0]\", CustomDetails))\n | project-keep SystemAlertId, id;\nDragosAlerts_CL\n| extend detectionQuads=strcat_array(detectionQuads, \",\")\n| extend threatInfo=strcat_array(threatInfo, \",\")\n| join kind=leftouter Addresses on id\n| join kind=leftouter MitreThreatInfo on id\n| extend notification_id = id\n| summarize SentinelEntities=make_list(SentinelEntities, 250), MacAddresses=make_list(MacAddresses, 250), IpAddresses=make_list(IpAddresses, 250), MitreTactics=make_set_if(MitreTactics, strlen(MitreTactics) > 0), MitreTechniques=make_set_if(MitreTechniques, strlen(MitreTechniques) > 0) by id=notification_id, source, summary, content, severity, detectionQuads, createdAt, firstSeenAt, lastSeenAt, occurredAt, state, threatInfo\n| extend MacAddresses = set_difference(MacAddresses,dynamic([\"\"]))\n| extend IpAddresses = set_difference(IpAddresses,dynamic([\"\"]))\n| extend MitreTactics=strcat_array(MitreTactics, \",\")\n| extend AlertProductName=\"Dragos\"\n| extend DragosConnectorSource=\"DragosCcp\"\n| extend MSSentinelSeverity = DragosSeverityToSentinelSeverity(severity)\n| join kind=leftouter (existingIncidents) on id\n| where isempty(SystemAlertId)\n| summarize arg_max(createdAt, *) by id\n",
"functionParameters": "",
"version": 2,
"tags": [
@@ -1256,12 +1256,12 @@
"username": {
"defaultValue": "Enter username value",
"type": "string",
- "minLength": 1
+ "minLength": 4
},
"password": {
"defaultValue": "-NA-",
"type": "securestring",
- "minLength": 1
+ "minLength": 4
},
"dragosSitestoreHostname": {
"defaultValue": "Enter dragosSitestoreHostname value",
@@ -1422,24 +1422,24 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "DragosSitestoreCCP",
"dataTypes": [
"DragosAlerts_CL"
- ],
- "connectorId": "DragosSitestoreCCP"
+ ]
},
{
+ "connectorId": "CefAma",
"dataTypes": [
"CommonSecurityLog"
- ],
- "connectorId": "CefAma"
+ ]
}
],
"entityMappings": [
{
"fieldMappings": [
{
- "identifier": "Entities",
- "columnName": "SentinelEntities"
+ "columnName": "SentinelEntities",
+ "identifier": "Entities"
}
],
"entityType": "SentinelEntities"
@@ -1449,23 +1449,25 @@
"aggregationKind": "AlertPerResult"
},
"customDetails": {
- "DragosCreatedAt": "createdAt",
- "DragosSeverity": "severity",
- "DragosState": "state",
- "DragosNotificationId": "id",
"DragosSource": "source",
"DragosIpAddresses": "IpAddresses",
+ "DragosCreatedAt": "createdAt",
"DragosFirstSeenAt": "firstSeenAt",
"DragosDetectionQuads": "detectionQuads",
- "DragosOccurredAt": "occurredAt",
"DragosMacAddresses": "MacAddresses",
- "DragosLastSeenAt": "lastSeenAt",
+ "DragosConnectSrc": "DragosConnectorSource",
+ "DragosSeverity": "severity",
+ "DragosOccurredAt": "occurredAt",
"DragosThreatInfo": "threatInfo",
- "DragosConnectSrc": "DragosConnectorSource"
+ "DragosState": "state",
+ "DragosIdentifier": "id",
+ "DragosLastSeenAt": "lastSeenAt"
},
"alertDetailsOverride": {
- "alertTacticsColumnName": "MitreTactics",
+ "alertDisplayNameFormat": "Dragos: {{summary}}",
+ "alertSeverityColumnName": "MSSentinelSeverity",
"alertDescriptionFormat": "{{content}}",
+ "alertTacticsColumnName": "MitreTactics",
"alertDynamicProperties": [
{
"value": "MitreTechniques",
@@ -1475,20 +1477,18 @@
"value": "AlertProductName",
"alertProperty": "ProductName"
}
- ],
- "alertSeverityColumnName": "MSSentinelSeverity",
- "alertDisplayNameFormat": "Dragos: {{summary}}"
+ ]
},
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
"matchingMethod": "Selected",
+ "enabled": true,
"lookbackDuration": "PT1H",
- "groupByCustomDetails": [
- "DragosNotificationId"
- ],
"reopenClosedIncident": false,
- "enabled": true
+ "groupByCustomDetails": [
+ "DragosIdentifier"
+ ]
}
}
}
diff --git a/Solutions/Dragos/Parsers/DragosNotificationsToSentinel.yaml b/Solutions/Dragos/Parsers/DragosNotificationsToSentinel.yaml
index e19701c93d1..0ad4e428120 100644
--- a/Solutions/Dragos/Parsers/DragosNotificationsToSentinel.yaml
+++ b/Solutions/Dragos/Parsers/DragosNotificationsToSentinel.yaml
@@ -10,7 +10,7 @@ FunctionQuery: |
let existingIncidents = SecurityAlert
| where ProductName == "Dragos"
| extend CustomDetails=tostring(parse_json(ExtendedProperties)["Custom Details"])
- | extend id = toint(extract_json("$.DragosNotificationId[0]", CustomDetails))
+ | extend id = toint(extract_json("$.DragosIdentifier[0]", CustomDetails))
| project-keep SystemAlertId, id;
union isfuzzy=true DragosPushNotificationsToSentinel, DragosPullNotificationsToSentinel
| join kind=leftouter (existingIncidents) on id
diff --git a/Solutions/Dragos/Parsers/DragosPullNotificationsToSentinel.yaml b/Solutions/Dragos/Parsers/DragosPullNotificationsToSentinel.yaml
index afc283da006..148ed7aba61 100644
--- a/Solutions/Dragos/Parsers/DragosPullNotificationsToSentinel.yaml
+++ b/Solutions/Dragos/Parsers/DragosPullNotificationsToSentinel.yaml
@@ -26,7 +26,7 @@ FunctionQuery: |
let existingIncidents = SecurityAlert
| where ProductName == "Dragos"
| extend CustomDetails=tostring(parse_json(ExtendedProperties)["Custom Details"])
- | extend id = toint(extract_json("$.DragosNotificationId[0]", CustomDetails))
+ | extend id = toint(extract_json("$.DragosIdentifier[0]", CustomDetails))
| project-keep SystemAlertId, id;
DragosAlerts_CL
| extend detectionQuads=strcat_array(detectionQuads, ",")
diff --git a/Solutions/Dragos/SolutionMetadata.json b/Solutions/Dragos/SolutionMetadata.json
index afc3a53dbbc..96c22c41279 100644
--- a/Solutions/Dragos/SolutionMetadata.json
+++ b/Solutions/Dragos/SolutionMetadata.json
@@ -1,6 +1,6 @@
{
"publisherId": "dragosinc1734451815609",
- "offerId": "azure-sentinel-solution-dragos",
+ "offerId": "microsoft-sentinel-solution-dragos",
"firstPublishDate": "2025-01-23",
"lastPublishDate": "2025-01-23",
"providers": [
diff --git a/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json b/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json
index 362c3c3540f..a4a19496df1 100644
--- a/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json
+++ b/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json
@@ -74,7 +74,7 @@
},
{
"title": "Step 3 - Deploy the ESET Protect Platform data connector using the Azure Resource Manager (ARM) template",
- "description": "\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-EsetProtectionPlatform-azuredeploy)\n\n2. Select the name of the **Log Analytics workspace** associated with your Microsoft Sentinel. Select the same **Resource Group** as the Resource Group of the Log Analytics workspace.\n\n3. Type the parameters of the registered application in Microsoft Entra ID: **Azure Client ID**, **Azure Client Secret**, **Azure Tenant ID**, **Object ID**. You can find the **Object ID** on Azure Portal by following this path \n> Microsoft Entra ID -> Manage (on the left-side menu) -> Enterprise applications -> Object ID column (the value next to your registered application name).\n\n4. Provide the ESET Connect API user account **Login** and **Password** obtained in **Step 1**."
+ "description": "\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-EsetProtectionPlatform-azuredeploy)\n\n2. Select the name of the **Log Analytics workspace** associated with your Microsoft Sentinel. Select the same **Resource Group** as the Resource Group of the Log Analytics workspace.\n\n3. Type the parameters of the registered application in Microsoft Entra ID: **Azure Client ID**, **Azure Client Secret**, **Azure Tenant ID**, **Object ID**. You can find the **Object ID** on Azure Portal by following this path \n> Microsoft Entra ID -> Manage (on the left-side menu) -> Enterprise applications -> Object ID column (the value next to your registered application name).\n\n4. Provide the ESET Connect API user account **Login** and **Password** obtained in **Step 1**.\n\n5. Select one or more ESET products (ESET PROTECT, ESET Inspect, ESET Cloud Office Security) from which detections are retrieved."
}
]
}
diff --git a/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip b/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip
index 7a62b6dc536..db963f2d46f 100644
Binary files a/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip and b/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip differ
diff --git a/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json b/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json
index 39dc94319e4..24b45450080 100644
--- a/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json
+++ b/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json
@@ -87,6 +87,30 @@
"description": "The ESET Connect API user account password."
}
},
+ "ESET PROTECT instance": {
+ "type": "string",
+ "defaultValue": "yes",
+ "allowedValues": ["yes", "no"],
+ "metadata": {
+ "description": "The ESET product from which detections are pulled. Set to 'yes' to pull ESET PROTECT detections. It is allowed to pick more than one ESET product if they are located in the same region."
+ }
+ },
+ "ESET Inspect instance": {
+ "type": "string",
+ "defaultValue": "no",
+ "allowedValues": ["yes", "no"],
+ "metadata": {
+ "description": "The ESET product from which detections are pulled. Set to 'yes' to pull ESET Inspect detections. It is allowed to pick more than one ESET product if they are located in the same region."
+ }
+ },
+ "ESET Cloud Office Security instance": {
+ "type": "string",
+ "defaultValue": "no",
+ "allowedValues": ["yes", "no"],
+ "metadata": {
+ "description": "The ESET product from which detections are pulled. Set to 'yes' to pull ESET Cloud Office Security detections. It is allowed to pick more than one ESET product if they are located in the same region."
+ }
+ },
"instanceRegion": {
"type": "string",
"defaultValue": "eu",
@@ -98,7 +122,7 @@
"de"
],
"metadata": {
- "description": "The region where your ESET Protect/Inspect/ECOS instance is running."
+ "description": "The region where your ESET PROTECT/Inspect/ECOS instance is running."
}
},
"keyBase": {
@@ -436,7 +460,7 @@
"principalType": "ServicePrincipal"
},
"dependsOn": ["[variables('dataCollectionRuleId')]"]
- },
+ },
{
"apiVersion": "2022-03-01",
"name": "[variables('applicationName')]",
@@ -477,23 +501,23 @@
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('contentShare'))]"
- },
+ },
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "https://aka.ms/sentinel-EsetProtectionPlatform-FunctionApp"
- },
+ },
{
"name": "ENDPOINT_URI",
"value": "[reference(variables('dataCollectionEndpointId'), '2021-04-01').logsIngestion.endpoint]"
- },
+ },
{
"name": "DCR_IMMUTABLEID",
"value": "[reference(variables('dataCollectionRuleId'), '2023-03-11').immutableId]"
- },
+ },
{
"name": "STREAM_NAME",
"value": "[variables('customTableName')]"
- },
+ },
{
"name": "AZURE_CLIENT_ID",
"value": "[parameters('azureClientID')]"
@@ -501,11 +525,11 @@
{
"name": "AZURE_CLIENT_SECRET",
"value": "[parameters('azureClientSecret')]"
- },
+ },
{
"name": "AZURE_TENANT_ID",
"value": "[parameters('azureTenantID')]"
- },
+ },
{
"name": "PASSWORD_INTEGRATION",
"value": "[parameters('password')]"
@@ -514,6 +538,18 @@
"name": "USERNAME_INTEGRATION",
"value": "[parameters('login')]"
},
+ {
+ "name": "EP_INSTANCE",
+ "value": "[parameters('ESET PROTECT instance')]"
+ },
+ {
+ "name": "EI_INSTANCE",
+ "value": "[parameters('ESET Inspect instance')]"
+ },
+ {
+ "name": "ECOS_INSTANCE",
+ "value": "[parameters('ESET Cloud Office Security instance')]"
+ },
{
"name": "INTERVAL",
"value": "[parameters('applicationRunInterval')]"
diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/main.py b/Solutions/ESET Protect Platform/Data Connectors/integration/main.py
index c837f792a77..5811a66b615 100644
--- a/Solutions/ESET Protect Platform/Data Connectors/integration/main.py
+++ b/Solutions/ESET Protect Platform/Data Connectors/integration/main.py
@@ -7,12 +7,7 @@
from aiohttp import ClientSession
from integration.models import Config, EnvVariables, TokenStorage
-from integration.utils import (
- LastDetectionTimeHandler,
- RequestSender,
- TokenProvider,
- TransformerDetections,
-)
+from integration.utils import LastDetectionTimeHandler, RequestSender, TokenProvider, TransformerDetections
class ServiceClient:
@@ -34,7 +29,9 @@ async def run(self) -> None:
start_time = time.time()
try:
await asyncio.gather(
- self._process_integration("EI", start_time), self._process_integration("ECOS", start_time)
+ self._process_integration("EP", start_time),
+ self._process_integration("EI", start_time),
+ self._process_integration("ECOS", start_time),
)
except Exception as e:
logging.error("Unexpected error happened", exc_info=e)
@@ -42,15 +39,36 @@ async def run(self) -> None:
finally:
await self.close()
+ def _validate_if_run_instance(self, data_source: str) -> bool:
+ if data_source == "EP" and self.env_vars.ep_instance == "yes" and self.env_vars.ei_instance == "no":
+ return True
+ if data_source == "EI" and self.env_vars.ei_instance == "yes":
+ return True
+ if data_source == "ECOS" and self.env_vars.ecos_instance == "yes":
+ return True
+ if data_source != "EP" and all(
+ v == "" for v in [self.env_vars.ep_instance, self.env_vars.ei_instance, self.env_vars.ecos_instance]
+ ):
+ self.config.version = "3.0.0"
+ return True
+ return False
+
async def _process_integration(self, data_source: str, start_time: float) -> None:
+ if not self._validate_if_run_instance(data_source):
+ return
+
last_detection_time_handler = LastDetectionTimeHandler(
self.env_vars.conn_str, self.env_vars.last_detection_time, data_source=data_source
)
next_page_token: str | None = None
cur_ld_time: str | None = None
- max_duration = self.env_vars.interval * 60
+ max_duration: int = self.env_vars.interval * 60
- if data_source == "EI" and not last_detection_time_handler.storage_table_handler.entities:
+ if (
+ self.config.version == "3.0.0"
+ and data_source == "EI"
+ and not last_detection_time_handler.storage_table_handler.entities
+ ):
data_source, last_detection_time_handler = await self._check_if_ei_is_right_data_source(
last_detection_time_handler, next_page_token
)
@@ -123,6 +141,7 @@ async def _call_service(
"Authorization": f"Bearer {self.token_provider.token.access_token}",
"Content-Type": "application/json",
"3rd-integration": "MS-Sentinel",
+ "Version": self.config.version,
},
last_detection_time_handler.last_detection_time,
next_page_token,
diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/models.py b/Solutions/ESET Protect Platform/Data Connectors/integration/models.py
index dbc2d9788e4..58b91c58c5b 100644
--- a/Solutions/ESET Protect Platform/Data Connectors/integration/models.py
+++ b/Solutions/ESET Protect Platform/Data Connectors/integration/models.py
@@ -55,6 +55,7 @@ def __init__(self) -> None:
self.requests_timeout = config.get("requests_timeout")
self.buffer: int = config.get("buffer") # type: ignore
self.data_sources: dict[str, t.Any] = config.get("data_sources") # type: ignore
+ self.version: str = config.get("version") # type: ignore
def get_config_params(self) -> dict[str, t.Any] | t.Any:
try:
@@ -78,14 +79,15 @@ def __init__(self) -> None:
self.endpoint_uri: str = os.getenv("ENDPOINT_URI", "")
self.dcr_immutableid: str = os.getenv("DCR_IMMUTABLEID", "")
self.stream_name: str = os.getenv("STREAM_NAME", "")
+ self.ep_instance: str = os.getenv("EP_INSTANCE", "")
+ self.ei_instance: str = os.getenv("EI_INSTANCE", "")
+ self.ecos_instance: str = os.getenv("ECOS_INSTANCE", "")
self.__conn_str: str = os.getenv("WEBSITE_CONTENTAZUREFILECONNECTIONSTRING", "")
self.__key_base64: str = os.getenv("KEY_BASE64", "")
region = os.getenv("INSTANCE_REGION", "eu")
self.oauth_url: str = f"https://{region}.business-account.iam.eset.systems"
- self.detections_url: str = (
- f"https://{region}.incident-management.eset.systems"
- )
+ self.detections_url: str = f"https://{region}.incident-management.eset.systems"
@property
def username(self) -> str | None:
diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py b/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py
index 99f63368290..0cd52b81416 100644
--- a/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py
+++ b/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py
@@ -51,6 +51,9 @@ async def send_request(
return await send_request_fun(session, headers, *data)
except ClientResponseError as e:
+ if e.headers:
+ logging.info(f"Request-ID: {e.headers.get('Request-ID')}")
+
if e.status in [400, 401, 403]:
raise AuthenticationException(status=e.status, message=e.message)
if e.status == 404:
diff --git a/Solutions/ESET Protect Platform/Data Connectors/requirements.txt b/Solutions/ESET Protect Platform/Data Connectors/requirements.txt
index ade7a02d953..f2e8f6904bf 100644
--- a/Solutions/ESET Protect Platform/Data Connectors/requirements.txt
+++ b/Solutions/ESET Protect Platform/Data Connectors/requirements.txt
@@ -10,7 +10,7 @@ azure-monitor-ingestion==1.0.4 ; python_version >= "3.11" and python_version < "
certifi==2024.8.30 ; python_version >= "3.11" and python_version < "4.0"
cffi==1.17.1 ; python_version >= "3.11" and python_version < "4.0" and platform_python_implementation != "PyPy"
charset-normalizer==3.3.2 ; python_version >= "3.11" and python_version < "4.0"
-cryptography==43.0.1 ; python_version >= "3.11" and python_version < "4.0"
+cryptography==44.0.1 ; python_version >= "3.11" and python_version < "4.0"
frozenlist==1.4.1 ; python_version >= "3.11" and python_version < "4.0"
idna==3.10 ; python_version >= "3.11" and python_version < "4.0"
isodate==0.6.1 ; python_version >= "3.11" and python_version < "4.0"
diff --git a/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json b/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json
index 8fd35f8c8ef..723334e3df8 100644
--- a/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json
+++ b/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json
@@ -10,7 +10,7 @@
"Parsers/ESETProtectPlatform.yaml"
],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\ESET Protect Platform",
- "Version": "1.0.0",
+ "Version": "3.1.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1Pconnector": false
diff --git a/Solutions/ESET Protect Platform/Package/3.1.0.zip b/Solutions/ESET Protect Platform/Package/3.1.0.zip
new file mode 100644
index 00000000000..fab13d9f789
Binary files /dev/null and b/Solutions/ESET Protect Platform/Package/3.1.0.zip differ
diff --git a/Solutions/ESET Protect Platform/Package/mainTemplate.json b/Solutions/ESET Protect Platform/Package/mainTemplate.json
index df01edfe4d6..fb1b09b5a63 100644
--- a/Solutions/ESET Protect Platform/Package/mainTemplate.json
+++ b/Solutions/ESET Protect Platform/Package/mainTemplate.json
@@ -31,7 +31,7 @@
},
"variables": {
"_solutionName": "ESET Protect Platform",
- "_solutionVersion": "3.0.0",
+ "_solutionVersion": "3.1.0",
"solutionId": "eset.eset-protect-platform-solution",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "ESETProtectPlatform",
@@ -62,7 +62,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ESET Protect Platform data connector with template version 3.0.0",
+ "description": "ESET Protect Platform data connector with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -163,7 +163,7 @@
"title": "Step 2 - Create a registered application"
},
{
- "description": "\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-EsetProtectionPlatform-azuredeploy)\n\n2. Select the name of the **Log Analytics workspace** associated with your Microsoft Sentinel. Select the same **Resource Group** as the Resource Group of the Log Analytics workspace.\n\n3. Type the parameters of the registered application in Microsoft Entra ID: **Azure Client ID**, **Azure Client Secret**, **Azure Tenant ID**, **Object ID**. You can find the **Object ID** on Azure Portal by following this path \n> Microsoft Entra ID -> Manage (on the left-side menu) -> Enterprise applications -> Object ID column (the value next to your registered application name).\n\n4. Provide the ESET Connect API user account **Login** and **Password** obtained in **Step 1**.",
+ "description": "\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-EsetProtectionPlatform-azuredeploy)\n\n2. Select the name of the **Log Analytics workspace** associated with your Microsoft Sentinel. Select the same **Resource Group** as the Resource Group of the Log Analytics workspace.\n\n3. Type the parameters of the registered application in Microsoft Entra ID: **Azure Client ID**, **Azure Client Secret**, **Azure Tenant ID**, **Object ID**. You can find the **Object ID** on Azure Portal by following this path \n> Microsoft Entra ID -> Manage (on the left-side menu) -> Enterprise applications -> Object ID column (the value next to your registered application name).\n\n4. Provide the ESET Connect API user account **Login** and **Password** obtained in **Step 1**.\n\n5. Select one or more ESET products (ESET PROTECT, ESET Inspect, ESET Cloud Office Security) from which detections are retrieved.",
"title": "Step 3 - Deploy the ESET Protect Platform data connector using the Azure Resource Manager (ARM) template"
}
]
@@ -332,7 +332,7 @@
"title": "Step 2 - Create a registered application"
},
{
- "description": "\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-EsetProtectionPlatform-azuredeploy)\n\n2. Select the name of the **Log Analytics workspace** associated with your Microsoft Sentinel. Select the same **Resource Group** as the Resource Group of the Log Analytics workspace.\n\n3. Type the parameters of the registered application in Microsoft Entra ID: **Azure Client ID**, **Azure Client Secret**, **Azure Tenant ID**, **Object ID**. You can find the **Object ID** on Azure Portal by following this path \n> Microsoft Entra ID -> Manage (on the left-side menu) -> Enterprise applications -> Object ID column (the value next to your registered application name).\n\n4. Provide the ESET Connect API user account **Login** and **Password** obtained in **Step 1**.",
+ "description": "\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-EsetProtectionPlatform-azuredeploy)\n\n2. Select the name of the **Log Analytics workspace** associated with your Microsoft Sentinel. Select the same **Resource Group** as the Resource Group of the Log Analytics workspace.\n\n3. Type the parameters of the registered application in Microsoft Entra ID: **Azure Client ID**, **Azure Client Secret**, **Azure Tenant ID**, **Object ID**. You can find the **Object ID** on Azure Portal by following this path \n> Microsoft Entra ID -> Manage (on the left-side menu) -> Enterprise applications -> Object ID column (the value next to your registered application name).\n\n4. Provide the ESET Connect API user account **Login** and **Password** obtained in **Step 1**.\n\n5. Select one or more ESET products (ESET PROTECT, ESET Inspect, ESET Cloud Office Security) from which detections are retrieved.",
"title": "Step 3 - Deploy the ESET Protect Platform data connector using the Azure Resource Manager (ARM) template"
}
],
@@ -349,7 +349,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ESETProtectPlatform Data Parser with template version 3.0.0",
+ "description": "ESETProtectPlatform Data Parser with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -475,7 +475,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.0",
+ "version": "3.1.0",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "ESET Protect Platform",
@@ -517,7 +517,7 @@
]
},
"firstPublishDate": "2024-10-29",
- "lastPublishDate": "2024-11-08",
+ "lastPublishDate": "2024-01-31",
"providers": [
"ESET Enterprise Integrations"
],
diff --git a/Solutions/ESET Protect Platform/ReleaseNotes.md b/Solutions/ESET Protect Platform/ReleaseNotes.md
index e5dd5cf78c4..29384d044e6 100644
--- a/Solutions/ESET Protect Platform/ReleaseNotes.md
+++ b/Solutions/ESET Protect Platform/ReleaseNotes.md
@@ -1,3 +1,4 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.1.0 | 06-02-2025 | Updated **Data Connector** FunctionApp code to work with old param and new |
| 3.0.0 | 04-11-2024 | Initial Solution Release |
\ No newline at end of file
diff --git a/Solutions/ESET Protect Platform/SolutionMetadata.json b/Solutions/ESET Protect Platform/SolutionMetadata.json
index 611c7dae729..9b4ace9d1fb 100644
--- a/Solutions/ESET Protect Platform/SolutionMetadata.json
+++ b/Solutions/ESET Protect Platform/SolutionMetadata.json
@@ -2,7 +2,7 @@
"publisherId": "eset",
"offerId": "eset-protect-platform-solution",
"firstPublishDate": "2024-10-29",
- "lastPublishDate": "2024-11-08",
+ "lastPublishDate": "2024-01-31",
"providers": ["ESET Enterprise Integrations"],
"categories": {
"domains" : ["Security - Automation (SOAR)", "Security - Threat Protection"]
diff --git a/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/constants.py b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/constants.py
new file mode 100644
index 00000000000..0cd1e754099
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/constants.py
@@ -0,0 +1,79 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'ASN_DCR_NAME', 'ASN_TABLE_NAME', 'ASN_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'MMDB_NAME',
+ 'ASN_TABLE_SCHEMA', 'ASN_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+ASN_DCR_NAME = "ipinfo_rule_for_ASN_tables"
+ASN_TABLE_NAME = "Ipinfo_ASN_CL"
+ASN_STREAM_DECLARATION = "Custom-Ipinfo_ASN_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+MMDB_NAME = "asn.mmdb"
+
+ASN_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": ASN_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "asn", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "route", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "asn_type", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{ASN_TABLE_NAME}",
+ "name": ASN_TABLE_NAME,
+}
+
+ASN_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "asn", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "domain", "type": "string"},
+ {"name": "route", "type": "string"},
+ {"name": "asn_type", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/function.json b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/main.py b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/main.py
new file mode 100644
index 00000000000..b1a570664a6
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/main.py
@@ -0,0 +1,84 @@
+import logging
+import time
+import maxminddb
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo ASN timer trigger function executed.")
+
+ def upload_data_to_ASN_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/asn.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Standard ASN Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["asn"] = ip_data.get("asn", "")
+ result["name"] = ip_data.get("name", "")
+ result["domain"] = ip_data.get("domain", "")
+ result["route"] = ip_data.get("route", "")
+ result["asn_type"] = ip_data.get("type", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Standard ASN Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(ASN_TABLE_NAME, ASN_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(ASN_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ ASN_dcr_immutableid, ASN_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ ASN_DCR_NAME,
+ ASN_STREAM_DECLARATION,
+ ASN_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_ASN_table(dce_endpoint, ASN_dcr_immutableid, ASN_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/utils.py b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/AzureFunctionIPinfoASN/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/ASN/IPifnoASNConn.zip b/Solutions/IPinfo/Data Connectors/ASN/IPifnoASNConn.zip
new file mode 100644
index 00000000000..283fcff6fab
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/ASN/IPifnoASNConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/ASN/IPinfo_ASN_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/ASN/IPinfo_ASN_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..b7cd31c15fb
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/IPinfo_ASN_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoASNDataConnector",
+ "title": "IPinfo ASN Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_ASN datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "ASN Data",
+ "legend": "Ipinfo_ASN_CL",
+ "baseQuery": "Ipinfo_ASN_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_ASN_CL",
+ "query": "Ipinfo_ASN_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_ASN_CL",
+ "lastDataReceivedQuery": "Ipinfo_ASN_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_ASN_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-ASN-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-ASN-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/ASN/azuredeploy_Connector_IPinfo_ASN_AzureFunction.json b/Solutions/IPinfo/Data Connectors/ASN/azuredeploy_Connector_IPinfo_ASN_AzureFunction.json
new file mode 100644
index 00000000000..c0c1895d233
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/azuredeploy_Connector_IPinfo_ASN_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo ASN",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-ASN-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/ASN/host.json b/Solutions/IPinfo/Data Connectors/ASN/host.json
new file mode 100644
index 00000000000..e53d8df199b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "00:10:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/ASN/proxies.json b/Solutions/IPinfo/Data Connectors/ASN/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/ASN/requirements.txt b/Solutions/IPinfo/Data Connectors/ASN/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/ASN/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/constants.py b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/constants.py
new file mode 100644
index 00000000000..c3354b13af8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/constants.py
@@ -0,0 +1,81 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'ABUSE_DCR_NAME', 'ABUSE_TABLE_NAME', 'ABUSE_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'MMDB_NAME',
+ 'ABUSE_TABLE_SCHEMA', 'ABUSE_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+ABUSE_DCR_NAME = "ipinfo_rule_for_abuse_tables"
+ABUSE_TABLE_NAME = "Ipinfo_Abuse_CL"
+ABUSE_STREAM_DECLARATION = "Custom-Ipinfo_Abuse_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+MMDB_NAME = "standard_abuse.mmdb"
+
+ABUSE_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": ABUSE_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "email", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "address", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "phone", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "network", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{ABUSE_TABLE_NAME}",
+ "name": ABUSE_TABLE_NAME,
+}
+
+ABUSE_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "name", "type": "string"},
+ {"name": "email", "type": "string"},
+ {"name": "address", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "phone", "type": "string"},
+ {"name": "network", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/function.json b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/main.py b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/main.py
new file mode 100644
index 00000000000..aa73eac9cf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/main.py
@@ -0,0 +1,85 @@
+import logging
+import time
+import maxminddb
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo Abuse timer trigger function executed.")
+
+ def upload_data_to_abuse_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/standard_abuse.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Standard Abuse Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["name"] = ip_data.get("name", "")
+ result["email"] = ip_data.get("email", "")
+ result["address"] = ip_data.get("address", "")
+ result["country"] = ip_data.get("country", "")
+ result["phone"] = ip_data.get("phone", "")
+ result["network"] = ip_data.get("network", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Standard Abuse Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(ABUSE_TABLE_NAME, ABUSE_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(ABUSE_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ abuse_dcr_immutableid, abuse_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ ABUSE_DCR_NAME,
+ ABUSE_STREAM_DECLARATION,
+ ABUSE_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_abuse_table(dce_endpoint, abuse_dcr_immutableid, abuse_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/utils.py b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/AzureFunctionIPinfoAbuse/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/IPinfoAbuseConn.zip b/Solutions/IPinfo/Data Connectors/Abuse/IPinfoAbuseConn.zip
new file mode 100644
index 00000000000..820d3354425
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/Abuse/IPinfoAbuseConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/IPinfo_Abuse_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/Abuse/IPinfo_Abuse_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..41d96727678
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/IPinfo_Abuse_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoAbuseDataConnector",
+ "title": "IPinfo Abuse Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_abuse datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "Abuse Data",
+ "legend": "Ipinfo_Abuse_CL",
+ "baseQuery": "Ipinfo_Abuse_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Abuse_CL",
+ "query": "Ipinfo_Abuse_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Abuse_CL",
+ "lastDataReceivedQuery": "Ipinfo_Abuse_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Abuse_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Abuse-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-Abuse-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/azuredeploy_Connector_IPinfo_Abuse_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Abuse/azuredeploy_Connector_IPinfo_Abuse_AzureFunction.json
new file mode 100644
index 00000000000..0ac8c54ba57
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/azuredeploy_Connector_IPinfo_Abuse_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo Abuse",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-Abuse-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/host.json b/Solutions/IPinfo/Data Connectors/Abuse/host.json
new file mode 100644
index 00000000000..eed246c12bf
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "03:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/proxies.json b/Solutions/IPinfo/Data Connectors/Abuse/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Abuse/requirements.txt b/Solutions/IPinfo/Data Connectors/Abuse/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Abuse/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/constants.py b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/constants.py
new file mode 100644
index 00000000000..73a5c6ff04c
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/constants.py
@@ -0,0 +1,79 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'CARRIER_DCR_NAME', 'CARRIER_TABLE_NAME', 'CARRIER_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'MMDB_NAME',
+ 'CARRIER_TABLE_SCHEMA', 'CARRIER_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+CARRIER_DCR_NAME = "ipinfo_rule_for_carrier_tables"
+CARRIER_TABLE_NAME = "Ipinfo_Carrier_CL"
+CARRIER_STREAM_DECLARATION = "Custom-Ipinfo_Carrier_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+MMDB_NAME = "carrier.mmdb"
+
+CARRIER_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": CARRIER_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "carrier", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "mcc", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "mnc", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "cc", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "network", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{CARRIER_TABLE_NAME}",
+ "name": CARRIER_TABLE_NAME,
+}
+
+CARRIER_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "carrier", "type": "string"},
+ {"name": "mcc", "type": "string"},
+ {"name": "mnc", "type": "string"},
+ {"name": "cc", "type": "string"},
+ {"name": "network", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/function.json b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/main.py b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/main.py
new file mode 100644
index 00000000000..55bd7133f81
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/main.py
@@ -0,0 +1,84 @@
+import logging
+import time
+import maxminddb
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo Carrier timer trigger function executed.")
+
+ def upload_data_to_carrier_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/carrier.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Standard Carrier Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["carrier"] = ip_data.get("carrier", "")
+ result["mcc"] = ip_data.get("mcc", "")
+ result["mnc"] = ip_data.get("mnc", "")
+ result["cc"] = ip_data.get("cc", "")
+ result["network"] = ip_data.get("network", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Standard Carrier Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(CARRIER_TABLE_NAME, CARRIER_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(CARRIER_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ carrier_dcr_immutableid, carrier_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ CARRIER_DCR_NAME,
+ CARRIER_STREAM_DECLARATION,
+ CARRIER_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_carrier_table(dce_endpoint, carrier_dcr_immutableid, carrier_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/utils.py b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/AzureFunctionIPinfoCarrier/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/IPinfoCarrierConn.zip b/Solutions/IPinfo/Data Connectors/Carrier/IPinfoCarrierConn.zip
new file mode 100644
index 00000000000..7cec4baf509
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/Carrier/IPinfoCarrierConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/IPinfo_Carrier_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/Carrier/IPinfo_Carrier_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..c707653669c
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/IPinfo_Carrier_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoCarrierDataConnector",
+ "title": "IPinfo Carrier Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_carrier datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "Carrier Data",
+ "legend": "Ipinfo_Carrier_CL",
+ "baseQuery": "Ipinfo_Carrier_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Carrier_CL",
+ "query": "Ipinfo_Carrier_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Carrier_CL",
+ "lastDataReceivedQuery": "Ipinfo_Carrier_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Carrier_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Carrier-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-Carrier-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/azuredeploy_Connector_IPinfo_Carrier_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Carrier/azuredeploy_Connector_IPinfo_Carrier_AzureFunction.json
new file mode 100644
index 00000000000..c9e05939bb3
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/azuredeploy_Connector_IPinfo_Carrier_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo Carrier",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-Carrier-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/host.json b/Solutions/IPinfo/Data Connectors/Carrier/host.json
new file mode 100644
index 00000000000..e53d8df199b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "00:10:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/proxies.json b/Solutions/IPinfo/Data Connectors/Carrier/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Carrier/requirements.txt b/Solutions/IPinfo/Data Connectors/Carrier/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Carrier/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Company/IPinfoCompanyConn.zip b/Solutions/IPinfo/Data Connectors/Company/IPinfoCompanyConn.zip
index 21e4a5254ee..87fee7105d4 100644
Binary files a/Solutions/IPinfo/Data Connectors/Company/IPinfoCompanyConn.zip and b/Solutions/IPinfo/Data Connectors/Company/IPinfoCompanyConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Company/azuredeploy_Connector_IPinfo_Company_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Company/azuredeploy_Connector_IPinfo_Company_AzureFunction.json
index cf67667aa15..0e075d92183 100644
--- a/Solutions/IPinfo/Data Connectors/Company/azuredeploy_Connector_IPinfo_Company_AzureFunction.json
+++ b/Solutions/IPinfo/Data Connectors/Company/azuredeploy_Connector_IPinfo_Company_AzureFunction.json
@@ -32,11 +32,11 @@
},
"RETENTION_IN_DAYS": {
"type": "string",
- "defaultValue": "IPinfo Token"
+ "defaultValue": "10"
},
"TOTAL_RETENTION_IN_DAYS": {
"type": "string",
- "defaultValue": "IPinfo Token"
+ "defaultValue": "30"
},
"SCHEDULE": {
"type": "string",
@@ -114,7 +114,7 @@
"reserved": true,
"maximumElasticWorkerCount": 20,
"siteConfig": {
- "linuxFxVersion": "Python|3.10"
+ "linuxFxVersion": "python|3.11"
}
}
},
diff --git a/Solutions/IPinfo/Data Connectors/Company/host.json b/Solutions/IPinfo/Data Connectors/Company/host.json
index f65ed7c548a..e65054b4c51 100644
--- a/Solutions/IPinfo/Data Connectors/Company/host.json
+++ b/Solutions/IPinfo/Data Connectors/Company/host.json
@@ -11,6 +11,6 @@
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
- "version": "[4.*, 5.0.0)"
+ "version": "[3.*, 4.0.0)"
}
}
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/constants.py b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/constants.py
new file mode 100644
index 00000000000..21cf652e1bb
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/constants.py
@@ -0,0 +1,83 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME',
+ 'WORKSPACE_NAME', 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS',
+ 'DATA_COLLECTION_ENDPOINT_NAME', 'COUNTRY_DCR_NAME', 'COUNTRY_TABLE_NAME',
+ 'COUNTRY_STREAM_DECLARATION', 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL',
+ 'MMDB_NAME', 'COUNTRY_TABLE_SCHEMA', 'COUNTRY_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+COUNTRY_DCR_NAME = "ipinfo_rule_for_country_table"
+COUNTRY_TABLE_NAME = "Ipinfo_Country_CL"
+COUNTRY_STREAM_DECLARATION = "Custom-Ipinfo_Country_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data/free"
+MMDB_NAME = "country_asn.mmdb"
+
+COUNTRY_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": COUNTRY_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "as_domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "as_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "asn", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "continent", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "continent_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{COUNTRY_TABLE_NAME}",
+ "name": COUNTRY_TABLE_NAME,
+}
+
+COUNTRY_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "as_domain", "type": "string"},
+ {"name": "as_name", "type": "string"},
+ {"name": "asn", "type": "string"},
+ {"name": "continent", "type": "string"},
+ {"name": "continent_name", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "country_name", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/function.json b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/function.json
new file mode 100644
index 00000000000..b0027ce9e99
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/function.json
@@ -0,0 +1,12 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+ }
+
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/main.py b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/main.py
new file mode 100644
index 00000000000..f1f6c8201f6
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/main.py
@@ -0,0 +1,86 @@
+import logging
+import maxminddb
+import time
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo Country ASN timer trigger function executed.")
+
+ def upload_data_to_country_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/country_asn.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Country ASN Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["as_domain"] = ip_data.get("as_domain", "")
+ result["as_name"] = ip_data.get("as_name", "")
+ result["asn"] = ip_data.get("asn", "")
+ result["continent"] = ip_data.get("continent", "")
+ result["continent_name"] = ip_data.get("continent_name", "")
+ result["country"] = ip_data.get("country", "")
+ result["country_name"] = ip_data.get("country_name", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Country ASN Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(COUNTRY_TABLE_NAME, COUNTRY_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(COUNTRY_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ country_dcr_immutableid, country_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ COUNTRY_DCR_NAME,
+ COUNTRY_STREAM_DECLARATION,
+ COUNTRY_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_country_table(dce_endpoint, country_dcr_immutableid, country_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/utils.py b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/AzureFunctionIPinfoCountryASN/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/IPinfoCountryConn.zip b/Solutions/IPinfo/Data Connectors/Country ASN/IPinfoCountryConn.zip
new file mode 100644
index 00000000000..cc0a9fa276c
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/Country ASN/IPinfoCountryConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/IPinfo_Country_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/Country ASN/IPinfo_Country_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..74878b4bac3
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/IPinfo_Country_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoCountryDataConnector",
+ "title": "IPinfo Country ASN Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download country_asn datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "Country Data",
+ "legend": "Ipinfo_Country_CL",
+ "baseQuery": "Ipinfo_Country_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Country_CL",
+ "query": "Ipinfo_Country_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Country_CL",
+ "lastDataReceivedQuery": "Ipinfo_Country_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Country_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Country-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-Country-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/azuredeploy_Connector_IPinfo_Country_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Country ASN/azuredeploy_Connector_IPinfo_Country_AzureFunction.json
new file mode 100644
index 00000000000..a3325ea3929
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/azuredeploy_Connector_IPinfo_Country_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo Country",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-Country-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/host.json b/Solutions/IPinfo/Data Connectors/Country ASN/host.json
new file mode 100644
index 00000000000..2b8b7bb60bd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "01:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/proxies.json b/Solutions/IPinfo/Data Connectors/Country ASN/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Country ASN/requirements.txt b/Solutions/IPinfo/Data Connectors/Country ASN/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Country ASN/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/constants.py b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/constants.py
new file mode 100644
index 00000000000..bf2ff3f2306
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/constants.py
@@ -0,0 +1,73 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'DOMAIN_DCR_NAME', 'DOMAIN_TABLE_NAME', 'DOMAIN_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'MMDB_NAME',
+ 'DOMAIN_TABLE_SCHEMA', 'DOMAIN_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+DOMAIN_DCR_NAME = "ipinfo_rule_for_domain_tables"
+DOMAIN_TABLE_NAME = "Ipinfo_Domain_CL"
+DOMAIN_STREAM_DECLARATION = "Custom-Ipinfo_Domain_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+MMDB_NAME = "standard_ip_hosted_domains.mmdb"
+
+DOMAIN_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": DOMAIN_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "domains", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "total", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{DOMAIN_TABLE_NAME}",
+ "name": DOMAIN_TABLE_NAME,
+}
+
+DOMAIN_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "domains", "type": "string"},
+ {"name": "total", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/function.json b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/main.py b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/main.py
new file mode 100644
index 00000000000..1d221f095d0
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/main.py
@@ -0,0 +1,81 @@
+import logging
+import time
+import maxminddb
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo Domain timer trigger function executed.")
+
+ def upload_data_to_domain_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/standard_ip_hosted_domains.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Standard Domain Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["domains"] = ip_data.get("domains", "")
+ result["total"] = ip_data.get("total", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Standard Domain Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(DOMAIN_TABLE_NAME, DOMAIN_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(DOMAIN_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ domain_dcr_immutableid, domain_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ DOMAIN_DCR_NAME,
+ DOMAIN_STREAM_DECLARATION,
+ DOMAIN_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_domain_table(dce_endpoint, domain_dcr_immutableid, domain_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/utils.py b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/AzureFunctionIPinfoDomain/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/Domain/IPinfoDomainConn.zip b/Solutions/IPinfo/Data Connectors/Domain/IPinfoDomainConn.zip
new file mode 100644
index 00000000000..e01362e4aa5
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/Domain/IPinfoDomainConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Domain/IPinfo_Domain_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/Domain/IPinfo_Domain_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..ef38b69e7e7
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/IPinfo_Domain_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoDomainDataConnector",
+ "title": "IPinfo Domain Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_domain datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "Domain Data",
+ "legend": "Ipinfo_Domain_CL",
+ "baseQuery": "Ipinfo_Domain_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Domain_CL",
+ "query": "Ipinfo_Domain_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Domain_CL",
+ "lastDataReceivedQuery": "Ipinfo_Domain_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Domain_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Domain-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-Domain-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Domain/azuredeploy_Connector_IPinfo_Domain_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Domain/azuredeploy_Connector_IPinfo_Domain_AzureFunction.json
new file mode 100644
index 00000000000..fb5715e0df4
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/azuredeploy_Connector_IPinfo_Domain_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo Domain",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-Domain-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Domain/host.json b/Solutions/IPinfo/Data Connectors/Domain/host.json
new file mode 100644
index 00000000000..eed246c12bf
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "03:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/Domain/proxies.json b/Solutions/IPinfo/Data Connectors/Domain/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Domain/requirements.txt b/Solutions/IPinfo/Data Connectors/Domain/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Domain/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/constants.py b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/constants.py
new file mode 100644
index 00000000000..b4f0d70d17f
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/constants.py
@@ -0,0 +1,91 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME',
+ 'WORKSPACE_NAME', 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS',
+ 'DATA_COLLECTION_ENDPOINT_NAME', 'LOCATION_EXTENDED_DCR_NAME', 'LOCATION_EXTENDED_TABLE_NAME',
+ 'LOCATION_EXTENDED_STREAM_DECLARATION', 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL',
+ 'MMDB_NAME', 'LOCATION_EXTENDED_TABLE_SCHEMA', 'LOCATION_EXTENDED_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+LOCATION_EXTENDED_DCR_NAME = "ipinfo_rule_for_location_extended_table"
+LOCATION_EXTENDED_TABLE_NAME = "Ipinfo_Location_extended_CL"
+LOCATION_EXTENDED_STREAM_DECLARATION = "Custom-Ipinfo_Location_extended_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+MMDB_NAME = "location_extended_v2.mmdb"
+
+LOCATION_EXTENDED_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": LOCATION_EXTENDED_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "city", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "latitude", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "longitude", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "postal_code", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "radius", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "region_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "region", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "timezone", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "geoname_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{LOCATION_EXTENDED_TABLE_NAME}",
+ "name": LOCATION_EXTENDED_TABLE_NAME,
+}
+
+LOCATION_EXTENDED_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "city", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "country_name", "type": "string"},
+ {"name": "latitude", "type": "string"},
+ {"name": "longitude", "type": "string"},
+ {"name": "postal_code", "type": "string"},
+ {"name": "radius", "type": "string"},
+ {"name": "region_name", "type": "string"},
+ {"name": "region", "type": "string"},
+ {"name": "timezone", "type": "string"},
+ {"name": "geoname_id", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/function.json b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/function.json
new file mode 100644
index 00000000000..b0027ce9e99
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/function.json
@@ -0,0 +1,12 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+ }
+
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/main.py b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/main.py
new file mode 100644
index 00000000000..e568c9659a6
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/main.py
@@ -0,0 +1,90 @@
+import logging
+import time
+import maxminddb
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo Iplocation Extended timer trigger function executed.")
+
+ def upload_data_to_location_extended_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/location_extended_v2.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Standard Location Extended Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["city"] = ip_data.get("city", "")
+ result["country"] = ip_data.get("country", "")
+ result["country_name"] = ip_data.get("country_name", "")
+ result["latitude"] = ip_data.get("latitude", "")
+ result["longitude"] = ip_data.get("longitude", "")
+ result["postal_code"] = ip_data.get("postal_code", "")
+ result["radius"] = ip_data.get("radius", "")
+ result["region_name"] = ip_data.get("region_name", "")
+ result["region"] = ip_data.get("region", "")
+ result["timezone"] = ip_data.get("timezone", "")
+ result["geoname_id"] = ip_data.get("geoname_id", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Standard Location Extended Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(LOCATION_EXTENDED_TABLE_NAME, LOCATION_EXTENDED_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(LOCATION_EXTENDED_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ location_extended_dcr_immutableid, location_extended_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ LOCATION_EXTENDED_DCR_NAME,
+ LOCATION_EXTENDED_STREAM_DECLARATION,
+ LOCATION_EXTENDED_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_location_extended_table(dce_endpoint, location_extended_dcr_immutableid, location_extended_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/utils.py b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/AzureFunctionIPinfoIplocationExtended/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfoIplocationExtendedConn.zip b/Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfoIplocationExtendedConn.zip
new file mode 100644
index 00000000000..527b7ed3509
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfoIplocationExtendedConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfo_Iplocation_Extended_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfo_Iplocation_Extended_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..348522b272d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfo_Iplocation_Extended_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoIplocationExtendedDataConnector",
+ "title": "IPinfo Iplocation Extended Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_location_extended datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "Location Extended Data",
+ "legend": "Ipinfo_Location_extended_CL",
+ "baseQuery": "Ipinfo_Location_extended_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Location_extended_CL",
+ "query": "Ipinfo_Location_extended_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Location_extended_CL",
+ "lastDataReceivedQuery": "Ipinfo_Location_extended_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Location_extended_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Iplocation-Extended-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-Iplocation-Extended-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/azuredeploy_Connector_IPinfo_Iplocation_Extended_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Iplocation Extended/azuredeploy_Connector_IPinfo_Iplocation_Extended_AzureFunction.json
new file mode 100644
index 00000000000..e65c0a718bb
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/azuredeploy_Connector_IPinfo_Iplocation_Extended_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo Iplocation Extended",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-Iplocation-extended-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/host.json b/Solutions/IPinfo/Data Connectors/Iplocation Extended/host.json
new file mode 100644
index 00000000000..cf39731eec6
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "15:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/proxies.json b/Solutions/IPinfo/Data Connectors/Iplocation Extended/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation Extended/requirements.txt b/Solutions/IPinfo/Data Connectors/Iplocation Extended/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Iplocation Extended/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation/IPinfoIplocationConn.zip b/Solutions/IPinfo/Data Connectors/Iplocation/IPinfoIplocationConn.zip
index 1d460b9519d..a50735c3105 100644
Binary files a/Solutions/IPinfo/Data Connectors/Iplocation/IPinfoIplocationConn.zip and b/Solutions/IPinfo/Data Connectors/Iplocation/IPinfoIplocationConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation/azuredeploy_Connector_IPinfo_Iplocation_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Iplocation/azuredeploy_Connector_IPinfo_Iplocation_AzureFunction.json
index 7855097241e..0124b50069b 100644
--- a/Solutions/IPinfo/Data Connectors/Iplocation/azuredeploy_Connector_IPinfo_Iplocation_AzureFunction.json
+++ b/Solutions/IPinfo/Data Connectors/Iplocation/azuredeploy_Connector_IPinfo_Iplocation_AzureFunction.json
@@ -32,11 +32,11 @@
},
"RETENTION_IN_DAYS": {
"type": "string",
- "defaultValue": "IPinfo Token"
+ "defaultValue": "10"
},
"TOTAL_RETENTION_IN_DAYS": {
"type": "string",
- "defaultValue": "IPinfo Token"
+ "defaultValue": "30"
},
"SCHEDULE": {
"type": "string",
@@ -114,7 +114,7 @@
"reserved": true,
"maximumElasticWorkerCount": 20,
"siteConfig": {
- "linuxFxVersion": "Python|3.10"
+ "linuxFxVersion": "python|3.11"
}
}
},
diff --git a/Solutions/IPinfo/Data Connectors/Iplocation/host.json b/Solutions/IPinfo/Data Connectors/Iplocation/host.json
index 57c55bc2913..cf39731eec6 100644
--- a/Solutions/IPinfo/Data Connectors/Iplocation/host.json
+++ b/Solutions/IPinfo/Data Connectors/Iplocation/host.json
@@ -11,6 +11,6 @@
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
- "version": "[4.*, 5.0.0)"
+ "version": "[3.*, 4.0.0)"
}
}
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/constants.py b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/constants.py
new file mode 100644
index 00000000000..1dca4096ef5
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/constants.py
@@ -0,0 +1,95 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'PRIVACY_EXTENDED_DCR_NAME', 'PRIVACY_EXTENDED_TABLE_NAME', 'PRIVACY_EXTENDED_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'MMDB_NAME',
+ 'PRIVACY_EXTENDED_TABLE_SCHEMA', 'PRIVACY_EXTENDED_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+PRIVACY_EXTENDED_DCR_NAME = "ipinfo_rule_for_privacy_extended_tables"
+PRIVACY_EXTENDED_TABLE_NAME = "Ipinfo_Privacy_extended_CL"
+PRIVACY_EXTENDED_STREAM_DECLARATION = "Custom-Ipinfo_Privacy_extended_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+MMDB_NAME = "privacy_extended.mmdb"
+
+PRIVACY_EXTENDED_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": PRIVACY_EXTENDED_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "anycast", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "census", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "census_port", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "device_activity", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "hosting", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "network", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "proxy", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "relay", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "tor", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "vpn", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "vpn_config", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "vpn_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{PRIVACY_EXTENDED_TABLE_NAME}",
+ "name": PRIVACY_EXTENDED_TABLE_NAME,
+}
+
+PRIVACY_EXTENDED_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "anycast", "type": "string"},
+ {"name": "census", "type": "string"},
+ {"name": "census_port", "type": "string"},
+ {"name": "device_activity", "type": "string"},
+ {"name": "hosting", "type": "string"},
+ {"name": "network", "type": "string"},
+ {"name": "proxy", "type": "string"},
+ {"name": "relay", "type": "string"},
+ {"name": "tor", "type": "string"},
+ {"name": "vpn", "type": "string"},
+ {"name": "vpn_config", "type": "string"},
+ {"name": "vpn_name", "type": "string"},
+ {"name": "whois", "type": "string"},
+ {"name": "range", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/function.json b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/main.py b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/main.py
new file mode 100644
index 00000000000..2aa838c3c41
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/main.py
@@ -0,0 +1,92 @@
+import logging
+import time
+import maxminddb
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo Privacy Extended timer trigger function executed.")
+
+ def upload_data_to_privacy_extended_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ mmdb_file_path = "/tmp/privacy_extended.mmdb"
+ reader = maxminddb.open_database(mmdb_file_path)
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading Standard Privacy Extended Data.\n")
+ for ip, ip_data in reader:
+ result = {}
+ result["anycast"] = ip_data.get("anycast", "")
+ result["census"] = ip_data.get("census", "")
+ result["census_port"] = ip_data.get("census_port", "")
+ result["device_activity"] = ip_data.get("device_activity", "")
+ result["hosting"] = ip_data.get("hosting", "")
+ result["network"] = ip_data.get("network", "")
+ result["proxy"] = ip_data.get("proxy", "")
+ result["relay"] = ip_data.get("relay", "")
+ result["tor"] = ip_data.get("tor", "")
+ result["vpn"] = ip_data.get("vpn", "")
+ result["vpn_config"] = ip_data.get("vpn_config", "")
+ result["vpn_name"] = ip_data.get("vpn_name", "")
+ result["whois"] = ip_data.get("whois", "")
+ result["range"] = str(ip)
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ reader.close()
+ logging.info("Standard Privacy Extended Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(PRIVACY_EXTENDED_TABLE_NAME, PRIVACY_EXTENDED_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(PRIVACY_EXTENDED_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ privacy_extended_dcr_immutableid, privacy_extended_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ PRIVACY_EXTENDED_DCR_NAME,
+ PRIVACY_EXTENDED_STREAM_DECLARATION,
+ PRIVACY_EXTENDED_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_privacy_extended_table(dce_endpoint, privacy_extended_dcr_immutableid, privacy_extended_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/utils.py b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/utils.py
new file mode 100644
index 00000000000..53397fd0b2b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/AzureFunctionIPinfoPrivacyExtended/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{MMDB_NAME}?token="
+ logging.info(f"Downloading '{MMDB_NAME}'...")
+ file_path = os.path.join("/tmp/", MMDB_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{MMDB_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{MMDB_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{MMDB_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfoPrivacyExtendedConn.zip b/Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfoPrivacyExtendedConn.zip
new file mode 100644
index 00000000000..8b9a6d6ff8f
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfoPrivacyExtendedConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfo_Privacy_Extended_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfo_Privacy_Extended_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..96c6ddad7c7
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfo_Privacy_Extended_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoPrivacyExtendedDataConnector",
+ "title": "IPinfo Privacy Extended Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_privacy datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "Privacy Extended Data",
+ "legend": "Ipinfo_Privacy_extended_CL",
+ "baseQuery": "Ipinfo_Privacy_extended_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Privacy_extended_CL",
+ "query": "Ipinfo_Privacy_extended_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Privacy_extended_CL",
+ "lastDataReceivedQuery": "Ipinfo_Privacy_extended_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Privacy_extended_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Privacy-Extended-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-Privacy-Extended-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/azuredeploy_Connector_IPinfo_Privacy_Extended_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Privacy Extended/azuredeploy_Connector_IPinfo_Privacy_Extended_AzureFunction.json
new file mode 100644
index 00000000000..66bfd6a7ad2
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/azuredeploy_Connector_IPinfo_Privacy_Extended_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo Privacy Extended",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-Privacy-Extended-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/host.json b/Solutions/IPinfo/Data Connectors/Privacy Extended/host.json
new file mode 100644
index 00000000000..cf39731eec6
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "15:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/proxies.json b/Solutions/IPinfo/Data Connectors/Privacy Extended/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/Privacy Extended/requirements.txt b/Solutions/IPinfo/Data Connectors/Privacy Extended/requirements.txt
new file mode 100644
index 00000000000..facd64c3bf9
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/Privacy Extended/requirements.txt
@@ -0,0 +1,9 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
+maxminddb
diff --git a/Solutions/IPinfo/Data Connectors/Privacy/IPinfoPrivacyConn.zip b/Solutions/IPinfo/Data Connectors/Privacy/IPinfoPrivacyConn.zip
index 78d887c7e93..c6ef7be30e4 100644
Binary files a/Solutions/IPinfo/Data Connectors/Privacy/IPinfoPrivacyConn.zip and b/Solutions/IPinfo/Data Connectors/Privacy/IPinfoPrivacyConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/Privacy/azuredeploy_Connector_IPinfo_Privacy_AzureFunction.json b/Solutions/IPinfo/Data Connectors/Privacy/azuredeploy_Connector_IPinfo_Privacy_AzureFunction.json
index 157e54dd8c0..90920e8b1cc 100644
--- a/Solutions/IPinfo/Data Connectors/Privacy/azuredeploy_Connector_IPinfo_Privacy_AzureFunction.json
+++ b/Solutions/IPinfo/Data Connectors/Privacy/azuredeploy_Connector_IPinfo_Privacy_AzureFunction.json
@@ -32,11 +32,11 @@
},
"RETENTION_IN_DAYS": {
"type": "string",
- "defaultValue": "IPinfo Token"
+ "defaultValue": "10"
},
"TOTAL_RETENTION_IN_DAYS": {
"type": "string",
- "defaultValue": "IPinfo Token"
+ "defaultValue": "30"
},
"SCHEDULE": {
"type": "string",
@@ -114,7 +114,7 @@
"reserved": true,
"maximumElasticWorkerCount": 20,
"siteConfig": {
- "linuxFxVersion": "Python|3.10"
+ "linuxFxVersion": "python|3.11"
}
}
},
diff --git a/Solutions/IPinfo/Data Connectors/Privacy/host.json b/Solutions/IPinfo/Data Connectors/Privacy/host.json
index f65ed7c548a..e65054b4c51 100644
--- a/Solutions/IPinfo/Data Connectors/Privacy/host.json
+++ b/Solutions/IPinfo/Data Connectors/Privacy/host.json
@@ -11,6 +11,6 @@
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
- "version": "[4.*, 5.0.0)"
+ "version": "[3.*, 4.0.0)"
}
}
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/constants.py b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/constants.py
new file mode 100644
index 00000000000..5eb00a52831
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/constants.py
@@ -0,0 +1,107 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'RIRWHOIS_DCR_NAME', 'RIRWHOIS_TABLE_NAME', 'RIRWHOIS_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'RIRWHOIS_TABLE_SCHEMA', 'RIRWHOIS_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+RIRWHOIS_DCR_NAME = "ipinfo_rule_for_RIRWHOIS_tables"
+RIRWHOIS_TABLE_NAME = "Ipinfo_RIRWHOIS_CL"
+RIRWHOIS_STREAM_DECLARATION = "Custom-Ipinfo_RIRWHOIS_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "rir.csv.gz"
+
+RIRWHOIS_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": RIRWHOIS_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "status", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "tech", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "maintainer", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "admin", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "source", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "org", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "rdns_domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "geoloc", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "org_address", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "asn", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "as_name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "as_domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "as_type", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{RIRWHOIS_TABLE_NAME}",
+ "name": RIRWHOIS_TABLE_NAME,
+}
+
+RIRWHOIS_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "range", "type": "string"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "status", "type": "string"},
+ {"name": "tech", "type": "string"},
+ {"name": "maintainer", "type": "string"},
+ {"name": "admin", "type": "string"},
+ {"name": "source", "type": "string"},
+ {"name": "whois_domain", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "org", "type": "string"},
+ {"name": "rdns_domain", "type": "string"},
+ {"name": "domain", "type": "string"},
+ {"name": "geoloc", "type": "string"},
+ {"name": "org_address", "type": "string"},
+ {"name": "asn", "type": "string"},
+ {"name": "as_name", "type": "string"},
+ {"name": "as_domain", "type": "string"},
+ {"name": "as_type", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/function.json b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/main.py b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/main.py
new file mode 100644
index 00000000000..bbe98c38a47
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/main.py
@@ -0,0 +1,98 @@
+import logging
+import time
+import csv
+import gzip
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo RIRWHOIS timer trigger function executed.")
+
+ def upload_data_to_RIRWHOIS_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/rir.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["country"] = ip_data.get("country", "")
+ result["status"] = ip_data.get("status", "")
+ result["tech"] = ip_data.get("tech", "")
+ result["maintainer"] = ip_data.get("maintainer", "")
+ result["admin"] = ip_data.get("admin", "")
+ result["source"] = ip_data.get("source", "")
+ result["whois_domain"] = ip_data.get("whois_domain", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["org"] = ip_data.get("org", "")
+ result["rdns_domain"] = ip_data.get("rdns_domain", "")
+ result["domain"] = ip_data.get("domain", "")
+ result["geoloc"] = ip_data.get("geoloc", "")
+ result["org_address"] = ip_data.get("org_address", "")
+ result["asn"] = ip_data.get("asn", "")
+ result["as_name"] = ip_data.get("as_name", "")
+ result["as_domain"] = ip_data.get("as_domain", "")
+ result["as_type"] = ip_data.get("as_type", "")
+ result["range"] = ip_data.get("range", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("RIRWHOIS Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(RIRWHOIS_TABLE_NAME, RIRWHOIS_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(RIRWHOIS_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ RIRWHOIS_dcr_immutableid, RIRWHOIS_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ RIRWHOIS_DCR_NAME,
+ RIRWHOIS_STREAM_DECLARATION,
+ RIRWHOIS_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_RIRWHOIS_table(dce_endpoint, RIRWHOIS_dcr_immutableid, RIRWHOIS_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/utils.py b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/utils.py
new file mode 100644
index 00000000000..ff1865193c1
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/AzureFunctionIPinfoRIRWHOIS/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfoRIRWHOISConn.zip b/Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfoRIRWHOISConn.zip
new file mode 100644
index 00000000000..be889dd70df
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfoRIRWHOISConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfo_RIRWHOIS_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfo_RIRWHOIS_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..15d5a286a14
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfo_RIRWHOIS_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoRIRWHOISDataConnector",
+ "title": "IPinfo RIRWHOIS Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download RIRWHOIS datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "RIRWHOIS Data",
+ "legend": "Ipinfo_RIRWHOIS_CL",
+ "baseQuery": "Ipinfo_RIRWHOIS_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_RIRWHOIS_CL",
+ "query": "Ipinfo_RIRWHOIS_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_RIRWHOIS_CL",
+ "lastDataReceivedQuery": "Ipinfo_RIRWHOIS_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_RIRWHOIS_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-RIRWHOIS-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-RIRWHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/azuredeploy_Connector_IPinfo_RIRWHOIS_AzureFunction.json b/Solutions/IPinfo/Data Connectors/RIRWHOIS/azuredeploy_Connector_IPinfo_RIRWHOIS_AzureFunction.json
new file mode 100644
index 00000000000..53806380ea4
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/azuredeploy_Connector_IPinfo_RIRWHOIS_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo RIRWHOIS",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-RIRWHOIS-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/host.json b/Solutions/IPinfo/Data Connectors/RIRWHOIS/host.json
new file mode 100644
index 00000000000..eed246c12bf
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "03:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/proxies.json b/Solutions/IPinfo/Data Connectors/RIRWHOIS/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/RIRWHOIS/requirements.txt b/Solutions/IPinfo/Data Connectors/RIRWHOIS/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RIRWHOIS/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/constants.py b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/constants.py
new file mode 100644
index 00000000000..54a665f0a90
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/constants.py
@@ -0,0 +1,95 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'RWHOIS_DCR_NAME', 'RWHOIS_TABLE_NAME', 'RWHOIS_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'RWHOIS_TABLE_SCHEMA', 'RWHOIS_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+RWHOIS_DCR_NAME = "ipinfo_rule_for_RWHOIS_tables"
+RWHOIS_TABLE_NAME = "Ipinfo_RWHOIS_CL"
+RWHOIS_STREAM_DECLARATION = "Custom-Ipinfo_RWHOIS_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "rwhois.csv.gz"
+
+RWHOIS_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": RWHOIS_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_desc", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "host", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "email", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "abuse", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "city", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "street", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "postal", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "imported", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{RWHOIS_TABLE_NAME}",
+ "name": RWHOIS_TABLE_NAME,
+}
+
+RWHOIS_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "range", "type": "string"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "whois_desc", "type": "string"},
+ {"name": "host", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "email", "type": "string"},
+ {"name": "abuse", "type": "string"},
+ {"name": "domain", "type": "string"},
+ {"name": "city", "type": "string"},
+ {"name": "street", "type": "string"},
+ {"name": "postal", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "imported", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/function.json b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/main.py b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/main.py
new file mode 100644
index 00000000000..8bcdad3b1d7
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/main.py
@@ -0,0 +1,93 @@
+import logging
+import time
+import csv
+import gzip
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo RWHOIS timer trigger function executed.")
+
+ def upload_data_to_RWHOIS_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/rwhois.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ logging.info("Uploading RWHOIS Data.\n")
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["whois_desc"] = ip_data.get("descr", "")
+ result["host"] = ip_data.get("host", "")
+ result["country"] = ip_data.get("country", "")
+ result["email"] = ip_data.get("email", "")
+ result["abuse"] = ip_data.get("abuse", "")
+ result["domain"] = ip_data.get("domain", "")
+ result["city"] = ip_data.get("city", "")
+ result["street"] = ip_data.get("street", "")
+ result["postal"] = ip_data.get("postal", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["imported"] = ip_data.get("imported", "")
+ result["range"] = ip_data.get("range", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("RWHOIS Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(RWHOIS_TABLE_NAME, RWHOIS_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(RWHOIS_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ RWHOIS_dcr_immutableid, RWHOIS_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ RWHOIS_DCR_NAME,
+ RWHOIS_STREAM_DECLARATION,
+ RWHOIS_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_RWHOIS_table(dce_endpoint, RWHOIS_dcr_immutableid, RWHOIS_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/utils.py b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/utils.py
new file mode 100644
index 00000000000..5e210f02b97
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/AzureFunctionIPinfoRWHOIS/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/IPinfoRWHOISConn.zip b/Solutions/IPinfo/Data Connectors/RWHOIS/IPinfoRWHOISConn.zip
new file mode 100644
index 00000000000..c2ef3ccd451
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/RWHOIS/IPinfoRWHOISConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/IPinfo_RWHOIS_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/RWHOIS/IPinfo_RWHOIS_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..e01d5902da4
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/IPinfo_RWHOIS_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoRWHOISDataConnector",
+ "title": "IPinfo RWHOIS Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download RWHOIS datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "RWHOIS Data",
+ "legend": "Ipinfo_RWHOIS_CL",
+ "baseQuery": "Ipinfo_RWHOIS_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_RWHOIS_CL",
+ "query": "Ipinfo_RWHOIS_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_RWHOIS_CL",
+ "lastDataReceivedQuery": "Ipinfo_RWHOIS_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_RWHOIS_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-RWHOIS-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-RWHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/azuredeploy_Connector_IPinfo_RWHOIS_AzureFunction.json b/Solutions/IPinfo/Data Connectors/RWHOIS/azuredeploy_Connector_IPinfo_RWHOIS_AzureFunction.json
new file mode 100644
index 00000000000..fe6a7bb5017
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/azuredeploy_Connector_IPinfo_RWHOIS_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo RWHOIS",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-RWHOIS-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/host.json b/Solutions/IPinfo/Data Connectors/RWHOIS/host.json
new file mode 100644
index 00000000000..e53d8df199b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "00:10:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/proxies.json b/Solutions/IPinfo/Data Connectors/RWHOIS/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/RWHOIS/requirements.txt b/Solutions/IPinfo/Data Connectors/RWHOIS/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/RWHOIS/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/constants.py b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/constants.py
new file mode 100644
index 00000000000..665ee34a7da
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/constants.py
@@ -0,0 +1,81 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'WHOIS_ASN_DCR_NAME', 'WHOIS_ASN_TABLE_NAME', 'WHOIS_ASN_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'WHOIS_ASN_TABLE_SCHEMA', 'WHOIS_ASN_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+WHOIS_ASN_DCR_NAME = "ipinfo_rule_for_WHOIS_ASN_tables"
+WHOIS_ASN_TABLE_NAME = "Ipinfo_WHOIS_ASN_CL"
+WHOIS_ASN_STREAM_DECLARATION = "Custom-Ipinfo_WHOIS_ASN_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "whois_asn.csv.gz"
+
+WHOIS_ASN_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": WHOIS_ASN_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "org_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "created", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "source", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{WHOIS_ASN_TABLE_NAME}",
+ "name": WHOIS_ASN_TABLE_NAME,
+}
+
+WHOIS_ASN_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "org_id", "type": "string"},
+ {"name": "created", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "source", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/function.json b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/main.py b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/main.py
new file mode 100644
index 00000000000..ae4db0ec224
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/main.py
@@ -0,0 +1,88 @@
+import logging
+import time
+import csv
+import gzip
+import sys
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo WHOIS_ASN timer trigger function executed.")
+
+ def upload_data_to_WHOIS_ASN_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/whois_asn.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ csv.field_size_limit(sys.maxsize)
+ logging.info("Uploading WHOIS_ASN Data.\n")
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["country"] = ip_data.get("country", "")
+ result["org_id"] = ip_data.get("org_id", "")
+ result["created"] = ip_data.get("created", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["source"] = ip_data.get("source", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("WHOIS_ASN Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(WHOIS_ASN_TABLE_NAME, WHOIS_ASN_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(WHOIS_ASN_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ WHOIS_ASN_dcr_immutableid, WHOIS_ASN_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ WHOIS_ASN_DCR_NAME,
+ WHOIS_ASN_STREAM_DECLARATION,
+ WHOIS_ASN_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_WHOIS_ASN_table(dce_endpoint, WHOIS_ASN_dcr_immutableid, WHOIS_ASN_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/utils.py b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/utils.py
new file mode 100644
index 00000000000..f44b4b0a099
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/AzureFunctionIPinfoWHOISASN/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/IPInfoWHOISASNConn.zip b/Solutions/IPinfo/Data Connectors/WHOIS ASN/IPInfoWHOISASNConn.zip
new file mode 100644
index 00000000000..ce751492cf3
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/WHOIS ASN/IPInfoWHOISASNConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/IPinfo_WHOIS_ASN_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/WHOIS ASN/IPinfo_WHOIS_ASN_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..cdf70cf33eb
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/IPinfo_WHOIS_ASN_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoWHOISASNDataConnector",
+ "title": "IPinfo WHOIS ASN Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download WHOIS_ASN datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_ASN Data",
+ "legend": "Ipinfo_WHOIS_ASN_CL",
+ "baseQuery": "Ipinfo_WHOIS_ASN_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_ASN_CL",
+ "query": "Ipinfo_WHOIS_ASN_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_ASN_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_ASN_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_ASN_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-ASN-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-WHOIS-ASN-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/azuredeploy_Connector_IPinfo_WHOIS_ASN_AzureFunction.json b/Solutions/IPinfo/Data Connectors/WHOIS ASN/azuredeploy_Connector_IPinfo_WHOIS_ASN_AzureFunction.json
new file mode 100644
index 00000000000..7cc4abb21e0
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/azuredeploy_Connector_IPinfo_WHOIS_ASN_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo WHOIS ASN",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-WHOIS-ASN-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/host.json b/Solutions/IPinfo/Data Connectors/WHOIS ASN/host.json
new file mode 100644
index 00000000000..e53d8df199b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "00:10:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/proxies.json b/Solutions/IPinfo/Data Connectors/WHOIS ASN/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ASN/requirements.txt b/Solutions/IPinfo/Data Connectors/WHOIS ASN/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ASN/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/constants.py b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/constants.py
new file mode 100644
index 00000000000..d085460b631
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/constants.py
@@ -0,0 +1,83 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'WHOIS_MNT_DCR_NAME', 'WHOIS_MNT_TABLE_NAME', 'WHOIS_MNT_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'WHOIS_MNT_TABLE_SCHEMA', 'WHOIS_MNT_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+WHOIS_MNT_DCR_NAME = "ipinfo_rule_for_WHOIS_MNT_tables"
+WHOIS_MNT_TABLE_NAME = "Ipinfo_WHOIS_MNT_CL"
+WHOIS_MNT_STREAM_DECLARATION = "Custom-Ipinfo_WHOIS_MNT_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "whois_mnt.csv.gz"
+
+WHOIS_MNT_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": WHOIS_MNT_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "admin_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "tech_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "org_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "created", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "source", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{WHOIS_MNT_TABLE_NAME}",
+ "name": WHOIS_MNT_TABLE_NAME,
+}
+
+WHOIS_MNT_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "admin_id", "type": "string"},
+ {"name": "tech_id", "type": "string"},
+ {"name": "org_id", "type": "string"},
+ {"name": "created", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "source", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/function.json b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/main.py b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/main.py
new file mode 100644
index 00000000000..dd924f436a0
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/main.py
@@ -0,0 +1,89 @@
+import logging
+import time
+import csv
+import gzip
+import sys
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo WHOIS_MNT timer trigger function executed.")
+
+ def upload_data_to_WHOIS_MNT_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/whois_mnt.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ csv.field_size_limit(sys.maxsize)
+ logging.info("Uploading WHOIS_MNT Data.\n")
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["admin_id"] = ip_data.get("admin_id", "")
+ result["tech_id"] = ip_data.get("tech_id", "")
+ result["org_id"] = ip_data.get("org_id", "")
+ result["created"] = ip_data.get("created", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["source"] = ip_data.get("source", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("WHOIS_MNT Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(WHOIS_MNT_TABLE_NAME, WHOIS_MNT_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(WHOIS_MNT_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ WHOIS_MNT_dcr_immutableid, WHOIS_MNT_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ WHOIS_MNT_DCR_NAME,
+ WHOIS_MNT_STREAM_DECLARATION,
+ WHOIS_MNT_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_WHOIS_MNT_table(dce_endpoint, WHOIS_MNT_dcr_immutableid, WHOIS_MNT_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/utils.py b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/utils.py
new file mode 100644
index 00000000000..f44b4b0a099
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/AzureFunctionIPinfoWHOISMNT/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfoWHOISMNTConn.zip b/Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfoWHOISMNTConn.zip
new file mode 100644
index 00000000000..4a3f288fa8a
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfoWHOISMNTConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfo_WHOIS_MNT_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfo_WHOIS_MNT_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..f9cf8455a55
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfo_WHOIS_MNT_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoWHOISMNTDataConnector",
+ "title": "IPinfo WHOIS MNT Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download WHOIS_MNT datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_MNT Data",
+ "legend": "Ipinfo_WHOIS_MNT_CL",
+ "baseQuery": "Ipinfo_WHOIS_MNT_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_MNT_CL",
+ "query": "Ipinfo_WHOIS_MNT_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_MNT_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_MNT_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_MNT_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-MNT-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-WHOIS-MNT-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/azuredeploy_Connector_IPinfo_WHOIS_MNT_AzureFunction.json b/Solutions/IPinfo/Data Connectors/WHOIS MNT/azuredeploy_Connector_IPinfo_WHOIS_MNT_AzureFunction.json
new file mode 100644
index 00000000000..240a02f1c4d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/azuredeploy_Connector_IPinfo_WHOIS_MNT_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo WHOIS MNT",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-WHOIS-MNT-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/host.json b/Solutions/IPinfo/Data Connectors/WHOIS MNT/host.json
new file mode 100644
index 00000000000..e53d8df199b
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "00:10:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/proxies.json b/Solutions/IPinfo/Data Connectors/WHOIS MNT/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS MNT/requirements.txt b/Solutions/IPinfo/Data Connectors/WHOIS MNT/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS MNT/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/constants.py b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/constants.py
new file mode 100644
index 00000000000..b9222f5201f
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/constants.py
@@ -0,0 +1,95 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'WHOIS_NET_DCR_NAME', 'WHOIS_NET_TABLE_NAME', 'WHOIS_NET_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'WHOIS_NET_TABLE_SCHEMA', 'WHOIS_NET_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+WHOIS_NET_DCR_NAME = "ipinfo_rule_for_WHOIS_NET_tables"
+WHOIS_NET_TABLE_NAME = "Ipinfo_WHOIS_NET_CL"
+WHOIS_NET_STREAM_DECLARATION = "Custom-Ipinfo_WHOIS_NET_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "whois_net.csv.gz"
+
+WHOIS_NET_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": WHOIS_NET_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "ip_range", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "org_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "status", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "tech_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "mnt_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "admin_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "abuse_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "created", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "source", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{WHOIS_NET_TABLE_NAME}",
+ "name": WHOIS_NET_TABLE_NAME,
+}
+
+WHOIS_NET_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "range", "type": "string"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "domain", "type": "string"},
+ {"name": "org_id", "type": "string"},
+ {"name": "status", "type": "string"},
+ {"name": "tech_id", "type": "string"},
+ {"name": "mnt_id", "type": "string"},
+ {"name": "admin_id", "type": "string"},
+ {"name": "abuse_id", "type": "string"},
+ {"name": "created", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "source", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/function.json b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/main.py b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/main.py
new file mode 100644
index 00000000000..a447e7d56c5
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/main.py
@@ -0,0 +1,95 @@
+import logging
+import time
+import csv
+import gzip
+import sys
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo WHOIS_NET timer trigger function executed.")
+
+ def upload_data_to_WHOIS_NET_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/whois_net.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ csv.field_size_limit(sys.maxsize)
+ logging.info("Uploading WHOIS_NET Data.\n")
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["country"] = ip_data.get("country", "")
+ result["domain"] = ip_data.get("domain", "")
+ result["org_id"] = ip_data.get("org_id", "")
+ result["status"] = ip_data.get("status", "")
+ result["tech_id"] = ip_data.get("tech_id", "")
+ result["mnt_id"] = ip_data.get("mnt_id", "")
+ result["admin_id"] = ip_data.get("admin_id", "")
+ result["abuse_id"] = ip_data.get("abuse_id", "")
+ result["created"] = ip_data.get("created", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["source"] = ip_data.get("source", "")
+ result["range"] = ip_data.get("range", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("WHOIS_NET Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(WHOIS_NET_TABLE_NAME, WHOIS_NET_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(WHOIS_NET_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ WHOIS_NET_dcr_immutableid, WHOIS_NET_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ WHOIS_NET_DCR_NAME,
+ WHOIS_NET_STREAM_DECLARATION,
+ WHOIS_NET_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_WHOIS_NET_table(dce_endpoint, WHOIS_NET_dcr_immutableid, WHOIS_NET_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/utils.py b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/utils.py
new file mode 100644
index 00000000000..5e210f02b97
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/AzureFunctionIPinfoWHOISNET/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename ip_range=range\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfoWHOISNETConn.zip b/Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfoWHOISNETConn.zip
new file mode 100644
index 00000000000..0a9965a555c
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfoWHOISNETConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfo_WHOIS_NET_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfo_WHOIS_NET_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..dc5e8ec0a48
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfo_WHOIS_NET_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoWHOISNETDataConnector",
+ "title": "IPinfo WHOIS NET Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download WHOIS_NET datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_NET Data",
+ "legend": "Ipinfo_WHOIS_NET_CL",
+ "baseQuery": "Ipinfo_WHOIS_NET_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_NET_CL",
+ "query": "Ipinfo_WHOIS_NET_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_NET_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_NET_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_NET_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-NET-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-WHOIS-NET-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/azuredeploy_Connector_IPinfo_WHOIS_NET_AzureFunction.json b/Solutions/IPinfo/Data Connectors/WHOIS NET/azuredeploy_Connector_IPinfo_WHOIS_NET_AzureFunction.json
new file mode 100644
index 00000000000..de54faff11f
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/azuredeploy_Connector_IPinfo_WHOIS_NET_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo WHOIS NET",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-WHOIS-NET-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/host.json b/Solutions/IPinfo/Data Connectors/WHOIS NET/host.json
new file mode 100644
index 00000000000..eed246c12bf
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "03:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/proxies.json b/Solutions/IPinfo/Data Connectors/WHOIS NET/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS NET/requirements.txt b/Solutions/IPinfo/Data Connectors/WHOIS NET/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS NET/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/constants.py b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/constants.py
new file mode 100644
index 00000000000..779ea8f95c1
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/constants.py
@@ -0,0 +1,101 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'WHOIS_ORG_DCR_NAME', 'WHOIS_ORG_TABLE_NAME', 'WHOIS_ORG_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'WHOIS_ORG_TABLE_SCHEMA', 'WHOIS_ORG_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+WHOIS_ORG_DCR_NAME = "ipinfo_rule_for_WHOIS_ORG_tables"
+WHOIS_ORG_TABLE_NAME = "Ipinfo_WHOIS_ORG_CL"
+WHOIS_ORG_STREAM_DECLARATION = "Custom-Ipinfo_WHOIS_ORG_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "whois_org.csv.gz"
+
+WHOIS_ORG_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": WHOIS_ORG_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "address", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "street", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "city", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "state", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "postalcode", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "admin_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "tech_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "abuse_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "mnt_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "email", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "domain", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "created", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "source", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{WHOIS_ORG_TABLE_NAME}",
+ "name": WHOIS_ORG_TABLE_NAME,
+}
+
+WHOIS_ORG_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "address", "type": "string"},
+ {"name": "street", "type": "string"},
+ {"name": "city", "type": "string"},
+ {"name": "state", "type": "string"},
+ {"name": "postalcode", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "admin_id", "type": "string"},
+ {"name": "tech_id", "type": "string"},
+ {"name": "abuse_id", "type": "string"},
+ {"name": "mnt_id", "type": "string"},
+ {"name": "email", "type": "string"},
+ {"name": "domain", "type": "string"},
+ {"name": "created", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "source", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/function.json b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/main.py b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/main.py
new file mode 100644
index 00000000000..0320b190063
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/main.py
@@ -0,0 +1,98 @@
+import logging
+import time
+import csv
+import gzip
+import sys
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo WHOIS_ORG timer trigger function executed.")
+
+ def upload_data_to_WHOIS_ORG_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/whois_org.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ csv.field_size_limit(sys.maxsize)
+ logging.info("Uploading WHOIS_ORG Data.\n")
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["address"] = ip_data.get("address", "")
+ result["street"] = ip_data.get("street", "")
+ result["city"] = ip_data.get("city", "")
+ result["state"] = ip_data.get("state", "")
+ result["postalcode"] = ip_data.get("postalcode", "")
+ result["country"] = ip_data.get("country", "")
+ result["admin_id"] = ip_data.get("admin_id", "")
+ result["tech_id"] = ip_data.get("tech_id", "")
+ result["abuse_id"] = ip_data.get("abuse_id", "")
+ result["mnt_id"] = ip_data.get("mnt_id", "")
+ result["email"] = ip_data.get("email", "")
+ result["domain"] = ip_data.get("domain", "")
+ result["created"] = ip_data.get("created", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["source"] = ip_data.get("source", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("WHOIS_ORG Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(WHOIS_ORG_TABLE_NAME, WHOIS_ORG_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(WHOIS_ORG_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ WHOIS_ORG_dcr_immutableid, WHOIS_ORG_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ WHOIS_ORG_DCR_NAME,
+ WHOIS_ORG_STREAM_DECLARATION,
+ WHOIS_ORG_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_WHOIS_ORG_table(dce_endpoint, WHOIS_ORG_dcr_immutableid, WHOIS_ORG_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/utils.py b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/utils.py
new file mode 100644
index 00000000000..f44b4b0a099
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/AzureFunctionIPinfoWHOISORG/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfoWHOISORGConn.zip b/Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfoWHOISORGConn.zip
new file mode 100644
index 00000000000..ca781ee5cf5
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfoWHOISORGConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfo_WHOIS_ORG_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfo_WHOIS_ORG_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..f7c8562669e
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfo_WHOIS_ORG_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoWHOISORGDataConnector",
+ "title": "IPinfo WHOIS ORG Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download WHOIS_ORG datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_ORG Data",
+ "legend": "Ipinfo_WHOIS_ORG_CL",
+ "baseQuery": "Ipinfo_WHOIS_ORG_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_ORG_CL",
+ "query": "Ipinfo_WHOIS_ORG_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_ORG_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_ORG_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_ORG_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-ORG-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-WHOIS-ORG-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/azuredeploy_Connector_IPinfo_WHOIS_ORG_AzureFunction.json b/Solutions/IPinfo/Data Connectors/WHOIS ORG/azuredeploy_Connector_IPinfo_WHOIS_ORG_AzureFunction.json
new file mode 100644
index 00000000000..8c55a7c040d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/azuredeploy_Connector_IPinfo_WHOIS_ORG_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo WHOIS ORG",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-WHOIS-ORG-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/host.json b/Solutions/IPinfo/Data Connectors/WHOIS ORG/host.json
new file mode 100644
index 00000000000..2b8b7bb60bd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "01:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/proxies.json b/Solutions/IPinfo/Data Connectors/WHOIS ORG/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS ORG/requirements.txt b/Solutions/IPinfo/Data Connectors/WHOIS ORG/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS ORG/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/constants.py b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/constants.py
new file mode 100644
index 00000000000..4e3d1569798
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/constants.py
@@ -0,0 +1,91 @@
+import os
+
+__all__ = [
+ 'RESOURCE_ID', 'IPINFO_TOKEN', 'TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET',
+ 'LOCATION', 'SUBCRIPTION_ID', 'RESOURCE_GROUP_NAME', 'WORKSPACE_NAME',
+ 'RETENTION_IN_DAYS', 'TOTAL_RETENTION_IN_DAYS', 'DATA_COLLECTION_ENDPOINT_NAME',
+ 'WHOIS_POC_DCR_NAME', 'WHOIS_POC_TABLE_NAME', 'WHOIS_POC_STREAM_DECLARATION',
+ 'AZURE_SCOPE', 'AZURE_BASE_URL', 'IPINFO_BASE_URL', 'CSV_NAME',
+ 'WHOIS_POC_TABLE_SCHEMA', 'WHOIS_POC_TABLE_COLUMNS'
+]
+
+# Enviornment Virables
+RESOURCE_ID = os.environ["RESOURCE_ID"]
+IPINFO_TOKEN = os.environ["IPINFO_TOKEN"]
+TENANT_ID = os.environ["TENANT_ID"]
+CLIENT_ID = os.environ["CLIENT_ID"]
+CLIENT_SECRET = os.environ["CLIENT_SECRET"]
+RETENTION_IN_DAYS = os.environ["RETENTION_IN_DAYS"]
+TOTAL_RETENTION_IN_DAYS = os.environ["TOTAL_RETENTION_IN_DAYS"]
+LOCATION = os.environ["LOCATION"]
+
+parts = RESOURCE_ID.split("/")
+SUBCRIPTION_ID = parts[2]
+RESOURCE_GROUP_NAME = parts[4]
+WORKSPACE_NAME = parts[8]
+
+DATA_COLLECTION_ENDPOINT_NAME = "ipinfo-logs-ingestion"
+WHOIS_POC_DCR_NAME = "ipinfo_rule_for_WHOIS_POC_tables"
+WHOIS_POC_TABLE_NAME = "Ipinfo_WHOIS_POC_CL"
+WHOIS_POC_STREAM_DECLARATION = "Custom-Ipinfo_WHOIS_POC_CL"
+
+AZURE_SCOPE = "https://management.azure.com/.default"
+AZURE_BASE_URL = f"https://management.azure.com/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft."
+IPINFO_BASE_URL = "https://ipinfo.io/data"
+CSV_NAME = "whois_poc.csv.gz"
+
+WHOIS_POC_TABLE_SCHEMA = {
+ "properties": {
+ "totalRetentionInDays": TOTAL_RETENTION_IN_DAYS,
+ "archiveRetentionInDays": 0,
+ "plan": "Analytics",
+ "retentionInDaysAsDefault": True,
+ "totalRetentionInDaysAsDefault": True,
+ "schema": {
+ "tableSubType": "DataCollectionRuleBased",
+ "name": WHOIS_POC_TABLE_NAME,
+ "tableType": "CustomLog",
+ "description": "Range based table",
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "whois_id", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "name", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "mobilephone", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "officephone", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "fax", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "address", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "country", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "email", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "abuse_email", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "created", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "updated", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ {"name": "source", "type": "string", "isDefaultDisplay": False, "isHidden": False},
+ ],
+ "standardColumns": [{"name": "TenantId", "type": "guid", "isDefaultDisplay": False, "isHidden": False}],
+ "solutions": ["LogManagement"],
+ "isTroubleshootingAllowed": True,
+ },
+ "provisioningState": "Succeeded",
+ "retentionInDays": RETENTION_IN_DAYS,
+ },
+ "id": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{WHOIS_POC_TABLE_NAME}",
+ "name": WHOIS_POC_TABLE_NAME,
+}
+
+WHOIS_POC_TABLE_COLUMNS = {
+ "columns": [
+ {"name": "TimeGenerated", "type": "datetime"},
+ {"name": "whois_id", "type": "string"},
+ {"name": "name", "type": "string"},
+ {"name": "mobilephone", "type": "string"},
+ {"name": "officephone", "type": "string"},
+ {"name": "fax", "type": "string"},
+ {"name": "address", "type": "string"},
+ {"name": "country", "type": "string"},
+ {"name": "email", "type": "string"},
+ {"name": "abuse_email", "type": "string"},
+ {"name": "created", "type": "string"},
+ {"name": "updated", "type": "string"},
+ {"name": "source", "type": "string"},
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/function.json b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/function.json
new file mode 100644
index 00000000000..194890db3dd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/function.json
@@ -0,0 +1,11 @@
+{
+ "scriptFile": "main.py",
+ "bindings": [
+ {
+ "name": "myTimer",
+ "type": "timerTrigger",
+ "direction": "in",
+ "schedule": "%SCHEDULE%"
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/main.py b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/main.py
new file mode 100644
index 00000000000..0e402f0bfb0
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/main.py
@@ -0,0 +1,93 @@
+import logging
+import time
+import csv
+import gzip
+import sys
+import azure.functions as func
+from azure.identity import ClientSecretCredential
+from azure.monitor.ingestion import LogsIngestionClient
+from .constants import *
+from .utils import download_mmdbs
+from .utils import check_and_create_data_collection_endpoint
+from .utils import check_and_create_table
+from .utils import check_and_create_data_collection_rules
+from .utils import get_table
+
+def main(myTimer: func.TimerRequest) -> None:
+ if myTimer.past_due:
+ logging.info("The timer is past due!")
+
+ logging.info("Ipinfo WHOIS_POC timer trigger function executed.")
+
+ def upload_data_to_WHOIS_POC_table(dce_endpoint, dcr_immutableid, stream_name):
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential, logging_enable=True)
+ csv_file_path = "/tmp/whois_poc.csv.gz"
+ chunk_size = 10000
+ data_chunk = []
+ csv.field_size_limit(sys.maxsize)
+ logging.info("Uploading WHOIS_POC Data.\n")
+ with gzip.open(csv_file_path, mode='rt') as csvfile:
+ reader = csv.DictReader(csvfile)
+ for ip_data in reader:
+ result = {}
+ result["whois_id"] = ip_data.get("id", "")
+ result["name"] = ip_data.get("name", "")
+ result["mobilephone"] = ip_data.get("mobilephone", "")
+ result["officephone"] = ip_data.get("officephone", "")
+ result["fax"] = ip_data.get("fax", "")
+ result["address"] = ip_data.get("address", "")
+ result["country"] = ip_data.get("country", "")
+ result["email"] = ip_data.get("email", "")
+ result["abuse_email"] = ip_data.get("abuse_email", "")
+ result["created"] = ip_data.get("created", "")
+ result["updated"] = ip_data.get("updated", "")
+ result["source"] = ip_data.get("source", "")
+ data_chunk.append(result)
+ if len(data_chunk) >= chunk_size:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("Wait for the next schedule run.")
+ break
+ data_chunk = []
+ if data_chunk:
+ try:
+ client.upload(rule_id=dcr_immutableid, stream_name=stream_name, logs=data_chunk)
+ except Exception as e:
+ logging.error(f"Upload failed: {e}")
+ logging.info("WHOIS_POC Data uploading completed.")
+
+ # Function flow starts here; above this line are function definitions
+ credential = ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET)
+ access_token = credential.get_token(AZURE_SCOPE).token
+ if access_token:
+ logging.info("\nAccess Token Retrieved\n")
+ logging.info(access_token)
+ else:
+ logging.error("\nFailed to retrieve access token\n")
+
+ download_mmdbs()
+ dce_endpoint = check_and_create_data_collection_endpoint(DATA_COLLECTION_ENDPOINT_NAME, access_token)
+ check_and_create_table(WHOIS_POC_TABLE_NAME, WHOIS_POC_TABLE_SCHEMA, access_token)
+ retries = 3
+ while retries > 0:
+ if get_table(WHOIS_POC_TABLE_NAME, access_token):
+ logging.info("Waiting for the table to be created properly, creating the data collection rule in 1 minute...")
+ time.sleep(60)
+ WHOIS_POC_dcr_immutableid, WHOIS_POC_stream_name = check_and_create_data_collection_rules(
+ access_token,
+ WHOIS_POC_DCR_NAME,
+ WHOIS_POC_STREAM_DECLARATION,
+ WHOIS_POC_TABLE_COLUMNS,
+ DATA_COLLECTION_ENDPOINT_NAME,
+ )
+ upload_data_to_WHOIS_POC_table(dce_endpoint, WHOIS_POC_dcr_immutableid, WHOIS_POC_stream_name)
+ break
+ else:
+ logging.info("Table not created yet, retrying in 1 minute...")
+ time.sleep(60)
+ retries -= 1
+ if retries == 0:
+ logging.error("Table creation timed out after 3 retries. Data collection rules were not created.")
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/utils.py b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/utils.py
new file mode 100644
index 00000000000..f44b4b0a099
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/AzureFunctionIPinfoWHOISPOC/utils.py
@@ -0,0 +1,167 @@
+import requests
+import logging
+import os
+from .constants import *
+
+def generate_url(resource_type, **kwargs):
+ url_templates = {
+ "dataCollectionEndpoint": f"{AZURE_BASE_URL}Insights/dataCollectionEndpoints/{{endpoint_name}}?api-version=2022-06-01",
+ "dataCollectionRule": f"{AZURE_BASE_URL}Insights/dataCollectionRules/{{rule_name}}?api-version=2022-06-01",
+ "table": f"{AZURE_BASE_URL}OperationalInsights/workspaces/{WORKSPACE_NAME}/tables/{{table_name}}?api-version=2022-10-01",
+ }
+ template = url_templates.get(resource_type)
+ if template:
+ return template.format(**kwargs)
+ return "Invalid resource type"
+
+def download_with_retry(url, file_path, retries=3):
+ for attempt in range(retries):
+ try:
+ with requests.get(url, stream=True) as response:
+ response.raise_for_status()
+ with open(file_path, "wb") as file:
+ for chunk in response.iter_content(chunk_size=8192):
+ if chunk:
+ file.write(chunk)
+ return True
+ except Exception as e:
+ logging.error(f"Attempt {attempt + 1} failed: {e}")
+ if attempt < retries - 1:
+ logging.info("Retrying...")
+ continue
+ return False
+
+def download_mmdbs():
+ url = f"{IPINFO_BASE_URL}/{CSV_NAME}?token="
+ logging.info(f"Downloading '{CSV_NAME}'...")
+ file_path = os.path.join("/tmp/", CSV_NAME)
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ logging.info(f"Previous file '{CSV_NAME}' deleted.")
+ success = download_with_retry(url + IPINFO_TOKEN, file_path)
+ if success:
+ logging.info(f"File '{CSV_NAME}' downloaded successfully.")
+ else:
+ logging.error(f"Failed to download the file '{CSV_NAME}'.")
+
+def create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ payload = {"location": LOCATION, "properties": {"networkAcls": {"publicNetworkAccess": "Enabled"}}}
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info("\nData collection endpoint created successfully.\n")
+ else:
+ logging.error(f"Failed to create data collection endpoint. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_data_collection_endpoint_url(data_collection_endpoint_name, access_token):
+ url = generate_url("dataCollectionEndpoint", endpoint_name=data_collection_endpoint_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ endpoint = data.get("properties", {}).get("logsIngestion", {}).get("endpoint")
+ if endpoint:
+ return endpoint
+ logging.info(f"\nData collection endpoint not exist. Status code: {response.status_code}. Creating ...")
+ create_data_collection_endpoint(data_collection_endpoint_name, access_token)
+ return get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+
+def check_and_create_data_collection_endpoint(data_collection_endpoint_name, access_token):
+ endpoint = get_data_collection_endpoint_url(data_collection_endpoint_name, access_token)
+ logging.info(f"Endpoint: {endpoint}\n")
+ return endpoint
+
+def create_table(table_name, schema_payload, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
+ response = requests.put(url, json=schema_payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\n{table_name} Table created successfully.\n")
+ elif response.status_code == 202:
+ logging.info(f"\n{table_name} Table creation initiated successfully.\n")
+ else:
+ logging.error(f"Failed to create {table_name} Table. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+
+def get_table(table_name, access_token):
+ url = generate_url("table", table_name=table_name)
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 404:
+ logging.info(f"\n{table_name} table not exists.\n")
+ return False
+ elif response.status_code == 200:
+ logging.info(f"\n{table_name} table already exists.\n")
+ return True
+ else:
+ logging.error(f"Failed to check {table_name}. Status code: {response.status_code}")
+ logging.error("Response body: %s", response.text)
+ return False
+
+def check_and_create_table(table_name, schema_payload, access_token):
+ table_status = get_table(table_name, access_token)
+ if table_status == False:
+ create_table(table_name, schema_payload, access_token)
+
+def get_data_collection_rule(access_token, data_collection_rule_name):
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ headers = {"Authorization": "Bearer " + access_token}
+ response = requests.get(url, headers=headers)
+ if response.status_code == 200:
+ data = response.json()
+ immutableId = data["properties"]["immutableId"]
+ streamDeclarations = list(data["properties"]["streamDeclarations"].keys())[0]
+ return immutableId, streamDeclarations
+
+ logging.info(f"{data_collection_rule_name} Data Rule endpoint not exist. Status code:{response.status_code}")
+ return None, None
+
+def create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint):
+ headers = {"Authorization": "Bearer " + access_token, "Content-Type": "application/json"}
+ url = generate_url("dataCollectionRule", rule_name=data_collection_rule_name)
+ payload = {
+ "properties": {
+ "dataCollectionEndpointId": f"/subscriptions/{SUBCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP_NAME}/providers/Microsoft.Insights/dataCollectionEndpoints/{endpoint}",
+ "streamDeclarations": {stream_declaration: {"columns": columns["columns"]}},
+ "dataSources": {},
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": f"/subscriptions/{SUBCRIPTION_ID}/resourcegroups/{RESOURCE_GROUP_NAME}/providers/microsoft.operationalinsights/workspaces/{WORKSPACE_NAME}",
+ "name": WORKSPACE_NAME,
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [stream_declaration],
+ "destinations": [WORKSPACE_NAME],
+ "transformKql": "source\n| extend TimeGenerated = now()\n",
+ "outputStream": stream_declaration,
+ }
+ ],
+ },
+ "location": LOCATION,
+ }
+ response = requests.put(url, json=payload, headers=headers)
+ if response.status_code == 200:
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} created successfully.\n")
+ else:
+ logging.error(
+ f"Failed to create data collection Rule for {data_collection_rule_name}. Status code: {response.status_code}"
+
+ )
+ logging.error("Response body: %s", response.text)
+
+def check_and_create_data_collection_rules(
+ access_token, data_collection_rule_name, stream_declaration, columns, endpoint
+):
+ dcr_immutableid, stream_name = get_data_collection_rule(access_token, data_collection_rule_name)
+ if dcr_immutableid is not None and stream_name is not None:
+ logging.info(f"\nData collection Rule `{data_collection_rule_name}` already exists.")
+ return dcr_immutableid, stream_name
+ logging.info(f"\nData collection Rule for {data_collection_rule_name} doesn't exist. Creating...")
+ create_data_collection_rule(access_token, data_collection_rule_name, stream_declaration, columns, endpoint)
+ return get_data_collection_rule(access_token, data_collection_rule_name)
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfoWHOISPOCConn.zip b/Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfoWHOISPOCConn.zip
new file mode 100644
index 00000000000..c481a73339b
Binary files /dev/null and b/Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfoWHOISPOCConn.zip differ
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfo_WHOIS_POC_API_AzureFunctionApp.json b/Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfo_WHOIS_POC_API_AzureFunctionApp.json
new file mode 100644
index 00000000000..2dc9233cd5a
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfo_WHOIS_POC_API_AzureFunctionApp.json
@@ -0,0 +1,114 @@
+{
+ "id": "IPinfoWHOISPOCDataConnector",
+ "title": "IPinfo WHOIS POC Data Connector",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download WHOIS_POC datasets and insert it into custom log table in Microsoft Sentinel",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_POC Data",
+ "legend": "Ipinfo_WHOIS_POC_CL",
+ "baseQuery": "Ipinfo_WHOIS_POC_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_POC_CL",
+ "query": "Ipinfo_WHOIS_POC_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_POC_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_POC_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_POC_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-POC-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-Ipinfo-WHOIS-POC-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/azuredeploy_Connector_IPinfo_WHOIS_POC_AzureFunction.json b/Solutions/IPinfo/Data Connectors/WHOIS POC/azuredeploy_Connector_IPinfo_WHOIS_POC_AzureFunction.json
new file mode 100644
index 00000000000..e8d952a10d7
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/azuredeploy_Connector_IPinfo_WHOIS_POC_AzureFunction.json
@@ -0,0 +1,244 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "FunctionName": {
+ "defaultValue": "IPinfo WHOIS POC",
+ "minLength": 1,
+ "maxLength": 11,
+ "type": "string"
+ },
+ "RESOURCE_ID": {
+ "type": "string",
+ "defaultValue": "Resouce ID",
+ "metadata": {
+ "description": "Use 'Log Analytic Workspace-->Properties' blade having 'Resource ID' property value. This is a fully qualified resourceId which is in format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ }
+ },
+ "TENANT_ID": {
+ "type": "string",
+ "defaultValue": "Tenant ID"
+ },
+ "CLIENT_ID": {
+ "type": "string",
+ "defaultValue": "Client ID"
+ },
+ "CLIENT_SECRET": {
+ "type": "securestring"
+ },
+ "IPINFO_TOKEN": {
+ "type": "string",
+ "defaultValue": "IPinfo Token"
+ },
+ "RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "10"
+ },
+ "TOTAL_RETENTION_IN_DAYS": {
+ "type": "string",
+ "defaultValue": "30"
+ },
+ "SCHEDULE": {
+ "type": "string",
+ "defaultValue": "0 30 9 * * *"
+ },
+ "LOCATION": {
+ "type": "string"
+ }
+ },
+ "variables": {
+ "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "StorageSuffix": "[environment().suffixes.storage]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/components",
+ "apiVersion": "2020-02-02",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "kind": "web",
+ "properties": {
+ "Application_Type": "web",
+ "ApplicationId": "[variables('FunctionName')]",
+ "WorkspaceResourceId": "[parameters('RESOURCE_ID')]"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts",
+ "apiVersion": "2023-04-01",
+ "name": "[tolower(variables('FunctionName'))]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "kind": "StorageV2",
+ "properties": {
+ "networkAcls": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ },
+ "supportsHttpsTrafficOnly": true,
+ "encryption": {
+ "services": {
+ "file": {
+ "keyType": "Account",
+ "enabled": true
+ },
+ "blob": {
+ "keyType": "Account",
+ "enabled": true
+ }
+ },
+ "keySource": "Microsoft.Storage"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/serverfarms",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "sku": {
+ "name": "EP2",
+ "tier": "ElasticPremium",
+ "family": "EP"
+ },
+ "kind": "elastic",
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "targetWorkerCount": 1,
+ "targetWorkerSizeId": 3,
+ "reserved": true,
+ "maximumElasticWorkerCount": 20,
+ "siteConfig": {
+ "linuxFxVersion": "python|3.11"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "properties": {
+ "deleteRetentionPolicy": {
+ "enabled": false
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
+ ],
+ "sku": {
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ }
+ },
+
+ {
+ "type": "Microsoft.Web/sites",
+ "apiVersion": "2023-01-01",
+ "name": "[variables('FunctionName')]",
+ "location": "[parameters('LOCATION')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
+ ],
+ "kind": "functionapp",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "name": "[variables('FunctionName')]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "httpsOnly": true,
+ "clientAffinityEnabled": true,
+ "alwaysOn": true
+ },
+ "resources": [
+ {
+ "apiVersion": "2023-01-01",
+ "type": "config",
+ "name": "appsettings",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/sites/', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "FUNCTIONS_EXTENSION_VERSION": "~4",
+ "FUNCTIONS_WORKER_RUNTIME": "python",
+ "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2020-02-02').InstrumentationKey]",
+ "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2020-02-02').ConnectionString]",
+ "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2023-04-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
+ "WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
+ "RESOURCE_ID": "[parameters('RESOURCE_ID')]",
+ "TENANT_ID": "[parameters('TENANT_ID')]",
+ "CLIENT_ID": "[parameters('CLIENT_ID')]",
+ "CLIENT_SECRET": "[parameters('CLIENT_SECRET')]",
+ "IPINFO_TOKEN": "[parameters('IPINFO_TOKEN')]",
+ "RETENTION_IN_DAYS": "[parameters('RETENTION_IN_DAYS')]",
+ "TOTAL_RETENTION_IN_DAYS": "[parameters('TOTAL_RETENTION_IN_DAYS')]",
+ "SCHEDULE": "[parameters('SCHEDULE')]",
+ "LOCATION": "[parameters('LOCATION')]",
+ "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-IPinfo-WHOIS-POC-functionapp"
+ }
+ }
+ ]
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "publicAccess": "None"
+ }
+ },
+
+ {
+ "type": "Microsoft.Storage/storageAccounts/fileServices/shares",
+ "apiVersion": "2023-04-01",
+ "name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
+ "[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
+ ],
+ "properties": {
+ "shareQuota": 5120
+ }
+ }
+ ]
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/host.json b/Solutions/IPinfo/Data Connectors/WHOIS POC/host.json
new file mode 100644
index 00000000000..2b8b7bb60bd
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/host.json
@@ -0,0 +1,16 @@
+{
+ "version": "2.0",
+ "functionTimeout": "01:00:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
+ }
+ }
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/proxies.json b/Solutions/IPinfo/Data Connectors/WHOIS POC/proxies.json
new file mode 100644
index 00000000000..13ca746ccf8
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/proxies.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "http://json.schemastore.org/proxies",
+ "proxies": {}
+}
\ No newline at end of file
diff --git a/Solutions/IPinfo/Data Connectors/WHOIS POC/requirements.txt b/Solutions/IPinfo/Data Connectors/WHOIS POC/requirements.txt
new file mode 100644
index 00000000000..5a811d57a2d
--- /dev/null
+++ b/Solutions/IPinfo/Data Connectors/WHOIS POC/requirements.txt
@@ -0,0 +1,8 @@
+# DO NOT include azure-functions-worker in this file
+# The Python Worker is managed by Azure Functions platform
+# Manually managing azure-functions-worker may cause unexpected issues
+
+azure-functions
+azure.identity
+azure.monitor.ingestion
+requests
diff --git a/Solutions/IPinfo/Data/Solution_IPinfo.json b/Solutions/IPinfo/Data/Solution_IPinfo.json
index e6a0130b45d..cede55b4ac4 100644
--- a/Solutions/IPinfo/Data/Solution_IPinfo.json
+++ b/Solutions/IPinfo/Data/Solution_IPinfo.json
@@ -13,13 +13,27 @@
"Hunting Queries": [],
"Data Connectors": [
"Solutions/IPinfo/Data Connectors/Company/IPinfo_Company_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/Company/IPinfo_Country_API_AzureFunctionApp.json",
"Solutions/IPinfo/Data Connectors/Iplocation/IPinfo_Iplocation_API_AzureFunctionApp.json",
- "Solutions/IPinfo/Data Connectors/Privacy/IPinfo_Privacy_API_AzureFunctionApp.json"
+ "Solutions/IPinfo/Data Connectors/Privacy/IPinfo_Privacy_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/Abuse/IPinfo_Abuse_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/ASN/IPinfo_ASN_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/Carrier/IPinfo_Carrier_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/Domain/IPinfo_Domain_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/Iplocation Extended/IPinfo_Iplocation_Extended_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/Privacy Extended/IPinfo_Privacy_Extended_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/RWHOIS/IPinfo_RWHOIS_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/RIRWHOIS/IPinfo_RIRWHOIS_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/WHOIS ASN/IPinfo_WHOIS_ASN_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/WHOIS MNT/IPinfo_WHOIS_MNT_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/WHOIS NET/IPinfo_WHOIS_NET_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/WHOIS ORG/IPinfo_WHOIS_ORG_API_AzureFunctionApp.json",
+ "Solutions/IPinfo/Data Connectors/WHOIS POC/IPinfo_WHOIS_POC_API_AzureFunctionApp.json"
],
"Watchlists": [],
"WatchlistDescription": [],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\IPinfo",
- "Version": "3.0.0",
+ "Version": "3.0.1",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1PConnector": false
diff --git a/Solutions/IPinfo/Package/3.0.1.zip b/Solutions/IPinfo/Package/3.0.1.zip
new file mode 100644
index 00000000000..c81ccbf9203
Binary files /dev/null and b/Solutions/IPinfo/Package/3.0.1.zip differ
diff --git a/Solutions/IPinfo/Package/mainTemplate.json b/Solutions/IPinfo/Package/mainTemplate.json
index 13cad67609a..ea03e1903fe 100644
--- a/Solutions/IPinfo/Package/mainTemplate.json
+++ b/Solutions/IPinfo/Package/mainTemplate.json
@@ -27,7 +27,7 @@
},
"variables": {
"_solutionName": "IPinfo",
- "_solutionVersion": "3.0.0",
+ "_solutionVersion": "3.1.0",
"solutionId": "idbllc1687537942583.microsoft-sentinel-solution-ipinfo-ipintelligence",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "IPinfoCompanyDataConnector",
@@ -57,9 +57,137 @@
"dataConnectorTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId3'))))]",
"dataConnectorVersion3": "1.0.0",
"_dataConnectorcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId3'),'-', variables('dataConnectorVersion3'))))]",
+ "uiConfigId4": "IPinfoAbuseDataConnector",
+ "_uiConfigId4": "[variables('uiConfigId4')]",
+ "dataConnectorContentId4": "IPinfoAbuseDataConnector",
+ "_dataConnectorContentId4": "[variables('dataConnectorContentId4')]",
+ "dataConnectorId4": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]",
+ "_dataConnectorId4": "[variables('dataConnectorId4')]",
+ "dataConnectorTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId4'))))]",
+ "dataConnectorVersion4": "1.0.0",
+ "_dataConnectorcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId4'),'-', variables('dataConnectorVersion4'))))]",
+ "uiConfigId5": "IPinfoASNDataConnector",
+ "_uiConfigId5": "[variables('uiConfigId5')]",
+ "dataConnectorContentId5": "IPinfoASNDataConnector",
+ "_dataConnectorContentId5": "[variables('dataConnectorContentId5')]",
+ "dataConnectorId5": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId5'))]",
+ "_dataConnectorId5": "[variables('dataConnectorId5')]",
+ "dataConnectorTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId5'))))]",
+ "dataConnectorVersion5": "1.0.0",
+ "_dataConnectorcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId5'),'-', variables('dataConnectorVersion5'))))]",
+ "uiConfigId6": "IPinfoCarrierDataConnector",
+ "_uiConfigId6": "[variables('uiConfigId6')]",
+ "dataConnectorContentId6": "IPinfoCarrierDataConnector",
+ "_dataConnectorContentId6": "[variables('dataConnectorContentId6')]",
+ "dataConnectorId6": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId6'))]",
+ "_dataConnectorId6": "[variables('dataConnectorId6')]",
+ "dataConnectorTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId6'))))]",
+ "dataConnectorVersion6": "1.0.0",
+ "_dataConnectorcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId6'),'-', variables('dataConnectorVersion6'))))]",
+ "uiConfigId7": "IPinfoDomainDataConnector",
+ "_uiConfigId7": "[variables('uiConfigId7')]",
+ "dataConnectorContentId7": "IPinfoDomainDataConnector",
+ "_dataConnectorContentId7": "[variables('dataConnectorContentId7')]",
+ "dataConnectorId7": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId7'))]",
+ "_dataConnectorId7": "[variables('dataConnectorId7')]",
+ "dataConnectorTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId7'))))]",
+ "dataConnectorVersion7": "1.0.0",
+ "_dataConnectorcontentProductId7": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId7'),'-', variables('dataConnectorVersion7'))))]",
+ "uiConfigId8": "IPinfoIplocationExtendedDataConnector",
+ "_uiConfigId8": "[variables('uiConfigId8')]",
+ "dataConnectorContentId8": "IPinfoIplocationExtendedDataConnector",
+ "_dataConnectorContentId8": "[variables('dataConnectorContentId8')]",
+ "dataConnectorId8": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId8'))]",
+ "_dataConnectorId8": "[variables('dataConnectorId8')]",
+ "dataConnectorTemplateSpecName8": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId8'))))]",
+ "dataConnectorVersion8": "1.0.0",
+ "_dataConnectorcontentProductId8": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId8'),'-', variables('dataConnectorVersion8'))))]",
+ "uiConfigId9": "IPinfoPrivacyExtendedDataConnector",
+ "_uiConfigId9": "[variables('uiConfigId9')]",
+ "dataConnectorContentId9": "IPinfoPrivacyExtendedDataConnector",
+ "_dataConnectorContentId9": "[variables('dataConnectorContentId9')]",
+ "dataConnectorId9": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId9'))]",
+ "_dataConnectorId9": "[variables('dataConnectorId9')]",
+ "dataConnectorTemplateSpecName9": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId9'))))]",
+ "dataConnectorVersion9": "1.0.0",
+ "_dataConnectorcontentProductId9": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId9'),'-', variables('dataConnectorVersion9'))))]",
+ "uiConfigId10": "IPinfoRWHOISDataConnector",
+ "_uiConfigId10": "[variables('uiConfigId10')]",
+ "dataConnectorContentId10": "IPinfoRWHOISDataConnector",
+ "_dataConnectorContentId10": "[variables('dataConnectorContentId10')]",
+ "dataConnectorId10": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId10'))]",
+ "_dataConnectorId10": "[variables('dataConnectorId10')]",
+ "dataConnectorTemplateSpecName10": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId10'))))]",
+ "dataConnectorVersion10": "1.0.0",
+ "_dataConnectorcontentProductId10": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId10'),'-', variables('dataConnectorVersion10'))))]",
+ "uiConfigId11": "IPinfoRIRWHOISDataConnector",
+ "_uiConfigId11": "[variables('uiConfigId11')]",
+ "dataConnectorContentId11": "IPinfoRIRWHOISDataConnector",
+ "_dataConnectorContentId11": "[variables('dataConnectorContentId11')]",
+ "dataConnectorId11": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId11'))]",
+ "_dataConnectorId11": "[variables('dataConnectorId11')]",
+ "dataConnectorTemplateSpecName11": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId11'))))]",
+ "dataConnectorVersion11": "1.0.0",
+ "_dataConnectorcontentProductId11": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId11'),'-', variables('dataConnectorVersion11'))))]",
+ "uiConfigId12": "IPinfoWHOISASNDataConnector",
+ "_uiConfigId12": "[variables('uiConfigId12')]",
+ "dataConnectorContentId12": "IPinfoWHOISASNDataConnector",
+ "_dataConnectorContentId12": "[variables('dataConnectorContentId12')]",
+ "dataConnectorId12": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId12'))]",
+ "_dataConnectorId12": "[variables('dataConnectorId12')]",
+ "dataConnectorTemplateSpecName12": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId12'))))]",
+ "dataConnectorVersion12": "1.0.0",
+ "_dataConnectorcontentProductId12": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId12'),'-', variables('dataConnectorVersion12'))))]",
+ "uiConfigId13": "IPinfoWHOISMNTDataConnector",
+ "_uiConfigId13": "[variables('uiConfigId13')]",
+ "dataConnectorContentId13": "IPinfoWHOISMNTDataConnector",
+ "_dataConnectorContentId13": "[variables('dataConnectorContentId13')]",
+ "dataConnectorId13": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId13'))]",
+ "_dataConnectorId13": "[variables('dataConnectorId13')]",
+ "dataConnectorTemplateSpecName13": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId13'))))]",
+ "dataConnectorVersion13": "1.0.0",
+ "_dataConnectorcontentProductId13": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId13'),'-', variables('dataConnectorVersion13'))))]",
+ "uiConfigId14": "IPinfoWHOISNETDataConnector",
+ "_uiConfigId14": "[variables('uiConfigId14')]",
+ "dataConnectorContentId14": "IPinfoWHOISNETDataConnector",
+ "_dataConnectorContentId14": "[variables('dataConnectorContentId14')]",
+ "dataConnectorId14": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId14'))]",
+ "_dataConnectorId14": "[variables('dataConnectorId14')]",
+ "dataConnectorTemplateSpecName14": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId14'))))]",
+ "dataConnectorVersion14": "1.0.0",
+ "_dataConnectorcontentProductId14": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId14'),'-', variables('dataConnectorVersion14'))))]",
+ "uiConfigId15": "IPinfoWHOISORGDataConnector",
+ "_uiConfigId15": "[variables('uiConfigId15')]",
+ "dataConnectorContentId15": "IPinfoWHOISORGDataConnector",
+ "_dataConnectorContentId15": "[variables('dataConnectorContentId15')]",
+ "dataConnectorId15": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId15'))]",
+ "_dataConnectorId15": "[variables('dataConnectorId15')]",
+ "dataConnectorTemplateSpecName15": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId15'))))]",
+ "dataConnectorVersion15": "1.0.0",
+ "_dataConnectorcontentProductId15": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId15'),'-', variables('dataConnectorVersion15'))))]",
+ "uiConfigId16": "IPinfoWHOISPOCDataConnector",
+ "_uiConfigId16": "[variables('uiConfigId16')]",
+ "dataConnectorContentId16": "IPinfoWHOISPOCDataConnector",
+ "_dataConnectorContentId16": "[variables('dataConnectorContentId16')]",
+ "dataConnectorId16": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId16'))]",
+ "_dataConnectorId16": "[variables('dataConnectorId16')]",
+ "dataConnectorTemplateSpecName16": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId16'))))]",
+ "dataConnectorVersion16": "1.0.0",
+ "_dataConnectorcontentProductId16": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId16'),'-', variables('dataConnectorVersion16'))))]",
+ "uiConfigId17": "IPinfoCountryDataConnector",
+ "_uiConfigId17": "[variables('uiConfigId17')]",
+ "dataConnectorContentId17": "IPinfoCountryDataConnector",
+ "_dataConnectorContentId17": "[variables('dataConnectorContentId17')]",
+ "dataConnectorId17": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId17'))]",
+ "_dataConnectorId17": "[variables('dataConnectorId17')]",
+ "dataConnectorTemplateSpecName17": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId17'))))]",
+ "dataConnectorVersion17": "1.0.0",
+ "_dataConnectorcontentProductId17": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId17'),'-', variables('dataConnectorVersion17'))))]",
+
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
"resources": [
+
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
@@ -69,7 +197,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPinfo Company data connector with template version 3.0.0",
+ "description": "IPinfo Company data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -187,7 +315,7 @@
},
{
"title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
}
]
},
@@ -376,7 +504,7 @@
},
{
"title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
}
]
},
@@ -389,7 +517,7 @@
}
}
},
-
+
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
@@ -399,7 +527,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPinfo data connector with template version 3.0.0",
+ "description": "IPinfo Iplocation data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion2')]",
@@ -517,7 +645,7 @@
},
{
"title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
}
]
},
@@ -706,7 +834,7 @@
},
{
"title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
}
]
},
@@ -715,11 +843,11 @@
]
}
],
- "id": "[variables('_uiConfigId1')]"
+ "id": "[variables('_uiConfigId2')]"
}
}
},
-
+
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
@@ -729,7 +857,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPinfo data connector with template version 3.0.0",
+ "description": "IPinfo Privacy data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion3')]",
@@ -847,7 +975,7 @@
},
{
"title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
}
]
},
@@ -934,7 +1062,7 @@
"kind": "GenericUI",
"properties": {
"connectorUiConfig": {
- "title": "IPinfo (using Azure Functions)",
+ "title": "IPinfo Privacy (using Azure Functions)",
"publisher": "IPinfo",
"descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_privacy datasets and insert them into custom log tables in Microsoft Sentinel.",
"graphQueries": [
@@ -1036,7 +1164,7 @@
},
{
"title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION \n5. Once all application settings have been entered, click **Save**."
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
}
]
},
@@ -1045,7 +1173,4627 @@
]
}
],
- "id": "[variables('_uiConfigId1')]"
+ "id": "[variables('_uiConfigId3')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName4')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo Abuse data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion4')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId4'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId4')]",
+ "title": "IPinfo Abuse (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_abuse datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Abuse Data",
+ "legend": "Ipinfo_Abuse_CL",
+ "baseQuery": "Ipinfo_Abuse_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Abuse_CL",
+ "query": "Ipinfo_Abuse_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Abuse_CL",
+ "lastDataReceivedQuery": "Ipinfo_Abuse_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Abuse_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Abuse-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Abuse-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId4'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]",
+ "contentId": "[variables('_dataConnectorContentId4')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId4')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo Abuse (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId4')]",
+ "id": "[variables('_dataConnectorcontentProductId4')]",
+ "version": "[variables('dataConnectorVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId4'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId4')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]",
+ "contentId": "[variables('_dataConnectorContentId4')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId4'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo Abuse (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_abuse datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Abuse Data",
+ "legend": "Ipinfo_Abuse_CL",
+ "baseQuery": "Ipinfo_Abuse_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Abuse_CL",
+ "query": "Ipinfo_Abuse_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Abuse_CL",
+ "lastDataReceivedQuery": "Ipinfo_Abuse_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Abuse_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-abuse-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-abuse-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId4')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName5')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo ASN data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion5')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId5'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId5')]",
+ "title": "IPinfo ASN (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download ASN datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "ASN Data",
+ "legend": "Ipinfo_ASN_CL",
+ "baseQuery": "Ipinfo_ASN_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_ASN_CL",
+ "query": "Ipinfo_ASN_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_ASN_CL",
+ "lastDataReceivedQuery": "Ipinfo_ASN_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_ASN_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-ASN-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-ASN-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId5'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId5'))]",
+ "contentId": "[variables('_dataConnectorContentId5')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion5')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId5')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo ASN (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId5')]",
+ "id": "[variables('_dataConnectorcontentProductId5')]",
+ "version": "[variables('dataConnectorVersion5')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId5'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId5')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId5'))]",
+ "contentId": "[variables('_dataConnectorContentId5')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion5')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId5'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo ASN (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download ASN datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "ASN Data",
+ "legend": "Ipinfo_ASN_CL",
+ "baseQuery": "Ipinfo_ASN_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_ASN_CL",
+ "query": "Ipinfo_ASN_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_ASN_CL",
+ "lastDataReceivedQuery": "Ipinfo_ASN_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_ASN_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-ASN-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-ASN-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId5')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName6')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo Carrier data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion6')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId6'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId6')]",
+ "title": "IPinfo Carrier (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download carrier datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Carrier Data",
+ "legend": "Ipinfo_Carrier_CL",
+ "baseQuery": "Ipinfo_Carrier_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Carrier_CL",
+ "query": "Ipinfo_Carrier_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Carrier_CL",
+ "lastDataReceivedQuery": "Ipinfo_Carrier_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Carrier_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Carrier-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Carrier-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId6'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId6'))]",
+ "contentId": "[variables('_dataConnectorContentId6')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion6')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId6')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo Carrier (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId6')]",
+ "id": "[variables('_dataConnectorcontentProductId6')]",
+ "version": "[variables('dataConnectorVersion6')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId6'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId6')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId6'))]",
+ "contentId": "[variables('_dataConnectorContentId6')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion6')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId6'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo Carrier (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download carrier datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Carrier Data",
+ "legend": "Ipinfo_Carrier_CL",
+ "baseQuery": "Ipinfo_Carrier_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Carrier_CL",
+ "query": "Ipinfo_Carrier_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Carrier_CL",
+ "lastDataReceivedQuery": "Ipinfo_Carrier_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Carrier_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Carrier-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Carrier-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId6')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName7')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo Domain data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion7')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId7'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId7')]",
+ "title": "IPinfo Domain (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_ip_hosted_domains datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Domain Data",
+ "legend": "Ipinfo_Domain_CL",
+ "baseQuery": "Ipinfo_Domain_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Domain_CL",
+ "query": "Ipinfo_Domain_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Domain_CL",
+ "lastDataReceivedQuery": "Ipinfo_Domain_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Domain_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Domain-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Domain-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId7'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId7'))]",
+ "contentId": "[variables('_dataConnectorContentId7')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion7')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId7')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo Domain (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId7')]",
+ "id": "[variables('_dataConnectorcontentProductId7')]",
+ "version": "[variables('dataConnectorVersion7')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId7'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId7')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId7'))]",
+ "contentId": "[variables('_dataConnectorContentId7')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion7')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId7'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo Domain (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_ip_hosted_domains datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Domain Data",
+ "legend": "Ipinfo_Domain_CL",
+ "baseQuery": "Ipinfo_Domain_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Domain_CL",
+ "query": "Ipinfo_Domain_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Domain_CL",
+ "lastDataReceivedQuery": "Ipinfo_Domain_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Domain_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Domain-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Domain-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId7')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName8')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo Iplocation Extended data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion8')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId8'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId8')]",
+ "title": "IPinfo Iplocation Extended (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download location_extended datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Iplocation Extended Data",
+ "legend": "Ipinfo_Location_extended_CL",
+ "baseQuery": "Ipinfo_Location_extended_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Location_extended_CL",
+ "query": "Ipinfo_Location_extended_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Location_extended_CL",
+ "lastDataReceivedQuery": "Ipinfo_Location_extended_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Location_extended_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Iplocation_extended-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Iplocation_extended-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId8'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId8'))]",
+ "contentId": "[variables('_dataConnectorContentId8')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion8')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId8')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo Iplocation Extended (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId8')]",
+ "id": "[variables('_dataConnectorcontentProductId8')]",
+ "version": "[variables('dataConnectorVersion8')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId8'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId8')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId8'))]",
+ "contentId": "[variables('_dataConnectorContentId8')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion8')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId8'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo Iplocation Extended (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download location_extended datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Iplocation Extended Data",
+ "legend": "Ipinfo_Location_extended_CL",
+ "baseQuery": "Ipinfo_Iplocation_extended_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Iplocation_extended_CL",
+ "query": "Ipinfo_Iplocation_extended_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Iplocation_extended_CL",
+ "lastDataReceivedQuery": "Ipinfo_Iplocation_extended_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Iplocation_extended_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Iplocation_extended-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Iplocation_extended-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId8')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName9')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo Privacy Extended data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion9')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId9'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId9')]",
+ "title": "IPinfo Privacy Extended (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download privacy_extended datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Privacy Extended Data",
+ "legend": "Ipinfo_Privacy_extended_CL",
+ "baseQuery": "Ipinfo_Privacy_extended_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Privacy_extended_CL",
+ "query": "Ipinfo_Privacy_extended_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Privacy_extended_CL",
+ "lastDataReceivedQuery": "Ipinfo_Privacy_extended_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Privacy_extended_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Privacy_extended-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Privacy_extended-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId9'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId9'))]",
+ "contentId": "[variables('_dataConnectorContentId9')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion9')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId9')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo Privacy Extended (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId9')]",
+ "id": "[variables('_dataConnectorcontentProductId9')]",
+ "version": "[variables('dataConnectorVersion9')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId9'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId9')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId9'))]",
+ "contentId": "[variables('_dataConnectorContentId9')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion9')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId9'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo Privacy Extended (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download privacy_extended datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Privacy Extended Data",
+ "legend": "Ipinfo_Privacy_extended_CL",
+ "baseQuery": "Ipinfo_Privacy_extended_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Privacy_extended_CL",
+ "query": "Ipinfo_Privacy_extended_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Privacy_extended_CL",
+ "lastDataReceivedQuery": "Ipinfo_Privacy_extended_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Privacy_extended_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Privacy_extended-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Privacy_extended-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId9')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName10')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo RWHOIS data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion10')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId10'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId10')]",
+ "title": "IPinfo RWHOIS (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_RWHOIS datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "RWHOIS Data",
+ "legend": "Ipinfo_RWHOIS_CL",
+ "baseQuery": "Ipinfo_RWHOIS_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_RWHOIS_CL",
+ "query": "Ipinfo_RWHOIS_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_RWHOIS_CL",
+ "lastDataReceivedQuery": "Ipinfo_RWHOIS_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_RWHOIS_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-RWHOIS-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-RWHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId10'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId10'))]",
+ "contentId": "[variables('_dataConnectorContentId10')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion10')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId10')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo RWHOIS (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId10')]",
+ "id": "[variables('_dataConnectorcontentProductId10')]",
+ "version": "[variables('dataConnectorVersion10')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId10'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId10')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId10'))]",
+ "contentId": "[variables('_dataConnectorContentId10')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion10')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId10'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo RWHOIS (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_RWHOIS datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "RWHOIS Data",
+ "legend": "Ipinfo_RWHOIS_CL",
+ "baseQuery": "Ipinfo_RWHOIS_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_RWHOIS_CL",
+ "query": "Ipinfo_RWHOIS_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_RWHOIS_CL",
+ "lastDataReceivedQuery": "Ipinfo_RWHOIS_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_RWHOIS_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-RWHOIS-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-RWHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId10')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName11')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo RIRWHOIS data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion11')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId11'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId11')]",
+ "title": "IPinfo RIRWHOIS (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_RIRWHOIS datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "RIRWHOIS Data",
+ "legend": "Ipinfo_RIRWHOIS_CL",
+ "baseQuery": "Ipinfo_RIRWHOIS_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_RIRWHOIS_CL",
+ "query": "Ipinfo_RIRWHOIS_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_RIRWHOIS_CL",
+ "lastDataReceivedQuery": "Ipinfo_RIRWHOIS_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_RIRWHOIS_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-RIRWHOIS-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-RIRWHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId11'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId11'))]",
+ "contentId": "[variables('_dataConnectorContentId11')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion11')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId11')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo RIRWHOIS (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId11')]",
+ "id": "[variables('_dataConnectorcontentProductId11')]",
+ "version": "[variables('dataConnectorVersion11')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId11'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId11')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId11'))]",
+ "contentId": "[variables('_dataConnectorContentId11')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion11')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId11'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo RIRWHOIS (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_RIRWHOIS datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "RIRWHOIS Data",
+ "legend": "Ipinfo_RIRWHOIS_CL",
+ "baseQuery": "Ipinfo_RIRWHOIS_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_RIRWHOIS_CL",
+ "query": "Ipinfo_RIRWHOIS_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_RIRWHOIS_CL",
+ "lastDataReceivedQuery": "Ipinfo_RIRWHOIS_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_RIRWHOIS_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-RIRWHOIS-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-RIRWHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId11')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName12')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo WHOIS ASN data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion12')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId12'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId12')]",
+ "title": "IPinfo WHOIS ASN (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_ASN datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_ASN Data",
+ "legend": "Ipinfo_WHOIS_ASN_CL",
+ "baseQuery": "Ipinfo_WHOIS_ASN_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_ASN_CL",
+ "query": "Ipinfo_WHOIS_ASN_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_ASN_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_ASN_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_ASN_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-ASN-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-ASN-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId12'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId12'))]",
+ "contentId": "[variables('_dataConnectorContentId12')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion12')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId12')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo WHOIS ASN (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId12')]",
+ "id": "[variables('_dataConnectorcontentProductId12')]",
+ "version": "[variables('dataConnectorVersion12')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId12'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId12')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId12'))]",
+ "contentId": "[variables('_dataConnectorContentId12')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion12')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId12'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo WHOIS ASN (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_ASN datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_ASN Data",
+ "legend": "Ipinfo_WHOIS_ASN_CL",
+ "baseQuery": "Ipinfo_WHOIS_ASN_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_ASN_CL",
+ "query": "Ipinfo_WHOIS_ASN_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_ASN_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_ASN_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_ASN_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-ASN-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-ASN-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId12')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName13')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo WHOIS MNT data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion13')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId13'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId13')]",
+ "title": "IPinfo WHOIS MNT (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_MNT datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_MNT Data",
+ "legend": "Ipinfo_WHOIS_MNT_CL",
+ "baseQuery": "Ipinfo_WHOIS_MNT_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_MNT_CL",
+ "query": "Ipinfo_WHOIS_MNT_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_MNT_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_MNT_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_MNT_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-MNT-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-MNT-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId13'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId13'))]",
+ "contentId": "[variables('_dataConnectorContentId13')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion13')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId13')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo WHOIS MNT (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId13')]",
+ "id": "[variables('_dataConnectorcontentProductId13')]",
+ "version": "[variables('dataConnectorVersion13')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId13'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId13')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId13'))]",
+ "contentId": "[variables('_dataConnectorContentId13')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion13')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId13'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo WHOIS MNT (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_MNT datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_MNT Data",
+ "legend": "Ipinfo_WHOIS_MNT_CL",
+ "baseQuery": "Ipinfo_WHOIS_MNT_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_MNT_CL",
+ "query": "Ipinfo_WHOIS_MNT_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_MNT_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_MNT_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_MNT_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-MNT-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId13')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName14')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo WHOIS NET data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion14')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId14'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId14')]",
+ "title": "IPinfo WHOIS NET (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_NET datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_NET Data",
+ "legend": "Ipinfo_WHOIS_NET_CL",
+ "baseQuery": "Ipinfo_WHOIS_NET_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_NET_CL",
+ "query": "Ipinfo_WHOIS_NET_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_NET_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_NET_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_NET_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-NET-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-NET-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId14'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId14'))]",
+ "contentId": "[variables('_dataConnectorContentId14')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion14')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId14')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo WHOIS NET (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId14')]",
+ "id": "[variables('_dataConnectorcontentProductId14')]",
+ "version": "[variables('dataConnectorVersion14')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId14'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId14')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId14'))]",
+ "contentId": "[variables('_dataConnectorContentId14')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion14')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId14'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo WHOIS NET (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_NET datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_NET Data",
+ "legend": "Ipinfo_WHOIS_NET_CL",
+ "baseQuery": "Ipinfo_WHOIS_NET_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_NET_CL",
+ "query": "Ipinfo_WHOIS_NET_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_NET_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_NET_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_NET_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-NET-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId14')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName15')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo WHOIS ORG data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion15')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId15'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId15')]",
+ "title": "IPinfo WHOIS ORG (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_ORG datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_ORG Data",
+ "legend": "Ipinfo_WHOIS_ORG_CL",
+ "baseQuery": "Ipinfo_WHOIS_ORG_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_ORG_CL",
+ "query": "Ipinfo_WHOIS_ORG_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_ORG_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_ORG_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_ORG_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-ORG-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-ORG-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId15'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId15'))]",
+ "contentId": "[variables('_dataConnectorContentId15')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion15')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId15')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo WHOIS ORG (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId15')]",
+ "id": "[variables('_dataConnectorcontentProductId15')]",
+ "version": "[variables('dataConnectorVersion15')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId15'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId15')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId15'))]",
+ "contentId": "[variables('_dataConnectorContentId15')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion15')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId15'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo WHOIS ORG (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_ORG datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_ORG Data",
+ "legend": "Ipinfo_WHOIS_ORG_CL",
+ "baseQuery": "Ipinfo_WHOIS_ORG_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_ORG_CL",
+ "query": "Ipinfo_WHOIS_ORG_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_ORG_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_ORG_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_ORG_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOI-ORG-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-ORG-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId15')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName16')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo WHOIS POC data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion16')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId16'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId16')]",
+ "title": "IPinfo WHOIS POC (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_POC datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_POC Data",
+ "legend": "Ipinfo_WHOIS_POC_CL",
+ "baseQuery": "Ipinfo_WHOIS_POC_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_POC_CL",
+ "query": "Ipinfo_WHOIS_POC_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_POC_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_POC_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_POC_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-POC-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-POC-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId16'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId16'))]",
+ "contentId": "[variables('_dataConnectorContentId16')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion16')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId16')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo WHOIS POC (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId16')]",
+ "id": "[variables('_dataConnectorcontentProductId16')]",
+ "version": "[variables('dataConnectorVersion16')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId16'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId16')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId16'))]",
+ "contentId": "[variables('_dataConnectorContentId16')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion16')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId16'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo WHOIS POC (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download standard_WHOIS_POC datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "WHOIS_POC Data",
+ "legend": "Ipinfo_WHOIS_POC_CL",
+ "baseQuery": "Ipinfo_WHOIS_POC_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_WHOIS_POC_CL",
+ "query": "Ipinfo_WHOIS_POC_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_WHOIS_POC_CL",
+ "lastDataReceivedQuery": "Ipinfo_WHOIS_POC_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_WHOIS_POC_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-POC-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-WHOIS-POC-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId16')]"
+ }
+ }
+ },
+
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName17')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IPinfo Country ASN data connector with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion17')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId17'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId17')]",
+ "title": "IPinfo Country ASN (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download country_asn datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Country Data",
+ "legend": "Ipinfo_Country_CL",
+ "baseQuery": "Ipinfo_Country_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Country_CL",
+ "query": "Ipinfo_Country_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Country_CL",
+ "lastDataReceivedQuery": "Ipinfo_Country_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Country_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-WHOIS-POC-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Country-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId17'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId17'))]",
+ "contentId": "[variables('_dataConnectorContentId17')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion17')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "1.0.0",
+ "contentId": "[variables('_dataConnectorContentId17')]",
+ "contentKind": "DataConnector",
+ "displayName": "IPinfo Country (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId17')]",
+ "id": "[variables('_dataConnectorcontentProductId17')]",
+ "version": "[variables('dataConnectorVersion17')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId17'),'/'))))]",
+ "dependsOn": ["[variables('_dataConnectorId17')]"],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId17'))]",
+ "contentId": "[variables('_dataConnectorContentId17')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion17')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IPinfo",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "IPinfo"
+ },
+ "support": {
+ "name": "IPinfo",
+ "email": "support@ipinfo.io",
+ "tier": "Partner",
+ "link": "https://www.ipinfo.io/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId17'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IPinfo Country ASN (using Azure Functions)",
+ "publisher": "IPinfo",
+ "descriptionMarkdown": "This IPinfo data connector installs an Azure Function app to download country_asn datasets and insert them into custom log tables in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Country Data",
+ "legend": "Ipinfo_Country_CL",
+ "baseQuery": "Ipinfo_Country_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Ipinfo_Country_CL",
+ "query": "Ipinfo_Country_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Ipinfo_Country_CL",
+ "lastDataReceivedQuery": "Ipinfo_Country_CL | summarize Time = max(TimeGenerated)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Ipinfo_Country_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": true
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "IPinfo API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Retrieve API Token",
+ "description": "Retrieve your IPinfo API Token [here](https://ipinfo.io/)."
+ },
+ {
+ "title": "2. In your Azure AD tenant, create an Azure Active Directory (AAD) application",
+ "description": "In your Azure AD tenant, create an Azure Active Directory (AAD) application and acquire Tenant ID, Client ID, and Client Secret: Use this Link."
+ },
+ {
+ "title": "3. Assign the AAD application the Microsoft Sentinel Contributor Role.",
+ "description": "Assign the AAD application you just created to the Contributor(Privileged administrator roles) and Monitoring Metrics Publisher(Job function roles) in the same “Resource Group” you use for “Log Analytic Workspace” on which “Microsoft Sentinel” is added: Use this Link."
+ },
+ {
+ "title": "4. Get Workspace Resource ID",
+ "description": "Use the Log Analytic Workspace -> Properties blade having the 'Resource ID' property value. This is a fully qualified resourceId which is in the format '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}'"
+ },
+ {
+ "title": "5. Deploy the Azure Function",
+ "description": "Use this for automated deployment of the IPinfo data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-IPinfo-Country-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **RESOURCE_ID**, **IPINFO_TOKEN**, **TENANT_ID**, **CLIENT_ID**, **CLIENT_SECRET**."
+ },
+ {
+ "title": "Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the IPinfo data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "1. Download the Azure Function App file. Extract the archive to your local development computer [Azure Function App](https://aka.ms/sentinel-IPinfo-Country-functionapp). \n2. Create Function App using Hosting Functions Premium or App service plan using advanced option using VSCode. \n3. Follow the function app manual deployment instructions to deploy the Azure Functions app using VSCode. \n4. After successful deployment of the function app, follow the next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Settings** -> **Configuration** or **Environment variables**. \n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tRESOURCE_ID\n\t\tIPINFO_TOKEN\n\t\tTENANT_ID\n\t\tCLIENT_ID\n\t\tCLIENT_SECRET\n\t\tSCHEDULE\n\t\tLOCATION\n\t\tRETENTION_IN_DAYS\n\t\tTOTAL_RETENTION_IN_DAYS \n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId17')]"
}
}
},
@@ -1055,9 +5803,9 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.0",
+ "version": "3.1.0",
"kind": "Solution",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.1.0",
"displayName": "IPinfo",
"publisherDisplayName": "IPinfo",
"descriptionHtml": "See Refrence",
diff --git a/Solutions/IPinfo/ReleaseNotes.md b/Solutions/IPinfo/ReleaseNotes.md
index 37ec7c18a96..367be8feb50 100644
--- a/Solutions/IPinfo/ReleaseNotes.md
+++ b/Solutions/IPinfo/ReleaseNotes.md
@@ -1,3 +1,4 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
-| 3.0.0 | 10-07-2024 | Initial Solution Release |
+| 3.0.1 | 19-08-2024 | IPinfo New Data Connectors |
+| 3.0.0 | 10-07-2024 | Initial Solution Release |
diff --git a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Clone_Detection_Query.yaml b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Clone_Detection_Query.yaml
index 69314502cda..6d5e0413716 100644
--- a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Clone_Detection_Query.yaml
+++ b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Clone_Detection_Query.yaml
@@ -8,6 +8,9 @@ requiredDataConnectors:
- connectorId: IllumioSaaSDataConnector
dataTypes:
- Illumio_Auditable_Events_CL
+ - connectorId: SyslogAma
+ datatypes:
+ - Syslog
queryFrequency: 60m
queryPeriod: 60m
triggerOperator: gt
@@ -18,6 +21,7 @@ relevantTechniques:
- T1562
query: |
Illumio_Auditable_Events_CL
+ | union IllumioSyslogAuditEvents
| where event_type has 'agent.clone_detected'
| extend hostname = created_by.agent.hostname,
ven_href = created_by.ven.href
@@ -33,5 +37,5 @@ alertDetailsOverride:
Illumio VEN Clone Detection Incident for {{hostname}}
alertDescriptionFormat: |
Illumio VEN Clone Detection for {{hostname}} generated at {{TimeGenerated}}
-version: 1.0.5
+version: 1.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Deactivated_Query.yaml b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Deactivated_Query.yaml
index 8f18e9e10cb..8e41d7904df 100644
--- a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Deactivated_Query.yaml
+++ b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Deactivated_Query.yaml
@@ -8,6 +8,9 @@ requiredDataConnectors:
- connectorId: IllumioSaaSDataConnector
dataTypes:
- Illumio_Auditable_Events_CL
+ - connectorId: SyslogAma
+ datatypes:
+ - Syslog
queryFrequency: 60m
queryPeriod: 60m
triggerOperator: gt
@@ -18,6 +21,7 @@ relevantTechniques:
- T1562
query: |
Illumio_Auditable_Events_CL
+ | union IllumioSyslogAuditEvents
| where event_type has 'agent.deactivate'
| mv-expand resource_changes
| extend hostname = resource_changes['resource']['workload']['hostname'],
@@ -39,8 +43,8 @@ entityMappings:
columnName: ipaddress
alertDetailsOverride:
alertDisplayNameFormat: |
- Illumio VEN Deactivated Incident for {{hostname}}
+ Illumio VEN Deactivated Incident
alertDescriptionFormat: |
- Illumio VEN Deactivated Incident for {{hostname}} generated at {{TimeGenerated}}
-version: 1.0.5
+ Illumio VEN Deactivated Incident generated at {{TimeGenerated}}
+version: 1.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Enforcement_Change_Detection_Query.yaml b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Enforcement_Change_Detection_Query.yaml
index 9b0bf4427c0..7ce00e0a2cc 100644
--- a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Enforcement_Change_Detection_Query.yaml
+++ b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Enforcement_Change_Detection_Query.yaml
@@ -8,6 +8,9 @@ requiredDataConnectors:
- connectorId: IllumioSaaSDataConnector
dataTypes:
- Illumio_Auditable_Events_CL
+ - connectorId: SyslogAma
+ datatypes:
+ - Syslog
queryFrequency: 60m
queryPeriod: 60m
triggerOperator: gt
@@ -20,6 +23,7 @@ query: |
let enf_state = dynamic(["full", "selective"]);
let visibility_state = dynamic(["visibility_only", "idle"]);
Illumio_Auditable_Events_CL
+ | union IllumioSyslogAuditEvents
| extend temp_resource_changes = parse_json(resource_changes)[0]
| where event_type == 'workloads.update'
| extend old_mode = temp_resource_changes.changes.enforcement_mode.before,
@@ -50,5 +54,5 @@ alertDetailsOverride:
Illumio Enforcement Change Incident for {{workload_name}}
alertDescriptionFormat: |
Illumio Enforcement Change Incident for {{workload_name}} generated at {{TimeGenerated}}
-version: 1.0.6
+version: 1.0.7
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Firewall_Tampering_Detection_Query.yaml b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Firewall_Tampering_Detection_Query.yaml
index 8ca1a9a8e73..59877b153b3 100644
--- a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Firewall_Tampering_Detection_Query.yaml
+++ b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Firewall_Tampering_Detection_Query.yaml
@@ -8,6 +8,9 @@ requiredDataConnectors:
- connectorId: IllumioSaaSDataConnector
dataTypes:
- Illumio_Auditable_Events_CL
+ - connectorId: SyslogAma
+ datatypes:
+ - Syslog
queryFrequency: 60m
queryPeriod: 60m
triggerOperator: gt
@@ -18,6 +21,7 @@ relevantTechniques:
- T1562
query: |
Illumio_Auditable_Events_CL
+ | union IllumioSyslogAuditEvents
| where event_type has 'tampering'
| extend ipaddress = action.src_ip,
hostname = created_by.agent.hostname,
@@ -39,5 +43,5 @@ alertDetailsOverride:
Illumio Firewall Tamper Incident for {{hostname}}
alertDescriptionFormat: |
Illumio Firewall Tamper Incident for {{hostname}} generated at {{TimeGenerated}}
-version: 1.0.6
+version: 1.0.7
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Offline_Detection_Query.yaml b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Offline_Detection_Query.yaml
index e7f7976415f..4256f6751e8 100644
--- a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Offline_Detection_Query.yaml
+++ b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Offline_Detection_Query.yaml
@@ -8,6 +8,9 @@ requiredDataConnectors:
- connectorId: IllumioSaaSDataConnector
dataTypes:
- Illumio_Auditable_Events_CL
+ - connectorId: SyslogAma
+ datatypes:
+ - Syslog
queryFrequency: 60m
queryPeriod: 60m
triggerOperator: gt
@@ -18,6 +21,7 @@ relevantTechniques:
- T1562
query: |
Illumio_Auditable_Events_CL
+ | union IllumioSyslogAuditEvents
| where event_type has 'agent_offline_check'
| mv-expand resource_changes
| extend hostname = resource_changes['resource']['workload']['hostname'],
@@ -36,5 +40,5 @@ alertDetailsOverride:
Illumio VEN Offline Incident for {{hostname}}
alertDescriptionFormat: |
Illumio VEN Offline Incident for {{hostname}} generated at {{TimeGenerated}}
-version: 1.0.6
+version: 1.0.7
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Suspend_Query.yaml b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Suspend_Query.yaml
index 916dbe90e3e..7b5edfbb687 100644
--- a/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Suspend_Query.yaml
+++ b/Solutions/IllumioSaaS/Analytic Rules/Illumio_VEN_Suspend_Query.yaml
@@ -8,6 +8,9 @@ requiredDataConnectors:
- connectorId: IllumioSaaSDataConnector
dataTypes:
- Illumio_Auditable_Events_CL
+ - connectorId: SyslogAma
+ datatypes:
+ - Syslog
queryFrequency: 60m
queryPeriod: 60m
triggerOperator: gt
@@ -18,6 +21,7 @@ relevantTechniques:
- T1562
query: |
Illumio_Auditable_Events_CL
+ | union IllumioSyslogAuditEvents
| where event_type has 'agent.suspend'
| extend ipaddress = action.src_ip,
hostname = created_by.agent.hostname
@@ -38,5 +42,5 @@ alertDetailsOverride:
Illumio VEN Suspended Incident for {{hostname}}
alertDescriptionFormat: |
Illumio VEN Suspended Incident for {{hostname}} generated at {{TimeGenerated}}
-version: 1.0.5
+version: 1.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Data Connectors/CommonCode/constants.py b/Solutions/IllumioSaaS/Data Connectors/CommonCode/constants.py
index 1e3fb141fb8..fb24bc75836 100644
--- a/Solutions/IllumioSaaS/Data Connectors/CommonCode/constants.py
+++ b/Solutions/IllumioSaaS/Data Connectors/CommonCode/constants.py
@@ -29,6 +29,13 @@
UNKNOWN_TRAFFIC = "unknown"
ALL_TRAFFIC = "all"
+# Onprem PCE config
+ONPREM_API_KEY = os.environ.get("ONPREM_API_KEY", None)
+ONPREM_API_SECRET = os.environ.get("ONPREM_API_SECRET", None)
+ONPREM_PCE_FQDN = os.environ.get("ONPREM_PCE_FQDN", None)
+ONPREM_PCE_PORT = int(os.environ.get("ONPREM_PCE_PORT", 443))
+ONPREM_PCE_ORGID = int(os.environ.get("ONPREM_PCE_ORGID", 1))
+
# Azure config
AZURE_TENANT_ID = os.environ["AZURE_TENANT_ID"]
AZURE_CLIENT_ID = os.environ["AZURE_CLIENT_ID"]
@@ -45,4 +52,4 @@
# Azure Storage Queue
AZURE_STORAGE_PRIMARY_QUEUE = "python-queue-items"
-AZURE_STORAGE_BACKLOG_QUEUE = "python-queue-items-backlog"
\ No newline at end of file
+AZURE_STORAGE_BACKLOG_QUEUE = "python-queue-items-backlog"
diff --git a/Solutions/IllumioSaaS/Data Connectors/IllumioEventsConn.zip b/Solutions/IllumioSaaS/Data Connectors/IllumioEventsConn.zip
index a5d9259a89e..e66b9371bec 100644
Binary files a/Solutions/IllumioSaaS/Data Connectors/IllumioEventsConn.zip and b/Solutions/IllumioSaaS/Data Connectors/IllumioEventsConn.zip differ
diff --git a/Solutions/IllumioSaaS/Data Connectors/OnPremHealthFunctionApp/function.json b/Solutions/IllumioSaaS/Data Connectors/OnPremHealthFunctionApp/function.json
new file mode 100644
index 00000000000..9795181c387
--- /dev/null
+++ b/Solutions/IllumioSaaS/Data Connectors/OnPremHealthFunctionApp/function.json
@@ -0,0 +1,19 @@
+{
+ "scriptFile": "onprem_health_api.py",
+ "bindings": [
+ {
+ "authLevel": "anonymous",
+ "type": "httpTrigger",
+ "direction": "in",
+ "name": "req",
+ "methods": [
+ "get"
+ ]
+ },
+ {
+ "type": "http",
+ "direction": "out",
+ "name": "$return"
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Data Connectors/OnPremHealthFunctionApp/onprem_health_api.py b/Solutions/IllumioSaaS/Data Connectors/OnPremHealthFunctionApp/onprem_health_api.py
new file mode 100644
index 00000000000..621d6dc92b4
--- /dev/null
+++ b/Solutions/IllumioSaaS/Data Connectors/OnPremHealthFunctionApp/onprem_health_api.py
@@ -0,0 +1,42 @@
+import azure.functions as func
+import logging
+import json
+import requests
+from base64 import b64encode
+from ..CommonCode.constants import (
+ ONPREM_API_KEY,
+ ONPREM_API_SECRET,
+ ONPREM_PCE_FQDN,
+ ONPREM_PCE_PORT,
+)
+
+URL = "https://{}:{}/api/v2/health".format(ONPREM_PCE_FQDN, ONPREM_PCE_PORT)
+
+credentials = b64encode(f"{ONPREM_API_KEY}:{ONPREM_API_SECRET}".encode()).decode(
+ "utf-8"
+)
+headers = {"Authorization": f"Basic {credentials}", "Content-type": "application/json"}
+
+
+def main(req: func.HttpRequest) -> func.HttpResponse:
+ logging.info("Making an api call to onprem PCE to get health metadata")
+ response = requests.request("GET", URL, headers=headers, data={})
+
+ if response:
+ logging.info("[OnPremHealth] Response from url is {}".format(response.headers))
+ else:
+ logging.info("[OnPremHealth] Error in response {}".format(response))
+ return
+
+ parsed_response = json.loads(response.text)
+ # if this has a notifications, just remove it.
+ if "notifications" in parsed_response[0].keys():
+ del parsed_response[0]["notifications"]
+
+ sanitized_response = json.dumps(parsed_response)
+
+ return func.HttpResponse(
+ sanitized_response,
+ status_code=response.status_code,
+ mimetype="application/json",
+ )
diff --git a/Solutions/IllumioSaaS/Data Connectors/TimedApiFunctionApp/api_response.py b/Solutions/IllumioSaaS/Data Connectors/TimedApiFunctionApp/api_response.py
index dedbf9d296e..9834fa011f8 100644
--- a/Solutions/IllumioSaaS/Data Connectors/TimedApiFunctionApp/api_response.py
+++ b/Solutions/IllumioSaaS/Data Connectors/TimedApiFunctionApp/api_response.py
@@ -19,15 +19,13 @@
DCR_ID,
WORKLOADS_API_LOGS_CUSTOM_TABLE,
MAX_WORKLOADS,
+ ONPREM_API_KEY,
+ ONPREM_API_SECRET,
+ ONPREM_PCE_FQDN,
+ ONPREM_PCE_PORT,
+ ONPREM_PCE_ORGID,
)
-URL = "https://{}:{}/api/v2/orgs/{}/workloads/?max_results={}".format(
- PCE_FQDN, PORT, ORG_ID, MAX_WORKLOADS
-)
-
-credentials = b64encode(f"{API_KEY}:{API_SECRET}".encode()).decode("utf-8")
-headers = {"Authorization": f"Basic {credentials}", "Content-type": "application/json"}
-
def getVensByVersion(data):
try:
@@ -116,56 +114,100 @@ def getVensBySyncState(data):
return {}
-async def main(mytimer: func.TimerRequest) -> None:
- logging.debug("url to be exercised is {} ".format(URL))
-
- response = requests.request("GET", URL, headers=headers, data={})
-
- if response:
- logging.info("[TimedApi] Response from url is {}".format(response.headers))
- else:
- logging.info("[TimedApi] Error in response {}".format(response))
- return
-
- response = json.loads(response.text)
- df = pl.json_normalize(response, infer_schema_length=None)
-
- vens_by_version = getVensByVersion(df)
- vens_by_managed = getVensByManaged(df)
- vens_by_type = getVensByType(df)
- vens_by_os = getVensByOS(df)
- vens_by_enf_mode = getVensByEnforcementMode(df)
- vens_by_status = getVensByStatus(df)
- vens_by_sync_state = getVensBySyncState(df)
- api_response = []
- api_response.append(
- {
- "vens_by_version": vens_by_version,
- "vens_by_managed": vens_by_managed,
- "vens_by_type": vens_by_type,
- "vens_by_os": vens_by_os,
- "vens_by_enforcement_mode": vens_by_enf_mode,
- "vens_by_status": vens_by_status,
- "vens_by_sync_state": vens_by_sync_state,
- "pce_fqdn": PCE_FQDN,
+# Return list of pce fqdns for which workloads api call is executed
+# If onprem pce and saas pce are configured to send events, then this method
+# should return 2 entries else return only saas
+def getPceType():
+ if ONPREM_PCE_FQDN:
+ return ["onprem", "saas"]
+ return ["saas"]
+
+
+def getWorkloads(pce_fqdn, port, org, api_key, api_secret):
+ if pce_fqdn:
+ url = "https://{}:{}/api/v2/orgs/{}/workloads/?max_results={}".format(
+ pce_fqdn, port, org, MAX_WORKLOADS
+ )
+
+ logging.debug("url to be exercised is {} ".format(url))
+
+ credentials = b64encode(f"{api_key}:{api_secret}".encode()).decode("utf-8")
+ headers = {
+ "Authorization": f"Basic {credentials}",
+ "Content-type": "application/json",
}
- )
- logging.info(
- "[TimedApi] Summary of workload api response that will be stored in log analytics table is {}".format(
- api_response
+ return requests.request("GET", url, headers=headers, data={})
+
+
+async def main(mytimer: func.TimerRequest) -> None:
+
+ for pce_type in getPceType():
+ pce_fqdn = None
+ if pce_type == "onprem":
+ pce_fqdn = ONPREM_PCE_FQDN
+ response = getWorkloads(
+ ONPREM_PCE_FQDN,
+ ONPREM_PCE_PORT,
+ ONPREM_PCE_ORGID,
+ ONPREM_API_KEY,
+ ONPREM_API_SECRET,
+ )
+ else:
+ pce_fqdn = PCE_FQDN
+ response = getWorkloads(
+ PCE_FQDN,
+ PORT,
+ ORG_ID,
+ API_KEY,
+ API_SECRET,
+ )
+
+ if response:
+ logging.info("[TimedApi] Response from url is {}".format(response.headers))
+ else:
+ logging.info("[TimedApi] Error in response {}".format(response))
+ continue
+
+ response = json.loads(response.text)
+ df = pl.json_normalize(response, infer_schema_length=None)
+
+ vens_by_version = getVensByVersion(df)
+ vens_by_managed = getVensByManaged(df)
+ vens_by_type = getVensByType(df)
+ vens_by_os = getVensByOS(df)
+ vens_by_enf_mode = getVensByEnforcementMode(df)
+ vens_by_status = getVensByStatus(df)
+ vens_by_sync_state = getVensBySyncState(df)
+ api_response = []
+ api_response.append(
+ {
+ "vens_by_version": vens_by_version,
+ "vens_by_managed": vens_by_managed,
+ "vens_by_type": vens_by_type,
+ "vens_by_os": vens_by_os,
+ "vens_by_enforcement_mode": vens_by_enf_mode,
+ "vens_by_status": vens_by_status,
+ "vens_by_sync_state": vens_by_sync_state,
+ "pce_fqdn": pce_fqdn,
+ }
)
- )
-
- async with aiohttp.ClientSession() as session:
- sentinel = AzureSentinelConnectorAsync(
- session,
- DCE_ENDPOINT,
- DCR_ID,
- WORKLOADS_API_LOGS_CUSTOM_TABLE,
- AZURE_CLIENT_ID,
- AZURE_CLIENT_SECRET,
- AZURE_TENANT_ID,
- queue_size=1,
+
+ logging.info(
+ "[TimedApi] Summary of workload api response that will be stored in log analytics table is {}".format(
+ api_response
+ )
)
- await sentinel.send(api_response)
+
+ async with aiohttp.ClientSession() as session:
+ sentinel = AzureSentinelConnectorAsync(
+ session,
+ DCE_ENDPOINT,
+ DCR_ID,
+ WORKLOADS_API_LOGS_CUSTOM_TABLE,
+ AZURE_CLIENT_ID,
+ AZURE_CLIENT_SECRET,
+ AZURE_TENANT_ID,
+ queue_size=1,
+ )
+ await sentinel.send(api_response)
diff --git a/Solutions/IllumioSaaS/Data Connectors/requirements.txt b/Solutions/IllumioSaaS/Data Connectors/requirements.txt
index 9bf651603be..72a00a06ec4 100644
--- a/Solutions/IllumioSaaS/Data Connectors/requirements.txt
+++ b/Solutions/IllumioSaaS/Data Connectors/requirements.txt
@@ -5,4 +5,5 @@ gzip_stream==1.2.0
aiobotocore==2.12.1
azure-identity==1.16.1
azure-monitor-ingestion==1.0.3
+requests
polars
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Package/3.4.0.zip b/Solutions/IllumioSaaS/Package/3.4.0.zip
new file mode 100644
index 00000000000..a7bc8acf69b
Binary files /dev/null and b/Solutions/IllumioSaaS/Package/3.4.0.zip differ
diff --git a/Solutions/IllumioSaaS/Package/createUiDefinition.json b/Solutions/IllumioSaaS/Package/createUiDefinition.json
index d5238de2525..0cf31eb36e9 100644
--- a/Solutions/IllumioSaaS/Package/createUiDefinition.json
+++ b/Solutions/IllumioSaaS/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/IllumioSaaS/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\n[IllumioSaaS](https://www.illumio.com/) solution provides ability to ingest auditable and flow events from AWS S3 bucket.\n\n**Data Connectors:** 1, **Workbooks:** 3, **Analytic Rules:** 6, **Function Apps:** 1, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/IllumioSaaS/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\n[IllumioSaaS](https://www.illumio.com/) solution provides ability to ingest auditable and flow events from AWS S3 bucket.\n\n**Data Connectors:** 1, **Parsers:** 2, **Workbooks:** 4, **Analytic Rules:** 6, **Function Apps:** 1, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
@@ -63,6 +63,13 @@
"text": "This Solution installs the data connector for IllumioSaaS. You can get IllumioSaaS custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
}
},
+ {
+ "name": "dataconnectors-parser-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "The Solution installs a parser that transforms the ingested data into Microsoft Sentinel normalized format. The normalized format enables better correlation of different types of data from different data sources to drive end-to-end outcomes seamlessly in security monitoring, hunting, incident investigation and response scenarios in Microsoft Sentinel."
+ }
+ },
{
"name": "dataconnectors-link2",
"type": "Microsoft.Common.TextBlock",
@@ -142,6 +149,20 @@
}
}
]
+ },
+ {
+ "name": "workbook4",
+ "type": "Microsoft.Common.Section",
+ "label": "Illumio OnPrem Health Workbook",
+ "elements": [
+ {
+ "name": "workbook4-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This workbook leverages events ingested by 'Syslog via AMA devices' and presents insights"
+ }
+ }
+ ]
}
]
},
diff --git a/Solutions/IllumioSaaS/Package/mainTemplate.json b/Solutions/IllumioSaaS/Package/mainTemplate.json
index 2c7e6dbd531..fd6bbf74dc1 100644
--- a/Solutions/IllumioSaaS/Package/mainTemplate.json
+++ b/Solutions/IllumioSaaS/Package/mainTemplate.json
@@ -51,11 +51,19 @@
"metadata": {
"description": "Name for the workbook"
}
+ },
+ "workbook4-name": {
+ "type": "string",
+ "defaultValue": "Illumio OnPrem Health Workbook",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
}
},
"variables": {
"_solutionName": "IllumioSaaS",
- "_solutionVersion": "3.3.0",
+ "_solutionVersion": "3.4.0",
"solutionId": "illumioinc1629822633689.illumio_sentinel",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "IllumioSaaSDataConnector",
@@ -86,47 +94,53 @@
"workbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3'))))]",
"_workbookContentId3": "[variables('workbookContentId3')]",
"_workbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId3'),'-', variables('workbookVersion3'))))]",
+ "workbookVersion4": "1.2.0",
+ "workbookContentId4": "IllumioOnPremHealthWorkbook",
+ "workbookId4": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId4'))]",
+ "workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]",
+ "_workbookContentId4": "[variables('workbookContentId4')]",
+ "_workbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId4'),'-', variables('workbookVersion4'))))]",
"analyticRuleObject1": {
- "analyticRuleVersion1": "1.0.6",
+ "analyticRuleVersion1": "1.0.7",
"_analyticRulecontentId1": "e9e4e466-3970-4165-bc8d-7721c6ef34a6",
"analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'e9e4e466-3970-4165-bc8d-7721c6ef34a6')]",
"analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('e9e4e466-3970-4165-bc8d-7721c6ef34a6')))]",
- "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','e9e4e466-3970-4165-bc8d-7721c6ef34a6','-', '1.0.6')))]"
+ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','e9e4e466-3970-4165-bc8d-7721c6ef34a6','-', '1.0.7')))]"
},
"analyticRuleObject2": {
- "analyticRuleVersion2": "1.0.6",
+ "analyticRuleVersion2": "1.0.7",
"_analyticRulecontentId2": "599fdc92-eb6d-4b54-8d79-2a3f740a846a",
"analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '599fdc92-eb6d-4b54-8d79-2a3f740a846a')]",
"analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('599fdc92-eb6d-4b54-8d79-2a3f740a846a')))]",
- "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','599fdc92-eb6d-4b54-8d79-2a3f740a846a','-', '1.0.6')))]"
+ "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','599fdc92-eb6d-4b54-8d79-2a3f740a846a','-', '1.0.7')))]"
},
"analyticRuleObject3": {
- "analyticRuleVersion3": "1.0.6",
+ "analyticRuleVersion3": "1.0.7",
"_analyticRulecontentId3": "ec07fcd3-724f-426d-9f53-041801ca5f6c",
"analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'ec07fcd3-724f-426d-9f53-041801ca5f6c')]",
"analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('ec07fcd3-724f-426d-9f53-041801ca5f6c')))]",
- "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','ec07fcd3-724f-426d-9f53-041801ca5f6c','-', '1.0.6')))]"
+ "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','ec07fcd3-724f-426d-9f53-041801ca5f6c','-', '1.0.7')))]"
},
"analyticRuleObject4": {
- "analyticRuleVersion4": "1.0.5",
+ "analyticRuleVersion4": "1.0.6",
"_analyticRulecontentId4": "b3c4b8f4-c12c-471e-9999-023c05852276",
"analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'b3c4b8f4-c12c-471e-9999-023c05852276')]",
"analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('b3c4b8f4-c12c-471e-9999-023c05852276')))]",
- "_analyticRulecontentProductId4": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b3c4b8f4-c12c-471e-9999-023c05852276','-', '1.0.5')))]"
+ "_analyticRulecontentProductId4": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b3c4b8f4-c12c-471e-9999-023c05852276','-', '1.0.6')))]"
},
"analyticRuleObject5": {
- "analyticRuleVersion5": "1.0.5",
+ "analyticRuleVersion5": "1.0.6",
"_analyticRulecontentId5": "c18bd8c2-50f0-4aa2-8122-d449243627d7",
"analyticRuleId5": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'c18bd8c2-50f0-4aa2-8122-d449243627d7')]",
"analyticRuleTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('c18bd8c2-50f0-4aa2-8122-d449243627d7')))]",
- "_analyticRulecontentProductId5": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','c18bd8c2-50f0-4aa2-8122-d449243627d7','-', '1.0.5')))]"
+ "_analyticRulecontentProductId5": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','c18bd8c2-50f0-4aa2-8122-d449243627d7','-', '1.0.6')))]"
},
"analyticRuleObject6": {
- "analyticRuleVersion6": "1.0.5",
+ "analyticRuleVersion6": "1.0.6",
"_analyticRulecontentId6": "7379f752-18a2-43ca-8b74-70747dd792f8",
"analyticRuleId6": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '7379f752-18a2-43ca-8b74-70747dd792f8')]",
"analyticRuleTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('7379f752-18a2-43ca-8b74-70747dd792f8')))]",
- "_analyticRulecontentProductId6": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','7379f752-18a2-43ca-8b74-70747dd792f8','-', '1.0.5')))]"
+ "_analyticRulecontentProductId6": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','7379f752-18a2-43ca-8b74-70747dd792f8','-', '1.0.6')))]"
},
"IllumioSaaS_FunctionAppConnector": "IllumioSaaS_FunctionAppConnector",
"_IllumioSaaS_FunctionAppConnector": "[variables('IllumioSaaS_FunctionAppConnector')]",
@@ -160,6 +174,20 @@
"playbookId4": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId4'))]",
"playbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId4'))))]",
"_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]",
+ "parserObject1": {
+ "_parserName1": "[concat(parameters('workspace'),'/','IllumioSyslogAuditEvents')]",
+ "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'IllumioSyslogAuditEvents')]",
+ "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('IllumioSyslogAuditEvents-Parser')))]",
+ "parserVersion1": "1.0.0",
+ "parserContentId1": "IllumioSyslogAuditEvents-Parser"
+ },
+ "parserObject2": {
+ "_parserName2": "[concat(parameters('workspace'),'/','IllumioSyslogNetworkTrafficEvents')]",
+ "_parserId2": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'IllumioSyslogNetworkTrafficEvents')]",
+ "parserTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('IllumioSyslogNetworkTrafficEvents-Parser')))]",
+ "parserVersion2": "1.0.0",
+ "parserContentId2": "IllumioSyslogNetworkTrafficEvents-Parser"
+ },
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
"resources": [
@@ -172,7 +200,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IllumioSaaS data connector with template version 3.3.0",
+ "description": "IllumioSaaS data connector with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -518,7 +546,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IllumioAuditableEvents Workbook with template version 3.3.0",
+ "description": "IllumioAuditableEvents Workbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -536,7 +564,7 @@
},
"properties": {
"displayName": "[parameters('workbook1-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"9875bc24-f51c-4151-96f0-2e4af7039364\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Time\",\"type\":4,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":86400000},{\"durationMs\":604800000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":86400000}}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| summarize count()\",\"size\":4,\"title\":\"Audit Events\",\"noDataMessage\":\"0\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"30\",\"name\":\"Audit Events\",\"styleSettings\":{\"maxWidth\":\"30\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"table('Illumio_Auditable_Events_CL')\\n| where event_type has 'tampering'\\n| summarize count()\",\"size\":4,\"title\":\"Tampering Events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"tileSettings\":{\"showBorder\":false},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"30\",\"name\":\"Tampering Events\",\"styleSettings\":{\"maxWidth\":\"30\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"table('Illumio_Auditable_Events_CL')\\n| where event_type has 'port_scan'\\n| summarize count()\",\"size\":4,\"title\":\"Port Scan Events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"30\",\"name\":\"Port Scan Events\",\"styleSettings\":{\"maxWidth\":\"30\"}}]},\"name\":\"group - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| summarize distinct_count = dcount(href) by event_type\\n| order by distinct_count \\n| top 10 by distinct_count\",\"size\":0,\"title\":\"Top Auditable events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\"},\"name\":\"query - 0\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Change Monitoring\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| summarize arg_max(TimeGenerated, *) by href\\n| where event_type == 'sec_policy.create' \\n| mv-expand resource_change = resource_changes\\n| project TimeGenerated,\\n workloads_affected_after_change = resource_change.changes.workloads_affected.after,\\n policy_version = resource_change.resource.sec_policy.version,\\n commit_message = resource_change.resource.sec_policy.commit_message,\\n modified_objects = resource_change.resource.sec_policy.modified_objects,\\n change_type = resource_change.change_type\\n\",\"size\":0,\"title\":\"Workloads affected by policy changes\",\"noDataMessage\":\"No workloads were affected by policy changes\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"name\":\"Workloads affected by policy changes\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| where resource_changes != '[]' and isnotempty(resource_changes) // ensure resource changes are not empty\\n| summarize arg_max(TimeGenerated, *) by href\\n| mv-expand parse_json(resource_changes)\\n| project resource_type = tostring(bag_keys(resource_changes.resource)[0])\\n| summarize Count=count() by resource_type\",\"size\":0,\"title\":\"Changes by Resource Type\",\"noDataMessage\":\"No changes by resource type\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"customWidth\":\"35\",\"name\":\"Changes by Resource Type\",\"styleSettings\":{\"maxWidth\":\"35\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| where resource_changes != '[]' and isnotempty(resource_changes) and not(event_type matches regex '^user.*') and (event_type has '.create' or event_type has '.update' or event_type has '.delete') and (created_by !has \\\"agent\\\" and created_by !has \\\"ven\\\" and created_by !has \\\"container\\\")\\n| extend User = tostring(parse_json(created_by)['user']['username'])\\n| summarize Count = count() by User\",\"size\":0,\"title\":\"Changes by User\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"35\",\"name\":\"Changes by User\",\"styleSettings\":{\"maxWidth\":\"35\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| where created_by has \\\"agent\\\" or created_by has \\\"ven\\\"\\n| project user = tostring(parse_json(created_by)['agent']['hostname'])\\n| summarize count() by user\",\"size\":0,\"title\":\"Events generated by agents\",\"noDataMessage\":\"Agents have not generated any events\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"20\",\"name\":\"Events generated by agents\",\"styleSettings\":{\"maxWidth\":\"20\"}}]},\"name\":\"ChangeMonitoring\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Auditable_Events_CL\\n| summarize arg_max(TimeGenerated, *) by href // try to filter what event_type to prioritize in bar chart\\n| make-series events = count() default = 0 on TimeGenerated from {Time:start} to {Time:end} step 1h by event_type //from ago(1d) to now() step 1h by event_type \",\"size\":0,\"title\":\"PCE events breakdown - every hour\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\",\"tileSettings\":{\"showBorder\":false},\"graphSettings\":{\"type\":0},\"mapSettings\":{\"locInfo\":\"LatLong\"}},\"name\":\"PCE events breakdown - every hour\"},{\"type\":1,\"content\":{\"json\":\"### Authentication events \\nChoose from below drop down to filter authentication events.\"},\"name\":\"text - 7\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"1ee7c425-b1b5-4a71-8dc3-9b447fa1f316\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"EventType\",\"label\":\"Include Event Type\",\"type\":2,\"description\":\"Types of events to be included \",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"user.logout\\\", \\\"label\\\":\\\"User logout\\\" },\\n { \\\"value\\\":\\\"user.sign_in\\\", \\\"label\\\":\\\"User signin\\\" },\\n { \\\"value\\\":\\\"user.sign_out\\\", \\\"label\\\":\\\"User signout\\\" },\\n { \\\"value\\\":\\\"user.login\\\", \\\"label\\\":\\\"User login\\\"},\\n { \\\"value\\\":\\\"user.pce_session_terminated\\\", \\\"label\\\":\\\"User session terminated\\\"},\\n { \\\"value\\\":\\\"request.authentication_failed\\\", \\\"label\\\":\\\"Authentication failed\\\"},\\n { \\\"value\\\":\\\"user.authenticate\\\", \\\"label\\\":\\\"User Authentication\\\"},\\n { \\\"value\\\":\\\"user.create_session\\\", \\\"label\\\":\\\"User create session\\\"}\\n]\",\"timeContext\":{\"durationMs\":86400000},\"value\":[\"value::all\"]},{\"id\":\"4f1ca215-f902-4fac-9bf0-834e4988a107\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"ExcludeEventType\",\"label\":\"Exclude Event Type\",\"type\":2,\"description\":\"Types of events to be excluded\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"user.logout\\\", \\\"label\\\":\\\"User logout\\\" },\\n { \\\"value\\\":\\\"user.sign_in\\\", \\\"label\\\":\\\"User signin\\\" },\\n { \\\"value\\\":\\\"user.sign_out\\\", \\\"label\\\":\\\"User signout\\\" },\\n { \\\"value\\\":\\\"user.login\\\", \\\"label\\\":\\\"User login\\\"},\\n { \\\"value\\\":\\\"user.pce_session_terminated\\\", \\\"label\\\":\\\"User session terminated\\\"},\\n { \\\"value\\\":\\\"request.authentication_failed\\\", \\\"label\\\":\\\"Authentication failed\\\"},\\n { \\\"value\\\":\\\"user.authenticate\\\", \\\"label\\\":\\\"User Authentication\\\"},\\n { \\\"value\\\":\\\"user.create_session\\\", \\\"label\\\":\\\"User create session\\\"},\\n { \\\"value\\\":\\\"None\\\", \\\"label\\\":\\\"None\\\", \\\"selected\\\": true}\\n]\",\"timeContext\":{\"durationMs\":86400000},\"value\":[\"None\"]},{\"version\":\"KqlParameterItem/1.0\",\"name\":\"Status\",\"type\":2,\"description\":\"Status values\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"failure\\\", \\\"label\\\":\\\"Failure\\\" },\\n { \\\"value\\\":\\\"success\\\", \\\"label\\\":\\\"Success\\\", \\\"selected\\\": true },\\n { \\\"value\\\":\\\"None\\\", \\\"label\\\":\\\"None\\\"}\\n]\",\"timeContext\":{\"durationMs\":86400000},\"id\":\"c8996627-2e77-4386-9c23-1eb5d50df311\",\"value\":[\"value::all\"]},{\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"description\":\"Status values\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"err\\\", \\\"label\\\":\\\"Error\\\" },\\n { \\\"value\\\":\\\"info\\\", \\\"label\\\":\\\"Info\\\", \\\"selected\\\": true } \\n]\",\"timeContext\":{\"durationMs\":86400000},\"id\":\"79d0945d-d0f8-4293-8dc2-3c57391cde95\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let included_event_types = iif(\\\"*\\\" in ({EventType}), dynamic(['user.login','user.logout', 'user.sign_in', 'user.sign_out', 'user.authenticate','user.create_session','user.pce_session_terminated']), dynamic([{EventType}]) );\\nIllumio_Auditable_Events_CL\\n| where event_type in (included_event_types)\\n| where \\\"*\\\" in ({Status}) or status in ({Status}) and \\\"*\\\" in ({Severity}) or severity in ({Severity})\\n| where not(event_type in ({ExcludeEventType}))\\n| project TimeGenerated, pce_fqdn, event_type, status, notification_type = parse_json(notifications)[0].notification_type,severity, created_by_username = iif(created_by == '{\\\"system\\\":{}}', parse_json(notifications)[0].info.user.username, parse_json(created_by).user.username)\",\"size\":0,\"title\":\"PCE Authentication Events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":100,\"filter\":true,\"sortBy\":[{\"itemKey\":\"severity\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"severity\",\"sortOrder\":1}]},\"name\":\"PCE Authentication Events\"}],\"fromTemplateId\":\"sentinel-AuditableEventsWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"9875bc24-f51c-4151-96f0-2e4af7039364\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Time\",\"type\":4,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":86400000},{\"durationMs\":604800000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":86400000}},{\"id\":\"264cba08-bf9e-44d6-9473-5f03e9aa9375\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Illumio_PCE\",\"label\":\"Illumio PCE\",\"type\":2,\"description\":\"Select the Illumio PCE from which you want to see events for\",\"isRequired\":true,\"isGlobal\":true,\"query\":\"Illumio_Auditable_Events_CL\\n| project pce_fqdn , table = \\\"Illumio_Auditable_Events_CL\\\"\\n| union ( IllumioSyslogAuditEvents \\n | project pce_fqdn , table = \\\"IllumioSyslogAuditEvents\\\"\\n )\\n| union (\\n print pce_fqdn = 'No PCE', table = 'Illumio_Auditable_Events_CL'\\n)\\n| distinct table, pce_fqdn \",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"IllumioSyslogAuditEvents\"},{\"id\":\"1b35142b-4e83-4645-83d3-29edd556ee3d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TableToSearchFrom\",\"type\":1,\"description\":\"use Illumio_PCE to define what table to fetch events from\",\"isGlobal\":true,\"isHiddenWhenLocked\":true,\"criteriaData\":[{\"criteriaContext\":{\"operator\":\"Default\",\"resultValType\":\"static\",\"resultVal\":\"{Illumio_PCE:value}\"}}]}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize dcount(href)\",\"size\":4,\"title\":\"Audit Events\",\"noDataMessage\":\"0\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"30\",\"name\":\"Audit Events\",\"styleSettings\":{\"maxWidth\":\"30\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where event_type has 'tampering'\\n| summarize dcount(href)\\n\",\"size\":4,\"title\":\"Tampering Events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"tileSettings\":{\"showBorder\":false},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"30\",\"name\":\"Tampering Events\",\"styleSettings\":{\"maxWidth\":\"30\"}}]},\"name\":\"group - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| summarize distinct_count = dcount(href) by event_type\\n| order by distinct_count \\n| top 10 by distinct_count\",\"size\":0,\"title\":\"Top Auditable events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\"},\"name\":\"query - 0\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Change Monitoring\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| summarize arg_max(TimeGenerated, *) by href\\n| where event_type == 'sec_policy.create' \\n| mv-expand resource_change = resource_changes\\n| project TimeGenerated,\\n workloads_affected_after_change = resource_change.changes.workloads_affected.after,\\n policy_version = resource_change.resource.sec_policy.version,\\n commit_message = resource_change.resource.sec_policy.commit_message,\\n modified_objects = resource_change.resource.sec_policy.modified_objects,\\n change_type = resource_change.change_type\\n\",\"size\":0,\"title\":\"Workloads affected by policy changes\",\"noDataMessage\":\"No workloads were affected by policy changes\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"name\":\"Workloads affected by policy changes\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| where resource_changes != '[]' and isnotempty(resource_changes) // ensure resource changes are not empty\\n| summarize arg_max(TimeGenerated, *) by href\\n| mv-expand parse_json(resource_changes)\\n| project resource_type = tostring(bag_keys(resource_changes.resource)[0])\\n| summarize Count=count() by resource_type\",\"size\":0,\"title\":\"Changes by Resource Type\",\"noDataMessage\":\"No changes by resource type\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"customWidth\":\"35\",\"name\":\"Changes by Resource Type\",\"styleSettings\":{\"maxWidth\":\"35\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| where resource_changes != '[]' and isnotempty(resource_changes) and not(event_type matches regex '^user.*') and (event_type has '.create' or event_type has '.update' or event_type has '.delete') and (created_by !has \\\"agent\\\" and created_by !has \\\"ven\\\" and created_by !has \\\"container\\\")\\n| extend User = tostring(parse_json(created_by)['user']['username'])\\n| summarize Count = count() by User\",\"size\":0,\"title\":\"Changes by User\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"35\",\"name\":\"Changes by User\",\"styleSettings\":{\"maxWidth\":\"35\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| where created_by has \\\"agent\\\" or created_by has \\\"ven\\\"\\n| project user = tostring(parse_json(created_by)['agent']['hostname'])\\n| summarize count() by user\",\"size\":0,\"title\":\"Events generated by agents\",\"noDataMessage\":\"Agents have not generated any events\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"20\",\"name\":\"Events generated by agents\",\"styleSettings\":{\"maxWidth\":\"20\"}}]},\"name\":\"ChangeMonitoring\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| summarize arg_max(TimeGenerated, *) by href // try to filter what event_type to prioritize in bar chart\\n| make-series events = count() default = 0 on TimeGenerated from {Time:start} to {Time:end} step 1h by event_type //from ago(1d) to now() step 1h by event_type \",\"size\":0,\"title\":\"PCE events breakdown - every hour\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\",\"tileSettings\":{\"showBorder\":false},\"graphSettings\":{\"type\":0},\"mapSettings\":{\"locInfo\":\"LatLong\"}},\"name\":\"PCE events breakdown - every hour\"},{\"type\":1,\"content\":{\"json\":\"### Authentication events \\nChoose from below drop down to filter authentication events.\"},\"name\":\"text - 7\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"1ee7c425-b1b5-4a71-8dc3-9b447fa1f316\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"EventType\",\"label\":\"Include Event Type\",\"type\":2,\"description\":\"Types of events to be included \",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"user.logout\\\", \\\"label\\\":\\\"User logout\\\" },\\n { \\\"value\\\":\\\"user.sign_in\\\", \\\"label\\\":\\\"User signin\\\" },\\n { \\\"value\\\":\\\"user.sign_out\\\", \\\"label\\\":\\\"User signout\\\" },\\n { \\\"value\\\":\\\"user.login\\\", \\\"label\\\":\\\"User login\\\"},\\n { \\\"value\\\":\\\"user.pce_session_terminated\\\", \\\"label\\\":\\\"User session terminated\\\"},\\n { \\\"value\\\":\\\"request.authentication_failed\\\", \\\"label\\\":\\\"Authentication failed\\\"},\\n { \\\"value\\\":\\\"user.authenticate\\\", \\\"label\\\":\\\"User Authentication\\\"},\\n { \\\"value\\\":\\\"user.create_session\\\", \\\"label\\\":\\\"User create session\\\"}\\n]\",\"timeContext\":{\"durationMs\":86400000},\"value\":[\"value::all\"]},{\"id\":\"4f1ca215-f902-4fac-9bf0-834e4988a107\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"ExcludeEventType\",\"label\":\"Exclude Event Type\",\"type\":2,\"description\":\"Types of events to be excluded\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"user.logout\\\", \\\"label\\\":\\\"User logout\\\" },\\n { \\\"value\\\":\\\"user.sign_in\\\", \\\"label\\\":\\\"User signin\\\" },\\n { \\\"value\\\":\\\"user.sign_out\\\", \\\"label\\\":\\\"User signout\\\" },\\n { \\\"value\\\":\\\"user.login\\\", \\\"label\\\":\\\"User login\\\"},\\n { \\\"value\\\":\\\"user.pce_session_terminated\\\", \\\"label\\\":\\\"User session terminated\\\"},\\n { \\\"value\\\":\\\"request.authentication_failed\\\", \\\"label\\\":\\\"Authentication failed\\\"},\\n { \\\"value\\\":\\\"user.authenticate\\\", \\\"label\\\":\\\"User Authentication\\\"},\\n { \\\"value\\\":\\\"user.create_session\\\", \\\"label\\\":\\\"User create session\\\"},\\n { \\\"value\\\":\\\"None\\\", \\\"label\\\":\\\"None\\\", \\\"selected\\\": true}\\n]\",\"timeContext\":{\"durationMs\":86400000},\"value\":[\"None\"]},{\"version\":\"KqlParameterItem/1.0\",\"name\":\"Status\",\"type\":2,\"description\":\"Status values\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"failure\\\", \\\"label\\\":\\\"Failure\\\" },\\n { \\\"value\\\":\\\"success\\\", \\\"label\\\":\\\"Success\\\", \\\"selected\\\": true },\\n { \\\"value\\\":\\\"None\\\", \\\"label\\\":\\\"None\\\"}\\n]\",\"timeContext\":{\"durationMs\":86400000},\"id\":\"c8996627-2e77-4386-9c23-1eb5d50df311\",\"value\":[\"value::all\"]},{\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"description\":\"Status values\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"err\\\", \\\"label\\\":\\\"Error\\\" },\\n { \\\"value\\\":\\\"info\\\", \\\"label\\\":\\\"Info\\\", \\\"selected\\\": true } \\n]\",\"timeContext\":{\"durationMs\":86400000},\"id\":\"79d0945d-d0f8-4293-8dc2-3c57391cde95\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let included_event_types = iif(\\\"*\\\" in ({EventType}), dynamic(['user.login','user.logout', 'user.sign_in', 'user.sign_out', 'user.authenticate','user.create_session','user.pce_session_terminated']), dynamic([{EventType}]) );\\nlet table_to_search_from = '{TableToSearchFrom}';\\n\\ntable(table_to_search_from)\\n| where event_type in (included_event_types)\\n| where \\\"*\\\" in ({Status}) or status in ({Status}) and \\\"*\\\" in ({Severity}) or severity in ({Severity})\\n| where not(event_type in ({ExcludeEventType}))\\n| project TimeGenerated, pce_fqdn, event_type, status, notification_type = parse_json(notifications)[0].notification_type,severity, created_by_username = iif(created_by == '{\\\"system\\\":{}}', parse_json(notifications)[0].info.user.username, parse_json(created_by).user.username)\",\"size\":0,\"title\":\"PCE Authentication Events\",\"timeContextFromParameter\":\"Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":100,\"filter\":true,\"sortBy\":[{\"itemKey\":\"severity\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"severity\",\"sortOrder\":1}]},\"name\":\"PCE Authentication Events\"}],\"fromTemplateId\":\"sentinel-AuditableEventsWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -605,7 +633,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IllumioFlowData Workbook with template version 3.3.0",
+ "description": "IllumioFlowData Workbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -623,7 +651,7 @@
},
"properties": {
"displayName": "[parameters('workbook2-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"ebc4e534-7a4a-41be-b365-ddcd4f564090\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_range\",\"label\":\"Time Range\",\"type\":4,\"description\":\"As a time filter\",\"isGlobal\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":259200000},{\"durationMs\":604800000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":86400000}}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Flow_Events_CL\\n| summarize count() by bin(TimeGenerated, 1h)\",\"size\":0,\"title\":\"Traffic every hour\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"showLegend\":true,\"showDataPoints\":true,\"xSettings\":{\"label\":\"Time\"},\"ySettings\":{\"label\":\"Traffic Connections\"}}},\"name\":\"traffic-every-hour\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Trafficked Workload Stats\",\"items\":[{\"type\":1,\"content\":{\"json\":\"#### Enter the number of workloads for which the inbound and outbound connections are to be fetched. These workloads will be ordered by connection count. \",\"style\":\"info\"},\"name\":\"text - 4\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"0dead08f-24f5-40b3-a011-a59e007a8e70\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"workload_count\",\"label\":\"Workload Count\",\"type\":1,\"description\":\"Provide an integer that denotes the limit for retrieving most trafficked workloads\",\"query\":\"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": 5, \\\\\\\"label\\\\\\\": 5, \\\\\\\"selected\\\\\\\": true}\\\"}\\r\\n\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":8,\"value\":\"10\"}],\"style\":\"pills\",\"queryType\":8},\"name\":\"parameters - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let workload_count = {workload_count};\\nIllumio_Flow_Events_CL\\n| extend hostname = coalesce(src_hostname, dst_hostname)\\n| summarize Count = count() by hostname, dir\\n| summarize InboundCount = sum(iff(dir == \\\"I\\\", Count, 0)), OutboundCount = sum(iff(dir == \\\"O\\\", Count, 0)) by hostname\\n| top workload_count by hostname\\n\",\"size\":0,\"title\":\"Most Trafficked Workloads\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"workload\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"xAxis\":\"hostname\",\"showLegend\":true,\"xSettings\":{\"label\":\"Workloads\"},\"ySettings\":{\"label\":\"Traffic Connections\"}}},\"name\":\"Most Trafficked Workloads\"}]},\"name\":\"MostTraffickedWorkload\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Traffic Explorer\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Filters for querying traffic data\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"## Traffic Explorer\\n### Please enter source ip, destination ip, destination port, protocol, time range to filter traffic records. \\n### All records are returned unless provided.\\n\",\"style\":\"info\"},\"name\":\"text - 9\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"8ab7ce90-16a6-4e7e-85b7-292234a9d3c1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"src_ip\",\"label\":\"Source IP\",\"type\":2,\"description\":\"Select source ip\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"Illumio_Flow_Events_CL\\n| summarize by src_ip\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"24f11ee0-0b0b-4c79-918b-01df57233aa2\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"dst_ip\",\"label\":\"Destination IP\",\"type\":2,\"description\":\"Select destination ips\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"Illumio_Flow_Events_CL\\n| summarize by dst_ip\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"eb9fe16e-be04-479d-9389-0095c2b43d50\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"dst_port\",\"label\":\"Destination Port\",\"type\":2,\"description\":\"Select destination port\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"Illumio_Flow_Events_CL\\n| summarize by dst_port\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\"},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"416ab303-c10f-47c1-9f01-7c1324699b49\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"protocol\",\"label\":\"Protocol\",\"type\":2,\"description\":\"Protocol for fetching traffic records. For multiple, use comma as delimiter like 6,17\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"Illumio_Flow_Events_CL\\n| summarize by proto\\n| extend protocolName = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"f07c08c2-ff0f-42a7-adc6-4fd5d7f1cb19\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"src_label\",\"label\":\"Source Label\",\"type\":2,\"description\":\"Filter for source labels\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"Illumio_Flow_Events_CL\\n| where src_labels != ''\\n| extend parsed_labels = parse_json(src_labels)\\n| mv-expand kind=array parsed_labels\\n| extend src_label=tostring(parsed_labels[1])\\n| summarize by src_label\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"9d5cb77f-31a5-41ed-8849-aaee2b513f54\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"dst_label\",\"label\":\"Destination Label\",\"type\":2,\"description\":\"Filter for destination label\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"Illumio_Flow_Events_CL\\n| where dst_labels != ''\\n| extend parsed_labels = parse_json(dst_labels)\\n| mv-expand kind=array parsed_labels\\n| extend dst_label=tostring(parsed_labels[1])\\n| summarize by dst_label\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"formHorizontal\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"30\",\"name\":\"all_traffic_params\",\"styleSettings\":{\"maxWidth\":\"30\"}}],\"exportParameters\":true},\"name\":\"parameters_group\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Flow_Events_CL\\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol})) \\n| extend policy_decision = \\n case(pd == 0, \\\"Allowed\\\",\\n pd == 1, \\\"Potentially Blocked\\\",\\n pd == 2, \\\"Blocked\\\",\\n \\\"Unknown\\\")\\n| summarize count() by policy_decision\\n\",\"size\":2,\"title\":\"Flow count by policy decision\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"Potentially Blocked\",\"color\":\"yellow\"},{\"seriesName\":\"Allowed\",\"color\":\"green\"},{\"seriesName\":\"Blocked\",\"color\":\"red\"},{\"seriesName\":\"Unknown\",\"color\":\"gray\"}]}},\"customWidth\":\"50\",\"name\":\"Flow count by policy decision\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\nIllumio_Flow_Events_CL\\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend class_type = \\n case(class == 'B', 'Broadcast',\\n class == 'M', 'Multicast',\\n class == 'U', \\\"Unicast\\\",\\n \\\"Unknown\\\")\\n| summarize count() by class_type\\n\",\"size\":2,\"title\":\"Flows by class\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"Flows by class\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":1,\"content\":{\"json\":\"### A service is indicated with a destination port and protocol, represented in the below graph as \\\"destination_port/protocol\\\"\",\"style\":\"info\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Flow_Events_CL\\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocolName = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| extend service = strcat(dst_port, '/', protocolName)\\n| summarize service_count = count() by service\\n| top 5 by service_count\\n\",\"size\":0,\"title\":\"Top 5 Services by Flow Count\",\"color\":\"blue\",\"noDataMessage\":\"No services found\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"chartSettings\":{\"xAxis\":\"service\",\"yAxis\":[\"service_count\"],\"xSettings\":{\"label\":\"Destination Service\"},\"ySettings\":{\"label\":\"Count\"}}},\"name\":\"Top 5 Services by Flow Count\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Flow_Events_CL\\n| where pd == 2 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocol = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\\n\\n\",\"size\":0,\"title\":\"Blocked Traffic\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Blocked Traffic\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Flow_Events_CL\\n| where pd == 1 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocol = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\\n\\n\",\"size\":0,\"title\":\"Potentially blocked traffic\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Potentially blocked traffic\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Flow_Events_CL\\n| where pd == 0 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocol = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\\n\",\"size\":0,\"title\":\"Allowed traffic\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Allowed traffic\"}]},\"name\":\"Traffic Explorer\"}],\"fromTemplateId\":\"sentinel-FlowDataWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"ebc4e534-7a4a-41be-b365-ddcd4f564090\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"time_range\",\"label\":\"Time Range\",\"type\":4,\"description\":\"As a time filter\",\"isGlobal\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":259200000},{\"durationMs\":604800000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":86400000}},{\"id\":\"ced5d7b4-3302-4479-bee9-563947af3a5d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Illumio_PCE\",\"label\":\"Illumio PCE\",\"type\":2,\"description\":\"Select the Illumio PCE from which you want to see events for\",\"isRequired\":true,\"isGlobal\":true,\"query\":\"Illumio_Flow_Events_CL\\n| project pce_fqdn, table = \\\"Illumio_Flow_Events_CL\\\"\\n| union (\\n IllumioSyslogAuditEvents\\n | project pce_fqdn, table = \\\"IllumioSyslogAuditEvents\\\"\\n)\\n| union (\\n print pce_fqdn = 'No PCE', table = 'Illumio_Flow_Events_CL'\\n)\\n| distinct table, pce_fqdn\",\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":604800000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"Illumio_Flow_Events_CL\"},{\"id\":\"01dea62f-0a96-4799-ad15-4410632e9665\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TableToSearchFrom\",\"type\":1,\"description\":\"use Illumio_PCE to define what table to fetch events from\",\"isGlobal\":true,\"isHiddenWhenLocked\":true,\"criteriaData\":[{\"criteriaContext\":{\"operator\":\"Default\",\"resultValType\":\"static\",\"resultVal\":\"{Illumio_PCE:value}\"}}]},{\"id\":\"eb392fcd-b6ea-4c7f-86d6-fc4053e65632\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"port_scan_threshold\",\"label\":\"Port Scan Threshold\",\"type\":1,\"description\":\"A port scan event is accounted for when a traffic flow with unique (src, dst, network) is observed for any destination port\",\"value\":\"2\"},{\"id\":\"1c8b3527-5c77-4f1e-93d6-aeb1b39d8dd9\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"allowed_ips\",\"label\":\"Allowed IPs\",\"type\":2,\"description\":\"Exclude source ips from port scan counts\",\"multiSelect\":true,\"quote\":\"\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize by src_ip\",\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":1800000},\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 7\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Port Scan Events\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\nlet port_scan_threshold_param = toint(coalesce('{port_scan_threshold}', '2')); // 2 is a default\\nlet allowed_ips_param = '{allowed_ips}';\\n//print port_scan_threshold_param, table_to_search_from, allowed_ips_param\\ntable(table_to_search_from)\\n| where dir == 'I' and TimeGenerated between ({time_range:start}..{time_range:end})\\n| summarize distinct_ports = dcount(dst_port) by src_ip, dst_ip, network, TimeGenerated\\n| summarize ports_scanned = sum(distinct_ports) by bin(TimeGenerated, 60s)\\n| where ports_scanned > port_scan_threshold_param\\n| summarize count()\\n\\n\",\"size\":3,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"name\":\"query - 0\"}]},\"name\":\"group - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize count() by bin(TimeGenerated, 1h)\",\"size\":0,\"title\":\"Traffic every hour\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"showLegend\":true,\"showDataPoints\":true,\"xSettings\":{\"label\":\"Time\"},\"ySettings\":{\"label\":\"Traffic Connections\"}}},\"name\":\"traffic-every-hour\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Trafficked Workload Stats\",\"items\":[{\"type\":1,\"content\":{\"json\":\"#### Enter the number of workloads for which the inbound and outbound connections are to be fetched. These workloads will be ordered by connection count. \",\"style\":\"info\"},\"name\":\"text - 4\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"0dead08f-24f5-40b3-a011-a59e007a8e70\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"workload_count\",\"label\":\"Workload Count\",\"type\":1,\"description\":\"Provide an integer that denotes the limit for retrieving most trafficked workloads\",\"query\":\"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": 5, \\\\\\\"label\\\\\\\": 5, \\\\\\\"selected\\\\\\\": true}\\\"}\\r\\n\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":8,\"value\":\"10\"}],\"style\":\"pills\",\"queryType\":8},\"name\":\"parameters - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let workload_count = {workload_count};\\nlet table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| extend hostname = coalesce(src_hostname, dst_hostname)\\n| summarize Count = count() by hostname, dir\\n| summarize InboundCount = sum(iff(dir == \\\"I\\\", Count, 0)), OutboundCount = sum(iff(dir == \\\"O\\\", Count, 0)) by hostname\\n| top workload_count by hostname\\n\",\"size\":0,\"title\":\"Most Trafficked Workloads\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"workload\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"xAxis\":\"hostname\",\"showLegend\":true,\"xSettings\":{\"label\":\"Workloads\"},\"ySettings\":{\"label\":\"Traffic Connections\"}}},\"name\":\"Most Trafficked Workloads\"}]},\"name\":\"MostTraffickedWorkload\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Traffic Explorer\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Filters for querying traffic data\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"## Traffic Explorer\\n### Please enter source ip, destination ip, destination port, protocol, time range to filter traffic records. \\n### All records are returned unless provided.\\n\",\"style\":\"info\"},\"name\":\"text - 9\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"8ab7ce90-16a6-4e7e-85b7-292234a9d3c1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"src_ip\",\"label\":\"Source IP\",\"type\":2,\"description\":\"Select source ip\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize by src_ip\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"24f11ee0-0b0b-4c79-918b-01df57233aa2\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"dst_ip\",\"label\":\"Destination IP\",\"type\":2,\"description\":\"Select destination ips\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize by dst_ip\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"eb9fe16e-be04-479d-9389-0095c2b43d50\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"dst_port\",\"label\":\"Destination Port\",\"type\":2,\"description\":\"Select destination port\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize by dst_port\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"416ab303-c10f-47c1-9f01-7c1324699b49\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"protocol\",\"label\":\"Protocol\",\"type\":2,\"description\":\"Protocol for fetching traffic records. For multiple, use comma as delimiter like 6,17\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| summarize by proto\\n| extend protocolName = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"f07c08c2-ff0f-42a7-adc6-4fd5d7f1cb19\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"src_label\",\"label\":\"Source Label\",\"type\":2,\"description\":\"Filter for source labels\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where src_labels != ''\\n| extend parsed_labels = parse_json(src_labels)\\n| mv-expand kind=array parsed_labels\\n| extend src_label=tostring(parsed_labels[1])\\n| summarize by src_label\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"9d5cb77f-31a5-41ed-8849-aaee2b513f54\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"dst_label\",\"label\":\"Destination Label\",\"type\":2,\"description\":\"Filter for destination label\",\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where dst_labels != ''\\n| extend parsed_labels = parse_json(dst_labels)\\n| mv-expand kind=array parsed_labels\\n| extend dst_label=tostring(parsed_labels[1])\\n| summarize by dst_label\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"timeContextFromParameter\":\"time_range\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"formHorizontal\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"30\",\"name\":\"all_traffic_params\",\"styleSettings\":{\"maxWidth\":\"30\"}}],\"exportParameters\":true},\"name\":\"parameters_group\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol})) \\n| extend policy_decision = \\n case(pd == 0, \\\"Allowed\\\",\\n pd == 1, \\\"Potentially Blocked\\\",\\n pd == 2, \\\"Blocked\\\",\\n \\\"Unknown\\\")\\n| summarize count() by policy_decision\\n\",\"size\":2,\"title\":\"Flow count by policy decision\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"Potentially Blocked\",\"color\":\"yellow\"},{\"seriesName\":\"Allowed\",\"color\":\"green\"},{\"seriesName\":\"Blocked\",\"color\":\"red\"},{\"seriesName\":\"Unknown\",\"color\":\"gray\"}]}},\"customWidth\":\"50\",\"name\":\"Flow count by policy decision\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\nlet table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend class_type = \\n case(class == 'B', 'Broadcast',\\n class == 'M', 'Multicast',\\n class == 'U', \\\"Unicast\\\",\\n \\\"Unknown\\\")\\n| summarize count() by class_type\\n\",\"size\":2,\"title\":\"Flows by class\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"Flows by class\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":1,\"content\":{\"json\":\"### A service is indicated with a destination port and protocol, represented in the below graph as \\\"destination_port/protocol\\\"\",\"style\":\"info\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocolName = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| extend service = strcat(dst_port, '/', protocolName)\\n| summarize service_count = count() by service\\n| top 5 by service_count\\n\",\"size\":0,\"title\":\"Top 5 Services by Flow Count\",\"color\":\"blue\",\"noDataMessage\":\"No services found\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"chartSettings\":{\"xAxis\":\"service\",\"yAxis\":[\"service_count\"],\"xSettings\":{\"label\":\"Destination Service\"},\"ySettings\":{\"label\":\"Count\"}}},\"name\":\"Top 5 Services by Flow Count\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where pd == 2 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocol = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\\n\\n\",\"size\":0,\"title\":\"Blocked Traffic\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Blocked Traffic\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where pd == 1 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocol = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\\n\\n\",\"size\":0,\"title\":\"Potentially blocked traffic\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Potentially blocked traffic\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let table_to_search_from = '{TableToSearchFrom}';\\ntable(table_to_search_from)\\n| where pd == 0 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\\n| extend protocol = case(\\n proto == -1, \\\"all\\\",\\n proto == 0, \\\"hopopt\\\",\\n proto == 1, \\\"icmp\\\",\\n proto == 2, \\\"igmp\\\",\\n proto == 3, \\\"ggp\\\",\\n proto == 4, \\\"ipv4\\\",\\n proto == 5, \\\"st\\\",\\n proto == 6, \\\"tcp\\\",\\n proto == 7, \\\"cbt\\\",\\n proto == 8, \\\"egp\\\",\\n proto == 9, \\\"igp\\\",\\n proto == 10, \\\"bbn-rcc-mon\\\",\\n proto == 11, \\\"nvp-ii\\\",\\n proto == 12, \\\"pup\\\",\\n proto == 13, \\\"argus\\\",\\n proto == 14, \\\"emcon\\\",\\n proto == 15, \\\"xnet\\\",\\n proto == 16, \\\"chaos\\\",\\n proto == 17, \\\"udp\\\",\\n proto == 18, \\\"mux\\\",\\n proto == 19, \\\"dcn-meas\\\",\\n proto == 20, \\\"hmp\\\",\\n proto == 21, \\\"prm\\\",\\n proto == 22, \\\"xns-idp\\\",\\n proto == 23, \\\"trunk-1\\\",\\n proto == 24, \\\"trunk-2\\\",\\n proto == 25, \\\"leaf-1\\\",\\n proto == 26, \\\"leaf-2\\\",\\n proto == 27, \\\"rdp\\\",\\n proto == 28, \\\"irtp\\\",\\n proto == 29, \\\"iso-tp4\\\",\\n proto == 30, \\\"netblt\\\",\\n proto == 31, \\\"mfe-nsp\\\",\\n proto == 32, \\\"merit-inp\\\",\\n proto == 33, \\\"dccp\\\",\\n proto == 34, \\\"3pc\\\",\\n proto == 35, \\\"idpr\\\",\\n proto == 36, \\\"xtp\\\",\\n proto == 37, \\\"ddp\\\",\\n proto == 38, \\\"idpr-cmtp\\\",\\n proto == 39, \\\"tp++\\\",\\n proto == 40, \\\"il\\\",\\n proto == 41, \\\"ipv6\\\",\\n proto == 42, \\\"sdrp\\\",\\n proto == 43, \\\"ipv6-route\\\",\\n proto == 44, \\\"ipv6-frag\\\",\\n proto == 45, \\\"idrp\\\",\\n proto == 46, \\\"rsvp\\\",\\n proto == 47, \\\"gre\\\",\\n proto == 48, \\\"dsr\\\",\\n proto == 49, \\\"bna\\\",\\n proto == 50, \\\"esp\\\",\\n proto == 51, \\\"ah\\\",\\n proto == 52, \\\"i-nlsp\\\",\\n proto == 53, \\\"swipe\\\",\\n proto == 54, \\\"narp\\\",\\n proto == 55, \\\"mobile\\\",\\n proto == 56, \\\"tlsp\\\",\\n proto == 57, \\\"skip\\\",\\n proto == 58, \\\"ipv6-icmp\\\",\\n proto == 59, \\\"ipv6-nonxt\\\",\\n proto == 60, \\\"ipv6-opts\\\",\\n proto == 62, \\\"cftp\\\",\\n proto == 64, \\\"sat-expak\\\",\\n proto == 65, \\\"kryptolan\\\",\\n proto == 66, \\\"rvd\\\",\\n proto == 67, \\\"ippc\\\",\\n proto == 69, \\\"sat-mon\\\",\\n proto == 70, \\\"visa\\\",\\n proto == 71, \\\"ipcv\\\",\\n proto == 72, \\\"cpnx\\\",\\n proto == 73, \\\"cphb\\\",\\n proto == 74, \\\"wsn\\\",\\n proto == 75, \\\"pvp\\\",\\n proto == 76, \\\"br-sat-mon\\\",\\n proto == 77, \\\"sun-nd\\\",\\n proto == 78, \\\"wb-mon\\\",\\n proto == 79, \\\"wb-expak\\\",\\n proto == 80, \\\"iso-ip\\\",\\n proto == 81, \\\"vmtp\\\",\\n proto == 82, \\\"secure-vmtp\\\",\\n proto == 83, \\\"vines\\\",\\n proto == 84, \\\"iptm\\\",\\n proto == 85, \\\"nsfnet-igp\\\",\\n proto == 86, \\\"dgp\\\",\\n proto == 87, \\\"tcf\\\",\\n proto == 88, \\\"eigrp\\\",\\n proto == 89, \\\"ospfigp\\\",\\n proto == 90, \\\"sprite-rpc\\\",\\n proto == 91, \\\"larp\\\",\\n proto == 92, \\\"mtp\\\",\\n proto == 93, \\\"ax.25\\\",\\n proto == 94, \\\"ipip\\\",\\n proto == 95, \\\"micp\\\",\\n proto == 96, \\\"scc-sp\\\",\\n proto == 97, \\\"etherip\\\",\\n proto == 98, \\\"encap\\\",\\n proto == 100, \\\"gmtp\\\",\\n proto == 101, \\\"ifmp\\\",\\n proto == 102, \\\"pnni\\\",\\n proto == 103, \\\"pim\\\",\\n proto == 104, \\\"aris\\\",\\n proto == 105, \\\"scps\\\",\\n proto == 106, \\\"qnx\\\",\\n proto == 107, \\\"a/n\\\",\\n proto == 108, \\\"ipcomp\\\",\\n proto == 109, \\\"snp\\\",\\n proto == 110, \\\"compaq-peer\\\",\\n proto == 111, \\\"ipx-in-ip\\\",\\n proto == 112, \\\"vrrp\\\",\\n proto == 113, \\\"pgm\\\",\\n proto == 115, \\\"l2tp\\\",\\n proto == 116, \\\"ddx\\\",\\n proto == 117, \\\"iatp\\\",\\n proto == 118, \\\"stp\\\",\\n proto == 119, \\\"srp\\\",\\n proto == 120, \\\"uti\\\",\\n proto == 121, \\\"smp\\\",\\n proto == 122, \\\"sm\\\",\\n proto == 123, \\\"ptp\\\",\\n proto == 124, \\\"isis over ipv4\\\",\\n proto == 125, \\\"fire\\\",\\n proto == 126, \\\"crtp\\\",\\n proto == 127, \\\"crudp\\\",\\n proto == 128, \\\"sscopmce\\\",\\n proto == 129, \\\"iplt\\\",\\n proto == 130, \\\"sps\\\",\\n proto == 131, \\\"pipe\\\",\\n proto == 132, \\\"sctp\\\",\\n proto == 133, \\\"fc\\\",\\n proto == 134, \\\"rsvp-e2e-ignore\\\",\\n proto == 135, \\\"mobility header\\\",\\n proto == 136, \\\"udplite\\\",\\n proto == 137, \\\"mpls-in-ip\\\",\\n proto == 138, \\\"manet\\\",\\n proto == 139, \\\"hip\\\",\\n proto == 140, \\\"shim6\\\",\\n proto == 141, \\\"wesp\\\",\\n proto == 142, \\\"rohc\\\",\\n proto == 143, \\\"ethernet\\\",\\n proto == 144, \\\"aggfrag\\\",\\n proto == 145, \\\"nsh\\\",\\n proto >= 146 and proto <= 252, \\\"unknown\\\",\\n proto == 253, \\\"unknown\\\",\\n proto == 254, \\\"unknown\\\",\\n proto == 255, \\\"reserved\\\",\\n \\\"unknown\\\"\\n)\\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\\n\",\"size\":0,\"title\":\"Allowed traffic\",\"timeContextFromParameter\":\"time_range\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Allowed traffic\"}]},\"name\":\"Traffic Explorer\"}],\"fromTemplateId\":\"sentinel-FlowDataWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -692,7 +720,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IllumioWorkloadsStats Workbook with template version 3.3.0",
+ "description": "IllumioWorkloadsStats Workbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -710,7 +738,7 @@
},
"properties": {
"displayName": "[parameters('workbook3-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"### Illumio Workloads Stats\\n---\\n\\nThis workbook uses Illumio APIs to fetch workload details and presents stats.\"},\"name\":\"text - 2\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"tabStyle\":\"bigger\",\"links\":[{\"id\":\"4de2c193-277e-4f8e-88b5-2caac1676e2b\",\"cellValue\":\"Tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Workload Operations\",\"subTarget\":\"0\",\"style\":\"link\",\"tabWidth\":\"500px\"},{\"id\":\"8b46c8dd-071a-4bd4-9d36-1247d8777702\",\"cellValue\":\"Tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Workload Investigations\",\"subTarget\":\"1\",\"style\":\"link\",\"tabWidth\":\"500px\"}]},\"name\":\"links - 9\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print workload_response = '{GETWorkloadsAPI}'\\n| project parse_json(workload_response)\\n| mv-apply workload_response on (\\n where workload_response.managed == 'true' and isnotempty(workload_response.risk_summary)\\n | project exposure_severity = workload_response.risk_summary.ransomware.workload_exposure_severity,\\n protection_percentage = workload_response.risk_summary.ransomware.ransomware_protection_percent,\\n updated_at = workload_response.risk_summary.ransomware.last_updated_at\\n )\",\"size\":0,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"protection_percentage\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"protection_percentage\",\"sortOrder\":2}],\"tileSettings\":{\"showBorder\":false}},\"name\":\"query - 0\"}]},\"conditionalVisibility\":{\"parameterName\":\"Tab\",\"comparison\":\"isEqualTo\",\"value\":\"2\"},\"name\":\"Ransomware\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_version)\\n| mv-expand keyValue = parsedJson\\n| extend version = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project version, count_\",\"size\":3,\"title\":\"Workloads by VEN Version\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 5\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_managed)\\n| mv-expand keyValue = parsedJson\\n| extend managed = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project managed = iff(managed == 'true', 'Managed', 'Unmanaged'), count_\",\"size\":3,\"title\":\"Managed and Unmanaged workload counts\",\"noDataMessage\":\"No workloads\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 4\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_type)\\n| mv-expand keyValue = parsedJson\\n| extend type = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project type, count_\",\"size\":3,\"title\":\"VENs by type\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_os)\\n| mv-expand keyValue = parsedJson\\n| extend os = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project os, count_\",\"size\":3,\"title\":\"Managed workloads by OS\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 6\",\"styleSettings\":{\"maxWidth\":\"50\"}}],\"exportParameters\":true},\"conditionalVisibility\":{\"parameterName\":\"Tab\",\"comparison\":\"isEqualTo\",\"value\":\"0\"},\"name\":\"WorkloadOperations\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_enforcement_mode)\\n| mv-expand keyValue = parsedJson\\n| extend mode = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project mode = case(mode == 'full', 'Full',\\n mode == 'visibility_only', 'Visibility Only',\\n mode == 'selective', \\\"Selective\\\",\\n \\\"Idle\\\"), count_\\n\",\"size\":3,\"title\":\"Workloads by enforcement modes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 7\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_status)\\n| mv-expand keyValue = parsedJson\\n| extend status = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project status, count_\\n\",\"size\":3,\"title\":\"VENs by Status\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_sync_state)\\n| mv-expand keyValue = parsedJson\\n| extend sync_state = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project sync_state, count_\\n\",\"size\":3,\"title\":\"VENs by synchronization state\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"name\":\"query - 2\"}]},\"conditionalVisibility\":{\"parameterName\":\"Tab\",\"comparison\":\"isEqualTo\",\"value\":\"1\"},\"name\":\"Workload Investigations\"}],\"fromTemplateId\":\"sentinel-apiWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"### Illumio Workloads Stats\\n---\\n\\nThis workbook uses Illumio APIs to fetch workload details and presents stats.\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"a089608b-daae-4b06-91ff-94b81c03bea8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Illumio_PCE\",\"label\":\"Illumio PCE\",\"type\":2,\"isRequired\":true,\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| summarize by pce_fqdn\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"scp4.illum.io\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"tabStyle\":\"bigger\",\"links\":[{\"id\":\"4de2c193-277e-4f8e-88b5-2caac1676e2b\",\"cellValue\":\"Tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Workload Operations\",\"subTarget\":\"0\",\"style\":\"link\",\"tabWidth\":\"500px\"},{\"id\":\"8b46c8dd-071a-4bd4-9d36-1247d8777702\",\"cellValue\":\"Tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Workload Investigations\",\"subTarget\":\"1\",\"style\":\"link\",\"tabWidth\":\"500px\"}]},\"name\":\"links - 9\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print workload_response = '{GETWorkloadsAPI}'\\n| project parse_json(workload_response)\\n| mv-apply workload_response on (\\n where workload_response.managed == 'true' and isnotempty(workload_response.risk_summary)\\n | project exposure_severity = workload_response.risk_summary.ransomware.workload_exposure_severity,\\n protection_percentage = workload_response.risk_summary.ransomware.ransomware_protection_percent,\\n updated_at = workload_response.risk_summary.ransomware.last_updated_at\\n )\",\"size\":0,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"protection_percentage\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"protection_percentage\",\"sortOrder\":2}],\"tileSettings\":{\"showBorder\":false}},\"name\":\"query - 0\"}]},\"conditionalVisibility\":{\"parameterName\":\"Tab\",\"comparison\":\"isEqualTo\",\"value\":\"2\"},\"name\":\"Ransomware\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_version)\\n| mv-expand keyValue = parsedJson\\n| extend version = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project version, count_\",\"size\":3,\"title\":\"Workloads by VEN Version\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 5\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_managed)\\n| mv-expand keyValue = parsedJson\\n| extend managed = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project managed = iff(managed == 'true', 'Managed', 'Unmanaged'), count_\",\"size\":3,\"title\":\"Managed and Unmanaged workload counts\",\"noDataMessage\":\"No workloads\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 4\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_type)\\n| mv-expand keyValue = parsedJson\\n| extend type = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project type, count_\",\"size\":3,\"title\":\"VENs by type\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_os)\\n| mv-expand keyValue = parsedJson\\n| extend os = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project os, count_\",\"size\":3,\"title\":\"Managed workloads by OS\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 6\",\"styleSettings\":{\"maxWidth\":\"50\"}}],\"exportParameters\":true},\"conditionalVisibility\":{\"parameterName\":\"Tab\",\"comparison\":\"isEqualTo\",\"value\":\"0\"},\"name\":\"WorkloadOperations\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_enforcement_mode)\\n| mv-expand keyValue = parsedJson\\n| extend mode = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project mode = case(mode == 'full', 'Full',\\n mode == 'visibility_only', 'Visibility Only',\\n mode == 'selective', \\\"Selective\\\",\\n \\\"Idle\\\"), count_\\n\",\"size\":3,\"title\":\"Workloads by enforcement modes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 7\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_status)\\n| mv-expand keyValue = parsedJson\\n| extend status = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project status, count_\\n\",\"size\":3,\"title\":\"VENs by Status\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Illumio_Workloads_Summarized_API_CL\\n| where pce_fqdn == ('{Illumio_PCE}')\\n| order by TimeGenerated desc\\n| top 1 by TimeGenerated\\n| extend parsedJson = parse_json(vens_by_sync_state)\\n| mv-expand keyValue = parsedJson\\n| extend sync_state = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\\n| project sync_state, count_\\n\",\"size\":3,\"title\":\"VENs by synchronization state\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumIntegerDigits\":1}}}}},\"name\":\"query - 2\"}]},\"conditionalVisibility\":{\"parameterName\":\"Tab\",\"comparison\":\"isEqualTo\",\"value\":\"1\"},\"name\":\"Workload Investigations\"}],\"fromTemplateId\":\"sentinel-apiWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -770,6 +798,93 @@
"version": "[variables('workbookVersion3')]"
}
},
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName4')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IllumioOnPremHealth Workbook with template version 3.4.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion4')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId4')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "This workbook leverages events ingested by 'Syslog via AMA devices' and presents insights"
+ },
+ "properties": {
+ "displayName": "[parameters('workbook4-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This workbook leverages a function app to make an API call to Illumio Health API. \\nThe function app has the context of the onprem deployment to which api call has to be made.\\n\\nSome of the widgets also use Syslog table to visualize data.\",\"style\":\"info\"},\"name\":\"text - 7\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f0562353-928f-41f0-875c-99eb0f95fa38\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Illumio_Health\",\"label\":\"Illumio Health\",\"type\":1,\"isRequired\":true,\"query\":\"{\\\"version\\\":\\\"CustomEndpoint/1.0\\\",\\\"headers\\\":[],\\\"method\\\":\\\"GET\\\",\\\"url\\\":\\\"https://azureonprempcehealth.azurewebsites.net/api/pce_onprem_http_trigger\\\",\\\"contentType\\\":\\\"text/plain\\\",\\\"urlParams\\\":[]}\\r\\n\",\"isHiddenWhenLocked\":true,\"timeContext\":{\"durationMs\":86400000},\"queryType\":10},{\"id\":\"2a4639d7-a9c8-4e65-8bd7-26b97d813f6d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":259200000},{\"durationMs\":604800000}],\"allowCustom\":true},\"value\":{\"durationMs\":259200000}}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print json = todynamic('{Illumio_Health}')[0]\\n| project ClusterStatus = strcat(toupper(substring(json.status, 0, 1)), substring(json.status, 1))\\n\",\"size\":1,\"title\":\"Cluster Status\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"stat\",\"statSettings\":{\"valueAggregation\":\"None\",\"colorSettings\":{\"type\":\"static\",\"mode\":\"background\",\"heatmapPalette\":\"greenRed\"},\"tagText\":\"\",\"valueFontStyle\":\"mega\"},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print json = todynamic('{Illumio_Health}')[0]['nodes'][0]\\n| project json.runlevel\",\"size\":1,\"title\":\"Cluster Runlevel \",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"stat\",\"statSettings\":{\"valueAggregation\":\"None\",\"colorSettings\":{\"type\":\"static\",\"mode\":\"background\",\"heatmapPalette\":\"greenRed\"},\"tagText\":\"\",\"valueFontStyle\":\"mega\"},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"group - 1\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print nodes = todynamic('{Illumio_Health}')[0]['nodes']\\n| mv-expand nodes\\n| project Services_Running = array_length(nodes['services']['running'])\\n\\n\\n\",\"size\":1,\"title\":\"Running Services\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"stat\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Services_Running\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"icons\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"success\",\"text\":\"{0}{1}\"}],\"customColumnWidthSetting\":\"45ch\"}},{\"columnMatch\":\"Services_Stopped\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"icons\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"3\",\"text\":\"{0}{1}\"}],\"customColumnWidthSetting\":\"45ch\"}},{\"columnMatch\":\"Services_Partial\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"icons\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"warning\",\"text\":\"{0}{1}\"}],\"customColumnWidthSetting\":\"45ch\"}},{\"columnMatch\":\"services_running\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"icons\",\"thresholdsGrid\":[{\"sourceColumn\":\"services_stopped\",\"representation\":\"3\",\"text\":\"{0}{1}\"},{\"sourceColumn\":\"services_partial\",\"representation\":\"2\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"success\",\"text\":\"{0}{1}\"}],\"customColumnWidthSetting\":\"45ch\"}}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"hostname\"},\"leftContent\":{\"columnMatch\":\"services_running\"},\"rightContent\":{\"columnMatch\":\"services_stopped\"},\"secondaryContent\":{\"columnMatch\":\"services_partial\"},\"showBorder\":false},\"graphSettings\":{\"type\":0},\"statSettings\":{\"valueAggregation\":\"None\",\"colorSettings\":{\"type\":\"static\",\"mode\":\"foreground\",\"staticColor\":\"green\",\"heatmapPalette\":\"greenRed\"},\"tagText\":\"\",\"valueFontStyle\":\"mega\"}},\"customWidth\":\"33.33\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print nodes = todynamic('{Illumio_Health}')[0]['nodes']\\n| mv-expand nodes\\n| project Services_stopped = coalesce(array_length(nodes['services']['stopped']), 0)\\n\\n\\n\",\"size\":1,\"title\":\"Stopped Services\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"stat\",\"statSettings\":{\"valueAggregation\":\"None\",\"colorSettings\":{\"type\":\"static\",\"mode\":\"foreground\",\"staticColor\":\"redBright\",\"heatmapPalette\":\"greenRed\"},\"tagText\":\"\",\"valueFontStyle\":\"mega\"}},\"customWidth\":\"33.33\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print nodes = todynamic('{Illumio_Health}')[0]['nodes']\\n| mv-expand nodes\\n| project Services_partial = coalesce(array_length(nodes['services']['partial']), 0)\\n\\n\\n\",\"size\":1,\"title\":\"Partial Services\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"stat\",\"statSettings\":{\"valueAggregation\":\"None\",\"colorSettings\":{\"type\":\"static\",\"mode\":\"foreground\",\"staticColor\":\"gray\",\"heatmapPalette\":\"greenRed\"},\"tagText\":\"\",\"valueFontStyle\":\"mega\"}},\"customWidth\":\"33\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"service stats\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Node Status\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print nodes = todynamic('{Illumio_Health}')[0]['nodes']\\n| mv-expand nodes\\n| project Hostname = nodes['hostname'], Runlevel = nodes['runlevel'], IpAddress = nodes['ip_address']\\n\\n\\n\",\"size\":3,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Hostname\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"15ch\"}}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Hostname\",\"formatter\":1,\"tooltipFormat\":{\"tooltip\":\"Hostname\"}},\"leftContent\":{\"columnMatch\":\"Runlevel\",\"formatter\":12,\"formatOptions\":{\"palette\":\"blue\"},\"tooltipFormat\":{\"tooltip\":\"Runlevel\"}},\"secondaryContent\":{\"columnMatch\":\"IpAddress\",\"formatter\":12,\"formatOptions\":{\"palette\":\"blue\"},\"tooltipFormat\":{\"tooltip\":\"Ip Address\"}},\"showBorder\":true,\"size\":\"full\"}},\"customWidth\":\"100\",\"name\":\"query - 0\"}]},\"name\":\"node_status\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Disk Latency (in milliseconds)\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Syslog\\n| where SyslogMessage has 'illumio_pce/system_health' and SyslogMessage has 'src=disk_latency' and SyslogMessage has 'disk=Traffic'\\n| extend traffic_disk_latency_milliseconds = toint(extract(@\\\"traffic_disk_latency_milliseconds=(\\\\d+)\\\", 1, SyslogMessage))\\n\",\"size\":0,\"aggregation\":3,\"title\":\"Traffic Disk\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\",\"chartSettings\":{\"xAxis\":\"TimeGenerated\",\"yAxis\":[\"traffic_disk_latency_milliseconds\"],\"seriesLabelSettings\":[{\"seriesName\":\"153035ad-fede-495a-b6c2-6d4308689f79\",\"label\":\"Latency in milliseconds\"}],\"customThresholdLine\":\"300\",\"customThresholdLineStyle\":5,\"xSettings\":{\"label\":\"Time\"},\"ySettings\":{\"label\":\"Traffic Disk Latency\"}}},\"customWidth\":\"50\",\"name\":\"query - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Syslog\\n| where SyslogMessage has 'illumio_pce/system_health' and SyslogMessage has 'src=disk_latency' and SyslogMessage has 'disk=Policy'\\n| extend policy_disk_latency_milliseconds = toint(extract(@\\\"policy_disk_latency_milliseconds=(\\\\d+)\\\", 1, SyslogMessage))\\n\",\"size\":0,\"aggregation\":3,\"title\":\"Policy Disk\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\",\"chartSettings\":{\"xAxis\":\"TimeGenerated\",\"yAxis\":[\"policy_disk_latency_milliseconds\"],\"seriesLabelSettings\":[{\"seriesName\":\"153035ad-fede-495a-b6c2-6d4308689f79\",\"label\":\"Latency in milliseconds\"}],\"customThresholdLine\":\"300\",\"customThresholdLineStyle\":5}},\"customWidth\":\"50\",\"name\":\"query - 1\"}]},\"name\":\"group - 4\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Traffic Ingestion Stats\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Syslog\\n| where SyslogMessage has 'illumio_pce/system_health'\\n| extend \\n collector_flows = iif(SyslogMessage has 'src=collector', toint(extract(@\\\"collector_summaries_per_second=(\\\\d+)\\\", 1, SyslogMessage)), 0),\\n traffic_flows = iif(SyslogMessage has 'src=flow_analytics', toint(extract(@\\\"traffic_summaries_per_second=(\\\\d+)\\\", 1, SyslogMessage)), 0)\\n| summarize \\n collector_flows = sum(collector_flows), \\n traffic_flows = sum(traffic_flows) \\n by bin(TimeGenerated, 10m) // Adjust bin size (e.g., 1m for minutes, 5m, etc.)\\n| order by TimeGenerated asc\\n\",\"size\":3,\"aggregation\":3,\"title\":\"Traffic Flow Ingestion Rate (Average)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"xAxis\":\"TimeGenerated\",\"yAxis\":[\"collector_flows\",\"traffic_flows\"]}},\"customWidth\":\"50\",\"name\":\"query - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Syslog\\n| where SyslogMessage has 'illumio_pce/system_health' and SyslogMessage has 'src=flow_analytics'\\n| extend traffic_summaries_per_second = todouble(extract(@\\\"traffic_summaries_per_second=([\\\\d\\\\.]+)\\\", 1, SyslogMessage))\\n| extend traffic_backlog_utilization_percentage = todouble(extract(@\\\"traffic_backlog_utilization_percentage=([\\\\d\\\\.]+)\\\", 1, SyslogMessage))\\n| extend traffic_database_size_gb = todouble(extract(@\\\"traffic_database_size_gb=([\\\\d\\\\.]+)\\\", 1, SyslogMessage))\\n| extend traffic_database_utilization_percentage = todouble(extract(@\\\"traffic_database_utilization_percentage=([\\\\d\\\\.]+)\\\", 1, SyslogMessage))\\n| extend traffic_database_size_days = todouble(extract(@\\\"traffic_database_size_days=([\\\\d\\\\.]+)\\\", 1, SyslogMessage))\\n| project TimeGenerated, traffic_summaries_per_second, traffic_backlog_utilization_percentage, traffic_database_size_gb, traffic_database_utilization_percentage, traffic_database_size_days\",\"size\":3,\"aggregation\":3,\"title\":\"Traffic Backlog vs Traffic DB Utilization\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"xAxis\":\"TimeGenerated\",\"yAxis\":[\"traffic_backlog_utilization_percentage\",\"traffic_database_utilization_percentage\"]}},\"customWidth\":\"50\",\"name\":\"query - 1\"}]},\"name\":\"group - 5\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print json = todynamic('{Illumio_Health}')[0]\\n| mv-expand group = parsejson(json.groups)\\n| extend components = group.components\\n| mv-expand section = parsejson(components)\\n| where section['section'] == 'VEN Heartbeat'\\n| mv-expand node = section.contents[0].cluster\\n| mv-expand node_metrics = node.metrics\\n| project NodeAddress = node.node, Metric = node_metrics['metric'], MetricValue = node_metrics['entries'][0]['values'][0]['value']\",\"size\":3,\"title\":\"VEN Heartbeat Stats\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print json = todynamic('{Illumio_Health}')[0]\\n| mv-expand group = parsejson(json.groups)\\n| extend components = group.components\\n| mv-expand section = parsejson(components)\\n| where section['section'] == 'VEN Policy'\\n| mv-expand node = section.contents[0].cluster\\n| mv-expand node_metrics = node.metrics\\n| project NodeAddress = node.node, Metric = node_metrics['metric'], MetricValue = node_metrics['entries'][0]['values'][0]['value']\",\"size\":3,\"title\":\"VEN Policy Stats\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print json = todynamic('{Illumio_Health}')[0]\\n| mv-expand group = parsejson(json.groups)\\n| extend components = group.components\\n| mv-expand section = parsejson(components)\\n| where section['section'] == 'Policy Database Summary'\\n| mv-expand content = section.contents\\n| project Metric = content['metric'], MetricValue = content['entries'][0]['values'][0]['value'], Unit = coalesce(content['entries'][0]['values'][0]['unit'], '')\",\"size\":0,\"title\":\"Policy Database Summary\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"print json = todynamic('{Illumio_Health}')[0]\\n| mv-expand group = parsejson(json.groups)\\n| extend components = group.components\\n| mv-expand section = parsejson(components)\\n| where section['section'] == 'Traffic Database Summary'\\n| mv-expand content = section.contents\\n| project Metric = content['metric'], MetricValue = content['entries'][0]['values'][0]['value'], Unit = coalesce(content['entries'][0]['values'][0]['unit'], '')\",\"size\":0,\"title\":\"Traffic Database Summary\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 3\"}]},\"name\":\"group - 6\"}],\"fromTemplateId\":\"sentinel-OnPremHealthWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId4'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=IllumioOnPremHealthWorkbook; logoFileName=IllumioLogo.svg; description=This workbook leverages events ingested by 'Syslog via AMA devices' and presents insights; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.2.0; title=Illumio OnPrem Health Workbook; templateRelativePath=IllumioOnPremHealth.json; subtitle=; provider=Illumio}.description",
+ "parentId": "[variables('workbookId4')]",
+ "contentId": "[variables('_workbookContentId4')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion4')]",
+ "source": {
+ "kind": "Solution",
+ "name": "IllumioSaaS",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "app-integrations@illumio.com"
+ },
+ "support": {
+ "name": "Illumio",
+ "email": "app-integrations@illumio.com",
+ "tier": "Partner",
+ "link": "https://www.illumio.com/support/support"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "Syslog",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "SyslogAMA",
+ "kind": "DataConnector"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId4')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook4-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId4')]",
+ "id": "[variables('_workbookcontentProductId4')]",
+ "version": "[variables('workbookVersion4')]"
+ }
+ },
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
@@ -779,7 +894,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio_VEN_Firewall_Tampering_Detection_Query_AnalyticalRules Analytics Rule with template version 3.3.0",
+ "description": "Illumio_VEN_Firewall_Tampering_Detection_Query_AnalyticalRules Analytics Rule with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -796,7 +911,7 @@
"description": "Create Microsoft Sentinel Incident When Firewall Is Tampered With",
"displayName": "Illumio Firewall Tampering Analytic Rule",
"enabled": false,
- "query": "Illumio_Auditable_Events_CL\n | where event_type has 'tampering'\n | extend ipaddress = action.src_ip,\n hostname = created_by.agent.hostname,\n ven_href = created_by.ven.href\n | project-away resource_changes, action, version\n",
+ "query": "Illumio_Auditable_Events_CL\n | union IllumioSyslogAuditEvents \n | where event_type has 'tampering'\n | extend ipaddress = action.src_ip,\n hostname = created_by.agent.hostname,\n ven_href = created_by.ven.href\n | project-away resource_changes, action, version\n",
"queryFrequency": "PT60M",
"queryPeriod": "PT60M",
"severity": "Medium",
@@ -807,10 +922,16 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "IllumioSaaSDataConnector",
"dataTypes": [
"Illumio_Auditable_Events_CL"
- ],
- "connectorId": "IllumioSaaSDataConnector"
+ ]
+ },
+ {
+ "connectorId": "SyslogAma",
+ "datatypes": [
+ "Syslog"
+ ]
}
],
"tactics": [
@@ -821,30 +942,30 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
"columnName": "hostname",
"identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
"columnName": "ipaddress",
"identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "Illumio Firewall Tamper Incident for {{hostname}} generated at {{TimeGenerated}}\n",
- "alertDisplayNameFormat": "Illumio Firewall Tamper Incident for {{hostname}}\n"
+ "alertDisplayNameFormat": "Illumio Firewall Tamper Incident for {{hostname}}\n",
+ "alertDescriptionFormat": "Illumio Firewall Tamper Incident for {{hostname}} generated at {{TimeGenerated}}\n"
}
}
},
@@ -898,7 +1019,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio_VEN_Enforcement_Change_Detection_Query_AnalyticalRules Analytics Rule with template version 3.3.0",
+ "description": "Illumio_VEN_Enforcement_Change_Detection_Query_AnalyticalRules Analytics Rule with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -915,7 +1036,7 @@
"description": "Create Microsoft Sentinel Incident When Ven Changes Enforcement State from Full/Selective To Idle/Visibility state",
"displayName": "Illumio Enforcement Change Analytic Rule",
"enabled": false,
- "query": "let enf_state = dynamic([\"full\", \"selective\"]);\nlet visibility_state = dynamic([\"visibility_only\", \"idle\"]);\nIllumio_Auditable_Events_CL\n| extend temp_resource_changes = parse_json(resource_changes)[0]\n| where event_type == 'workloads.update' \n| extend old_mode = temp_resource_changes.changes.enforcement_mode.before,\n new_mode = temp_resource_changes.changes.enforcement_mode.after,\n workload_href = temp_resource_changes.resource.workload.href,\n workload_name = temp_resource_changes.resource.workload.hostname,\n ipaddress = action.src_ip\n| where new_mode in (visibility_state) and old_mode in (enf_state)\n| project-away temp_*\n| project old_mode, new_mode, workload_href, workload_name, TimeGenerated, created_by, ipaddress\n",
+ "query": "let enf_state = dynamic([\"full\", \"selective\"]);\nlet visibility_state = dynamic([\"visibility_only\", \"idle\"]);\nIllumio_Auditable_Events_CL\n| union IllumioSyslogAuditEvents\n| extend temp_resource_changes = parse_json(resource_changes)[0]\n| where event_type == 'workloads.update' \n| extend old_mode = temp_resource_changes.changes.enforcement_mode.before,\n new_mode = temp_resource_changes.changes.enforcement_mode.after,\n workload_href = temp_resource_changes.resource.workload.href,\n workload_name = temp_resource_changes.resource.workload.hostname,\n ipaddress = action.src_ip\n| where new_mode in (visibility_state) and old_mode in (enf_state)\n| project-away temp_*\n| project old_mode, new_mode, workload_href, workload_name, TimeGenerated, created_by, ipaddress\n",
"queryFrequency": "PT60M",
"queryPeriod": "PT60M",
"severity": "Medium",
@@ -926,10 +1047,16 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "IllumioSaaSDataConnector",
"dataTypes": [
"Illumio_Auditable_Events_CL"
- ],
- "connectorId": "IllumioSaaSDataConnector"
+ ]
+ },
+ {
+ "connectorId": "SyslogAma",
+ "datatypes": [
+ "Syslog"
+ ]
}
],
"tactics": [
@@ -940,39 +1067,39 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
"columnName": "workload_name",
"identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "Account",
"fieldMappings": [
{
"columnName": "created_by",
"identifier": "Name"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
"columnName": "ipaddress",
"identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "Illumio Enforcement Change Incident for {{workload_name}} generated at {{TimeGenerated}}\n",
- "alertDisplayNameFormat": "Illumio Enforcement Change Incident for {{workload_name}}\n"
+ "alertDisplayNameFormat": "Illumio Enforcement Change Incident for {{workload_name}}\n",
+ "alertDescriptionFormat": "Illumio Enforcement Change Incident for {{workload_name}} generated at {{TimeGenerated}}\n"
}
}
},
@@ -1026,7 +1153,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio_VEN_Offline_Detection_Query_AnalyticalRules Analytics Rule with template version 3.3.0",
+ "description": "Illumio_VEN_Offline_Detection_Query_AnalyticalRules Analytics Rule with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -1043,7 +1170,7 @@
"description": "Create Microsoft Sentinel Incident When Ven Goes Into Offline state",
"displayName": "Illumio VEN Offline Detection Rule",
"enabled": false,
- "query": "Illumio_Auditable_Events_CL\n| where event_type has 'agent_offline_check'\n| mv-expand resource_changes\n| extend hostname = resource_changes['resource']['workload']['hostname'],\n workload_href = resource_changes['resource']['workload']['href'],\n workload_labels = resource_changes['resource']['workload']['labels']\n| project-away resource_changes, version, notifications, action, severity, status // action field will have filtered ip addr, so no point of using IP entity\n",
+ "query": "Illumio_Auditable_Events_CL\n| union IllumioSyslogAuditEvents \n| where event_type has 'agent_offline_check'\n| mv-expand resource_changes\n| extend hostname = resource_changes['resource']['workload']['hostname'],\n workload_href = resource_changes['resource']['workload']['href'],\n workload_labels = resource_changes['resource']['workload']['labels']\n| project-away resource_changes, version, notifications, action, severity, status // action field will have filtered ip addr, so no point of using IP entity\n",
"queryFrequency": "PT60M",
"queryPeriod": "PT60M",
"severity": "High",
@@ -1054,10 +1181,16 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "IllumioSaaSDataConnector",
"dataTypes": [
"Illumio_Auditable_Events_CL"
- ],
- "connectorId": "IllumioSaaSDataConnector"
+ ]
+ },
+ {
+ "connectorId": "SyslogAma",
+ "datatypes": [
+ "Syslog"
+ ]
}
],
"tactics": [
@@ -1068,21 +1201,21 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
"columnName": "hostname",
"identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "Illumio VEN Offline Incident for {{hostname}} generated at {{TimeGenerated}}\n",
- "alertDisplayNameFormat": "Illumio VEN Offline Incident for {{hostname}}\n"
+ "alertDisplayNameFormat": "Illumio VEN Offline Incident for {{hostname}}\n",
+ "alertDescriptionFormat": "Illumio VEN Offline Incident for {{hostname}} generated at {{TimeGenerated}}\n"
}
}
},
@@ -1136,7 +1269,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio_VEN_Clone_Detection_Query_AnalyticalRules Analytics Rule with template version 3.3.0",
+ "description": "Illumio_VEN_Clone_Detection_Query_AnalyticalRules Analytics Rule with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -1153,7 +1286,7 @@
"description": "Create Microsoft Sentinel Incident When A Cloned Ven Is Detected",
"displayName": "Illumio VEN Clone Detection Rule",
"enabled": false,
- "query": "Illumio_Auditable_Events_CL\n| where event_type has 'agent.clone_detected'\n| extend hostname = created_by.agent.hostname,\n ven_href = created_by.ven.href\n",
+ "query": "Illumio_Auditable_Events_CL\n| union IllumioSyslogAuditEvents \n| where event_type has 'agent.clone_detected'\n| extend hostname = created_by.agent.hostname,\n ven_href = created_by.ven.href\n",
"queryFrequency": "PT60M",
"queryPeriod": "PT60M",
"severity": "High",
@@ -1164,10 +1297,16 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "IllumioSaaSDataConnector",
"dataTypes": [
"Illumio_Auditable_Events_CL"
- ],
- "connectorId": "IllumioSaaSDataConnector"
+ ]
+ },
+ {
+ "connectorId": "SyslogAma",
+ "datatypes": [
+ "Syslog"
+ ]
}
],
"tactics": [
@@ -1178,21 +1317,21 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
"columnName": "hostname",
"identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "Illumio VEN Clone Detection for {{hostname}} generated at {{TimeGenerated}}\n",
- "alertDisplayNameFormat": "Illumio VEN Clone Detection Incident for {{hostname}}\n"
+ "alertDisplayNameFormat": "Illumio VEN Clone Detection Incident for {{hostname}}\n",
+ "alertDescriptionFormat": "Illumio VEN Clone Detection for {{hostname}} generated at {{TimeGenerated}}\n"
}
}
},
@@ -1246,7 +1385,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio_VEN_Deactivated_Query_AnalyticalRules Analytics Rule with template version 3.3.0",
+ "description": "Illumio_VEN_Deactivated_Query_AnalyticalRules Analytics Rule with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -1263,7 +1402,7 @@
"description": "Create Microsoft Sentinel Incident When Ven Goes Into Deactivated state",
"displayName": "Illumio VEN Deactivated Detection Rule",
"enabled": false,
- "query": "Illumio_Auditable_Events_CL\n| where event_type has 'agent.deactivate'\n| mv-expand resource_changes\n| extend hostname = resource_changes['resource']['workload']['hostname'],\n workload_href = resource_changes['resource']['workload']['href'],\n workload_labels = resource_changes['resource']['workload']['labels']\n| extend ipaddress = action.src_ip, \n ven_href = created_by.ven.href\n| project-away resource_changes, action, version \n",
+ "query": "Illumio_Auditable_Events_CL\n| union IllumioSyslogAuditEvents \n| where event_type has 'agent.deactivate'\n| mv-expand resource_changes\n| extend hostname = resource_changes['resource']['workload']['hostname'],\n workload_href = resource_changes['resource']['workload']['href'],\n workload_labels = resource_changes['resource']['workload']['labels']\n| extend ipaddress = action.src_ip, \n ven_href = created_by.ven.href\n| project-away resource_changes, action, version \n",
"queryFrequency": "PT60M",
"queryPeriod": "PT60M",
"severity": "High",
@@ -1274,10 +1413,16 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "IllumioSaaSDataConnector",
"dataTypes": [
"Illumio_Auditable_Events_CL"
- ],
- "connectorId": "IllumioSaaSDataConnector"
+ ]
+ },
+ {
+ "connectorId": "SyslogAma",
+ "datatypes": [
+ "Syslog"
+ ]
}
],
"tactics": [
@@ -1288,30 +1433,30 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
"columnName": "hostname",
"identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
"columnName": "ipaddress",
"identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "Illumio VEN Deactivated Incident for {{hostname}} generated at {{TimeGenerated}}\n",
- "alertDisplayNameFormat": "Illumio VEN Deactivated Incident for {{hostname}}\n"
+ "alertDisplayNameFormat": "Illumio VEN Deactivated Incident\n",
+ "alertDescriptionFormat": "Illumio VEN Deactivated Incident generated at {{TimeGenerated}}\n"
}
}
},
@@ -1365,7 +1510,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio_VEN_Suspend_Query_AnalyticalRules Analytics Rule with template version 3.3.0",
+ "description": "Illumio_VEN_Suspend_Query_AnalyticalRules Analytics Rule with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -1382,7 +1527,7 @@
"description": "Create Microsoft Sentinel Incident When Ven Goes Into Suspended state",
"displayName": "Illumio VEN Suspend Detection Rule",
"enabled": false,
- "query": "Illumio_Auditable_Events_CL\n| where event_type has 'agent.suspend'\n| extend ipaddress = action.src_ip,\n hostname = created_by.agent.hostname\n| project-away resource_changes, action, version \n",
+ "query": "Illumio_Auditable_Events_CL\n| union IllumioSyslogAuditEvents \n| where event_type has 'agent.suspend'\n| extend ipaddress = action.src_ip,\n hostname = created_by.agent.hostname\n| project-away resource_changes, action, version \n",
"queryFrequency": "PT60M",
"queryPeriod": "PT60M",
"severity": "High",
@@ -1393,10 +1538,16 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "IllumioSaaSDataConnector",
"dataTypes": [
"Illumio_Auditable_Events_CL"
- ],
- "connectorId": "IllumioSaaSDataConnector"
+ ]
+ },
+ {
+ "connectorId": "SyslogAma",
+ "datatypes": [
+ "Syslog"
+ ]
}
],
"tactics": [
@@ -1407,30 +1558,30 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
"columnName": "hostname",
"identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
"columnName": "ipaddress",
"identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "Illumio VEN Suspended Incident for {{hostname}} generated at {{TimeGenerated}}\n",
- "alertDisplayNameFormat": "Illumio VEN Suspended Incident for {{hostname}}\n"
+ "alertDisplayNameFormat": "Illumio VEN Suspended Incident for {{hostname}}\n",
+ "alertDescriptionFormat": "Illumio VEN Suspended Incident for {{hostname}} generated at {{TimeGenerated}}\n"
}
}
},
@@ -1484,7 +1635,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IllumioSaaS_FunctionAppConnector Playbook with template version 3.3.0",
+ "description": "IllumioSaaS_FunctionAppConnector Playbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion1')]",
@@ -1723,7 +1874,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio-Ven-Details Playbook with template version 3.3.0",
+ "description": "Illumio-Ven-Details Playbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion2')]",
@@ -1789,7 +1940,8 @@
"location": "[[variables('workspace-location-inline')]",
"name": "[[parameters('PlaybookName')]",
"dependsOn": [
- "[[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]"
+ "[[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "[[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]"
],
"properties": {
"state": "Enabled",
@@ -2167,7 +2319,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio-Port-Blocking-Switch Playbook with template version 3.3.0",
+ "description": "Illumio-Port-Blocking-Switch Playbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion3')]",
@@ -2192,16 +2344,50 @@
"storageAccountName": "[[parameters('FunctionAppName')]",
"functionAppName": "[[parameters('FunctionAppName')]",
"applicationInsightsName": "[[parameters('FunctionAppName')]",
+ "o365ConnectionName": "[[concat('o365-', parameters('PlaybookName'))]",
+ "sentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
+ "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]",
+ "_connection-1": "[[variables('connection-1')]",
+ "connection-2": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "_connection-2": "[[variables('connection-2')]",
"workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
"workspace-name": "[parameters('workspace')]",
"workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
},
"resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('o365ConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "properties": {
+ "displayName": "[[variables('o365ConnectionName')]",
+ "api": {
+ "id": "[[variables('_connection-1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('sentinelConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "properties": {
+ "displayName": "[[variables('sentinelConnectionName')]",
+ "api": {
+ "id": "[[variables('_connection-2')]"
+ }
+ }
+ },
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[[parameters('PlaybookName')]",
"location": "[[variables('workspace-location-inline')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "[[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]"
+ ],
"properties": {
"state": "Enabled",
"definition": {
@@ -2327,6 +2513,22 @@
}
}
}
+ },
+ "parameters": {
+ "$connections": {
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]",
+ "connectionName": "[[variables('sentinelConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]"
+ },
+ "office365": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "connectionName": "[[variables('o365ConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]"
+ }
+ }
+ }
}
},
"tags": {
@@ -2414,7 +2616,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Illumio-Quarantine-Workload Playbook with template version 3.3.0",
+ "description": "Illumio-Quarantine-Workload Playbook with template version 3.4.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion4')]",
@@ -2436,15 +2638,49 @@
},
"variables": {
"functionAppName": "[[parameters('FunctionAppName')]",
+ "o365ConnectionName": "[[concat('o365-', parameters('PlaybookName'))]",
+ "sentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
+ "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]",
+ "_connection-1": "[[variables('connection-1')]",
+ "connection-2": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "_connection-2": "[[variables('connection-2')]",
"workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
"workspace-name": "[parameters('workspace')]",
"workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
},
"resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('o365ConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "properties": {
+ "displayName": "[[variables('o365ConnectionName')]",
+ "api": {
+ "id": "[[variables('_connection-1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('sentinelConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "properties": {
+ "displayName": "[[variables('sentinelConnectionName')]",
+ "api": {
+ "id": "[[variables('_connection-2')]"
+ }
+ }
+ },
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[[parameters('PlaybookName')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "[[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]"
+ ],
"location": "[[variables('workspace-location-inline')]",
"properties": {
"state": "Enabled",
@@ -2493,6 +2729,22 @@
}
}
}
+ },
+ "parameters": {
+ "$connections": {
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]",
+ "connectionName": "[[variables('sentinelConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]"
+ },
+ "office365": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "connectionName": "[[variables('o365ConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]"
+ }
+ }
+ }
}
},
"tags": {
@@ -2571,17 +2823,277 @@
"version": "[variables('playbookVersion4')]"
}
},
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserObject1').parserTemplateSpecName1]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IllumioSyslogAuditEvents Data Parser with template version 3.4.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('parserObject1').parserVersion1]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[variables('parserObject1')._parserName1]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for Illumio Syslog Audit Events",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "IllumioSyslogAuditEvents",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/agent'\n| extend JsonPayload = extract(@\"\\{.*\\}\", 0, SyslogMessage)\n| where isnotempty(JsonPayload)\n| extend ParsedJson = parse_json(JsonPayload)\n| project \n TimeGenerated = todatetime(ParsedJson.timestamp),\n href = tostring(ParsedJson.href),\n pce_fqdn = tostring(ParsedJson.pce_fqdn),\n created_by = todynamic(ParsedJson.created_by),\n event_type = tostring(ParsedJson.event_type),\n status = tostring(ParsedJson.status),\n severity = tostring(ParsedJson.severity),\n action = todynamic(ParsedJson.action),\n resource_changes = todynamic(ParsedJson.resource_changes),\n notifications = todynamic(ParsedJson.notifications),\n version = toint(ParsedJson.version),\n Type = 'Illumio Syslog Audit Events'\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'IllumioSyslogAuditEvents')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
+ "source": {
+ "name": "IllumioSaaS",
+ "kind": "Solution",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "app-integrations@illumio.com"
+ },
+ "support": {
+ "name": "Illumio",
+ "email": "app-integrations@illumio.com",
+ "tier": "Partner",
+ "link": "https://www.illumio.com/support/support"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "contentKind": "Parser",
+ "displayName": "Parser for Illumio Syslog Audit Events",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]",
+ "version": "[variables('parserObject1').parserVersion1]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('parserObject1')._parserName1]",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for Illumio Syslog Audit Events",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "IllumioSyslogAuditEvents",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/agent'\n| extend JsonPayload = extract(@\"\\{.*\\}\", 0, SyslogMessage)\n| where isnotempty(JsonPayload)\n| extend ParsedJson = parse_json(JsonPayload)\n| project \n TimeGenerated = todatetime(ParsedJson.timestamp),\n href = tostring(ParsedJson.href),\n pce_fqdn = tostring(ParsedJson.pce_fqdn),\n created_by = todynamic(ParsedJson.created_by),\n event_type = tostring(ParsedJson.event_type),\n status = tostring(ParsedJson.status),\n severity = tostring(ParsedJson.severity),\n action = todynamic(ParsedJson.action),\n resource_changes = todynamic(ParsedJson.resource_changes),\n notifications = todynamic(ParsedJson.notifications),\n version = toint(ParsedJson.version),\n Type = 'Illumio Syslog Audit Events'\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'IllumioSyslogAuditEvents')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
+ "source": {
+ "kind": "Solution",
+ "name": "IllumioSaaS",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "app-integrations@illumio.com"
+ },
+ "support": {
+ "name": "Illumio",
+ "email": "app-integrations@illumio.com",
+ "tier": "Partner",
+ "link": "https://www.illumio.com/support/support"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserObject2').parserTemplateSpecName2]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "IllumioSyslogNetworkTrafficEvents Data Parser with template version 3.4.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('parserObject2').parserVersion2]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[variables('parserObject2')._parserName2]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for Illumio Syslog Network Traffic Events",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "IllumioSyslogNetworkTrafficEvents",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/collector'\n| extend JsonPayload = extract(@\"\\{.*\\}\", 0, SyslogMessage)\n| where isnotempty(JsonPayload)\n| extend ParsedJson = parse_json(JsonPayload)\n| project\n TimeGenerated = todatetime(ParsedJson.timestamp),\n tdms = toint(ParsedJson.tdms),\n ddms = toint(ParsedJson.ddms),\n pn = tostring(ParsedJson.pn),\n un = tostring(ParsedJson.un),\n src_ip = tostring(ParsedJson.src_ip),\n dst_ip = tostring(ParsedJson.dst_ip),\n class = tostring(ParsedJson.class),\n proto = toint(ParsedJson.proto),\n dst_port = toint(ParsedJson.dst_port),\n flow_count = toint(ParsedJson['count']),\n dir = tostring(ParsedJson.dir), \n dst_hostname = tostring(ParsedJson.dst_hostname),\n network = tostring(ParsedJson.network),\n org_id = toint(ParsedJson.org_id),\n state = tostring(ParsedJson.state),\n pd_qualifier = toint(ParsedJson.pd_qualifier),\n pd = toint(ParsedJson.pd),\n src_hostname = tostring(ParsedJson.src_hostname), \n src_href = tostring(ParsedJson.src_href),\n dst_href = tostring(ParsedJson.dst_href),\n src_labels = todynamic(ParsedJson.src_labels),\n dst_labels = todynamic(ParsedJson.dst_labels),\n interval_sec = toint(ParsedJson.interval_sec),\n pce_fqdn = tostring(ParsedJson.pce_fqdn),\n version = toint(ParsedJson.version),\n Type = 'Illumio Syslog Network Traffic Events'\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject2')._parserId2,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject2')._parserId2]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'IllumioSyslogNetworkTrafficEvents')]",
+ "contentId": "[variables('parserObject2').parserContentId2]",
+ "kind": "Parser",
+ "version": "[variables('parserObject2').parserVersion2]",
+ "source": {
+ "name": "IllumioSaaS",
+ "kind": "Solution",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "app-integrations@illumio.com"
+ },
+ "support": {
+ "name": "Illumio",
+ "email": "app-integrations@illumio.com",
+ "tier": "Partner",
+ "link": "https://www.illumio.com/support/support"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('parserObject2').parserContentId2]",
+ "contentKind": "Parser",
+ "displayName": "Parser for Illumio Syslog Network Traffic Events",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject2').parserContentId2,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject2').parserContentId2,'-', '1.0.0')))]",
+ "version": "[variables('parserObject2').parserVersion2]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('parserObject2')._parserName2]",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for Illumio Syslog Network Traffic Events",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "IllumioSyslogNetworkTrafficEvents",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/collector'\n| extend JsonPayload = extract(@\"\\{.*\\}\", 0, SyslogMessage)\n| where isnotempty(JsonPayload)\n| extend ParsedJson = parse_json(JsonPayload)\n| project\n TimeGenerated = todatetime(ParsedJson.timestamp),\n tdms = toint(ParsedJson.tdms),\n ddms = toint(ParsedJson.ddms),\n pn = tostring(ParsedJson.pn),\n un = tostring(ParsedJson.un),\n src_ip = tostring(ParsedJson.src_ip),\n dst_ip = tostring(ParsedJson.dst_ip),\n class = tostring(ParsedJson.class),\n proto = toint(ParsedJson.proto),\n dst_port = toint(ParsedJson.dst_port),\n flow_count = toint(ParsedJson['count']),\n dir = tostring(ParsedJson.dir), \n dst_hostname = tostring(ParsedJson.dst_hostname),\n network = tostring(ParsedJson.network),\n org_id = toint(ParsedJson.org_id),\n state = tostring(ParsedJson.state),\n pd_qualifier = toint(ParsedJson.pd_qualifier),\n pd = toint(ParsedJson.pd),\n src_hostname = tostring(ParsedJson.src_hostname), \n src_href = tostring(ParsedJson.src_href),\n dst_href = tostring(ParsedJson.dst_href),\n src_labels = todynamic(ParsedJson.src_labels),\n dst_labels = todynamic(ParsedJson.dst_labels),\n interval_sec = toint(ParsedJson.interval_sec),\n pce_fqdn = tostring(ParsedJson.pce_fqdn),\n version = toint(ParsedJson.version),\n Type = 'Illumio Syslog Network Traffic Events'\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject2')._parserId2,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject2')._parserId2]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'IllumioSyslogNetworkTrafficEvents')]",
+ "contentId": "[variables('parserObject2').parserContentId2]",
+ "kind": "Parser",
+ "version": "[variables('parserObject2').parserVersion2]",
+ "source": {
+ "kind": "Solution",
+ "name": "IllumioSaaS",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "app-integrations@illumio.com"
+ },
+ "support": {
+ "name": "Illumio",
+ "email": "app-integrations@illumio.com",
+ "tier": "Partner",
+ "link": "https://www.illumio.com/support/support"
+ }
+ }
+ },
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.3.0",
+ "version": "3.4.0",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "IllumioSaaS",
"publisherDisplayName": "Illumio",
- "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nIllumioSaaS solution provides ability to ingest auditable and flow events from AWS S3 bucket.
\nData Connectors: 1, Workbooks: 3, Analytic Rules: 6, Function Apps: 1, Playbooks: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nIllumioSaaS solution provides ability to ingest auditable and flow events from AWS S3 bucket.
\nData Connectors: 1, Parsers: 2, Workbooks: 4, Analytic Rules: 6, Function Apps: 1, Playbooks: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
"id": "[variables('_solutioncontentProductId')]",
@@ -2625,6 +3137,11 @@
"contentId": "[variables('_workbookContentId3')]",
"version": "[variables('workbookVersion3')]"
},
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId4')]",
+ "version": "[variables('workbookVersion4')]"
+ },
{
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
@@ -2674,6 +3191,16 @@
"kind": "Playbook",
"contentId": "[variables('_Illumio-Quarantine-Workload')]",
"version": "[variables('playbookVersion4')]"
+ },
+ {
+ "kind": "Parser",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "version": "[variables('parserObject1').parserVersion1]"
+ },
+ {
+ "kind": "Parser",
+ "contentId": "[variables('parserObject2').parserContentId2]",
+ "version": "[variables('parserObject2').parserVersion2]"
}
]
},
diff --git a/Solutions/IllumioSaaS/Package/testParameters.json b/Solutions/IllumioSaaS/Package/testParameters.json
index 47149fc5efb..5dfce5d6192 100644
--- a/Solutions/IllumioSaaS/Package/testParameters.json
+++ b/Solutions/IllumioSaaS/Package/testParameters.json
@@ -44,5 +44,13 @@
"metadata": {
"description": "Name for the workbook"
}
+ },
+ "workbook4-name": {
+ "type": "string",
+ "defaultValue": "Illumio OnPrem Health Workbook",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
}
}
diff --git a/Solutions/IllumioSaaS/Parsers/IllumioSyslogAuditEvents.yaml b/Solutions/IllumioSaaS/Parsers/IllumioSyslogAuditEvents.yaml
new file mode 100644
index 00000000000..b9d3ea99eb6
--- /dev/null
+++ b/Solutions/IllumioSaaS/Parsers/IllumioSyslogAuditEvents.yaml
@@ -0,0 +1,27 @@
+id: b455e6af-bf95-4712-bd4c-d40090e82105
+Function:
+ Title: Parser for Illumio Syslog Audit Events
+ Version: '1.0.0'
+ LastUpdated: '2025-01-20'
+Category: Microsoft Sentinel Parser
+FunctionName: IllumioSyslogAuditEvents
+FunctionAlias: IllumioSyslogAuditEvents
+FunctionQuery: |
+ Syslog
+ | where SyslogMessage has 'illumio_pce/agent'
+ | extend JsonPayload = extract(@"\{.*\}", 0, SyslogMessage)
+ | where isnotempty(JsonPayload)
+ | extend ParsedJson = parse_json(JsonPayload)
+ | project
+ TimeGenerated = todatetime(ParsedJson.timestamp),
+ href = tostring(ParsedJson.href),
+ pce_fqdn = tostring(ParsedJson.pce_fqdn),
+ created_by = todynamic(ParsedJson.created_by),
+ event_type = tostring(ParsedJson.event_type),
+ status = tostring(ParsedJson.status),
+ severity = tostring(ParsedJson.severity),
+ action = todynamic(ParsedJson.action),
+ resource_changes = todynamic(ParsedJson.resource_changes),
+ notifications = todynamic(ParsedJson.notifications),
+ version = toint(ParsedJson.version),
+ Type = 'Illumio Syslog Audit Events'
diff --git a/Solutions/IllumioSaaS/Parsers/IllumioSyslogNetworkTrafficEvents.yaml b/Solutions/IllumioSaaS/Parsers/IllumioSyslogNetworkTrafficEvents.yaml
new file mode 100644
index 00000000000..73e6da03eec
--- /dev/null
+++ b/Solutions/IllumioSaaS/Parsers/IllumioSyslogNetworkTrafficEvents.yaml
@@ -0,0 +1,42 @@
+id: a1569c0d-0826-4f87-b139-0853203f6b9c
+Function:
+ Title: Parser for Illumio Syslog Network Traffic Events
+ Version: '1.0.0'
+ LastUpdated: '2025-01-20'
+Category: Microsoft Sentinel Parser
+FunctionName: IllumioSyslogNetworkTrafficEvents
+FunctionAlias: IllumioSyslogNetworkTrafficEvents
+FunctionQuery: |
+ Syslog
+ | where SyslogMessage has 'illumio_pce/collector'
+ | extend JsonPayload = extract(@"\{.*\}", 0, SyslogMessage)
+ | where isnotempty(JsonPayload)
+ | extend ParsedJson = parse_json(JsonPayload)
+ | project
+ TimeGenerated = todatetime(ParsedJson.timestamp),
+ tdms = toint(ParsedJson.tdms),
+ ddms = toint(ParsedJson.ddms),
+ pn = tostring(ParsedJson.pn),
+ un = tostring(ParsedJson.un),
+ src_ip = tostring(ParsedJson.src_ip),
+ dst_ip = tostring(ParsedJson.dst_ip),
+ class = tostring(ParsedJson.class),
+ proto = toint(ParsedJson.proto),
+ dst_port = toint(ParsedJson.dst_port),
+ flow_count = toint(ParsedJson['count']),
+ dir = tostring(ParsedJson.dir),
+ dst_hostname = tostring(ParsedJson.dst_hostname),
+ network = tostring(ParsedJson.network),
+ org_id = toint(ParsedJson.org_id),
+ state = tostring(ParsedJson.state),
+ pd_qualifier = toint(ParsedJson.pd_qualifier),
+ pd = toint(ParsedJson.pd),
+ src_hostname = tostring(ParsedJson.src_hostname),
+ src_href = tostring(ParsedJson.src_href),
+ dst_href = tostring(ParsedJson.dst_href),
+ src_labels = todynamic(ParsedJson.src_labels),
+ dst_labels = todynamic(ParsedJson.dst_labels),
+ interval_sec = toint(ParsedJson.interval_sec),
+ pce_fqdn = tostring(ParsedJson.pce_fqdn),
+ version = toint(ParsedJson.version),
+ Type = 'Illumio Syslog Network Traffic Events'
diff --git a/Solutions/IllumioSaaS/Playbooks/Illumio-Get-Ven-Details/azuredeploy.json b/Solutions/IllumioSaaS/Playbooks/Illumio-Get-Ven-Details/azuredeploy.json
index a07ddfc2d56..cc463d57811 100644
--- a/Solutions/IllumioSaaS/Playbooks/Illumio-Get-Ven-Details/azuredeploy.json
+++ b/Solutions/IllumioSaaS/Playbooks/Illumio-Get-Ven-Details/azuredeploy.json
@@ -88,7 +88,8 @@
"location": "[resourceGroup().location]",
"name": "[parameters('PlaybookName')]",
"dependsOn": [
- "[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]"
+ "[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]"
],
"properties": {
"state": "Enabled",
diff --git a/Solutions/IllumioSaaS/Playbooks/Illumio-Port-Blocking-Switch/azuredeploy.json b/Solutions/IllumioSaaS/Playbooks/Illumio-Port-Blocking-Switch/azuredeploy.json
index dd3e255161e..c92c9b9d0ba 100644
--- a/Solutions/IllumioSaaS/Playbooks/Illumio-Port-Blocking-Switch/azuredeploy.json
+++ b/Solutions/IllumioSaaS/Playbooks/Illumio-Port-Blocking-Switch/azuredeploy.json
@@ -50,14 +50,47 @@
"hostingPlanName": "[parameters('FunctionAppName')]",
"storageAccountName": "[parameters('FunctionAppName')]",
"functionAppName": "[parameters('FunctionAppName')]",
- "applicationInsightsName": "[parameters('FunctionAppName')]"
+ "applicationInsightsName": "[parameters('FunctionAppName')]",
+ "o365ConnectionName": "[concat('o365-', parameters('PlaybookName'))]",
+ "sentinelConnectionName": "[concat('azuresentinel-', parameters('PlaybookName'))]"
+
},
"resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[variables('o365ConnectionName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "displayName": "[variables('o365ConnectionName')]",
+ "customParameterValues": {},
+ "api": {
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[variables('sentinelConnectionName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "displayName": "[variables('sentinelConnectionName')]",
+ "customParameterValues": {},
+ "api": {
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
+ }
+ }
+ },
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]"
+ ],
"properties": {
"state": "Enabled",
"definition": {
@@ -189,7 +222,18 @@
},
"parameters": {
"$connections": {
- "value": {}
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]",
+ "connectionName": "[variables('sentinelConnectionName')]",
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
+ },
+ "office365": {
+ "connectionId": "[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "connectionName": "[variables('o365ConnectionName')]",
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]"
+ }
+ }
}
}
}
diff --git a/Solutions/IllumioSaaS/Playbooks/Illumio-Quarantine-Workload/azuredeploy.json b/Solutions/IllumioSaaS/Playbooks/Illumio-Quarantine-Workload/azuredeploy.json
index 291c961400c..f40f1a921e9 100644
--- a/Solutions/IllumioSaaS/Playbooks/Illumio-Quarantine-Workload/azuredeploy.json
+++ b/Solutions/IllumioSaaS/Playbooks/Illumio-Quarantine-Workload/azuredeploy.json
@@ -37,7 +37,7 @@
"metadata": {
"description": "PlayBook Name"
}
- },
+ },
"FunctionAppName": {
"defaultValue": "illumiopbfuncapp",
"type": "String",
@@ -47,13 +47,45 @@
}
},
"variables": {
- "functionAppName": "[parameters('FunctionAppName')]"
+ "functionAppName": "[parameters('FunctionAppName')]",
+ "o365ConnectionName": "[concat('o365-', parameters('PlaybookName'))]",
+ "sentinelConnectionName": "[concat('azuresentinel-', parameters('PlaybookName'))]"
},
"resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[variables('o365ConnectionName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "displayName": "[variables('o365ConnectionName')]",
+ "customParameterValues": {},
+ "api": {
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[variables('sentinelConnectionName')]",
+ "location": "[resourceGroup().location]",
+ "properties": {
+ "displayName": "[variables('sentinelConnectionName')]",
+ "customParameterValues": {},
+ "api": {
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
+ }
+ }
+ },
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[parameters('PlaybookName')]",
+ "dependsOn": [
+ "[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]"
+ ],
"location": "[resourceGroup().location]",
"properties": {
"state": "Enabled",
@@ -108,7 +140,18 @@
},
"parameters": {
"$connections": {
- "value": {}
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[resourceId('Microsoft.Web/connections', variables('sentinelConnectionName'))]",
+ "connectionName": "[variables('sentinelConnectionName')]",
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
+ },
+ "office365": {
+ "connectionId": "[resourceId('Microsoft.Web/connections', variables('o365ConnectionName'))]",
+ "connectionName": "[variables('o365ConnectionName')]",
+ "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]"
+ }
+ }
}
}
}
diff --git a/Solutions/IllumioSaaS/ReleaseNotes.md b/Solutions/IllumioSaaS/ReleaseNotes.md
index 3057a7f27db..e05a5ff1215 100644
--- a/Solutions/IllumioSaaS/ReleaseNotes.md
+++ b/Solutions/IllumioSaaS/ReleaseNotes.md
@@ -1,7 +1,10 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------------------|
-| 3.2.0 | 01-10-2024 | Added new **Analytic Rules** |
-| 3.1.0 | 04-08-2024 | Solution packaged with Modified logo link |
-| 3.0.0 | 13-05-2024 | Initial Solution Release |
+| 3.4.0 | 03-02-2025 | Added 2 new **Parser**.
Added new connectorid SyslogAma to **Analytic Rules**.
Resolved **Playbook** deployment error.
Made minor visualization changes to **Workbooks**. |
+| 3.3.0 | 12-12-2024 | Version fixed 3.2.3 to 3.3.0. |
+| 3.2.2 | 24-10-2024 | Bump up package to 3.2.2 version. |
+| 3.2.0 | 01-10-2024 | Added new **Analytic Rules**. |
+| 3.1.0 | 04-08-2024 | Solution packaged with Modified logo link. |
+| 3.0.0 | 13-05-2024 | Initial Solution Release. |
diff --git a/Solutions/IllumioSaaS/Workbooks/IllumioAuditableEvents.json b/Solutions/IllumioSaaS/Workbooks/IllumioAuditableEvents.json
index a5d7d23f639..39dd0abec84 100644
--- a/Solutions/IllumioSaaS/Workbooks/IllumioAuditableEvents.json
+++ b/Solutions/IllumioSaaS/Workbooks/IllumioAuditableEvents.json
@@ -37,6 +37,42 @@
"value": {
"durationMs": 86400000
}
+ },
+ {
+ "id": "264cba08-bf9e-44d6-9473-5f03e9aa9375",
+ "version": "KqlParameterItem/1.0",
+ "name": "Illumio_PCE",
+ "label": "Illumio PCE",
+ "type": 2,
+ "description": "Select the Illumio PCE from which you want to see events for",
+ "isRequired": true,
+ "isGlobal": true,
+ "query": "Illumio_Auditable_Events_CL\n| project pce_fqdn , table = \"Illumio_Auditable_Events_CL\"\n| union ( IllumioSyslogAuditEvents \n | project pce_fqdn , table = \"IllumioSyslogAuditEvents\"\n )\n| union (\n print pce_fqdn = 'No PCE', table = 'Illumio_Auditable_Events_CL'\n)\n| distinct table, pce_fqdn ",
+ "typeSettings": {
+ "additionalResourceOptions": [],
+ "showDefault": false
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "value": "IllumioSyslogAuditEvents"
+ },
+ {
+ "id": "1b35142b-4e83-4645-83d3-29edd556ee3d",
+ "version": "KqlParameterItem/1.0",
+ "name": "TableToSearchFrom",
+ "type": 1,
+ "description": "use Illumio_PCE to define what table to fetch events from",
+ "isGlobal": true,
+ "isHiddenWhenLocked": true,
+ "criteriaData": [
+ {
+ "criteriaContext": {
+ "operator": "Default",
+ "resultValType": "static",
+ "resultVal": "{Illumio_PCE:value}"
+ }
+ }
+ ]
}
],
"style": "above",
@@ -55,7 +91,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| summarize count()",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize dcount(href)",
"size": 4,
"title": "Audit Events",
"noDataMessage": "0",
@@ -77,7 +113,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "table('Illumio_Auditable_Events_CL')\n| where event_type has 'tampering'\n| summarize count()",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where event_type has 'tampering'\n| summarize dcount(href)\n",
"size": 4,
"title": "Tampering Events",
"timeContextFromParameter": "Time",
@@ -96,27 +132,6 @@
"styleSettings": {
"maxWidth": "30"
}
- },
- {
- "type": 3,
- "content": {
- "version": "KqlItem/1.0",
- "query": "table('Illumio_Auditable_Events_CL')\n| where event_type has 'port_scan'\n| summarize count()",
- "size": 4,
- "title": "Port Scan Events",
- "timeContextFromParameter": "Time",
- "queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "visualization": "card",
- "textSettings": {
- "style": "bignumber"
- }
- },
- "customWidth": "30",
- "name": "Port Scan Events",
- "styleSettings": {
- "maxWidth": "30"
- }
}
]
},
@@ -126,7 +141,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| summarize distinct_count = dcount(href) by event_type\n| order by distinct_count \n| top 10 by distinct_count",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| summarize distinct_count = dcount(href) by event_type\n| order by distinct_count \n| top 10 by distinct_count",
"size": 0,
"title": "Top Auditable events",
"timeContextFromParameter": "Time",
@@ -147,7 +162,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| summarize arg_max(TimeGenerated, *) by href\n| where event_type == 'sec_policy.create' \n| mv-expand resource_change = resource_changes\n| project TimeGenerated,\n workloads_affected_after_change = resource_change.changes.workloads_affected.after,\n policy_version = resource_change.resource.sec_policy.version,\n commit_message = resource_change.resource.sec_policy.commit_message,\n modified_objects = resource_change.resource.sec_policy.modified_objects,\n change_type = resource_change.change_type\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| summarize arg_max(TimeGenerated, *) by href\n| where event_type == 'sec_policy.create' \n| mv-expand resource_change = resource_changes\n| project TimeGenerated,\n workloads_affected_after_change = resource_change.changes.workloads_affected.after,\n policy_version = resource_change.resource.sec_policy.version,\n commit_message = resource_change.resource.sec_policy.commit_message,\n modified_objects = resource_change.resource.sec_policy.modified_objects,\n change_type = resource_change.change_type\n",
"size": 0,
"title": "Workloads affected by policy changes",
"noDataMessage": "No workloads were affected by policy changes",
@@ -175,7 +190,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| where resource_changes != '[]' and isnotempty(resource_changes) // ensure resource changes are not empty\n| summarize arg_max(TimeGenerated, *) by href\n| mv-expand parse_json(resource_changes)\n| project resource_type = tostring(bag_keys(resource_changes.resource)[0])\n| summarize Count=count() by resource_type",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| where resource_changes != '[]' and isnotempty(resource_changes) // ensure resource changes are not empty\n| summarize arg_max(TimeGenerated, *) by href\n| mv-expand parse_json(resource_changes)\n| project resource_type = tostring(bag_keys(resource_changes.resource)[0])\n| summarize Count=count() by resource_type",
"size": 0,
"title": "Changes by Resource Type",
"noDataMessage": "No changes by resource type",
@@ -207,7 +222,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| where resource_changes != '[]' and isnotempty(resource_changes) and not(event_type matches regex '^user.*') and (event_type has '.create' or event_type has '.update' or event_type has '.delete') and (created_by !has \"agent\" and created_by !has \"ven\" and created_by !has \"container\")\n| extend User = tostring(parse_json(created_by)['user']['username'])\n| summarize Count = count() by User",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| where resource_changes != '[]' and isnotempty(resource_changes) and not(event_type matches regex '^user.*') and (event_type has '.create' or event_type has '.update' or event_type has '.delete') and (created_by !has \"agent\" and created_by !has \"ven\" and created_by !has \"container\")\n| extend User = tostring(parse_json(created_by)['user']['username'])\n| summarize Count = count() by User",
"size": 0,
"title": "Changes by User",
"timeContextFromParameter": "Time",
@@ -224,7 +239,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| where created_by has \"agent\" or created_by has \"ven\"\n| project user = tostring(parse_json(created_by)['agent']['hostname'])\n| summarize count() by user",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| where created_by has \"agent\" or created_by has \"ven\"\n| project user = tostring(parse_json(created_by)['agent']['hostname'])\n| summarize count() by user",
"size": 0,
"title": "Events generated by agents",
"noDataMessage": "Agents have not generated any events",
@@ -248,7 +263,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Auditable_Events_CL\n| summarize arg_max(TimeGenerated, *) by href // try to filter what event_type to prioritize in bar chart\n| make-series events = count() default = 0 on TimeGenerated from {Time:start} to {Time:end} step 1h by event_type //from ago(1d) to now() step 1h by event_type ",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| summarize arg_max(TimeGenerated, *) by href // try to filter what event_type to prioritize in bar chart\n| make-series events = count() default = 0 on TimeGenerated from {Time:start} to {Time:end} step 1h by event_type //from ago(1d) to now() step 1h by event_type ",
"size": 0,
"title": "PCE events breakdown - every hour",
"timeContextFromParameter": "Time",
@@ -319,7 +334,6 @@
"quote": "'",
"delimiter": ",",
"typeSettings": {
- "additionalResourceOptions": [],
"showDefault": false
},
"jsonData": "[\n { \"value\":\"user.logout\", \"label\":\"User logout\" },\n { \"value\":\"user.sign_in\", \"label\":\"User signin\" },\n { \"value\":\"user.sign_out\", \"label\":\"User signout\" },\n { \"value\":\"user.login\", \"label\":\"User login\"},\n { \"value\":\"user.pce_session_terminated\", \"label\":\"User session terminated\"},\n { \"value\":\"request.authentication_failed\", \"label\":\"Authentication failed\"},\n { \"value\":\"user.authenticate\", \"label\":\"User Authentication\"},\n { \"value\":\"user.create_session\", \"label\":\"User create session\"},\n { \"value\":\"None\", \"label\":\"None\", \"selected\": true}\n]",
@@ -393,7 +407,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "let included_event_types = iif(\"*\" in ({EventType}), dynamic(['user.login','user.logout', 'user.sign_in', 'user.sign_out', 'user.authenticate','user.create_session','user.pce_session_terminated']), dynamic([{EventType}]) );\nIllumio_Auditable_Events_CL\n| where event_type in (included_event_types)\n| where \"*\" in ({Status}) or status in ({Status}) and \"*\" in ({Severity}) or severity in ({Severity})\n| where not(event_type in ({ExcludeEventType}))\n| project TimeGenerated, pce_fqdn, event_type, status, notification_type = parse_json(notifications)[0].notification_type,severity, created_by_username = iif(created_by == '{\"system\":{}}', parse_json(notifications)[0].info.user.username, parse_json(created_by).user.username)",
+ "query": "let included_event_types = iif(\"*\" in ({EventType}), dynamic(['user.login','user.logout', 'user.sign_in', 'user.sign_out', 'user.authenticate','user.create_session','user.pce_session_terminated']), dynamic([{EventType}]) );\nlet table_to_search_from = '{TableToSearchFrom}';\n\ntable(table_to_search_from)\n| where event_type in (included_event_types)\n| where \"*\" in ({Status}) or status in ({Status}) and \"*\" in ({Severity}) or severity in ({Severity})\n| where not(event_type in ({ExcludeEventType}))\n| project TimeGenerated, pce_fqdn, event_type, status, notification_type = parse_json(notifications)[0].notification_type,severity, created_by_username = iif(created_by == '{\"system\":{}}', parse_json(notifications)[0].info.user.username, parse_json(created_by).user.username)",
"size": 0,
"title": "PCE Authentication Events",
"timeContextFromParameter": "Time",
diff --git a/Solutions/IllumioSaaS/Workbooks/IllumioFlowData.json b/Solutions/IllumioSaaS/Workbooks/IllumioFlowData.json
index 129c4a9a33d..3063136eeda 100644
--- a/Solutions/IllumioSaaS/Workbooks/IllumioFlowData.json
+++ b/Solutions/IllumioSaaS/Workbooks/IllumioFlowData.json
@@ -46,6 +46,76 @@
"value": {
"durationMs": 86400000
}
+ },
+ {
+ "id": "ced5d7b4-3302-4479-bee9-563947af3a5d",
+ "version": "KqlParameterItem/1.0",
+ "name": "Illumio_PCE",
+ "label": "Illumio PCE",
+ "type": 2,
+ "description": "Select the Illumio PCE from which you want to see events for",
+ "isRequired": true,
+ "isGlobal": true,
+ "query": "Illumio_Flow_Events_CL\n| project pce_fqdn, table = \"Illumio_Flow_Events_CL\"\n| union (\n IllumioSyslogAuditEvents\n | project pce_fqdn, table = \"IllumioSyslogAuditEvents\"\n)\n| union (\n print pce_fqdn = 'No PCE', table = 'Illumio_Flow_Events_CL'\n)\n| distinct table, pce_fqdn",
+ "typeSettings": {
+ "additionalResourceOptions": [],
+ "showDefault": false
+ },
+ "timeContext": {
+ "durationMs": 604800000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "value": "Illumio_Flow_Events_CL"
+ },
+ {
+ "id": "01dea62f-0a96-4799-ad15-4410632e9665",
+ "version": "KqlParameterItem/1.0",
+ "name": "TableToSearchFrom",
+ "type": 1,
+ "description": "use Illumio_PCE to define what table to fetch events from",
+ "isGlobal": true,
+ "isHiddenWhenLocked": true,
+ "criteriaData": [
+ {
+ "criteriaContext": {
+ "operator": "Default",
+ "resultValType": "static",
+ "resultVal": "{Illumio_PCE:value}"
+ }
+ }
+ ]
+ },
+ {
+ "id": "eb392fcd-b6ea-4c7f-86d6-fc4053e65632",
+ "version": "KqlParameterItem/1.0",
+ "name": "port_scan_threshold",
+ "label": "Port Scan Threshold",
+ "type": 1,
+ "description": "A port scan event is accounted for when a traffic flow with unique (src, dst, network) is observed for any destination port",
+ "value": "2"
+ },
+ {
+ "id": "1c8b3527-5c77-4f1e-93d6-aeb1b39d8dd9",
+ "version": "KqlParameterItem/1.0",
+ "name": "allowed_ips",
+ "label": "Allowed IPs",
+ "type": 2,
+ "description": "Exclude source ips from port scan counts",
+ "multiSelect": true,
+ "quote": "",
+ "delimiter": ",",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize by src_ip",
+ "typeSettings": {
+ "showDefault": false
+ },
+ "timeContext": {
+ "durationMs": 1800000
+ },
+ "timeContextFromParameter": "time_range",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "value": null
}
],
"style": "above",
@@ -54,11 +124,37 @@
},
"name": "parameters - 7"
},
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "title": "Port Scan Events",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\nlet port_scan_threshold_param = toint(coalesce('{port_scan_threshold}', '2')); // 2 is a default\nlet allowed_ips_param = '{allowed_ips}';\n//print port_scan_threshold_param, table_to_search_from, allowed_ips_param\ntable(table_to_search_from)\n| where dir == 'I' and TimeGenerated between ({time_range:start}..{time_range:end})\n| summarize distinct_ports = dcount(dst_port) by src_ip, dst_ip, network, TimeGenerated\n| summarize ports_scanned = sum(distinct_ports) by bin(TimeGenerated, 60s)\n| where ports_scanned > port_scan_threshold_param\n| summarize count()\n\n",
+ "size": 3,
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "card",
+ "textSettings": {
+ "style": "bignumber"
+ }
+ },
+ "name": "query - 0"
+ }
+ ]
+ },
+ "name": "group - 4"
+ },
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Flow_Events_CL\n| summarize count() by bin(TimeGenerated, 1h)",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize count() by bin(TimeGenerated, 1h)",
"size": 0,
"title": "Traffic every hour",
"timeContextFromParameter": "time_range",
@@ -122,7 +218,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "let workload_count = {workload_count};\nIllumio_Flow_Events_CL\n| extend hostname = coalesce(src_hostname, dst_hostname)\n| summarize Count = count() by hostname, dir\n| summarize InboundCount = sum(iff(dir == \"I\", Count, 0)), OutboundCount = sum(iff(dir == \"O\", Count, 0)) by hostname\n| top workload_count by hostname\n",
+ "query": "let workload_count = {workload_count};\nlet table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| extend hostname = coalesce(src_hostname, dst_hostname)\n| summarize Count = count() by hostname, dir\n| summarize InboundCount = sum(iff(dir == \"I\", Count, 0)), OutboundCount = sum(iff(dir == \"O\", Count, 0)) by hostname\n| top workload_count by hostname\n",
"size": 0,
"title": "Most Trafficked Workloads",
"timeContextFromParameter": "time_range",
@@ -206,7 +302,7 @@
"multiSelect": true,
"quote": "'",
"delimiter": ",",
- "query": "Illumio_Flow_Events_CL\n| summarize by src_ip",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize by src_ip",
"typeSettings": {
"additionalResourceOptions": [
"value::all"
@@ -220,10 +316,7 @@
"timeContextFromParameter": "time_range",
"defaultValue": "value::all",
"queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "value": [
- "value::all"
- ]
+ "resourceType": "microsoft.operationalinsights/workspaces"
},
{
"id": "24f11ee0-0b0b-4c79-918b-01df57233aa2",
@@ -235,7 +328,7 @@
"multiSelect": true,
"quote": "'",
"delimiter": ",",
- "query": "Illumio_Flow_Events_CL\n| summarize by dst_ip",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize by dst_ip",
"typeSettings": {
"additionalResourceOptions": [
"value::all"
@@ -244,7 +337,7 @@
"showDefault": false
},
"timeContext": {
- "durationMs": 86400000
+ "durationMs": 0
},
"timeContextFromParameter": "time_range",
"defaultValue": "value::all",
@@ -261,12 +354,13 @@
"multiSelect": true,
"quote": "'",
"delimiter": ",",
- "query": "Illumio_Flow_Events_CL\n| summarize by dst_port",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize by dst_port",
"typeSettings": {
"additionalResourceOptions": [
"value::all"
],
- "selectAllValue": "*"
+ "selectAllValue": "*",
+ "showDefault": false
},
"timeContext": {
"durationMs": 0
@@ -274,10 +368,7 @@
"timeContextFromParameter": "time_range",
"defaultValue": "value::all",
"queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "value": [
- "value::all"
- ]
+ "resourceType": "microsoft.operationalinsights/workspaces"
},
{
"id": "416ab303-c10f-47c1-9f01-7c1324699b49",
@@ -289,7 +380,7 @@
"multiSelect": true,
"quote": "'",
"delimiter": ",",
- "query": "Illumio_Flow_Events_CL\n| summarize by proto\n| extend protocolName = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| summarize by proto\n| extend protocolName = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n",
"typeSettings": {
"additionalResourceOptions": [
"value::all"
@@ -298,15 +389,12 @@
"showDefault": false
},
"timeContext": {
- "durationMs": 0
+ "durationMs": 86400000
},
"timeContextFromParameter": "time_range",
"defaultValue": "value::all",
"queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "value": [
- "value::all"
- ]
+ "resourceType": "microsoft.operationalinsights/workspaces"
},
{
"id": "f07c08c2-ff0f-42a7-adc6-4fd5d7f1cb19",
@@ -318,7 +406,7 @@
"multiSelect": true,
"quote": "'",
"delimiter": ",",
- "query": "Illumio_Flow_Events_CL\n| where src_labels != ''\n| extend parsed_labels = parse_json(src_labels)\n| mv-expand kind=array parsed_labels\n| extend src_label=tostring(parsed_labels[1])\n| summarize by src_label",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where src_labels != ''\n| extend parsed_labels = parse_json(src_labels)\n| mv-expand kind=array parsed_labels\n| extend src_label=tostring(parsed_labels[1])\n| summarize by src_label",
"typeSettings": {
"additionalResourceOptions": [
"value::all"
@@ -327,15 +415,12 @@
"showDefault": false
},
"timeContext": {
- "durationMs": 0
+ "durationMs": 86400000
},
"timeContextFromParameter": "time_range",
"defaultValue": "value::all",
"queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "value": [
- "value::all"
- ]
+ "resourceType": "microsoft.operationalinsights/workspaces"
},
{
"id": "9d5cb77f-31a5-41ed-8849-aaee2b513f54",
@@ -347,7 +432,7 @@
"multiSelect": true,
"quote": "'",
"delimiter": ",",
- "query": "Illumio_Flow_Events_CL\n| where dst_labels != ''\n| extend parsed_labels = parse_json(dst_labels)\n| mv-expand kind=array parsed_labels\n| extend dst_label=tostring(parsed_labels[1])\n| summarize by dst_label",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where dst_labels != ''\n| extend parsed_labels = parse_json(dst_labels)\n| mv-expand kind=array parsed_labels\n| extend dst_label=tostring(parsed_labels[1])\n| summarize by dst_label",
"typeSettings": {
"additionalResourceOptions": [
"value::all"
@@ -356,15 +441,12 @@
"showDefault": false
},
"timeContext": {
- "durationMs": 0
+ "durationMs": 86400000
},
"timeContextFromParameter": "time_range",
"defaultValue": "value::all",
"queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "value": [
- "value::all"
- ]
+ "resourceType": "microsoft.operationalinsights/workspaces"
}
],
"style": "formHorizontal",
@@ -386,7 +468,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Flow_Events_CL\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol})) \n| extend policy_decision = \n case(pd == 0, \"Allowed\",\n pd == 1, \"Potentially Blocked\",\n pd == 2, \"Blocked\",\n \"Unknown\")\n| summarize count() by policy_decision\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol})) \n| extend policy_decision = \n case(pd == 0, \"Allowed\",\n pd == 1, \"Potentially Blocked\",\n pd == 2, \"Blocked\",\n \"Unknown\")\n| summarize count() by policy_decision\n",
"size": 2,
"title": "Flow count by policy decision",
"timeContextFromParameter": "time_range",
@@ -424,7 +506,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "\nIllumio_Flow_Events_CL\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend class_type = \n case(class == 'B', 'Broadcast',\n class == 'M', 'Multicast',\n class == 'U', \"Unicast\",\n \"Unknown\")\n| summarize count() by class_type\n",
+ "query": "\nlet table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend class_type = \n case(class == 'B', 'Broadcast',\n class == 'M', 'Multicast',\n class == 'U', \"Unicast\",\n \"Unknown\")\n| summarize count() by class_type\n",
"size": 2,
"title": "Flows by class",
"timeContextFromParameter": "time_range",
@@ -450,7 +532,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Flow_Events_CL\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocolName = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| extend service = strcat(dst_port, '/', protocolName)\n| summarize service_count = count() by service\n| top 5 by service_count\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where (src_ip in ({src_ip}) or '*' in ({src_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocolName = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| extend service = strcat(dst_port, '/', protocolName)\n| summarize service_count = count() by service\n| top 5 by service_count\n",
"size": 0,
"title": "Top 5 Services by Flow Count",
"color": "blue",
@@ -478,7 +560,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Flow_Events_CL\n| where pd == 2 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocol = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\n\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where pd == 2 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocol = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\n\n",
"size": 0,
"title": "Blocked Traffic",
"timeContextFromParameter": "time_range",
@@ -491,7 +573,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Flow_Events_CL\n| where pd == 1 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocol = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\n\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where pd == 1 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocol = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\n\n",
"size": 0,
"title": "Potentially blocked traffic",
"timeContextFromParameter": "time_range",
@@ -504,7 +586,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Flow_Events_CL\n| where pd == 0 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocol = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\n",
+ "query": "let table_to_search_from = '{TableToSearchFrom}';\ntable(table_to_search_from)\n| where pd == 0 and (src_ip in ({src_ip}) or '*' in ({src_ip})) and (dst_ip in ({dst_ip}) or '*' in ({dst_ip})) and (src_labels has_any ({src_label}) or '*' in ({src_label})) and (dst_labels has_any ({dst_label}) or '*' in ({dst_label})) and (dst_port in ({dst_port}) or '*' in ({dst_port})) and (proto in ({protocol}) or '*' in ({protocol}))\n| extend protocol = case(\n proto == -1, \"all\",\n proto == 0, \"hopopt\",\n proto == 1, \"icmp\",\n proto == 2, \"igmp\",\n proto == 3, \"ggp\",\n proto == 4, \"ipv4\",\n proto == 5, \"st\",\n proto == 6, \"tcp\",\n proto == 7, \"cbt\",\n proto == 8, \"egp\",\n proto == 9, \"igp\",\n proto == 10, \"bbn-rcc-mon\",\n proto == 11, \"nvp-ii\",\n proto == 12, \"pup\",\n proto == 13, \"argus\",\n proto == 14, \"emcon\",\n proto == 15, \"xnet\",\n proto == 16, \"chaos\",\n proto == 17, \"udp\",\n proto == 18, \"mux\",\n proto == 19, \"dcn-meas\",\n proto == 20, \"hmp\",\n proto == 21, \"prm\",\n proto == 22, \"xns-idp\",\n proto == 23, \"trunk-1\",\n proto == 24, \"trunk-2\",\n proto == 25, \"leaf-1\",\n proto == 26, \"leaf-2\",\n proto == 27, \"rdp\",\n proto == 28, \"irtp\",\n proto == 29, \"iso-tp4\",\n proto == 30, \"netblt\",\n proto == 31, \"mfe-nsp\",\n proto == 32, \"merit-inp\",\n proto == 33, \"dccp\",\n proto == 34, \"3pc\",\n proto == 35, \"idpr\",\n proto == 36, \"xtp\",\n proto == 37, \"ddp\",\n proto == 38, \"idpr-cmtp\",\n proto == 39, \"tp++\",\n proto == 40, \"il\",\n proto == 41, \"ipv6\",\n proto == 42, \"sdrp\",\n proto == 43, \"ipv6-route\",\n proto == 44, \"ipv6-frag\",\n proto == 45, \"idrp\",\n proto == 46, \"rsvp\",\n proto == 47, \"gre\",\n proto == 48, \"dsr\",\n proto == 49, \"bna\",\n proto == 50, \"esp\",\n proto == 51, \"ah\",\n proto == 52, \"i-nlsp\",\n proto == 53, \"swipe\",\n proto == 54, \"narp\",\n proto == 55, \"mobile\",\n proto == 56, \"tlsp\",\n proto == 57, \"skip\",\n proto == 58, \"ipv6-icmp\",\n proto == 59, \"ipv6-nonxt\",\n proto == 60, \"ipv6-opts\",\n proto == 62, \"cftp\",\n proto == 64, \"sat-expak\",\n proto == 65, \"kryptolan\",\n proto == 66, \"rvd\",\n proto == 67, \"ippc\",\n proto == 69, \"sat-mon\",\n proto == 70, \"visa\",\n proto == 71, \"ipcv\",\n proto == 72, \"cpnx\",\n proto == 73, \"cphb\",\n proto == 74, \"wsn\",\n proto == 75, \"pvp\",\n proto == 76, \"br-sat-mon\",\n proto == 77, \"sun-nd\",\n proto == 78, \"wb-mon\",\n proto == 79, \"wb-expak\",\n proto == 80, \"iso-ip\",\n proto == 81, \"vmtp\",\n proto == 82, \"secure-vmtp\",\n proto == 83, \"vines\",\n proto == 84, \"iptm\",\n proto == 85, \"nsfnet-igp\",\n proto == 86, \"dgp\",\n proto == 87, \"tcf\",\n proto == 88, \"eigrp\",\n proto == 89, \"ospfigp\",\n proto == 90, \"sprite-rpc\",\n proto == 91, \"larp\",\n proto == 92, \"mtp\",\n proto == 93, \"ax.25\",\n proto == 94, \"ipip\",\n proto == 95, \"micp\",\n proto == 96, \"scc-sp\",\n proto == 97, \"etherip\",\n proto == 98, \"encap\",\n proto == 100, \"gmtp\",\n proto == 101, \"ifmp\",\n proto == 102, \"pnni\",\n proto == 103, \"pim\",\n proto == 104, \"aris\",\n proto == 105, \"scps\",\n proto == 106, \"qnx\",\n proto == 107, \"a/n\",\n proto == 108, \"ipcomp\",\n proto == 109, \"snp\",\n proto == 110, \"compaq-peer\",\n proto == 111, \"ipx-in-ip\",\n proto == 112, \"vrrp\",\n proto == 113, \"pgm\",\n proto == 115, \"l2tp\",\n proto == 116, \"ddx\",\n proto == 117, \"iatp\",\n proto == 118, \"stp\",\n proto == 119, \"srp\",\n proto == 120, \"uti\",\n proto == 121, \"smp\",\n proto == 122, \"sm\",\n proto == 123, \"ptp\",\n proto == 124, \"isis over ipv4\",\n proto == 125, \"fire\",\n proto == 126, \"crtp\",\n proto == 127, \"crudp\",\n proto == 128, \"sscopmce\",\n proto == 129, \"iplt\",\n proto == 130, \"sps\",\n proto == 131, \"pipe\",\n proto == 132, \"sctp\",\n proto == 133, \"fc\",\n proto == 134, \"rsvp-e2e-ignore\",\n proto == 135, \"mobility header\",\n proto == 136, \"udplite\",\n proto == 137, \"mpls-in-ip\",\n proto == 138, \"manet\",\n proto == 139, \"hip\",\n proto == 140, \"shim6\",\n proto == 141, \"wesp\",\n proto == 142, \"rohc\",\n proto == 143, \"ethernet\",\n proto == 144, \"aggfrag\",\n proto == 145, \"nsh\",\n proto >= 146 and proto <= 252, \"unknown\",\n proto == 253, \"unknown\",\n proto == 254, \"unknown\",\n proto == 255, \"reserved\",\n \"unknown\"\n)\n| project TimeGenerated, src_ip, src_hostname, src_labels, dst_ip, dst_hostname, dst_port, dst_labels, protocol\n",
"size": 0,
"title": "Allowed traffic",
"timeContextFromParameter": "time_range",
diff --git a/Solutions/IllumioSaaS/Workbooks/IllumioOnPremHealth.json b/Solutions/IllumioSaaS/Workbooks/IllumioOnPremHealth.json
new file mode 100644
index 00000000000..eb167639e36
--- /dev/null
+++ b/Solutions/IllumioSaaS/Workbooks/IllumioOnPremHealth.json
@@ -0,0 +1,647 @@
+{
+ "version": "Notebook/1.0",
+ "items": [
+ {
+ "type": 1,
+ "content": {
+ "json": "This workbook leverages a function app to make an API call to Illumio Health API. \nThe function app has the context of the onprem deployment to which api call has to be made.\n\nSome of the widgets also use Syslog table to visualize data.",
+ "style": "info"
+ },
+ "name": "text - 7"
+ },
+ {
+ "type": 9,
+ "content": {
+ "version": "KqlParameterItem/1.0",
+ "parameters": [
+ {
+ "id": "f0562353-928f-41f0-875c-99eb0f95fa38",
+ "version": "KqlParameterItem/1.0",
+ "name": "Illumio_Health",
+ "label": "Illumio Health",
+ "type": 1,
+ "isRequired": true,
+ "query": "{\"version\":\"CustomEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"url\":\"https://azureonprempcehealth.azurewebsites.net/api/pce_onprem_http_trigger\",\"contentType\":\"text/plain\",\"urlParams\":[],\"transformers\":null}",
+ "isHiddenWhenLocked": true,
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 10
+ },
+ {
+ "id": "2a4639d7-a9c8-4e65-8bd7-26b97d813f6d",
+ "version": "KqlParameterItem/1.0",
+ "name": "TimeRange",
+ "type": 4,
+ "isRequired": true,
+ "typeSettings": {
+ "selectableValues": [
+ {
+ "durationMs": 1800000
+ },
+ {
+ "durationMs": 3600000
+ },
+ {
+ "durationMs": 14400000
+ },
+ {
+ "durationMs": 43200000
+ },
+ {
+ "durationMs": 86400000
+ },
+ {
+ "durationMs": 259200000
+ },
+ {
+ "durationMs": 604800000
+ }
+ ],
+ "allowCustom": true
+ },
+ "value": {
+ "durationMs": 259200000
+ }
+ }
+ ],
+ "style": "above",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces"
+ },
+ "name": "parameters - 2"
+ },
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print json = todynamic('{Illumio_Health}')[0]\n| project ClusterStatus = strcat(toupper(substring(json.status, 0, 1)), substring(json.status, 1))\n",
+ "size": 1,
+ "title": "Cluster Status",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "stat",
+ "statSettings": {
+ "valueAggregation": "None",
+ "colorSettings": {
+ "type": "static",
+ "mode": "background",
+ "heatmapPalette": "greenRed",
+ "thresholdsGrid": []
+ },
+ "iconSettings": {
+ "thresholdsGrid": []
+ },
+ "tagText": "",
+ "valueFontStyle": "mega"
+ },
+ "textSettings": {
+ "style": "bignumber"
+ }
+ },
+ "customWidth": "50",
+ "name": "query - 2",
+ "styleSettings": {
+ "showBorder": true
+ }
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print json = todynamic('{Illumio_Health}')[0]['nodes'][0]\n| project json.runlevel",
+ "size": 1,
+ "title": "Cluster Runlevel ",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "stat",
+ "statSettings": {
+ "valueAggregation": "None",
+ "colorSettings": {
+ "type": "static",
+ "mode": "background",
+ "heatmapPalette": "greenRed",
+ "thresholdsGrid": []
+ },
+ "iconSettings": {
+ "thresholdsGrid": []
+ },
+ "tagText": "",
+ "valueFontStyle": "mega"
+ },
+ "textSettings": {
+ "style": "bignumber"
+ }
+ },
+ "customWidth": "50",
+ "name": "query - 3",
+ "styleSettings": {
+ "showBorder": true
+ }
+ }
+ ]
+ },
+ "name": "group - 1"
+ },
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print nodes = todynamic('{Illumio_Health}')[0]['nodes']\n| mv-expand nodes\n| project Services_Running = array_length(nodes['services']['running'])\n\n\n",
+ "size": 1,
+ "title": "Running Services",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "stat",
+ "gridSettings": {
+ "formatters": [
+ {
+ "columnMatch": "Services_Running",
+ "formatter": 18,
+ "formatOptions": {
+ "thresholdsOptions": "icons",
+ "thresholdsGrid": [
+ {
+ "operator": "Default",
+ "thresholdValue": null,
+ "representation": "success",
+ "text": "{0}{1}"
+ }
+ ],
+ "customColumnWidthSetting": "45ch"
+ }
+ },
+ {
+ "columnMatch": "Services_Stopped",
+ "formatter": 18,
+ "formatOptions": {
+ "thresholdsOptions": "icons",
+ "thresholdsGrid": [
+ {
+ "operator": "Default",
+ "thresholdValue": null,
+ "representation": "3",
+ "text": "{0}{1}"
+ }
+ ],
+ "customColumnWidthSetting": "45ch"
+ }
+ },
+ {
+ "columnMatch": "Services_Partial",
+ "formatter": 18,
+ "formatOptions": {
+ "thresholdsOptions": "icons",
+ "thresholdsGrid": [
+ {
+ "operator": "Default",
+ "thresholdValue": null,
+ "representation": "warning",
+ "text": "{0}{1}"
+ }
+ ],
+ "customColumnWidthSetting": "45ch"
+ }
+ },
+ {
+ "columnMatch": "services_running",
+ "formatter": 18,
+ "formatOptions": {
+ "thresholdsOptions": "icons",
+ "thresholdsGrid": [
+ {
+ "sourceColumn": "services_stopped",
+ "representation": "3",
+ "text": "{0}{1}"
+ },
+ {
+ "sourceColumn": "services_partial",
+ "representation": "2",
+ "text": "{0}{1}"
+ },
+ {
+ "operator": "Default",
+ "thresholdValue": null,
+ "representation": "success",
+ "text": "{0}{1}"
+ }
+ ],
+ "customColumnWidthSetting": "45ch"
+ }
+ }
+ ]
+ },
+ "tileSettings": {
+ "titleContent": {
+ "columnMatch": "hostname"
+ },
+ "leftContent": {
+ "columnMatch": "services_running"
+ },
+ "rightContent": {
+ "columnMatch": "services_stopped"
+ },
+ "secondaryContent": {
+ "columnMatch": "services_partial"
+ },
+ "showBorder": false
+ },
+ "graphSettings": {
+ "type": 0
+ },
+ "statSettings": {
+ "valueAggregation": "None",
+ "colorSettings": {
+ "type": "static",
+ "mode": "foreground",
+ "staticColor": "green",
+ "heatmapPalette": "greenRed",
+ "thresholdsGrid": []
+ },
+ "iconSettings": {
+ "thresholdsGrid": []
+ },
+ "tagText": "",
+ "valueFontStyle": "mega"
+ }
+ },
+ "customWidth": "33.33",
+ "name": "query - 2",
+ "styleSettings": {
+ "showBorder": true
+ }
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print nodes = todynamic('{Illumio_Health}')[0]['nodes']\n| mv-expand nodes\n| project Services_stopped = coalesce(array_length(nodes['services']['stopped']), 0)\n\n\n",
+ "size": 1,
+ "title": "Stopped Services",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "stat",
+ "statSettings": {
+ "valueAggregation": "None",
+ "colorSettings": {
+ "type": "static",
+ "mode": "foreground",
+ "staticColor": "redBright",
+ "heatmapPalette": "greenRed",
+ "thresholdsGrid": []
+ },
+ "iconSettings": {
+ "thresholdsGrid": []
+ },
+ "tagText": "",
+ "valueFontStyle": "mega"
+ }
+ },
+ "customWidth": "33.33",
+ "name": "query - 1",
+ "styleSettings": {
+ "showBorder": true
+ }
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print nodes = todynamic('{Illumio_Health}')[0]['nodes']\n| mv-expand nodes\n| project Services_partial = coalesce(array_length(nodes['services']['partial']), 0)\n\n\n",
+ "size": 1,
+ "title": "Partial Services",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "stat",
+ "statSettings": {
+ "valueAggregation": "None",
+ "colorSettings": {
+ "type": "static",
+ "mode": "foreground",
+ "staticColor": "gray",
+ "heatmapPalette": "greenRed",
+ "thresholdsGrid": []
+ },
+ "iconSettings": {
+ "thresholdsGrid": []
+ },
+ "tagText": "",
+ "valueFontStyle": "mega"
+ }
+ },
+ "customWidth": "33",
+ "name": "query - 2",
+ "styleSettings": {
+ "showBorder": true
+ }
+ }
+ ]
+ },
+ "name": "service stats"
+ },
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "title": "Node Status",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print nodes = todynamic('{Illumio_Health}')[0]['nodes']\n| mv-expand nodes\n| project Hostname = nodes['hostname'], Runlevel = nodes['runlevel'], IpAddress = nodes['ip_address']\n\n\n",
+ "size": 3,
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "table",
+ "gridSettings": {
+ "formatters": [
+ {
+ "columnMatch": "Hostname",
+ "formatter": 0,
+ "formatOptions": {
+ "customColumnWidthSetting": "15ch"
+ }
+ }
+ ]
+ },
+ "tileSettings": {
+ "titleContent": {
+ "columnMatch": "Hostname",
+ "formatter": 1,
+ "tooltipFormat": {
+ "tooltip": "Hostname"
+ }
+ },
+ "leftContent": {
+ "columnMatch": "Runlevel",
+ "formatter": 12,
+ "formatOptions": {
+ "palette": "blue"
+ },
+ "tooltipFormat": {
+ "tooltip": "Runlevel"
+ }
+ },
+ "secondaryContent": {
+ "columnMatch": "IpAddress",
+ "formatter": 12,
+ "formatOptions": {
+ "palette": "blue"
+ },
+ "tooltipFormat": {
+ "tooltip": "Ip Address"
+ }
+ },
+ "showBorder": true,
+ "size": "full"
+ }
+ },
+ "customWidth": "100",
+ "name": "query - 0"
+ }
+ ]
+ },
+ "name": "node_status"
+ },
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "title": "Disk Latency (in milliseconds)",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/system_health' and SyslogMessage has 'src=disk_latency' and SyslogMessage has 'disk=Traffic'\n| extend traffic_disk_latency_milliseconds = toint(extract(@\"traffic_disk_latency_milliseconds=(\\d+)\", 1, SyslogMessage))\n",
+ "size": 0,
+ "aggregation": 3,
+ "title": "Traffic Disk",
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "barchart",
+ "chartSettings": {
+ "xAxis": "TimeGenerated",
+ "yAxis": [
+ "traffic_disk_latency_milliseconds"
+ ],
+ "seriesLabelSettings": [
+ {
+ "seriesName": "153035ad-fede-495a-b6c2-6d4308689f79",
+ "label": "Latency in milliseconds"
+ }
+ ],
+ "customThresholdLine": "300",
+ "customThresholdLineStyle": 5,
+ "xSettings": {
+ "label": "Time"
+ },
+ "ySettings": {
+ "label": "Traffic Disk Latency"
+ }
+ }
+ },
+ "customWidth": "50",
+ "name": "query - 0"
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/system_health' and SyslogMessage has 'src=disk_latency' and SyslogMessage has 'disk=Policy'\n| extend policy_disk_latency_milliseconds = toint(extract(@\"policy_disk_latency_milliseconds=(\\d+)\", 1, SyslogMessage))\n",
+ "size": 0,
+ "aggregation": 3,
+ "title": "Policy Disk",
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "barchart",
+ "chartSettings": {
+ "xAxis": "TimeGenerated",
+ "yAxis": [
+ "policy_disk_latency_milliseconds"
+ ],
+ "seriesLabelSettings": [
+ {
+ "seriesName": "153035ad-fede-495a-b6c2-6d4308689f79",
+ "label": "Latency in milliseconds"
+ }
+ ],
+ "customThresholdLine": "300",
+ "customThresholdLineStyle": 5
+ }
+ },
+ "customWidth": "50",
+ "name": "query - 1"
+ }
+ ]
+ },
+ "name": "group - 4"
+ },
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "title": "Traffic Ingestion Stats",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/system_health'\n| extend \n collector_flows = iif(SyslogMessage has 'src=collector', toint(extract(@\"collector_summaries_per_second=(\\d+)\", 1, SyslogMessage)), 0),\n traffic_flows = iif(SyslogMessage has 'src=flow_analytics', toint(extract(@\"traffic_summaries_per_second=(\\d+)\", 1, SyslogMessage)), 0)\n| summarize \n collector_flows = sum(collector_flows), \n traffic_flows = sum(traffic_flows) \n by bin(TimeGenerated, 10m) // Adjust bin size (e.g., 1m for minutes, 5m, etc.)\n| order by TimeGenerated asc\n",
+ "size": 3,
+ "aggregation": 3,
+ "title": "Traffic Flow Ingestion Rate (Average)",
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "linechart",
+ "chartSettings": {
+ "xAxis": "TimeGenerated",
+ "yAxis": [
+ "collector_flows",
+ "traffic_flows"
+ ]
+ }
+ },
+ "customWidth": "50",
+ "name": "query - 0"
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "Syslog\n| where SyslogMessage has 'illumio_pce/system_health' and SyslogMessage has 'src=flow_analytics'\n| extend traffic_summaries_per_second = todouble(extract(@\"traffic_summaries_per_second=([\\d\\.]+)\", 1, SyslogMessage))\n| extend traffic_backlog_utilization_percentage = todouble(extract(@\"traffic_backlog_utilization_percentage=([\\d\\.]+)\", 1, SyslogMessage))\n| extend traffic_database_size_gb = todouble(extract(@\"traffic_database_size_gb=([\\d\\.]+)\", 1, SyslogMessage))\n| extend traffic_database_utilization_percentage = todouble(extract(@\"traffic_database_utilization_percentage=([\\d\\.]+)\", 1, SyslogMessage))\n| extend traffic_database_size_days = todouble(extract(@\"traffic_database_size_days=([\\d\\.]+)\", 1, SyslogMessage))\n| project TimeGenerated, traffic_summaries_per_second, traffic_backlog_utilization_percentage, traffic_database_size_gb, traffic_database_utilization_percentage, traffic_database_size_days",
+ "size": 3,
+ "aggregation": 3,
+ "title": "Traffic Backlog vs Traffic DB Utilization",
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "linechart",
+ "chartSettings": {
+ "xAxis": "TimeGenerated",
+ "yAxis": [
+ "traffic_backlog_utilization_percentage",
+ "traffic_database_utilization_percentage"
+ ]
+ }
+ },
+ "customWidth": "50",
+ "name": "query - 1"
+ }
+ ]
+ },
+ "name": "group - 5"
+ },
+ {
+ "type": 12,
+ "content": {
+ "version": "NotebookGroup/1.0",
+ "groupType": "editable",
+ "items": [
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print json = todynamic('{Illumio_Health}')[0]\n| mv-expand group = parsejson(json.groups)\n| extend components = group.components\n| mv-expand section = parsejson(components)\n| where section['section'] == 'VEN Heartbeat'\n| mv-expand node = section.contents[0].cluster\n| mv-expand node_metrics = node.metrics\n| project NodeAddress = node.node, Metric = node_metrics['metric'], MetricValue = node_metrics['entries'][0]['values'][0]['value']",
+ "size": 3,
+ "title": "VEN Heartbeat Stats",
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces"
+ },
+ "customWidth": "50",
+ "name": "query - 0"
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print json = todynamic('{Illumio_Health}')[0]\n| mv-expand group = parsejson(json.groups)\n| extend components = group.components\n| mv-expand section = parsejson(components)\n| where section['section'] == 'VEN Policy'\n| mv-expand node = section.contents[0].cluster\n| mv-expand node_metrics = node.metrics\n| project NodeAddress = node.node, Metric = node_metrics['metric'], MetricValue = node_metrics['entries'][0]['values'][0]['value']",
+ "size": 3,
+ "title": "VEN Policy Stats",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces"
+ },
+ "customWidth": "50",
+ "name": "query - 1"
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print json = todynamic('{Illumio_Health}')[0]\n| mv-expand group = parsejson(json.groups)\n| extend components = group.components\n| mv-expand section = parsejson(components)\n| where section['section'] == 'Policy Database Summary'\n| mv-expand content = section.contents\n| project Metric = content['metric'], MetricValue = content['entries'][0]['values'][0]['value'], Unit = coalesce(content['entries'][0]['values'][0]['unit'], '')",
+ "size": 0,
+ "title": "Policy Database Summary",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces"
+ },
+ "customWidth": "50",
+ "name": "query - 2"
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "print json = todynamic('{Illumio_Health}')[0]\n| mv-expand group = parsejson(json.groups)\n| extend components = group.components\n| mv-expand section = parsejson(components)\n| where section['section'] == 'Traffic Database Summary'\n| mv-expand content = section.contents\n| project Metric = content['metric'], MetricValue = content['entries'][0]['values'][0]['value'], Unit = coalesce(content['entries'][0]['values'][0]['unit'], '')",
+ "size": 0,
+ "title": "Traffic Database Summary",
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces"
+ },
+ "customWidth": "50",
+ "name": "query - 3"
+ }
+ ]
+ },
+ "name": "group - 6"
+ }
+ ],
+ "fromTemplateId": "sentinel-OnPremHealthWorkbook",
+ "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
+ }
\ No newline at end of file
diff --git a/Solutions/IllumioSaaS/Workbooks/IllumioWorkloadsStats.json b/Solutions/IllumioSaaS/Workbooks/IllumioWorkloadsStats.json
index 3583b80ede9..a85f660089a 100644
--- a/Solutions/IllumioSaaS/Workbooks/IllumioWorkloadsStats.json
+++ b/Solutions/IllumioSaaS/Workbooks/IllumioWorkloadsStats.json
@@ -8,6 +8,36 @@
},
"name": "text - 2"
},
+ {
+ "type": 9,
+ "content": {
+ "version": "KqlParameterItem/1.0",
+ "parameters": [
+ {
+ "id": "a089608b-daae-4b06-91ff-94b81c03bea8",
+ "version": "KqlParameterItem/1.0",
+ "name": "Illumio_PCE",
+ "label": "Illumio PCE",
+ "type": 2,
+ "isRequired": true,
+ "query": "Illumio_Workloads_Summarized_API_CL\n| summarize by pce_fqdn",
+ "typeSettings": {
+ "additionalResourceOptions": []
+ },
+ "timeContext": {
+ "durationMs": 86400000
+ },
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "value": "scp4.illum.io"
+ }
+ ],
+ "style": "above",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces"
+ },
+ "name": "parameters - 5"
+ },
{
"type": 11,
"content": {
@@ -70,7 +100,6 @@
}
],
"tileSettings": {
- "titleContent": {},
"showBorder": false
}
},
@@ -95,7 +124,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_version)\n| mv-expand keyValue = parsedJson\n| extend version = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project version, count_",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_version)\n| mv-expand keyValue = parsedJson\n| extend version = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project version, count_",
"size": 3,
"title": "Workloads by VEN Version",
"queryType": 0,
@@ -126,7 +155,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_managed)\n| mv-expand keyValue = parsedJson\n| extend managed = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project managed = iff(managed == 'true', 'Managed', 'Unmanaged'), count_",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_managed)\n| mv-expand keyValue = parsedJson\n| extend managed = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project managed = iff(managed == 'true', 'Managed', 'Unmanaged'), count_",
"size": 3,
"title": "Managed and Unmanaged workload counts",
"noDataMessage": "No workloads",
@@ -158,7 +187,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_type)\n| mv-expand keyValue = parsedJson\n| extend type = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project type, count_",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_type)\n| mv-expand keyValue = parsedJson\n| extend type = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project type, count_",
"size": 3,
"title": "VENs by type",
"queryType": 0,
@@ -187,7 +216,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_os)\n| mv-expand keyValue = parsedJson\n| extend os = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project os, count_",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_os)\n| mv-expand keyValue = parsedJson\n| extend os = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project os, count_",
"size": 3,
"title": "Managed workloads by OS",
"queryType": 0,
@@ -234,7 +263,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_enforcement_mode)\n| mv-expand keyValue = parsedJson\n| extend mode = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project mode = case(mode == 'full', 'Full',\n mode == 'visibility_only', 'Visibility Only',\n mode == 'selective', \"Selective\",\n \"Idle\"), count_\n",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_enforcement_mode)\n| mv-expand keyValue = parsedJson\n| extend mode = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project mode = case(mode == 'full', 'Full',\n mode == 'visibility_only', 'Visibility Only',\n mode == 'selective', \"Selective\",\n \"Idle\"), count_\n",
"size": 3,
"title": "Workloads by enforcement modes",
"queryType": 0,
@@ -263,7 +292,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_status)\n| mv-expand keyValue = parsedJson\n| extend status = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project status, count_\n",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_status)\n| mv-expand keyValue = parsedJson\n| extend status = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project status, count_\n",
"size": 3,
"title": "VENs by Status",
"queryType": 0,
@@ -292,7 +321,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Illumio_Workloads_Summarized_API_CL\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_sync_state)\n| mv-expand keyValue = parsedJson\n| extend sync_state = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project sync_state, count_\n",
+ "query": "Illumio_Workloads_Summarized_API_CL\n| where pce_fqdn == ('{Illumio_PCE}')\n| order by TimeGenerated desc\n| top 1 by TimeGenerated\n| extend parsedJson = parse_json(vens_by_sync_state)\n| mv-expand keyValue = parsedJson\n| extend sync_state = tostring(bag_keys(keyValue)[0]), count_ = toint(keyValue[tostring(bag_keys(keyValue)[0])])\n| project sync_state, count_\n",
"size": 3,
"title": "VENs by synchronization state",
"queryType": 0,
diff --git a/Solutions/IllumioSaaS/data/Solution_IllumioSaaS.json b/Solutions/IllumioSaaS/data/Solution_IllumioSaaS.json
index 156e98dccd3..dc822e0ced9 100644
--- a/Solutions/IllumioSaaS/data/Solution_IllumioSaaS.json
+++ b/Solutions/IllumioSaaS/data/Solution_IllumioSaaS.json
@@ -9,7 +9,8 @@
"Workbooks": [
"Workbooks/IllumioAuditableEvents.json",
"Workbooks/IllumioFlowData.json",
- "Workbooks/IllumioWorkloadsStats.json"
+ "Workbooks/IllumioWorkloadsStats.json",
+ "Workbooks/IllumioOnPremHealth.json"
],
"Analytic Rules": [
"Analytic Rules/Illumio_VEN_Firewall_Tampering_Detection_Query.yaml",
@@ -25,8 +26,12 @@
"Playbooks/Illumio-Port-Blocking-Switch/azuredeploy.json",
"Playbooks/Illumio-Quarantine-Workload/azuredeploy.json"
],
+ "Parsers": [
+ "Parsers/IllumioSyslogAuditEvents.yaml",
+ "Parsers/IllumioSyslogNetworkTrafficEvents.yaml"
+ ],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\IllumioSaaS",
- "Version": "3.3.0",
+ "Version": "3.4.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1Pconnector": false
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json
new file mode 100644
index 00000000000..b8ed113ca42
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json
@@ -0,0 +1,277 @@
+{
+ "name": "JamfProtectCustomDCR",
+ "apiVersion": "2021-09-01-preview",
+ "type": "Microsoft.Insights/dataCollectionRules",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "streamDeclarations": {
+ "Custom-jamfprotecttelemetryv2": {
+ "columns": [
+ {
+ "name": "action",
+ "type": "dynamic"
+ },
+ {
+ "name": "action_type",
+ "type": "int"
+ },
+ {
+ "name": "deadline",
+ "type": "int"
+ },
+ {
+ "name": "event",
+ "type": "dynamic"
+ },
+ {
+ "name": "event_type",
+ "type": "int"
+ },
+ {
+ "name": "glob_seq_num",
+ "type": "int"
+ },
+ {
+ "name": "host",
+ "type": "dynamic"
+ },
+ {
+ "name": "mach_time",
+ "type": "long"
+ },
+ {
+ "name": "metadata",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "seq_num",
+ "type": "int"
+ },
+ {
+ "name": "thread",
+ "type": "dynamic"
+ },
+ {
+ "name": "time",
+ "type": "datetime"
+ },
+ {
+ "name": "uuid",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "int"
+ }
+ ]
+ },
+ "Custom-jamfprotectunifiedlogs": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "caid",
+ "type": "string"
+ },
+ {
+ "name": "certid",
+ "type": "string"
+ },
+ {
+ "name": "input",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "Custom-jamfprotecttelemetryv1": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "arguments",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain",
+ "type": "dynamic"
+ },
+ {
+ "name": "header",
+ "type": "dynamic"
+ },
+ {
+ "name": "host_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "key",
+ "type": "string"
+ },
+ {
+ "name": "return",
+ "type": "dynamic"
+ },
+ {
+ "name": "subject",
+ "type": "dynamic"
+ },
+ {
+ "name": "identity",
+ "type": "dynamic"
+ },
+ {
+ "name": "texts",
+ "type": "string"
+ },
+ {
+ "name": "metrics",
+ "type": "dynamic"
+ },
+ {
+ "name": "page_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "attributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_child",
+ "type": "dynamic"
+ },
+ {
+ "name": "path",
+ "type": "dynamic"
+ },
+ {
+ "name": "_event_score",
+ "type": "int"
+ },
+ {
+ "name": "contents",
+ "type": "string"
+ },
+ {
+ "name": "file",
+ "type": "dynamic"
+ },
+ {
+ "name": "socket_inet",
+ "type": "dynamic"
+ },
+ {
+ "name": "exit",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_args",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_env",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_parent",
+ "type": "dynamic"
+ },
+ {
+ "name": "architecture",
+ "type": "string"
+ },
+ {
+ "name": "bios_firmware_versions",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "rateLimitingSeconds",
+ "type": "int"
+ }
+ ]
+ },
+ "Custom-jamfprotectalerts": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "caid",
+ "type": "string"
+ },
+ {
+ "name": "certid",
+ "type": "string"
+ },
+ {
+ "name": "input",
+ "type": "dynamic"
+ }
+ ]
+ }
+ },
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": "[variables('workspaceResourceId')]",
+ "name": "clv2ws1"
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [
+ "Custom-jamfprotecttelemetryv2"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = metadata.vendor,\n EventProduct = metadata.product,\n EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = host.protectVersion,\n EventSeverity = \"Informational\",\n //\n // Jamf Protect - Device Hostnames\n TargetHostname = host.hostname,\n DvcHostname = host.hostname,\n DvcSerial = host.serial,\n DvcIpAddr = host.ips,\n DvcId = host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = host.os,\n SrcDeviceType = \"Computer\"\n| project-rename\n TimeGenerated = ['time'],\n EventOriginalUid = uuid,\n EventOriginalType = event_type,\n EventCount = glob_seq_num\n| project-away\n metadata,\n host,\n seq_num,\n version,\n deadline,\n mach_time,\n action_type\n\n",
+ "outputStream": "Custom-jamfprotecttelemetryv2_CL"
+ },
+ {
+ "streams": [
+ "Custom-jamfprotectunifiedlogs"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Unified Log Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = \"UnifiedLog\",\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.event.name,\n EventResultMessage = input.match.event.composedMessage,\n // EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", input.match.uuid),\n // //\n // // Jamf Protect - Device Hostnames\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n // Jamf Protect - Event Details\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = \"Create\",\n ProcessEventSubType = \"Exec\",\n TargetProcessName = tostring(input.match.event.process),\n TargetProcessId = toreal(input.match.event.processIdentifier),\n TargetProcessGuid = tostring(input.match.event.uuid),\n TargetProcessCommandLine = input.match.event.process.args,\n TargetProcessCurrentDirectory = input.match.event.processImagePath\n| project-away\n caid,\n certid\n\n",
+ "outputStream": "Custom-jamfprotectunifiedlogs_CL"
+ },
+ {
+ "streams": [
+ "Custom-jamfprotecttelemetryv1"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Device Telemetry Stream'\n// Data Field Normalization\n| extend\n EventSeverity = \"Informational\",\n //\n // Jamf Protect Telemetry - Endpoint Information\n //\n TargetModel = metrics.hw_model,\n DvcOsVersion = host_info.osversion,\n TargetHostname = host_info.host_name,\n DvcHostname = host_info.host_name,\n DvcId = host_info.host_uuid,\n // Jamf Protect - Event Types\n EventType = case(\n header.event_name == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header.event_name == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header.event_name == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header.event_name == \"AUE_auth_user\",\n \"Elevate\",\n header.event_name == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header.event_name == \"AUE_CHDIR\",\n \"FolderMoved\",\n header.event_name == \"AUE_CHROOT\",\n \"FolderModified\",\n header.event_name == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_create_group\",\n \"GroupCreated\",\n header.event_name == \"AUE_create_user\",\n \"UserCreated\",\n header.event_name == \"AUE_delete_group\",\n \"GroupDeleted\",\n header.event_name == \"AUE_delete_user\",\n \"UserDeleted\",\n header.event_name == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header.event_name == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_FORK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_GETAUID\",\n \"\",\n header.event_name == \"AUE_KILL\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_logout\",\n \"Logoff\",\n header.event_name == \"AUE_lw_login\",\n \"Logon\",\n header.event_name == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header.event_name == \"AUE_modify_group\",\n \"GroupModified\",\n header.event_name == \"AUE_modify_password\",\n \"PasswordChanged\",\n header.event_name == \"AUE_modify_user\",\n \"UserModified\",\n header.event_name == \"AUE_MOUNT\",\n \"VolumeMount\",\n header.event_name == \"AUE_openssh\",\n \"SshInitiated\",\n header.event_name == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header.event_name == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header.event_name == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_END\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_START\",\n \"Logon\",\n header.event_name == \"AUE_SESSION_UPDATE\",\n \"\",\n header.event_name == \"AUE_SETPRIORITY\",\n \"\",\n header.event_name == \"AUE_SETSOCKOPT\",\n \"\",\n header.event_name == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header.event_name == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header.event_name == \"AUE_SOCKETPAIR\",\n \"\",\n header.event_name == \"AUE_ssauthint\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthmech\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthorize\",\n \"Elevate\",\n header.event_name == \"AUE_TASKFORPID\",\n \"\",\n header.event_name == \"AUE_TASKNAMEFORPID\",\n \"\",\n header.event_name == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header.event_name == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header.event_name == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header.event_name == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n //\n // Jamf Protect Telemetry - Process\n //\n ActingProcessId = toreal(subject.responsible_process_id),\n ActingProcessName = tostring(subject.responsible_process_name),\n ParentProcessName = tostring(subject.parent_path),\n ParentProcessId = toreal(subject.parent_pid),\n ParentProcessGuid = tostring(subject.parent_uuid),\n TargetProcessName = tostring(subject.process_name),\n TargetProcessId = toreal(subject.process_id),\n TargetProcessGuid = tostring(exec_chain.uuid),\n TargetProcessSHA256 = tostring(subject.process_hash),\n TargetUserId = toreal(subject.user_id),\n TargetUsername = tostring(subject.user_name),\n TargetProcessCommandLine = exec_args.args_compiled,\n ActorUsername = tostring(subject.effective_user_name),\n ActorUserId = toreal(subject.audit_user_name),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = tostring(subject.group_name),\n GroupID = toreal(subject.group_id),\n EffectiveGroupName = tostring(subject.effective_group_name),\n EffectiveGroupID = toreal(subject.effective_group_id),\n //\n // Jamf Protect Telemetry - Network\n //\n DstIpAddr = socket_inet.ip_address,\n DstPortNumber = socket_inet.port,\n NetworkProtocolVersion = case(socket_inet.id == 128, \"IPV4\", socket_inet.id == 129, \"IPV6\", \"\"),\n SrcIpAddr = subject.terminal.id.ip.address,\n //\n // Jamf Protect Telemetry - Binaries\n //\n TargetBinarySHA256 = tostring(identity.cd_hash),\n TargetbinarySignerType = case(identity.signer_type == 0, \"Developer\", identity.signer_type == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity.team_id),\n TargetBinarySigningAppID = tostring(identity.signer_id),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = path\n| project-away _event_score\n\n",
+ "outputStream": "Custom-jamfprotecttelemetryv1_CL"
+ },
+ {
+ "streams": [
+ "Custom-jamfprotectalerts"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Alerts Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = case(\n input.eventType == \"GPClickEvent\",\n \"Click\",\n input.eventType == \"GPDownloadEvent\",\n \"Download\",\n input.eventType == \"GPFSEvent\",\n \"FileSystem\",\n input.eventType == \"GPProcessEvent\",\n \"Process\",\n input.eventType == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input.eventType == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input.eventType == \"GPMRTEvent\",\n \"MRT\",\n input.eventType == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input.eventType == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input.eventType == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input.eventType == \"GPUSBEvent\",\n \"USB\",\n input.eventType == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.facts[0].name,\n EventResultMessage = input.match.facts[0].human,\n //\n // Jamf Protect - Device Hostnames\n //\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input.match.event.type == 0, \"None\", input.match.event.type == 1, \"Create\", input.match.event.type == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input.match.event.subType == 7, \"Exec\", input.match.event.subType == 1, \"Fork\", input.match.event.subType == 23, \"Execve\", input.match.event.subType == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(input.related.processes[array_length(input.related.processes) - 1].path),\n ActingProcessId = toreal(input.related.processes[0].responsiblePID),\n ActingProcessGuid = tostring(input.related.processes[array_length(input.related.processes) - 1].uuid),\n ParentProcessName = todynamic(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].path), \"\")),\n ParentProcessId = iff(array_length(input.related.processes) > 1, toreal(input.related.processes[1].pid), double(null)),\n ParentProcessGuid = tostring(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].uuid), \"\")),\n TargetProcessName = todynamic(input.related.processes[0].name),\n TargetProcessId = input.related.processes[0].pid,\n TargetProcessGuid = input.related.processes[0].uuid,\n TargetProcessSHA1 = tostring(input.related.binaries[0].sha1hex),\n TargetProcessSHA256 = tostring(input.related.binaries[0].sha256hex),\n TargetProcessCommandLine = input.related.processes[0].args,\n TargetProcessCurrentDirectory = tostring(input.related.processes[0].path),\n TargetProcessStatusCode = toreal(input.related.processes[0].exitCode),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = input.related.files[0].path,\n TargetFileSHA1 = input.related.files[0].sha1hex,\n TargetFileSHA256 = input.related.files[0].sha256hex,\n TargetFileSize = input.related.files[0].size,\n TargetFileSigningInfoMessage = input.related.files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(input.related.files[0].signingInfo.signerType == 0, \"Apple\", input.related.files[0].signingInfo.signerType == 1, \"App Store\", input.related.files[0].signingInfo.signerType == 2, \"Developer\", input.related.files[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = input.related.files[0].signingInfo.teamid,\n TargetFileIsDownload = tobool(input.related.files[0].isDownload),\n TargetFileIsAppBundle = tobool(input.related.files[0].isAppBundle),\n TargetFileIsDirectory = tobool(input.related.files[0].isDirectory),\n TargetFileIsScreenshot = tobool(input.related.files[0].isScreenShot),\n TargetFileExtendedAttributes = input.related.files[0].xattrs,\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = input.related.binaries[0].path,\n TargetBinarySHA1 = input.related.binaries[0].sha1hex,\n TargetBinarySHA256 = input.related.binaries[0].sha256hex,\n TargetBinarySigningInfoMessage = input.related.binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(input.related.binaries[0].signingInfo.signerType == 0, \"Apple\", input.related.binaries[0].signingInfo.signerType == 1, \"App Store\", input.related.binaries[0].signingInfo.signerType == 2, \"Developer\", input.related.binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = input.related.binaries[0].signingInfo.teamid,\n TargetBinarySigningAppID = input.related.binaries[0].signingInfo.appid\n| project-away\n caid,\n certid\n",
+ "outputStream": "Custom-jamfprotectalerts_CL"
+ }
+ ],
+ "dataCollectionEndpointId": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]"
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json
new file mode 100644
index 00000000000..0f2aae2766c
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json
@@ -0,0 +1,208 @@
+{
+ "name": "JamfProtectPush",
+ "apiVersion": "2022-09-01-preview",
+ "type": "Microsoft.SecurityInsights/dataConnectorDefinitions",
+ "location": "[parameters('workspace-location')]",
+ "kind": "Customizable",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "JamfProtectPush",
+ "title": "Jamf Protect Push Connector",
+ "publisher": "Jamf",
+ "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Telemetry",
+ "legend": "jamfprotecttelemetryv2_CL",
+ "baseQuery": "jamfprotecttelemetryv2_CL"
+ },
+ {
+ "metricName": "Unified Logs",
+ "legend": "jamfprotectunifiedlogs_CL",
+ "baseQuery": "jamfprotectunifiedlogs_CL"
+ },
+ {
+ "metricName": "Telemetry (Legacy)",
+ "legend": "jamfprotecttelemetryv1_CL",
+ "baseQuery": "jamfprotecttelemetryv1_CL"
+ },
+ {
+ "metricName": "Alerts",
+ "legend": "jamfprotectalerts_CL",
+ "baseQuery": "jamfprotectalerts_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Jamf Protect - All Alerts",
+ "query": "jamfprotectalerts_CL\n | sort by TimeGenerated desc"
+ },
+ {
+ "description": "Jamf Protect - All Telemetry events",
+ "query": "jamfprotecttelemetry_CL\n | sort by TimeGenerated desc"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "jamfprotecttelemetryv2_CL",
+ "lastDataReceivedQuery": "jamfprotecttelemetryv2_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotectunifiedlogs_CL",
+ "lastDataReceivedQuery": "jamfprotectunifiedlogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotecttelemetryv1_CL",
+ "lastDataReceivedQuery": "jamfprotecttelemetryv1_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotectalerts_CL",
+ "lastDataReceivedQuery": "jamfprotectalerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriteria": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "jamfprotecttelemetryv2_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotectunifiedlogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotecttelemetryv1_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotectalerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft Entra",
+ "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher."
+ },
+ {
+ "name": "Microsoft Azure",
+ "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Create ARM Resources and Provide the Required Permissions",
+ "description": "This connector reads data from the tables that Jamf Protect uses in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API.",
+ "instructions": [
+ {
+ "type": "Markdown",
+ "parameters": {
+ "content": "#### Automated Configuration and Secure Data Ingestion with Entra Application \nClicking on \"Connect\" will trigger the creation of Log Analytics tables and a Data Collection Rule (DCR). \nIt will then create an Entra application, link the DCR to it, and set the entered secret in the application. This setup enables data to be sent securely to the DCR using an Entra token."
+ }
+ },
+ {
+ "parameters": {
+ "label": "Deploy Jamf Protect connector resources",
+ "applicationDisplayName": "Jamf Protect Connector Application"
+ },
+ "type": "DeployPushConnectorButton"
+ }
+ ]
+ },
+ {
+ "title": "2. Push your logs into the workspace",
+ "description": "Use the following parameters to configure the your machine to send the logs to the workspace.",
+ "instructions": [
+ {
+ "parameters": {
+ "label": "Tenant ID (Directory ID)",
+ "fillWith": [
+ "TenantId"
+ ]
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Entra Application ID",
+ "fillWith": [
+ "ApplicationId"
+ ],
+ "placeholder": "Deploy push connector to get the Application ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Entra Application Secret",
+ "fillWith": [
+ "ApplicationSecret"
+ ],
+ "placeholder": "Deploy push connector to get the Application Secret"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "DCE Uri",
+ "fillWith": [
+ "DataCollectionEndpoint"
+ ],
+ "placeholder": "Deploy push connector to get the DCR Uri"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "DCR Immutable ID",
+ "fillWith": [
+ "DataCollectionRuleId"
+ ],
+ "placeholder": "Deploy push connector to get the DCR ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Telemetry (Legacy) Stream ID",
+ "value": "Custom-jamfprotecttelemetryv1_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Unified Logs Stream ID",
+ "value": "Custom-jamfprotectunifiedlogs_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Telemetry Stream ID",
+ "value": "Custom-jamfprotecttelemetryv2_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Alerts Stream ID",
+ "value": "Custom-jamfprotectalerts_CL"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
\ No newline at end of file
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json
new file mode 100644
index 00000000000..1c6d5191e6f
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json
@@ -0,0 +1,27 @@
+{
+ "name": "JamfProtectPushConnectorPolling",
+ "apiVersion": "2023-02-01-preview",
+ "type": "Microsoft.SecurityInsights/dataConnectors",
+ "kind": "Push",
+ "properties": {
+ "connectorDefinitionName": "JamfProtectPush",
+ "dcrConfig": {
+ "streamName": "Custom-jamfprotecttelemetryv2",
+ "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]",
+ "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]"
+ },
+ "auth": {
+ "type": "Push",
+ "AppId": "[[parameters('auth').appId]",
+ "ServicePrincipalId": "[[parameters('auth').servicePrincipalId]"
+ },
+ "request": {
+ "RetryCount":1
+ },
+ "response": {
+ "eventsJsonPaths": [
+ "$.messages"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json
new file mode 100644
index 00000000000..6fca438aa2e
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json
@@ -0,0 +1,11 @@
+{
+ "SolutionName":"Jamf Protect for Microsoft Sentinel",
+ "SolutionAuthor": "Thijs Xhaflaire",
+ "SolutionVersion":"3.2.0",
+ "PackageId": "azuresentinel.azure-sentinel-solution-JamfProtectPushV1",
+ "TemplateName": "JamfProtectPushV1",
+ "ConnectorDefinitionTemplateVersion": "1.0.0",
+ "DataConnectorsTemplateVersion": "1.0.0",
+ "PackageIcon":"JamfProtect",
+ "SolutionTier": "Partner"
+}
\ No newline at end of file
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json
new file mode 100644
index 00000000000..eb812edc9c2
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json
@@ -0,0 +1,236 @@
+{
+ "name": "jamfprotectalerts_CL",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2021-03-01-privatepreview",
+ "tags": {},
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotectalerts_CL",
+ "columns": [
+ {
+ "name": "input",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventVendor",
+ "type": "string"
+ },
+ {
+ "name": "EventProduct",
+ "type": "string"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "EventResult",
+ "type": "string"
+ },
+ {
+ "name": "EventMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventResultMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventSubType",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessName",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessId",
+ "type": "real"
+ },
+ {
+ "name": "ActingProcessGuid",
+ "type": "string"
+ },
+ {
+ "name": "ParentProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessId",
+ "type": "real"
+ },
+ {
+ "name": "ParentProcessGuid",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessSHA1",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessSHA256",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCurrentDirectory",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessStatusCode",
+ "type": "real"
+ },
+ {
+ "name": "TargetFilePath",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSHA1",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSize",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSigningInfoMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetFileSigningTeamID",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileIsDownload",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsAppBundle",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsDirectory",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsScreenshot",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileExtendedAttributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinaryFilePath",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA1",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySigningInfoMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetbinarySignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningTeamID",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySigningAppID",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+ }
+
\ No newline at end of file
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json
new file mode 100644
index 00000000000..b3286c3b049
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json
@@ -0,0 +1,263 @@
+{
+ "name": "jamfprotecttelemetryv1_CL",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2021-03-01-privatepreview",
+ "tags": {},
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotecttelemetryv1_CL",
+ "columns": [
+ {
+ "name": "architecture",
+ "type": "string"
+ },
+ {
+ "name": "arguments",
+ "type": "dynamic"
+ },
+ {
+ "name": "attributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "bios_firmware_versions",
+ "type": "dynamic"
+ },
+ {
+ "name": "contents",
+ "type": "string"
+ },
+ {
+ "name": "exec_args",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_child",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_parent",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_env",
+ "type": "dynamic"
+ },
+ {
+ "name": "exit",
+ "type": "dynamic"
+ },
+ {
+ "name": "file",
+ "type": "dynamic"
+ },
+ {
+ "name": "header",
+ "type": "dynamic"
+ },
+ {
+ "name": "host_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "identity",
+ "type": "dynamic"
+ },
+ {
+ "name": "key",
+ "type": "string"
+ },
+ {
+ "name": "metrics",
+ "type": "dynamic"
+ },
+ {
+ "name": "page_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "path",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "rateLimitingSeconds",
+ "type": "int"
+ },
+ {
+ "name": "return",
+ "type": "dynamic"
+ },
+ {
+ "name": "socket_inet",
+ "type": "dynamic"
+ },
+ {
+ "name": "subject",
+ "type": "dynamic"
+ },
+ {
+ "name": "texts",
+ "type": "string"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventVendor",
+ "type": "string"
+ },
+ {
+ "name": "EventProduct",
+ "type": "string"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "TargetModel",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActingProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessSHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetUserId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetUsername",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActorUsername",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActorUserId",
+ "type": "dynamic"
+ },
+ {
+ "name": "GroupName",
+ "type": "dynamic"
+ },
+ {
+ "name": "GroupID",
+ "type": "dynamic"
+ },
+ {
+ "name": "EffectiveGroupName",
+ "type": "dynamic"
+ },
+ {
+ "name": "EffectiveGroupID",
+ "type": "dynamic"
+ },
+ {
+ "name": "DstIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DstPortNumber",
+ "type": "dynamic"
+ },
+ {
+ "name": "NetworkProtocolVersion",
+ "type": "string"
+ },
+ {
+ "name": "SrcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetbinarySignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningTeamID",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningAppID",
+ "type": "string"
+ },
+ {
+ "name": "TargetFilePath",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+}
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json
new file mode 100644
index 00000000000..f523f6ac233
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json
@@ -0,0 +1,99 @@
+{
+ "name": "jamfprotecttelemetryv2_CL",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2021-03-01-privatepreview",
+ "tags": {},
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotecttelemetryv2_CL",
+ "columns": [
+ {
+ "name": "action",
+ "type": "dynamic"
+ },
+ {
+ "name": "event",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "int"
+ },
+ {
+ "name": "EventCount",
+ "type": "int"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "thread",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "string"
+ },
+ {
+ "name": "EventVendor",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventProduct",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSchemaVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+}
diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json
new file mode 100644
index 00000000000..1bbe8388cdb
--- /dev/null
+++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json
@@ -0,0 +1,115 @@
+{
+ "name": "jamfprotectunifiedlogs_CL",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2021-03-01-privatepreview",
+ "tags": {},
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotectunifiedlogs_CL",
+ "columns": [
+ {
+ "name": "input",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "EventResult",
+ "type": "string"
+ },
+ {
+ "name": "EventMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventResultMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventSubType",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCurrentDirectory",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+}
diff --git a/Solutions/Jamf Protect/Data/Solution_JamfProtect.json b/Solutions/Jamf Protect/Data/Solution_JamfProtect.json
index 67b25873a60..0a8194f8011 100644
--- a/Solutions/Jamf Protect/Data/Solution_JamfProtect.json
+++ b/Solutions/Jamf Protect/Data/Solution_JamfProtect.json
@@ -4,7 +4,8 @@
"Logo": "
",
"Description": "The [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) solution for Microsoft Sentinel enables you to ingest [Jamf Protect events](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html#task-4227) forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.",
"Data Connectors": [
- "Data Connectors/JamfProtect.json"
+ "Data Connectors/JamfProtect.json",
+ "Data Connectors/JamfProtect_ccp/connectorDefinition.json"
],
"Parsers": [
"Parsers/JamfProtect.yaml"
@@ -32,8 +33,8 @@
"Playbooks/JamfProtect_Alert_Status_Resolved/azuredeploy.json",
"Playbooks/JamfProtect_LockComputer_with_JamfPro/azuredeploy.json"
],
- "BasePath": "/Users/thijs.xhaflaire/Documents/GitHub/Microsoft/Azure-Sentinel/Solutions/Jamf Protect",
- "Version": "3.1.1",
+ "BasePath": "C:\\Github\\Azure-Sentinel\\Solutions\\Jamf Protect",
+ "Version": "3.2.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1PConnector": false
diff --git a/Solutions/Jamf Protect/Package/3.2.0.zip b/Solutions/Jamf Protect/Package/3.2.0.zip
new file mode 100644
index 00000000000..d979e61f5e6
Binary files /dev/null and b/Solutions/Jamf Protect/Package/3.2.0.zip differ
diff --git a/Solutions/Jamf Protect/Package/createUiDefinition.json b/Solutions/Jamf Protect/Package/createUiDefinition.json
index 5ccb070d126..a1e79a0187c 100644
--- a/Solutions/Jamf Protect/Package/createUiDefinition.json
+++ b/Solutions/Jamf Protect/Package/createUiDefinition.json
@@ -1,354 +1,347 @@
-{
- "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
- "handler": "Microsoft.Azure.CreateUIDef",
- "version": "0.1.2-preview",
- "parameters": {
- "config": {
- "isWizard": false,
- "basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Jamf%20Protect/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) solution for Microsoft Sentinel enables you to ingest [Jamf Protect events](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html#task-4227) forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.\n\n**Data Connectors:** 1, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3, **Hunting Queries:** 7, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
- "subscription": {
- "resourceProviders": [
- "Microsoft.OperationsManagement/solutions",
- "Microsoft.OperationalInsights/workspaces/providers/alertRules",
- "Microsoft.Insights/workbooks",
- "Microsoft.Logic/workflows"
- ]
- },
- "location": {
- "metadata": {
- "hidden": "Hiding location, we get it from the log analytics workspace"
- },
- "visible": false
- },
- "resourceGroup": {
- "allowExisting": true
- }
- }
- },
- "basics": [
- {
- "name": "getLAWorkspace",
- "type": "Microsoft.Solutions.ArmApiControl",
- "toolTip": "This filters by workspaces that exist in the Resource Group selected",
- "condition": "[greater(length(resourceGroup().name),0)]",
- "request": {
- "method": "GET",
- "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]"
- }
- },
- {
- "name": "workspace",
- "type": "Microsoft.Common.DropDown",
- "label": "Workspace",
- "placeholder": "Select a workspace",
- "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected",
- "constraints": {
- "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]",
- "required": true
- },
- "visible": true
- }
- ],
- "steps": [
- {
- "name": "dataconnectors",
- "label": "Data Connectors",
- "bladeTitle": "Data Connectors",
- "elements": [
- {
- "name": "dataconnectors1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This Solution installs the data connector for Jamf Protect. You can get Jamf Protect custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
- }
- },
- {
- "name": "dataconnectors-parser-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "The Solution installs a parser that transforms the ingested data into Microsoft Sentinel normalized format. The normalized format enables better correlation of different types of data from different data sources to drive end-to-end outcomes seamlessly in security monitoring, hunting, incident investigation and response scenarios in Microsoft Sentinel."
- }
- },
- {
- "name": "dataconnectors-link2",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more about connecting data sources",
- "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources"
- }
- }
- }
- ]
- },
- {
- "name": "workbooks",
- "label": "Workbooks",
- "subLabel": {
- "preValidation": "Configure the workbooks",
- "postValidation": "Done"
- },
- "bladeTitle": "Workbooks",
- "elements": [
- {
- "name": "workbooks-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This solution installs workbook(s) to help you gain insights into the telemetry collected in Microsoft Sentinel. After installing the solution, start using the workbook in Manage solution view."
- }
- },
- {
- "name": "workbooks-link",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more",
- "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data"
- }
- }
- },
- {
- "name": "workbook1",
- "type": "Microsoft.Common.Section",
- "label": "Jamf Protect Workbook",
- "elements": [
- {
- "name": "workbook1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This Jamf Protect Workbook for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel.\n Providing reports into all alerts, device controls and Unfied Logs."
- }
- }
- ]
- }
- ]
- },
- {
- "name": "analytics",
- "label": "Analytics",
- "subLabel": {
- "preValidation": "Configure the analytics",
- "postValidation": "Done"
- },
- "bladeTitle": "Analytics",
- "elements": [
- {
- "name": "analytics-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view."
- }
- },
- {
- "name": "analytics-link",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more",
- "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
- }
- }
- },
- {
- "name": "analytic1",
- "type": "Microsoft.Common.Section",
- "label": "Jamf Protect - Alerts",
- "elements": [
- {
- "name": "analytic1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Creates an incident based on Jamf Protect Alert data in Microsoft Sentinel"
- }
- }
- ]
- },
- {
- "name": "analytic2",
- "type": "Microsoft.Common.Section",
- "label": "Jamf Protect - Network Threats",
- "elements": [
- {
- "name": "analytic2-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Creates an incident based based on Jamf Protect's Network Threat Event Stream alerts."
- }
- }
- ]
- },
- {
- "name": "analytic3",
- "type": "Microsoft.Common.Section",
- "label": "Jamf Protect - Unified Logs",
- "elements": [
- {
- "name": "analytic3-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Creates an informational incident based on Jamf Protect Unified Log data in Microsoft Sentinel"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "huntingqueries",
- "label": "Hunting Queries",
- "bladeTitle": "Hunting Queries",
- "elements": [
- {
- "name": "huntingqueries-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This solution installs the following hunting queries. After installing the solution, run these hunting queries to hunt for threats in Manage solution view. "
- }
- },
- {
- "name": "huntingqueries-link",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more",
- "uri": "https://docs.microsoft.com/azure/sentinel/hunting"
- }
- }
- },
- {
- "name": "huntingquery1",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - DazzleSpy",
- "elements": [
- {
- "name": "huntingquery1-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for alerts related to DazzleSpy activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- },
- {
- "name": "huntingquery2",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - JokerSpy",
- "elements": [
- {
- "name": "huntingquery2-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for alerts related to JokerSpy activity, Known to use various back doors to deploy spyware on victims' systems in order to perform reconnaissance and for command and control. This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- },
- {
- "name": "huntingquery3",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - KandyKorn",
- "elements": [
- {
- "name": "huntingquery3-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for activity related to KandyKorn activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- },
- {
- "name": "huntingquery4",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - PureLand",
- "elements": [
- {
- "name": "huntingquery4-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for activity related to PureLand activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- },
- {
- "name": "huntingquery5",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - RustBucket",
- "elements": [
- {
- "name": "huntingquery5-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for activity related to RustBucket activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- },
- {
- "name": "huntingquery6",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - Turtle",
- "elements": [
- {
- "name": "huntingquery6-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for activity related to Turtle activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- },
- {
- "name": "huntingquery7",
- "type": "Microsoft.Common.Section",
- "label": "JamfProtect - macOS - AtomicStealer",
- "elements": [
- {
- "name": "huntingquery7-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "Use this query to look for activity related to AtomicStealer activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "playbooks",
- "label": "Playbooks",
- "subLabel": {
- "preValidation": "Configure the playbooks",
- "postValidation": "Done"
- },
- "bladeTitle": "Playbooks",
- "elements": [
- {
- "name": "playbooks-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub."
- }
- },
- {
- "name": "playbooks-link",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "link": {
- "label": "Learn more",
- "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
- }
- }
- }
- ]
- }
- ],
- "outputs": {
- "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]",
- "location": "[location()]",
- "workspace": "[basics('workspace')]"
- }
- }
-}
+{
+ "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
+ "handler": "Microsoft.Azure.CreateUIDef",
+ "version": "0.1.2-preview",
+ "parameters": {
+ "config": {
+ "isWizard": false,
+ "basics": {
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Jamf%20Protect/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) solution for Microsoft Sentinel enables you to ingest [Jamf Protect events](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html#task-4227) forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.\n\n**Data Connectors:** 2, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3, **Hunting Queries:** 7, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "subscription": {
+ "resourceProviders": [
+ "Microsoft.OperationsManagement/solutions",
+ "Microsoft.OperationalInsights/workspaces/providers/alertRules",
+ "Microsoft.Insights/workbooks",
+ "Microsoft.Logic/workflows"
+ ]
+ },
+ "location": {
+ "metadata": {
+ "hidden": "Hiding location, we get it from the log analytics workspace"
+ },
+ "visible": false
+ },
+ "resourceGroup": {
+ "allowExisting": true
+ }
+ }
+ },
+ "basics": [
+ {
+ "name": "getLAWorkspace",
+ "type": "Microsoft.Solutions.ArmApiControl",
+ "toolTip": "This filters by workspaces that exist in the Resource Group selected",
+ "condition": "[greater(length(resourceGroup().name),0)]",
+ "request": {
+ "method": "GET",
+ "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]"
+ }
+ },
+ {
+ "name": "workspace",
+ "type": "Microsoft.Common.DropDown",
+ "label": "Workspace",
+ "placeholder": "Select a workspace",
+ "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected",
+ "constraints": {
+ "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]",
+ "required": true
+ },
+ "visible": true
+ }
+ ],
+ "steps": [
+ {
+ "name": "dataconnectors",
+ "label": "Data Connectors",
+ "bladeTitle": "Data Connectors",
+ "elements": [
+ {
+ "name": "dataconnectors1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for Jamf Protect. You can get Jamf Protect custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
+ },
+ {
+ "name": "dataconnectors-link2",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more about connecting data sources",
+ "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "name": "workbooks",
+ "label": "Workbooks",
+ "subLabel": {
+ "preValidation": "Configure the workbooks",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Workbooks",
+ "elements": [
+ {
+ "name": "workbooks-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This solution installs workbook(s) to help you gain insights into the telemetry collected in Microsoft Sentinel. After installing the solution, start using the workbook in Manage solution view."
+ }
+ },
+ {
+ "name": "workbooks-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data"
+ }
+ }
+ },
+ {
+ "name": "workbook1",
+ "type": "Microsoft.Common.Section",
+ "label": "Jamf Protect Workbook",
+ "elements": [
+ {
+ "name": "workbook1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Jamf Protect Workbook for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel.\n Providing reports into all alerts, device controls and Unfied Logs."
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "analytics",
+ "label": "Analytics",
+ "subLabel": {
+ "preValidation": "Configure the analytics",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Analytics",
+ "elements": [
+ {
+ "name": "analytics-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view."
+ }
+ },
+ {
+ "name": "analytics-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
+ }
+ }
+ },
+ {
+ "name": "analytic1",
+ "type": "Microsoft.Common.Section",
+ "label": "Jamf Protect - Alerts",
+ "elements": [
+ {
+ "name": "analytic1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Creates an incident based on Jamf Protect Alert data in Microsoft Sentinel"
+ }
+ }
+ ]
+ },
+ {
+ "name": "analytic2",
+ "type": "Microsoft.Common.Section",
+ "label": "Jamf Protect - Network Threats",
+ "elements": [
+ {
+ "name": "analytic2-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Creates an incident based based on Jamf Protect's Network Threat Event Stream alerts."
+ }
+ }
+ ]
+ },
+ {
+ "name": "analytic3",
+ "type": "Microsoft.Common.Section",
+ "label": "Jamf Protect - Unified Logs",
+ "elements": [
+ {
+ "name": "analytic3-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Creates an informational incident based on Jamf Protect Unified Log data in Microsoft Sentinel"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "huntingqueries",
+ "label": "Hunting Queries",
+ "bladeTitle": "Hunting Queries",
+ "elements": [
+ {
+ "name": "huntingqueries-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This solution installs the following hunting queries. After installing the solution, run these hunting queries to hunt for threats in Manage solution view. "
+ }
+ },
+ {
+ "name": "huntingqueries-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/hunting"
+ }
+ }
+ },
+ {
+ "name": "huntingquery1",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - DazzleSpy",
+ "elements": [
+ {
+ "name": "huntingquery1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for alerts related to DazzleSpy activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ },
+ {
+ "name": "huntingquery2",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - JokerSpy",
+ "elements": [
+ {
+ "name": "huntingquery2-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for alerts related to JokerSpy activity, Known to use various back doors to deploy spyware on victims' systems in order to perform reconnaissance and for command and control. This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ },
+ {
+ "name": "huntingquery3",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - KandyKorn",
+ "elements": [
+ {
+ "name": "huntingquery3-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for activity related to KandyKorn activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ },
+ {
+ "name": "huntingquery4",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - PureLand",
+ "elements": [
+ {
+ "name": "huntingquery4-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for activity related to PureLand activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ },
+ {
+ "name": "huntingquery5",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - RustBucket",
+ "elements": [
+ {
+ "name": "huntingquery5-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for activity related to RustBucket activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ },
+ {
+ "name": "huntingquery6",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - Turtle",
+ "elements": [
+ {
+ "name": "huntingquery6-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for activity related to Turtle activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ },
+ {
+ "name": "huntingquery7",
+ "type": "Microsoft.Common.Section",
+ "label": "JamfProtect - macOS - AtomicStealer",
+ "elements": [
+ {
+ "name": "huntingquery7-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Use this query to look for activity related to AtomicStealer activity, known to affect macOS devices via a MachO binary This hunting query depends on JamfProtect data connector (jamfprotect_CL Parser or Table)"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "playbooks",
+ "label": "Playbooks",
+ "subLabel": {
+ "preValidation": "Configure the playbooks",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Playbooks",
+ "elements": [
+ {
+ "name": "playbooks-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub."
+ }
+ },
+ {
+ "name": "playbooks-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "outputs": {
+ "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]",
+ "location": "[location()]",
+ "workspace": "[basics('workspace')]"
+ }
+ }
+}
diff --git a/Solutions/Jamf Protect/Package/mainTemplate.json b/Solutions/Jamf Protect/Package/mainTemplate.json
index 4b2df75e1c5..d927dfc92b7 100644
--- a/Solutions/Jamf Protect/Package/mainTemplate.json
+++ b/Solutions/Jamf Protect/Package/mainTemplate.json
@@ -1,3801 +1,5447 @@
-{
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
- "metadata": {
- "author": "Thijs Xhaflaire - thijs.xhaflaire@jamf.com",
- "comments": "Solution template for Jamf Protect"
- },
- "parameters": {
- "location": {
- "type": "string",
- "minLength": 1,
- "defaultValue": "[resourceGroup().location]",
- "metadata": {
- "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
- }
- },
- "workspace-location": {
- "type": "string",
- "defaultValue": "",
- "metadata": {
- "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
- }
- },
- "workspace": {
- "defaultValue": "",
- "type": "string",
- "metadata": {
- "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
- }
- },
- "workbook1-name": {
- "type": "string",
- "defaultValue": "Jamf Protect Workbook",
- "minLength": 1,
- "metadata": {
- "description": "Name for the workbook"
- }
- }
- },
- "variables": {
- "email": "thijs.xhaflaire@jamf.com",
- "_email": "[variables('email')]",
- "_solutionName": "Jamf Protect",
- "_solutionVersion": "3.1.1",
- "solutionId": "jamfsoftwareaustraliaptyltd1620360395539.jamf_protect",
- "_solutionId": "[variables('solutionId')]",
- "uiConfigId1": "JamfProtect",
- "_uiConfigId1": "[variables('uiConfigId1')]",
- "dataConnectorContentId1": "JamfProtect",
- "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]",
- "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "_dataConnectorId1": "[variables('dataConnectorId1')]",
- "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
- "dataConnectorVersion1": "3.1.0",
- "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
- "parserObject1": {
- "_parserName1": "[concat(parameters('workspace'),'/','JamfProtect')]",
- "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]",
- "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('JamfProtect-Parser')))]",
- "parserVersion1": "3.1.0",
- "parserContentId1": "JamfProtect-Parser"
- },
- "workbookVersion1": "2.0.0",
- "workbookContentId1": "JamfProtectWorkbook",
- "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
- "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]",
- "_workbookContentId1": "[variables('workbookContentId1')]",
- "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
- "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
- "analyticRuleObject1": {
- "analyticRuleVersion1": "1.0.5",
- "_analyticRulecontentId1": "6098daa0-f05e-44d5-b5a0-913e63ba3179",
- "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '6098daa0-f05e-44d5-b5a0-913e63ba3179')]",
- "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('6098daa0-f05e-44d5-b5a0-913e63ba3179')))]",
- "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','6098daa0-f05e-44d5-b5a0-913e63ba3179','-', '1.0.5')))]"
- },
- "analyticRuleObject2": {
- "analyticRuleVersion2": "1.0.3",
- "_analyticRulecontentId2": "44da53c3-f3b0-4b70-afff-f79275cb9442",
- "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '44da53c3-f3b0-4b70-afff-f79275cb9442')]",
- "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('44da53c3-f3b0-4b70-afff-f79275cb9442')))]",
- "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','44da53c3-f3b0-4b70-afff-f79275cb9442','-', '1.0.3')))]"
- },
- "analyticRuleObject3": {
- "analyticRuleVersion3": "1.0.2",
- "_analyticRulecontentId3": "9eb2f758-003b-4303-83c6-97aed4c03e41",
- "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '9eb2f758-003b-4303-83c6-97aed4c03e41')]",
- "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('9eb2f758-003b-4303-83c6-97aed4c03e41')))]",
- "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','9eb2f758-003b-4303-83c6-97aed4c03e41','-', '1.0.2')))]"
- },
- "huntingQueryObject1": {
- "huntingQueryVersion1": "1.0.0",
- "_huntingQuerycontentId1": "f0a1bacb-eb6a-4edc-99a9-839a77be3a33",
- "huntingQueryTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('f0a1bacb-eb6a-4edc-99a9-839a77be3a33')))]"
- },
- "huntingQueryObject2": {
- "huntingQueryVersion2": "1.0.0",
- "_huntingQuerycontentId2": "8d9a199b-7968-476b-b02b-d030a010609c",
- "huntingQueryTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('8d9a199b-7968-476b-b02b-d030a010609c')))]"
- },
- "huntingQueryObject3": {
- "huntingQueryVersion3": "1.0.0",
- "_huntingQuerycontentId3": "60b1269f-374e-49dd-8b10-e4ef85d5bd65",
- "huntingQueryTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('60b1269f-374e-49dd-8b10-e4ef85d5bd65')))]"
- },
- "huntingQueryObject4": {
- "huntingQueryVersion4": "1.0.0",
- "_huntingQuerycontentId4": "ec2f21aa-a9c5-42fd-9ee1-c59f30b4fdd6",
- "huntingQueryTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('ec2f21aa-a9c5-42fd-9ee1-c59f30b4fdd6')))]"
- },
- "huntingQueryObject5": {
- "huntingQueryVersion5": "1.0.0",
- "_huntingQuerycontentId5": "223f6758-e134-45e8-a9d6-4ca8455799fb",
- "huntingQueryTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('223f6758-e134-45e8-a9d6-4ca8455799fb')))]"
- },
- "huntingQueryObject6": {
- "huntingQueryVersion6": "1.0.0",
- "_huntingQuerycontentId6": "09161cb2-f28a-437c-83e3-60b8545dc8f2",
- "huntingQueryTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('09161cb2-f28a-437c-83e3-60b8545dc8f2')))]"
- },
- "huntingQueryObject7": {
- "huntingQueryVersion7": "1.0.0",
- "_huntingQuerycontentId7": "2b0ec436-80d6-4e63-b3da-e35048724f37",
- "huntingQueryTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('2b0ec436-80d6-4e63-b3da-e35048724f37')))]"
- },
- "JamfProtect_Alert_Status_InProgress": "JamfProtect_Alert_Status_InProgress",
- "_JamfProtect_Alert_Status_InProgress": "[variables('JamfProtect_Alert_Status_InProgress')]",
- "playbookVersion1": "1.0",
- "playbookContentId1": "JamfProtect_Alert_Status_InProgress",
- "_playbookContentId1": "[variables('playbookContentId1')]",
- "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]",
- "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]",
- "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]",
- "JamfProtect_Alert_Status_Resolved": "JamfProtect_Alert_Status_Resolved",
- "_JamfProtect_Alert_Status_Resolved": "[variables('JamfProtect_Alert_Status_Resolved')]",
- "playbookVersion2": "1.0",
- "playbookContentId2": "JamfProtect_Alert_Status_Resolved",
- "_playbookContentId2": "[variables('playbookContentId2')]",
- "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]",
- "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]",
- "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]",
- "JamfProtect_LockComputer_with_JamfPro": "JamfProtect_LockComputer_with_JamfPro",
- "_JamfProtect_LockComputer_with_JamfPro": "[variables('JamfProtect_LockComputer_with_JamfPro')]",
- "playbookVersion3": "1.0",
- "playbookContentId3": "JamfProtect_LockComputer_with_JamfPro",
- "_playbookContentId3": "[variables('playbookContentId3')]",
- "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]",
- "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]",
- "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]",
- "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
- },
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('dataConnectorTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "Jamf Protect data connector with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('dataConnectorVersion1')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
- "apiVersion": "2021-03-01-preview",
- "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
- "location": "[parameters('workspace-location')]",
- "kind": "GenericUI",
- "properties": {
- "connectorUiConfig": {
- "id": "[variables('_uiConfigId1')]",
- "title": "Jamf Protect",
- "publisher": "Jamf",
- "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
- "graphQueries": [
- {
- "metricName": "Total Activities data received",
- "legend": "jamfprotect_CL",
- "baseQuery": "jamfprotect_CL"
- }
- ],
- "sampleQueries": [
- {
- "description": "Jamf Protect - All events.",
- "query": "jamfprotect_CL\n | sort by TimeGenerated desc"
- },
- {
- "description": "Jamf Protect - All active endpoints.",
- "query": "jamfprotect_CL\n | where notempty(input_host_hostname_s) | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | sort by Event desc"
- },
- {
- "description": "Jamf Protect - Top 10 endpoints with Alerts",
- "query": "jamfprotect_CL\n | where topicType_s == 'alert' and notempty(input_eventType_s) and notempty(input_host_hostname_s)\n | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | top 10 by Event"
- }
- ],
- "dataTypes": [
- {
- "name": "jamfprotect_CL",
- "lastDataReceivedQuery": "jamfprotect_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
- }
- ],
- "connectivityCriterias": [
- {
- "type": "IsConnectedQuery",
- "value": [
- "jamfprotect_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
- ]
- }
- ],
- "availability": {
- "status": 1,
- "isPreview": false
- },
- "permissions": {
- "resourceProvider": [
- {
- "provider": "Microsoft.OperationalInsights/workspaces",
- "permissionsDisplayText": "read and write permissions are required.",
- "providerDisplayName": "Workspace",
- "scope": "Workspace",
- "requiredPermissions": {
- "write": true,
- "read": true,
- "delete": true
- }
- },
- {
- "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
- "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
- "providerDisplayName": "Keys",
- "scope": "Workspace",
- "requiredPermissions": {
- "action": true
- }
- }
- ]
- },
- "instructionSteps": [
- {
- "description": "This connector reads data from the jamfprotect_CL table created by Jamf Protect in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API."
- }
- ],
- "metadata": {
- "id": "AF74EDD7-5534-46CD-B75D-7119BE1D161D",
- "version": "3.1.0",
- "kind": "dataConnector",
- "source": {
- "kind": "solution",
- "name": "Jamf Protect for Microsoft Sentinel"
- },
- "author": {
- "name": "Thijs Xhaflaire"
- },
- "support": {
- "tier": "developer",
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "link": "https://jamf.com/support/"
- }
- }
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2023-04-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
- "properties": {
- "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "kind": "DataConnector",
- "version": "[variables('dataConnectorVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "contentKind": "DataConnector",
- "displayName": "Jamf Protect",
- "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
- "id": "[variables('_dataConnectorcontentProductId1')]",
- "version": "[variables('dataConnectorVersion1')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2023-04-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
- "dependsOn": [
- "[variables('_dataConnectorId1')]"
- ],
- "location": "[parameters('workspace-location')]",
- "properties": {
- "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "kind": "DataConnector",
- "version": "[variables('dataConnectorVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- },
- {
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
- "apiVersion": "2021-03-01-preview",
- "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
- "location": "[parameters('workspace-location')]",
- "kind": "GenericUI",
- "properties": {
- "connectorUiConfig": {
- "title": "Jamf Protect",
- "publisher": "Jamf",
- "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
- "graphQueries": [
- {
- "metricName": "Total Activities data received",
- "legend": "jamfprotect_CL",
- "baseQuery": "jamfprotect_CL"
- }
- ],
- "dataTypes": [
- {
- "name": "jamfprotect_CL",
- "lastDataReceivedQuery": "jamfprotect_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
- }
- ],
- "connectivityCriterias": [
- {
- "type": "IsConnectedQuery",
- "value": [
- "jamfprotect_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
- ]
- }
- ],
- "sampleQueries": [
- {
- "description": "Jamf Protect - All events.",
- "query": "jamfprotect_CL\n | sort by TimeGenerated desc"
- },
- {
- "description": "Jamf Protect - All active endpoints.",
- "query": "jamfprotect_CL\n | where notempty(input_host_hostname_s) | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | sort by Event desc"
- },
- {
- "description": "Jamf Protect - Top 10 endpoints with Alerts",
- "query": "jamfprotect_CL\n | where topicType_s == 'alert' and notempty(input_eventType_s) and notempty(input_host_hostname_s)\n | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | top 10 by Event"
- }
- ],
- "availability": {
- "status": 1,
- "isPreview": false
- },
- "permissions": {
- "resourceProvider": [
- {
- "provider": "Microsoft.OperationalInsights/workspaces",
- "permissionsDisplayText": "read and write permissions are required.",
- "providerDisplayName": "Workspace",
- "scope": "Workspace",
- "requiredPermissions": {
- "write": true,
- "read": true,
- "delete": true
- }
- },
- {
- "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
- "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
- "providerDisplayName": "Keys",
- "scope": "Workspace",
- "requiredPermissions": {
- "action": true
- }
- }
- ]
- },
- "instructionSteps": [
- {
- "description": "This connector reads data from the jamfprotect_CL table created by Jamf Protect in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API."
- }
- ],
- "id": "[variables('_uiConfigId1')]"
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('parserObject1').parserTemplateSpecName1]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect Data Parser with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('parserObject1').parserVersion1]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "name": "[variables('parserObject1')._parserName1]",
- "apiVersion": "2022-10-01",
- "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect",
- "category": "Microsoft Sentinel Parser",
- "functionAlias": "JamfProtect",
- "query": "let JamfProtectAlerts_view = view () {\n jamfprotect_CL\n| where topicType_s == \"alert\"\n and input_eventType_s <> \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n// JSON Parsing at earliest stage\n| extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Jamf Protect - Alerts'\n| project-rename\n EventOriginalUid = input_match_uuid_g\n| extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventMessage = coalesce(Match_facts[1].name, Match_facts[0].name),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventProductVersion = column_ifexists(\"input_host_protectVersion_s\", \"\"),\n //\n // Jamf Protect - Alert details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(Related_processes[array_length(Related_processes) - 1].path),\n ActingProcessCreationTime = format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[array_length(Related_processes) - 1].startTimestamp)), 'HH:mm:ss'),\n ActingProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].responsiblePID)),\n ActingProcessGuid = tostring(Related_processes[array_length(Related_processes) - 1].uuid),\n ParentProcessName = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].path), \"\"),\n ParentProcessCreationTime = iff(array_length(Related_processes) > 1, format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[1].startTimestamp)), 'HH:mm:ss'), \"\"),\n ParentProcessId = iff(array_length(Related_processes) > 1, toreal(Related_processes[1].pid), double(null)),\n ParentProcessGuid = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].uuid), \"\"),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessSHA256 = Related_binaries[0].sha256hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n //TargetProcessStatusCode = column_ifexists(Related_processes[0].exitCode, \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_processes[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].uid)),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\"),\n //\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = Related_binaries[0].path,\n TargetBinarySHA1 = tostring(Related_binaries[0].sha1hex),\n TargetBinarySHA256 = tostring(Related_binaries[0].sha256hex),\n TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(Related_binaries[0].signingInfo.signerType == 0, \"Apple\", Related_binaries[0].signingInfo.signerType == 1, \"App Store\", Related_binaries[0].signingInfo.signerType == 2, \"Developer\", Related_binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = tostring(Related_binaries[0].signingInfo.teamid),\n TargetBinarySigningAppID = tostring(Related_binaries[0].signingInfo.appid)\n| project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventProductVersion,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n| project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventProductVersion,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n};\n//\n// Jamf Protect - Unified Logs\n//\nlet JamfProtectUnifiedLog_view = view () {\n jamfprotect_CL\n | where input_eventType_s == \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n // JSON Parsing at earliest stage\n | extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Unified Log'\n | project-rename\n EventOriginalUid = input_match_uuid_g\n | extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"Auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n //\n // Jamf Protect - Unified Logs details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Unified Logs - Process\n //\n //ParentProcessName = coalesce(input_match_event_process_ppid_d, parse_json('input_related_processes_s')[0].ppid), //column_ifexists(\"exec_chain_child_parent_path_s\", \"\"), coalesce('input.match.event.process.ppid', mvindex('input.related.processes{}.ppid', 0))\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ParentProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].ppid)),\n ParentProcessGuid = tostring(coalesce(input_match_event_process_pgid_d, toreal(Related_processes[0].pgid))),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_users[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect Unified Logs - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\")\n | project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags\n | project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event*\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetry_view = view () {\n jamfprotect_CL\n | where header_event_name_s startswith \"AUE_\" \n or header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\"\n or header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Telemetry'\n // Data Field Normalization\n //| project-rename \n // DvcIpAddr = input_host_ips_s,\n // DvcId = context_identity_claims_clientid_g\n | extend\n // Jamf Protect Alerts - Generic Information\n EventSeverity = case(\n input_match_severity_d == 0,\n \"Informational\",\n input_match_severity_d == 1,\n \"Low\",\n input_match_severity_d == 2,\n \"Medium\",\n input_match_severity_d == 3,\n \"High\",\n \"Informational\"\n ),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = coalesce(return_description_s, texts_s),\n // Jamf Protect Telemetry - Endpoint Information\n TargetModel = column_ifexists(\"metrics_hw_model_s\", \"\"),\n DvcOsVersion = column_ifexists(\"host_info_osversion_s\", \"\"),\n TargetHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"context_identity_claims_clientid_g\", \"\"),\n // Jamf Protect - Event Types\n EventType = case(\n header_event_name_s == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header_event_name_s == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_auth_user\",\n \"Elevate\",\n header_event_name_s == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header_event_name_s == \"AUE_CHDIR\",\n \"FolderMoved\",\n header_event_name_s == \"AUE_CHROOT\",\n \"FolderModified\",\n header_event_name_s == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_create_group\",\n \"GroupCreated\",\n header_event_name_s == \"AUE_create_user\",\n \"UserCreated\",\n header_event_name_s == \"AUE_delete_group\",\n \"GroupDeleted\",\n header_event_name_s == \"AUE_delete_user\",\n \"UserDeleted\",\n header_event_name_s == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_FORK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_GETAUID\",\n \"\",\n header_event_name_s == \"AUE_KILL\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_logout\",\n \"Logoff\",\n header_event_name_s == \"AUE_lw_login\",\n \"Logon\",\n header_event_name_s == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_modify_group\",\n \"GroupModified\",\n header_event_name_s == \"AUE_modify_password\",\n \"PasswordChanged\",\n header_event_name_s == \"AUE_modify_user\",\n \"UserModified\",\n header_event_name_s == \"AUE_MOUNT\",\n \"VolumeMount\",\n header_event_name_s == \"AUE_openssh\",\n \"SshInitiated\",\n header_event_name_s == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header_event_name_s == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_END\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_START\",\n \"Logon\",\n header_event_name_s == \"AUE_SESSION_UPDATE\",\n \"\",\n header_event_name_s == \"AUE_SETPRIORITY\",\n \"\",\n header_event_name_s == \"AUE_SETSOCKOPT\",\n \"\",\n header_event_name_s == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header_event_name_s == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header_event_name_s == \"AUE_SOCKETPAIR\",\n \"\",\n header_event_name_s == \"AUE_ssauthint\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthmech\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthorize\",\n \"Elevate\",\n header_event_name_s == \"AUE_TASKFORPID\",\n \"\",\n header_event_name_s == \"AUE_TASKNAMEFORPID\",\n \"\",\n header_event_name_s == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header_event_name_s == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n // Jamf Protect Telemetry - Process\n ParentProcessName = column_ifexists(\"subject_responsible_process_name_s\", \"\"),\n ParentProcessId = column_ifexists(\"subject_responsible_process_id_d\", \"\"),\n ParentProcessGuid = column_ifexists(\"exec_chain_child_parent_uuid_g\", \"\"),\n TargetProcessName = column_ifexists(\"subject_process_name_s\", \"\"),\n TargetProcessId = column_ifexists(\"subject_process_id_d\", \"\"),\n TargetProcessGuid = column_ifexists(\"exec_chain_thread_uuid_g\", \"\"),\n TargetProcessSHA256 = todynamic(column_ifexists(\"subject_process_hash_s\", \"\")),\n TargetUserId = toreal(column_ifexists(\"subject_user_id_d\", \"\")),\n TargetUsername = tostring(column_ifexists(\"subject_user_name_s\", \"\")),\n TargetProcessCommandLine = column_ifexists(\"exec_args_args_compiled_s\", \"\"),\n ActorUsername = tostring(column_ifexists(\"subject_effective_user_name_s\", \"\")),\n ActorUserId = column_ifexists(\"subject_audit_user_name_s\", \"\"),\n //column_ifexists(\"application_name_s\", \"\"),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = todynamic(column_ifexists(\"subject_group_name_s\", \"\")),\n // Jamf Protect Telemetry - Network\n DstIpAddr = column_ifexists(\"socket_inet_ip_address_s\", \"\"),\n DstPortNumber = column_ifexists(\"socket_inet_port_d\", \"\"),\n NetworkProtocolVersion = case(socket_inet_id_d == 128, \"IPV4\", socket_inet_id_d == 129, \"IPV6\", \"\"),\n SrcIpAddr = column_ifexists(\"subject_terminal_id_ip_address_s\", \"\"),\n //\n // Jamf Protect Telemetry - Binaries\n //\n // TargetBinaryFilePath = todynamic(Related_binaries[0].path),\n TargetBinarySHA256 = tostring(identity_cd_hash_s),\n // TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(identity_signer_type_d == 0, \"Developer\", identity_signer_type_d == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity_team_id_s),\n TargetBinarySigningAppID = tostring(identity_signer_id_s),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = tostring(parse_json(path_s))\n | project-reorder\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventSeverity,\n EventResult,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOsVersion,\n DvcIpAddr,\n TargetModel,\n TargetUserId,\n TargetUsername,\n ParentProcessName,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA256,\n TargetProcessCommandLine,\n ActorUsername,\n ActorUserId,\n TargetBinarySHA256,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n GroupName,\n SrcIpAddr,\n DstIpAddr,\n DstPortNumber,\n NetworkProtocolVersion,\n TargetFilePath\n | project-away\n arguments_sflags_d,\n arguments_am_failure_d,\n arguments_am_success_d\n};\n//\n// Jamf Protect - Threat Events\n//\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectNetworkTraffic_view, JamfProtectTelemetry_view, JamfProtectThreatEvents_view\n",
- "functionParameters": "",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": ""
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
- "dependsOn": [
- "[variables('parserObject1')._parserId1]"
- ],
- "properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]",
- "contentId": "[variables('parserObject1').parserContentId1]",
- "kind": "Parser",
- "version": "[variables('parserObject1').parserVersion1]",
- "source": {
- "name": "Jamf Protect",
- "kind": "Solution",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('parserObject1').parserContentId1]",
- "contentKind": "Parser",
- "displayName": "JamfProtect",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.1.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.1.0')))]",
- "version": "[variables('parserObject1').parserVersion1]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "[variables('parserObject1')._parserName1]",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect",
- "category": "Microsoft Sentinel Parser",
- "functionAlias": "JamfProtect",
- "query": "let JamfProtectAlerts_view = view () {\n jamfprotect_CL\n| where topicType_s == \"alert\"\n and input_eventType_s <> \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n// JSON Parsing at earliest stage\n| extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Jamf Protect - Alerts'\n| project-rename\n EventOriginalUid = input_match_uuid_g\n| extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventMessage = coalesce(Match_facts[1].name, Match_facts[0].name),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventProductVersion = column_ifexists(\"input_host_protectVersion_s\", \"\"),\n //\n // Jamf Protect - Alert details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(Related_processes[array_length(Related_processes) - 1].path),\n ActingProcessCreationTime = format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[array_length(Related_processes) - 1].startTimestamp)), 'HH:mm:ss'),\n ActingProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].responsiblePID)),\n ActingProcessGuid = tostring(Related_processes[array_length(Related_processes) - 1].uuid),\n ParentProcessName = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].path), \"\"),\n ParentProcessCreationTime = iff(array_length(Related_processes) > 1, format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[1].startTimestamp)), 'HH:mm:ss'), \"\"),\n ParentProcessId = iff(array_length(Related_processes) > 1, toreal(Related_processes[1].pid), double(null)),\n ParentProcessGuid = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].uuid), \"\"),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessSHA256 = Related_binaries[0].sha256hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n //TargetProcessStatusCode = column_ifexists(Related_processes[0].exitCode, \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_processes[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].uid)),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\"),\n //\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = Related_binaries[0].path,\n TargetBinarySHA1 = tostring(Related_binaries[0].sha1hex),\n TargetBinarySHA256 = tostring(Related_binaries[0].sha256hex),\n TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(Related_binaries[0].signingInfo.signerType == 0, \"Apple\", Related_binaries[0].signingInfo.signerType == 1, \"App Store\", Related_binaries[0].signingInfo.signerType == 2, \"Developer\", Related_binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = tostring(Related_binaries[0].signingInfo.teamid),\n TargetBinarySigningAppID = tostring(Related_binaries[0].signingInfo.appid)\n| project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventProductVersion,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n| project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventProductVersion,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n};\n//\n// Jamf Protect - Unified Logs\n//\nlet JamfProtectUnifiedLog_view = view () {\n jamfprotect_CL\n | where input_eventType_s == \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n // JSON Parsing at earliest stage\n | extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Unified Log'\n | project-rename\n EventOriginalUid = input_match_uuid_g\n | extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"Auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n //\n // Jamf Protect - Unified Logs details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Unified Logs - Process\n //\n //ParentProcessName = coalesce(input_match_event_process_ppid_d, parse_json('input_related_processes_s')[0].ppid), //column_ifexists(\"exec_chain_child_parent_path_s\", \"\"), coalesce('input.match.event.process.ppid', mvindex('input.related.processes{}.ppid', 0))\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ParentProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].ppid)),\n ParentProcessGuid = tostring(coalesce(input_match_event_process_pgid_d, toreal(Related_processes[0].pgid))),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_users[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect Unified Logs - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\")\n | project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags\n | project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event*\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetry_view = view () {\n jamfprotect_CL\n | where header_event_name_s startswith \"AUE_\" \n or header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\"\n or header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Telemetry'\n // Data Field Normalization\n //| project-rename \n // DvcIpAddr = input_host_ips_s,\n // DvcId = context_identity_claims_clientid_g\n | extend\n // Jamf Protect Alerts - Generic Information\n EventSeverity = case(\n input_match_severity_d == 0,\n \"Informational\",\n input_match_severity_d == 1,\n \"Low\",\n input_match_severity_d == 2,\n \"Medium\",\n input_match_severity_d == 3,\n \"High\",\n \"Informational\"\n ),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = coalesce(return_description_s, texts_s),\n // Jamf Protect Telemetry - Endpoint Information\n TargetModel = column_ifexists(\"metrics_hw_model_s\", \"\"),\n DvcOsVersion = column_ifexists(\"host_info_osversion_s\", \"\"),\n TargetHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"context_identity_claims_clientid_g\", \"\"),\n // Jamf Protect - Event Types\n EventType = case(\n header_event_name_s == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header_event_name_s == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_auth_user\",\n \"Elevate\",\n header_event_name_s == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header_event_name_s == \"AUE_CHDIR\",\n \"FolderMoved\",\n header_event_name_s == \"AUE_CHROOT\",\n \"FolderModified\",\n header_event_name_s == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_create_group\",\n \"GroupCreated\",\n header_event_name_s == \"AUE_create_user\",\n \"UserCreated\",\n header_event_name_s == \"AUE_delete_group\",\n \"GroupDeleted\",\n header_event_name_s == \"AUE_delete_user\",\n \"UserDeleted\",\n header_event_name_s == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_FORK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_GETAUID\",\n \"\",\n header_event_name_s == \"AUE_KILL\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_logout\",\n \"Logoff\",\n header_event_name_s == \"AUE_lw_login\",\n \"Logon\",\n header_event_name_s == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_modify_group\",\n \"GroupModified\",\n header_event_name_s == \"AUE_modify_password\",\n \"PasswordChanged\",\n header_event_name_s == \"AUE_modify_user\",\n \"UserModified\",\n header_event_name_s == \"AUE_MOUNT\",\n \"VolumeMount\",\n header_event_name_s == \"AUE_openssh\",\n \"SshInitiated\",\n header_event_name_s == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header_event_name_s == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_END\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_START\",\n \"Logon\",\n header_event_name_s == \"AUE_SESSION_UPDATE\",\n \"\",\n header_event_name_s == \"AUE_SETPRIORITY\",\n \"\",\n header_event_name_s == \"AUE_SETSOCKOPT\",\n \"\",\n header_event_name_s == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header_event_name_s == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header_event_name_s == \"AUE_SOCKETPAIR\",\n \"\",\n header_event_name_s == \"AUE_ssauthint\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthmech\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthorize\",\n \"Elevate\",\n header_event_name_s == \"AUE_TASKFORPID\",\n \"\",\n header_event_name_s == \"AUE_TASKNAMEFORPID\",\n \"\",\n header_event_name_s == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header_event_name_s == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n // Jamf Protect Telemetry - Process\n ParentProcessName = column_ifexists(\"subject_responsible_process_name_s\", \"\"),\n ParentProcessId = column_ifexists(\"subject_responsible_process_id_d\", \"\"),\n ParentProcessGuid = column_ifexists(\"exec_chain_child_parent_uuid_g\", \"\"),\n TargetProcessName = column_ifexists(\"subject_process_name_s\", \"\"),\n TargetProcessId = column_ifexists(\"subject_process_id_d\", \"\"),\n TargetProcessGuid = column_ifexists(\"exec_chain_thread_uuid_g\", \"\"),\n TargetProcessSHA256 = todynamic(column_ifexists(\"subject_process_hash_s\", \"\")),\n TargetUserId = toreal(column_ifexists(\"subject_user_id_d\", \"\")),\n TargetUsername = tostring(column_ifexists(\"subject_user_name_s\", \"\")),\n TargetProcessCommandLine = column_ifexists(\"exec_args_args_compiled_s\", \"\"),\n ActorUsername = tostring(column_ifexists(\"subject_effective_user_name_s\", \"\")),\n ActorUserId = column_ifexists(\"subject_audit_user_name_s\", \"\"),\n //column_ifexists(\"application_name_s\", \"\"),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = todynamic(column_ifexists(\"subject_group_name_s\", \"\")),\n // Jamf Protect Telemetry - Network\n DstIpAddr = column_ifexists(\"socket_inet_ip_address_s\", \"\"),\n DstPortNumber = column_ifexists(\"socket_inet_port_d\", \"\"),\n NetworkProtocolVersion = case(socket_inet_id_d == 128, \"IPV4\", socket_inet_id_d == 129, \"IPV6\", \"\"),\n SrcIpAddr = column_ifexists(\"subject_terminal_id_ip_address_s\", \"\"),\n //\n // Jamf Protect Telemetry - Binaries\n //\n // TargetBinaryFilePath = todynamic(Related_binaries[0].path),\n TargetBinarySHA256 = tostring(identity_cd_hash_s),\n // TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(identity_signer_type_d == 0, \"Developer\", identity_signer_type_d == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity_team_id_s),\n TargetBinarySigningAppID = tostring(identity_signer_id_s),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = tostring(parse_json(path_s))\n | project-reorder\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventSeverity,\n EventResult,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOsVersion,\n DvcIpAddr,\n TargetModel,\n TargetUserId,\n TargetUsername,\n ParentProcessName,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA256,\n TargetProcessCommandLine,\n ActorUsername,\n ActorUserId,\n TargetBinarySHA256,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n GroupName,\n SrcIpAddr,\n DstIpAddr,\n DstPortNumber,\n NetworkProtocolVersion,\n TargetFilePath\n | project-away\n arguments_sflags_d,\n arguments_am_failure_d,\n arguments_am_success_d\n};\n//\n// Jamf Protect - Threat Events\n//\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectNetworkTraffic_view, JamfProtectTelemetry_view, JamfProtectThreatEvents_view\n",
- "functionParameters": "",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": ""
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "location": "[parameters('workspace-location')]",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
- "dependsOn": [
- "[variables('parserObject1')._parserId1]"
- ],
- "properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]",
- "contentId": "[variables('parserObject1').parserContentId1]",
- "kind": "Parser",
- "version": "[variables('parserObject1').parserVersion1]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtectDashboard Workbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion1')]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId1')]",
- "location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "This Jamf Protect Workbook for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel.\n Providing reports into all alerts, device controls and Unfied Logs."
- },
- "properties": {
- "displayName": "[parameters('workbook1-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"b608e714-b3ec-4380-b666-1aa781513ab4\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Subscription\",\"type\":6,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"includeAll\":false},\"label\":\"☁️ Subscription\"},{\"id\":\"f408f1cf-dbcb-4f57-9409-272374bd3cd4\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Workspace\",\"type\":5,\"isRequired\":true,\"query\":\"Resources | where type =~ \\\"microsoft.operationalinsights/workspaces\\\" | order by name | project id, name, selected=row_number()==1, group=resourceGroup\",\"crossComponentResources\":[\"{Subscription}\"],\"queryType\":1,\"resourceType\":\"microsoft.resourcegraph/resources\",\"label\":\"🗂️ Workspace\",\"value\":\"\"},{\"id\":\"397d983f-ea80-4aa5-8c65-547d40cb312b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_timetoken\",\"label\":\"⏱️ Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"value\":{\"durationMs\":172800000}},{\"id\":\"d716fb1e-0d71-4e99-9406-18ae7df6e037\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"changelog\",\"label\":\"📖 Changelog\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\": \\\"Yes\\\", \\\"label\\\": \\\"Yes\\\"},\\r\\n {\\\"value\\\": \\\"No\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Parameters Picker\"},{\"type\":1,\"content\":{\"json\":\"## Jamf Protect for Microsoft Sentinel!\\n\\nThe [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) for Microsoft Sentinel solution creates detailed event data from macOS endpoints into a Microsoft Sentinel workspace in a simple and easy workflow. The solution provides you with full visibility into Apple Endpoint Security by leveraging Workbooks containing [Alert](https://docs.jamf.com/jamf-protect/documentation/Alerts.html) and [Unified Logging](https://docs.jamf.com/jamf-protect/documentation/Unified_Logging.html) events captured by Jamf Protect and the [macOS built-in security events](https://support.apple.com/en-gb/guide/security/sec469d47bd8/web) that occurred across the protected organisational endpoints\\n\\n\\n#### Changelog\\n\\n**v2.2.0**\\n\\n***Workbook***\\n - Added System Performance Metrics\\n - Includes Energy Impact\\n - Added Network Traffic Stream\\n - Updated Workbook to make use of the newly added parser\\n - Added and tweaked querys and graphs\\n\\n ***Parser***\\n - Added JamfProtect parser for parsing and mapping all incoming raw data.\\n\\n ***Analytic Rules***\\n - Updated Analytic Rules to make use of the newly added parser. \\n\\t\\n**v2.1**\\n\\n***Workbook***\\n - Added Endpoint Telemetry\\n - Includes graphs and visualisations\\n\\t- Includes Endpoint Information\\n\\t- Includes Jamf Pro log parser\\n- Added Network Threat Events\\n \\t- Includes graphs and visualisations\\n- Added new Pickers\\n - Allows selecting different Log Analytic Workspaces\\n - Changed TimeRanger picker\\n- Added Changelog\\n\\n**Analytic Rules**\\n\\n- Added Analytic Rules\\n\\t- Jamf Protect - Alerts\\n\\t- Jamf Protect - Unified Logs\\n\\t- Jamf Protect - Network Threat Events\\n\\n\\n **v2.0**\\n \\n- Initial release of the solution containing a basic Workbook\\n\"},\"conditionalVisibility\":{\"parameterName\":\"changelog\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"Text - Changelog\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Threat Hunting {_timetoken:value}\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"Set an type and provide values to search on File hash, CVE numbers or report on Alerts mapped to the MITRE framework or display latest alerts for a single endpoint.\",\"style\":\"info\"},\"name\":\"Text - Threat Hunting\",\"styleSettings\":{\"showBorder\":true}},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"5f5886d0-e83e-4ffc-a48c-bfed7370aa66\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_type\",\"label\":\"Type\",\"type\":2,\"description\":\"Please choose the type\",\"isGlobal\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"filehash\\\", \\\"label\\\":\\\"File Hash\\\" },\\n { \\\"value\\\":\\\"CVE\\\", \\\"label\\\":\\\"CVE\\\" },\\n { \\\"value\\\":\\\"mitre\\\", \\\"label\\\":\\\"Framework: MITRE\\\" },\\n { \\\"value\\\":\\\"endpointalerts\\\", \\\"label\\\":\\\"Latest alerts for a single endpoint\\\" }\\n]\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"15\",\"name\":\"Picker - Threat Hunting Type\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"{Workspace}\"],\"parameters\":[{\"id\":\"49255f47-8f93-4746-8260-aad07befdb06\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_hostnamealert\",\"label\":\"Hostname\",\"type\":2,\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n | project-keep DvcHostname\\n| project-rename Hostname = DvcHostname\\n| summarize by Hostname\",\"crossComponentResources\":[\"{Workspace}\"],\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"conditionalVisibilities\":[{\"parameterName\":\"_type\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"endpointalerts\"}],\"name\":\"Picker - Threat Hunting Hostname\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"bcdd945e-4dfe-47d6-9489-f76ce012c224\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_filehash\",\"label\":\"File Hash\",\"type\":1,\"description\":\"Thish value can be used for searching all alerts for a certain hash\",\"isRequired\":true,\"isGlobal\":true,\"value\":\"5e54bccbd4d93447e79cda0558b0b308a186c2be571c739e5460a3cb6ef665c0\"}],\"style\":\"formHorizontal\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"conditionalVisibility\":{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"filehash\"},\"name\":\"Search - Threat Hunting Hash\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"0344768b-16c4-44ec-a4ac-73a8bc83d0e2\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_CVE\",\"label\":\"CVE Number\",\"type\":1,\"description\":\"Please search on the CVE number\",\"isRequired\":true,\"isGlobal\":true,\"value\":\"T15\"}],\"style\":\"formHorizontal\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"conditionalVisibility\":{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"CVE\"},\"name\":\"Search - Threat Hunting CVE\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"ProcessPrevented\\\" or EventType == \\\"ProcessCreated\\\"\\n| where TargetProcessSHA1 has \\\"{_filehash:value}\\\" or TargetBinarySHA256 has \\\"{_filehash:value}\\\"\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\",\"size\":4,\"title\":\"Matches on FileHash\",\"noDataMessage\":\"No matches found based on the hash value\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to navigate to original event in Jamf Protect\"}}]}},\"conditionalVisibilities\":[{\"parameterName\":\"_filehash\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"filehash\"}],\"name\":\"Query - Threat Hunting Hash\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where Match_tags contains \\\"{_CVE:value}\\\"\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n Match_tags,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n Match_tags,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\",\"size\":1,\"title\":\"Matches on CVE\",\"noDataMessage\":\"No matches found based on the _CVE:value CVE number\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to nagivate to original event in Jamf Protect\"}}]}},\"conditionalVisibilities\":[{\"parameterName\":\"_cve\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"CVE\"}],\"name\":\"Query - Threat Hunting CVE\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where Match_tags contains \\\"MITREattack\\\"\\n| extend\\n Tactics = case(Match_tags has \\\"Execution\\\", \\\"Execution\\\", Match_tags has \\\"Visibility\\\", \\\"Visibility\\\", Match_tags has \\\"Persistence\\\", \\\"Persistence\\\", Match_tags has \\\"LateralMovement\\\", \\\"Lateral Movement\\\", Match_tags has \\\"CredentialAccess\\\", \\\"Credential Acccess\\\", Match_tags has \\\"DefenseEvasion\\\", \\\"Defense Evasion\\\", Match_tags has \\\"PrivilegeEscalation\\\", \\\"Privilege Escalation\\\", Match_tags has \\\"Impact\\\", \\\"Impact\\\", Match_tags has \\\"CommandAndControl\\\", \\\"Command and Control\\\", Match_tags has \\\"Discovery\\\", \\\"Discovery\\\", Match_tags has \\\"InitialAccess\\\", \\\"Initial Access\\\", \\\"\\\"),\\n Techniques = extract(@\\\"[A-Za-z]\\\\d{4}\\\", 0, tostring(Match_tags))\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Tactics,\\n Techniques,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Tactics,\\n Techniques,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\",\"size\":1,\"title\":\"Alerts mapped to MITRE\",\"noDataMessage\":\"No alerts found that are mapped to the MITRE framework\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to navigate to original event in Jamf Protect\"}}],\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"conditionalVisibilities\":[{\"parameterName\":\"_type\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"mitre\"}],\"name\":\"Query - Threat Hunting MITRE\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where DvcHostname contains \\\"{_hostnamealert:value}\\\"\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\" and isnotempty(EventType)\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\\n| limit 10\",\"size\":1,\"title\":\"Recent 10 alerts in the past {_timetoken:value} for {_hostnamealert:value}\",\"noDataMessage\":\"No alerts found\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to nagivage to original event in Jamf Protect\"}}],\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"conditionalVisibilities\":[{\"parameterName\":\"_type\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"endpointalerts\"},{\"parameterName\":\"_hostnamealert\",\"comparison\":\"isNotEqualTo\",\"value\":\"\"}],\"name\":\"Query - Threat Hunting 10 Recent Alerts Endpoint\"}]},\"customWidth\":\"100\",\"name\":\"Group - Threat Hunting\",\"styleSettings\":{\"margin\":\"200\",\"padding\":\"200\",\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| where EventSeverity != \\\"Informational\\\"\\n| sort by EventStartTime\\n| limit 10\",\"size\":0,\"title\":\"Recent 10 alerts in the past {_timetoken:value}\",\"noDataMessage\":\"No alerts found\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to navigate to Alert in Jamf Protect\"}},{\"columnMatch\":\"AlertURL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"name\":\"Query - 10 Recent Alerts\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"datatable (Count: long, severity: string) [\\n 0, \\\"Informational\\\",\\n 0, \\\"Low\\\",\\n 0, \\\"Medium\\\",\\n 0, \\\"High\\\"\\n]\\n| union\\n (\\n JamfProtect\\n | where EventProduct == \\\"Jamf Protect - Alerts\\\" \\n and isnotempty(EventType)\\n and EventSeverity != \\\"True\\\"\\n | summarize Count = count() by EventSeverity\\n )\\n| where isnotempty(EventSeverity)\\n| summarize Count=sum(Count) by EventSeverity\",\"size\":3,\"title\":\"All Alerts {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"EventSeverity\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"==\",\"thresholdValue\":\"Informational\",\"representation\":\"green\",\"text\":\"{0}{1}\"},{\"operator\":\"==\",\"thresholdValue\":\"Low\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"},{\"operator\":\"==\",\"thresholdValue\":\"Medium\",\"representation\":\"orange\",\"text\":\"{0}{1}\"},{\"operator\":\"==\",\"thresholdValue\":\"High\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"green\",\"text\":\"{0}{1}\"}],\"compositeBarSettings\":{\"labelText\":\"\"}}},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumSignificantDigits\":1,\"maximumSignificantDigits\":3},\"emptyValCustomText\":\"0\"}},\"showBorder\":true,\"sortCriteriaField\":\"Count\",\"sortOrderField\":2}},\"name\":\"Datatable - Alerts per Severity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n and isnotempty(EventType)\\n| where EventSeverity != \\\"True\\\"\\n| summarize count() by EventSeverity, bin(TimeGenerated,{_timetoken:grain})\\n| render areachart \",\"size\":0,\"title\":\"Events Detected (Count By Severity) {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"chartSettings\":{\"showLegend\":true,\"seriesLabelSettings\":[{\"seriesName\":\"0\",\"label\":\"Informational\"},{\"seriesName\":\"1\",\"label\":\"Low\"},{\"seriesName\":\"2\",\"label\":\"Medium\"},{\"seriesName\":\"3\",\"label\":\"High\"}]}},\"customWidth\":\"50\",\"name\":\"Query - Events detected by Severity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"UnifiedLog\\\"\\n| summarize count() by tostring(EventDescription), bin(TimeGenerated,{_timetoken:grain})\\n| render areachart \",\"size\":0,\"title\":\"Unified Logging Events {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Unified Logs\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\" \\n and isnotempty(EventType)\\n and isnotempty(DvcHostname)\\n| summarize Event = count() by DvcHostname\\n| sort by Event desc\",\"size\":3,\"title\":\"Most Active Endpoints (Total, last {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"table\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"HostName\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Event\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"HostName\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Event\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"100\",\"name\":\"Query - Most active endpoints with Alerts\",\"styleSettings\":{\"maxWidth\":\"100\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n and isnotempty(EventType)\\n| summarize Events = count() by EventProduct, bin(TimeGenerated,{_timetoken:grain})\\n| render columnchart \",\"size\":0,\"title\":\"Events detected (Total by date, {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"jamfprotect_CL\",\"label\":\"Jamf Protect\"}]}},\"customWidth\":\"50\",\"name\":\"Query - Total events detected\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| summarize Events = count() by EventType, bin(EventStartTime,{_timetoken:grain})\\n| render areachart with(kind=stacked)\\n\",\"size\":0,\"title\":\"Events Detected (Count by Type, {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"areachart\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Events\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Events\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"Query - Events detected counted by Type\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Event Types\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| summarize Events = count() by EventType\\n| render piechart\",\"size\":3,\"showAnalytics\":true,\"title\":\"Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - Events by Type\",\"styleSettings\":{\"maxWidth\":\"100\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"FileSystem\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"File System Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - File System Events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"Process\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \\n\",\"size\":3,\"showAnalytics\":true,\"title\":\"Process Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - Process Event Types\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"USB\\\"\\nor EventType == \\\"UsbBlock\\\" and EventMessage == \\\"USBWrite\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"USB Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - USB Event Types\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"Gatekeeper\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"Gatekeeper Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"GatekeeperBlockedSigned\",\"label\":\"Signed\"},{\"seriesName\":\"GatekeeperBlockedRevoked\",\"label\":\"Revoked\"},{\"seriesName\":\"GatekeeperBlockedUnsignedOrUnknown\",\"label\":\"UnsignedOrUnknown\"}]}},\"customWidth\":\"33\",\"name\":\"Query - GateKeeper Events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"ProcessPrevented\\\"\\n| summarize Threat = count() by EventMatch\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"Threat Prevention Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - Threat Prevention Types\"}]},\"name\":\"Group - Event Types\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| summarize count() by tostring(EventType), tostring(EventMessage)\\n| project-rename Count = count_\\n| sort by Count desc\\n| limit 10\\n\",\"size\":3,\"showAnalytics\":true,\"title\":\"Top 10 Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 Events\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"ProcessDenied\\\"\\n| where isnotempty(DvcHostname)\\n| summarize Count= count() by TargetProcessName, EventMatch, TargetBinarySigningAppID, TargetBinarySigningTeamID\\n| sort by Count asc nulls first\\n| limit 25\",\"size\":0,\"showAnalytics\":true,\"title\":\"Process Blocked by Custom Prevent List {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Process Blocked by Custom Prevent List\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"macOS Built-In Security Tools\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"Gatekeeper\\\"\\n| summarize count() by tostring(EventMessage), TargetFilePath\\n| project-rename BlockType = EventMessage, Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":3,\"showAnalytics\":true,\"title\":\"Top Gatekeeper Blocked Items {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"Query - Top Blocked GateKeepers events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Unified Log\\\"\\n| where input_match_event_subsystem_s == \\\"com.apple.XProtectFramework.PluginAPI\\\"\\n| where tostring(parse_json(input_match_event_composedMessage_s).status_message) <> \\\"[]\\\"\\n| extend status_message_ = tostring(parse_json(input_match_event_composedMessage_s).status_message)\\n| extend execution_duration_ = tostring(parse_json(input_match_event_composedMessage_s).execution_duration)\\n| project \\n EventStartTime, \\n DvcHostname, \\n Status=status_message_, \\n Module=input_match_event_process_s, \\n Execution_Duration=execution_duration_\\n| sort by EventStartTime desc\\n| limit 25\",\"size\":0,\"showAnalytics\":true,\"title\":\"XProtect Remediator Scans {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - XProtect Remediator Activity\"}]},\"name\":\"macOS Built-In Security Tools Group\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Device Controls\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"UsbBlock\\\"\\n| where EventMessage == \\\"EnforcedRemovableDevicePolicy\\\"\\n| extend EventMessage = replace_string(tostring(EventMessage), \\\"EnforcedRemovableDevicePolicy\\\", \\\"Blocked\\\")\\n| summarize count() by tostring(EventMessage)\\n\\n\",\"size\":2,\"title\":\"Device Controls Blocked {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"piechart\",\"tileSettings\":{\"titleContent\":{\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"icons\",\"thresholdsGrid\":[{\"thresholdValue\":\"Alerts\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"Notifications\",\"text\":\"Devices Blocked\"}]}},\"leftContent\":{\"columnMatch\":\"count_\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":true,\"sortOrderField\":2},\"graphSettings\":{\"type\":0,\"centerContent\":{\"columnMatch\":\"count_\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"showMetrics\":false},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"count_\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"count_\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"count_\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"25\",\"name\":\"Query - Blocked USB Events\",\"styleSettings\":{\"maxWidth\":\"25\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"UsbBlock\\\"\\n| where EventMessage == \\\"EnforcedRemovableDevicePolicy\\\"\\n| extend device_ = strcat(input_match_event_device_vendorName_s, \\\" \\\",input_match_event_device_productName_s)\\n| summarize count() by DvcHostname, device_\\n| project-rename Hostname = DvcHostname, Device = device_, Count = count_\\n| sort by Count desc\\n\\n\",\"size\":0,\"title\":\"Device Controls Endpoint {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"65\",\"name\":\"Query - Blocked USB Devices\",\"styleSettings\":{\"maxWidth\":\"100\"}}]},\"name\":\"Group - Device Controls\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Endpoint Telemetry\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where identity_signer_id_s == \\\"com.apple.sudo\\\"\\n and ParentProcessName == \\\"/usr/bin/sudo\\\"\\n and ActorUsername == \\\"root\\\"\\n and ActorUserId != \\\"-1\\\"\\n| extend Compiled_Arguments = replace_string(TargetProcessCommandLine, \\\",\\\", \\\" \\\")\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n DvcHostname,\\n ActorUserId,\\n Compiled_Arguments\\n| project-rename Hostname = DvcHostname, Elevated_User = ActorUserId\\n| limit 50\\n| sort by EventStartTime\",\"size\":0,\"title\":\"Succesful sudo events {_timetoken:value}\",\"noDataMessage\":\"No events occured\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Compiled_Arguments\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"69.5714ch\"}}],\"sortBy\":[{\"itemKey\":\"EventStartTime\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"EventStartTime\",\"sortOrder\":2}]},\"name\":\"Query - Successful sudo events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n//| where SrcIpAddr != \\\"0.0.0.0\\\" and EventType != \\\"AUE_SESSION_START\\\" and EventType != \\\"PLAINTEXT_LOG_COLLECTION_EVENT\\\" and EventType != \\\"BIOS_FIRMWARE_VERSIONS\\\" and EventType != \\\"SYSTEM_PERFORMANCE_METRICS\\\" and EventType != \\\"RATE_LIMITING_APPLIED\\\"\\n| where SrcIpAddr != \\\"0.0.0.0\\\" and EventType == \\\"ProcessCreated\\\"\\n or SrcIpAddr != \\\"0.0.0.0\\\" and EventType == \\\"Logoff\\\"\\n or SrcIpAddr != \\\"0.0.0.0\\\" and EventType == \\\"SshInitiated\\\"\\n| where isnotempty(DvcHostname)\\n| where isnotempty(EventType)\\n| where EventProduct != \\\"Jamf Protect - Alerts\\\"\\n//| extend binary=parse_json(path_s)[0]\\n| extend Compiled_Arguments = replace_string(TargetProcessCommandLine, \\\",\\\", \\\" \\\")\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n return_description_s,\\n TargetProcessName,\\n DvcHostname,\\n SrcIpAddr,\\n ActorUsername,\\n ActorUserId,\\n Compiled_Arguments\\n| project-rename\\n EventName = EventType,\\n Description = return_description_s,\\n Hostname = DvcHostname,\\n Process_Name = TargetProcessName,\\n IP_Adress = SrcIpAddr,\\n Elevated_User = ActorUserId\\n| limit 15\\n| sort by EventStartTime\",\"size\":0,\"title\":\"Remotely Controlled Commands (Outbound) {_timetoken:value}\",\"noDataMessage\":\"No events occured\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"name\":\"Query - Remotely Controlled Commands\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n| where isnotempty(TargetProcessName)\\n| project-keep TimeGenerated, ParentProcessName, TargetProcessName\\n| summarize Rare_Process_Count = count() by TargetProcessName, ParentProcessName\\n| sort by Rare_Process_Count asc nulls first\\n| limit 200\",\"size\":0,\"title\":\"Rare Process Executions (All Executions) {_timetoken:value}\",\"noDataMessage\":\"No events occured\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Rare_Process_Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Rare_Process_Count\",\"sortOrder\":1}]},\"customWidth\":\"100\",\"name\":\"Query - Rare Process Executions\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n and isnotempty(ParentProcessName)\\n| project\\n DvcHostname,\\n TargetProcessName,\\n ParentProcessName,\\n ParentProcessGuid,\\n exec_chain_thread_uuid_g\\n| summarize\\n thread_uuid = make_set(exec_chain_thread_uuid_g, 128),\\n Hostnames = make_set(DvcHostname, 128),\\n process = make_set(TargetProcessName, 128)\\n by ParentProcessName\\n| project \\n Hostnames,\\n process,\\n parent_process=ParentProcessName,\\n thread_uuid\",\"size\":0,\"title\":\"Parent/child process with thread uuid {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"100\",\"name\":\"Query - Parent and Child Process UUID\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Endpoint Information\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"SystemPerformanceMetrics\\\"\\n| extend metrics = parse_json(metrics_tasks_s)\\n| project-keep DvcHostname, metrics, TimeGenerated\\n| project-reorder DvcHostname, metrics\\n| mv-expand metrics\\n| extend energy_impact = metrics.energy_impact\\n| extend process_name = metrics.name\\n| project-rename\\n Hostname = DvcHostname\\n| extend avg = toreal(energy_impact)\\n| summarize Average = avg(avg) by tostring(process_name), bin(TimeGenerated,{_timetoken:grain})\\n| render timechart\\n\\n\\n\\n\",\"size\":0,\"aggregation\":3,\"title\":\"Overall System Energy Impact on all endpoints {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"tileSettings\":{\"showBorder\":false},\"graphSettings\":{\"type\":0,\"nodeIdField\":\"Hostname\",\"sourceIdField\":\"Hostname\",\"targetIdField\":\"Hostname\",\"graphOrientation\":3,\"showOrientationToggles\":false,\"staticNodeSize\":100,\"hivesMargin\":5},\"chartSettings\":{\"group\":\"process_name\",\"createOtherGroup\":15,\"showLegend\":true},\"mapSettings\":{\"locInfo\":\"LatLong\"}},\"customWidth\":\"100\",\"name\":\"Query - System Performance Metrics - Energy Impact\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Log Parser {_timetoken:value}\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"Please select a hostname in order to show the collected plain-text log files.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"_hostnamelogparser\",\"comparison\":\"isEqualTo\"},\"name\":\"Text - Jamf Log Parser Note\",\"styleSettings\":{\"showBorder\":true}},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"{Workspace}\"],\"parameters\":[{\"id\":\"f747e125-851e-45f7-b500-5d22049da6a6\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_hostnamelogparser\",\"label\":\"Hostname\",\"type\":2,\"isRequired\":true,\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n and EventType == \\\"LogFileCollected\\\"\\n| project-keep DvcHostname\\n| project-rename Hostname = DvcHostname\\n| summarize by Hostname\",\"crossComponentResources\":[\"{Workspace}\"],\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"7d123ad2-1768-4d22-b438-565ab483c044\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_logselectlogparser\",\"label\":\"Available Log File\",\"type\":2,\"isRequired\":true,\"query\":\"JamfProtect\\n| where EventType == \\\"LogFileCollected\\\"\\n and DvcHostname == \\\"{_hostnamelogparser:value}\\\"\\n| project-keep TargetFilePath\\n| project-keep TargetFilePath\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"[\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"]\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, '\\\"', \\\"\\\")\\n| summarize by TargetFilePath\",\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":7776000000},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"/var/log/jamf.log\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"40\",\"name\":\"Picker - Hostname\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"LogFileCollected\\\"\\n and DvcHostname == \\\"{_hostnamelogparser:value}\\\"\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"[\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"]\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, '\\\"', \\\"\\\")\\n| where TargetFilePath == \\\"{_logselectlogparser:escapejson}\\\"\\n| project EventResult, EventStartTime\\n| project-rename Logs = EventResult\\n| project-reorder EventStartTime, Logs\\n| mv-expand parse_json(Logs)\\n| sort by EventStartTime desc\\n| limit 50\",\"size\":0,\"showAnalytics\":true,\"title\":\"Log File Collection on \\\"{_hostnamelogparser:value}\\\"\",\"noDataMessage\":\"No matches found based on the hostname\",\"timeContextFromParameter\":\"_timetoken\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Logs\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"150ch\"}}]}},\"conditionalVisibility\":{\"parameterName\":\"_hostnamelogparser\",\"comparison\":\"isNotEqualTo\"},\"name\":\"Query - Parse Logs\"}]},\"customWidth\":\"100\",\"name\":\"Group - Log Parser\",\"styleSettings\":{\"margin\":\"200\",\"padding\":\"200\",\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Endpoint System Performance {_timetoken:value}\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"Please select a hostname in order to show the system performance metrics.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"_hostnamelogparser\",\"comparison\":\"isEqualTo\"},\"name\":\"Text - Jamf Log Parser Note\",\"styleSettings\":{\"showBorder\":true}},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"{Workspace}\"],\"parameters\":[{\"id\":\"f747e125-851e-45f7-b500-5d22049da6a6\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_hostname\",\"label\":\"Hostname\",\"type\":2,\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n and EventType == \\\"SystemPerformanceMetrics\\\"\\n| project-keep DvcHostname\\n| project-rename Hostname = DvcHostname\\n| summarize by Hostname\",\"crossComponentResources\":[\"{Workspace}\"],\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"LMAC-ZW0GTLVDL\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"40\",\"name\":\"Picker - Hostname\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"SystemPerformanceMetrics\\\"\\n and DvcHostname == \\\"{_hostname:value}\\\"\\n| extend metrics = parse_json(metrics_tasks_s)\\n| project-keep DvcHostname, metrics, TimeGenerated\\n| project-reorder DvcHostname, metrics\\n| mv-expand metrics\\n| extend energy_impact = metrics.energy_impact\\n| extend process_name = metrics.name\\n| project-rename\\n Hostname = DvcHostname\\n| extend avg = toreal(energy_impact)\\n| summarize Average = avg(avg) by tostring(process_name), bin(TimeGenerated,{_timetoken:grain})\\n| render timechart\",\"size\":0,\"aggregation\":3,\"title\":\"Energy Impact on {_hostname:value}\",\"noDataMessage\":\"No metrics found based on the hostname\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"TimeGenerated\",\"formatter\":5},{\"columnMatch\":\"JamfLogs\",\"formatter\":1,\"formatOptions\":{\"customColumnWidthSetting\":\"100ch\"}}]},\"chartSettings\":{\"group\":\"process_name\",\"createOtherGroup\":15,\"showLegend\":true}},\"conditionalVisibility\":{\"parameterName\":\"_hostname\",\"comparison\":\"isNotEqualTo\"},\"name\":\"Query - Endpoint System Performance - Energy Impact\"}]},\"customWidth\":\"100\",\"name\":\"Group - Endpoint System Performance\",\"styleSettings\":{\"margin\":\"200\",\"padding\":\"200\",\"showBorder\":true}}]},\"name\":\"Group - Endpoint Information\"}]},\"name\":\"Group - Telemetry\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Network Threat Events\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and EventResult == \\\"Blocked\\\"\\n| extend blocks = case(EventResult == \\\"Blocked\\\", \\\"Blocked\\\", \\\"True\\\")\\n| summarize arg_max(EventResult, *) by EventStartTime\\n| summarize Count = count() by blocks\\n\\n\",\"size\":4,\"title\":\"Threats blocked by NTP {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Count\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"==\",\"thresholdValue\":\"0\",\"representation\":\"green\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\"<\",\"thresholdValue\":\"15\",\"representation\":\"gray\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\"<\",\"thresholdValue\":\"30\",\"representation\":\"orange\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\">\",\"thresholdValue\":\"50\",\"representation\":\"redBright\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\"Default\",\"representation\":\"gray\",\"text\":\"Threats blocked by NTP\"}],\"compositeBarSettings\":{\"labelText\":\"\"}}},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumSignificantDigits\":1,\"maximumSignificantDigits\":3},\"emptyValCustomText\":\"0\"}},\"showBorder\":true,\"sortCriteriaField\":\"blocks\",\"sortOrderField\":1,\"size\":\"auto\"}},\"name\":\"Query - Threats blocked by NTP\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n| where isnotempty(EventSeverity)\\n| summarize arg_max(EventSeverity, *) by EventStartTime\\n| summarize count() by EventSeverity, bin(TimeGenerated,{_timetoken:grain})\\n| render areachart\",\"size\":0,\"title\":\"Network Events Detected (Count By Severity) {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Network Events by Severity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and isnotempty(DvcHostname)\\n| summarize arg_max(DvcHostname, *) by EventStartTime\\n| summarize Event = count() by DvcHostname\\n| sort by Event desc\",\"size\":0,\"title\":\"Most Active Endpoints (Total, last {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Most Active Endoints with Alerts\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and isnotempty(ThreatCategory)\\n| summarize arg_max(ThreatCategory, *) by EventStartTime\\n| summarize Events = count() by ThreatCategory, bin(EventStartTime, {_timetoken:grain})\\n| render areachart with(kind=stacked)\",\"size\":0,\"title\":\"Network Events Detected (Count by Type, {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Network Events by Category\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and isnotempty(ThreatCategory)\\n| summarize arg_max(ThreatCategory, *) by EventStartTime\\n| summarize Events = count() by ThreatCategory\\n| render piechart\",\"size\":0,\"title\":\"Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Network Events by Description\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\" \\n and notempty(ThreatCategory) and notempty(DnsQueryName)\\n| extend name_ = ThreatCategory\\n| summarize arg_max(DnsQueryName, *) by EventStartTime\\n| summarize count() by DnsQueryName, ThreatCategory\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 Blocked destinations {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 blocked destinations\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\" \\n and notempty(ThreatCategory)\\n and notempty(DstIpAddr)\\n| extend name_ = ThreatCategory\\n| summarize arg_max(DstIpAddr, *) by EventStartTime\\n| summarize count() by DstIpAddr\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 Blocked IPs {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 Blocked IPs\"}]},\"name\":\"Network Threat Events - Group\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Network Traffic\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Network Traffic Stream\\\"\\n and isnotempty(DnsQuery)\\n| summarize arg_max(DnsQuery, *) by EventStartTime\\n| summarize count() by DnsQuery, DnsQueryTypeName\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 resolved destinations {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 resolved destinations\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Network Traffic Stream\\\"\\n and isnotempty(DstIpAddr) and DstIpAddr != \\\"[]\\\"\\n| summarize arg_max(DstIpAddr, *) by EventStartTime\\n| summarize count() by DstIpAddr\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 Resolved IPs {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 Resolved IPs\"}]},\"name\":\"Network Traffic - Group\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-JamfProtectDashboard\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
- "properties": {
- "description": "@{workbookKey=JamfProtectWorkbook; logoFileName=jamf_logo.svg; description=This Jamf Protect Workbook for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel.\n Providing reports into all alerts, device controls and Unfied Logs.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0.0; title=Jamf Protect Workbook; templateRelativePath=JamfProtectDashboard.json; subtitle=; provider=Jamf Software, LLC}.description",
- "parentId": "[variables('workbookId1')]",
- "contentId": "[variables('_workbookContentId1')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "jamfprotect_CL",
- "kind": "DataType"
- }
- ]
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId1')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook1-name')]",
- "contentProductId": "[variables('_workbookcontentProductId1')]",
- "id": "[variables('_workbookcontentProductId1')]",
- "version": "[variables('workbookVersion1')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtectAlerts_AnalyticalRules Analytics Rule with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "apiVersion": "2023-02-01-preview",
- "kind": "NRT",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "Creates an incident based on Jamf Protect Alert data in Microsoft Sentinel",
- "displayName": "Jamf Protect - Alerts",
- "enabled": false,
- "query": "JamfProtect\n| where EventProduct == \"Jamf Protect - Alerts\"\n and isnotempty(EventSeverity)\n| extend\n algorithm = \"SHA256\",\n Host_IPs = tostring(parse_json(DvcIpAddr)[0]),\n Tags = tostring(Match_facts[0].tags),\n Tactics = case(Match_tags has \"Execution\", \"Execution\", Match_tags has \"Visibility\", \"Visibility\", Match_tags has \"Persistence\", \"Persistence\", Match_tags has \"LateralMovement\", \"LateralMovement\", Match_tags has \"CredentialAccess\", \"CredentialAcccess\", Match_tags has \"DefenseEvasion\", \"DefenseEvasion\", Match_tags has \"PrivilegeEscalation\", \"PrivilegeEscalation\", Match_tags has \"Impact\", \"Impact\", Match_tags has \"CommandAndControl\", \"CommandandControl\", Match_tags has \"Discovery\", \"Discovery\", Match_tags has \"InitialAccess\", \"InitialAccess\", \"\"),\n Techniques = pack_array(extract(@\"[A-Za-z]\\d{4}\", 0, tostring(Match_tags))),\n JamfPro = case(Match_actions has \"SmartGroup\", \"Workflow with Jamf Pro\", Match_actions has \"Prevented\", \"No workflow, Prevented by Protect\", \"No workflow\")\n",
- "severity": "High",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "connectorId": "JamfProtect",
- "dataTypes": [
- "jamfprotect_CL"
- ]
- }
- ],
- "entityMappings": [
- {
- "entityType": "Host",
- "fieldMappings": [
- {
- "columnName": "DvcHostname",
- "identifier": "HostName"
- },
- {
- "columnName": "DvcOs",
- "identifier": "OSFamily"
- },
- {
- "columnName": "DvcOsVersion",
- "identifier": "OSVersion"
- }
- ]
- },
- {
- "entityType": "IP",
- "fieldMappings": [
- {
- "columnName": "Host_IPs",
- "identifier": "Address"
- }
- ]
- },
- {
- "entityType": "Account",
- "fieldMappings": [
- {
- "columnName": "TargetUsername",
- "identifier": "Name"
- }
- ]
- },
- {
- "entityType": "Process",
- "fieldMappings": [
- {
- "columnName": "TargetProcessCurrentDirectory",
- "identifier": "CommandLine"
- },
- {
- "columnName": "TargetProcessId",
- "identifier": "ProcessId"
- }
- ]
- },
- {
- "entityType": "FileHash",
- "fieldMappings": [
- {
- "columnName": "algorithm",
- "identifier": "Algorithm"
- },
- {
- "columnName": "TargetBinarySHA256",
- "identifier": "Value"
- }
- ]
- }
- ],
- "eventGroupingSettings": {
- "aggregationKind": "AlertPerResult"
- },
- "customDetails": {
- "TargetbinarySign": "TargetbinarySignerType",
- "JamfPro_Status": "JamfPro",
- "Protect_Tags": "Tags",
- "TargetBinarySigner": "TargetBinarySigningTeamID",
- "Related_File_hash": "TargetBinarySHA256",
- "Protect_Analytic": "EventMessage",
- "Protect_Event_Type": "EventType",
- "TargetBinarySignMsg": "TargetBinarySigningInfoMessage",
- "Related_Binaries": "TargetBinaryFilePath"
- },
- "alertDetailsOverride": {
- "alertTacticsColumnName": "Tactics",
- "alertSeverityColumnName": "EventSeverity",
- "alertDynamicProperties": [
- {
- "value": "EventReportUrl",
- "alertProperty": "AlertLink"
- },
- {
- "value": "EventVendor",
- "alertProperty": "ProviderName"
- },
- {
- "value": "EventProduct",
- "alertProperty": "ProductName"
- },
- {
- "value": "Techniques",
- "alertProperty": "Techniques"
- }
- ],
- "alertDisplayNameFormat": "{{EventMessage}} detected on {{DvcHostname}}",
- "alertDescriptionFormat": "{{EventDescription}} - Please investigate"
- },
- "incidentConfiguration": {
- "createIncident": true,
- "groupingConfiguration": {
- "lookbackDuration": "PT5H",
- "matchingMethod": "AllEntities",
- "enabled": false,
- "reopenClosedIncident": false
- }
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]",
- "properties": {
- "description": "Jamf Protect Analytics Rule 1",
- "parentId": "[variables('analyticRuleObject1').analyticRuleId1]",
- "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleObject1').analyticRuleVersion1]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "contentKind": "AnalyticsRule",
- "displayName": "Jamf Protect - Alerts",
- "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
- "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
- "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtectNetworkThreats_AnalyticalRules Analytics Rule with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "apiVersion": "2023-02-01-preview",
- "kind": "NRT",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "Creates an incident based based on Jamf Protect's Network Threat Event Stream alerts.",
- "displayName": "Jamf Protect - Network Threats",
- "enabled": false,
- "query": "JamfProtect\n| where EventProduct == \"Jamf Protect - Threat Events Stream\"\n and EventResult == \"Blocked\"\n and isnotempty(EventSeverity)\n| extend Tactics = \"Initial Access\"\n| extend Techniques = \"T1566\"\n",
- "severity": "Informational",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "connectorId": "JamfProtect",
- "dataTypes": [
- "jamfprotect_CL"
- ]
- }
- ],
- "tactics": [
- "InitialAccess"
- ],
- "entityMappings": [
- {
- "entityType": "Host",
- "fieldMappings": [
- {
- "columnName": "Hostname",
- "identifier": "HostName"
- },
- {
- "columnName": "DvcOs",
- "identifier": "OSFamily"
- }
- ]
- },
- {
- "entityType": "IP",
- "fieldMappings": [
- {
- "columnName": "DstIpAddr",
- "identifier": "Address"
- }
- ]
- },
- {
- "entityType": "Account",
- "fieldMappings": [
- {
- "columnName": "SrcUsermail",
- "identifier": "AadUserId"
- },
- {
- "columnName": "SrcUsername",
- "identifier": "FullName"
- }
- ]
- },
- {
- "entityType": "URL",
- "fieldMappings": [
- {
- "columnName": "DnsQueryName",
- "identifier": "Url"
- }
- ]
- }
- ],
- "eventGroupingSettings": {
- "aggregationKind": "AlertPerResult"
- },
- "customDetails": {
- "Category": "ThreatCategory"
- },
- "alertDetailsOverride": {
- "alertTacticsColumnName": "Tactics",
- "alertSeverityColumnName": "EventSeverity",
- "alertDynamicProperties": [
- {
- "value": "EventReportUrl",
- "alertProperty": "AlertLink"
- },
- {
- "value": "EventVendor",
- "alertProperty": "ProviderName"
- },
- {
- "value": "EventProduct",
- "alertProperty": "ProductName"
- },
- {
- "value": "EventResult",
- "alertProperty": "RemediationSteps"
- },
- {
- "value": "Techniques",
- "alertProperty": "Techniques"
- }
- ],
- "alertDisplayNameFormat": "Network Threat detected on {{DvcHostname}}",
- "alertDescriptionFormat": "A Network Threat has been {{EventResult}} on {{DvcHostname}}"
- },
- "incidentConfiguration": {
- "createIncident": true,
- "groupingConfiguration": {
- "lookbackDuration": "PT5H",
- "matchingMethod": "AllEntities",
- "enabled": false,
- "reopenClosedIncident": false
- }
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]",
- "properties": {
- "description": "Jamf Protect Analytics Rule 2",
- "parentId": "[variables('analyticRuleObject2').analyticRuleId2]",
- "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleObject2').analyticRuleVersion2]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "contentKind": "AnalyticsRule",
- "displayName": "Jamf Protect - Network Threats",
- "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
- "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
- "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtectUnifiedLogs_AnalyticalRules Analytics Rule with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "apiVersion": "2023-02-01-preview",
- "kind": "NRT",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "Creates an informational incident based on Jamf Protect Unified Log data in Microsoft Sentinel",
- "displayName": "Jamf Protect - Unified Logs",
- "enabled": false,
- "query": "JamfProtect\n| where EventType == \"UnifiedLog\"\n| where isnotempty(EventSeverity)\n| extend Host_IPs = tostring(parse_json(DvcIpAddr)[0])\n",
- "severity": "Informational",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "connectorId": "JamfProtect",
- "dataTypes": [
- "jamfprotect_CL"
- ]
- }
- ],
- "entityMappings": [
- {
- "entityType": "Host",
- "fieldMappings": [
- {
- "columnName": "DvcHostname",
- "identifier": "HostName"
- }
- ]
- },
- {
- "entityType": "IP",
- "fieldMappings": [
- {
- "columnName": "Host_IPs",
- "identifier": "Address"
- }
- ]
- }
- ],
- "eventGroupingSettings": {
- "aggregationKind": "AlertPerResult"
- },
- "customDetails": {
- "Protect_Event_Type": "EventType",
- "Event_Process": "TargetProcessName",
- "Unified_Log": "EventDescription",
- "Tags": "Match_tags"
- },
- "alertDetailsOverride": {
- "alertSeverityColumnName": "EventSeverity",
- "alertDynamicProperties": [
- {
- "value": "EventVendor",
- "alertProperty": "ProviderName"
- },
- {
- "value": "EventProduct",
- "alertProperty": "ProductName"
- }
- ],
- "alertDisplayNameFormat": "{{EventDescription}} on {{DvcHostname}}",
- "alertDescriptionFormat": "{{EventDescription}} has been captured in the unified logs"
- },
- "incidentConfiguration": {
- "createIncident": true,
- "groupingConfiguration": {
- "lookbackDuration": "PT5H",
- "matchingMethod": "AllEntities",
- "enabled": false,
- "reopenClosedIncident": false
- }
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]",
- "properties": {
- "description": "Jamf Protect Analytics Rule 3",
- "parentId": "[variables('analyticRuleObject3').analyticRuleId3]",
- "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleObject3').analyticRuleVersion3]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "contentKind": "AnalyticsRule",
- "displayName": "Jamf Protect - Unified Logs",
- "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
- "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
- "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject1').huntingQueryTemplateSpecName1]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_DazzleSpy_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_1",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - DazzleSpy",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"341bc86bc9b76ac69dca0a48a328fd37d74c96c2e37210304cfa66ccdbe72b27\", \n \"4c67717fdf1ba588c8be62b6137c92d344a7d4f46b24fa525e5eaa3de330b16c\", \n \"570cd76bf49cf52e0cb347a68bdcf0590b2eaece134e1b1eba7e8d66261bdbe6\", \n \"623f99cbe20af8b79cbfea7f485d47d3462d927153d24cac4745d7043c15619a\", \n \"8fae0d5860aa44b5c7260ef7a0b277bcddae8c02cea7d3a9c19f1a40388c223f\", \n \"9b71fad3280cf36501fe110e022845b29c1fb1343d5250769eada7c36bc45f70\", \n \"a63466d09c3a6a2596a98de36083b6d268f393a27f7b781e52eeb98ae055af97\", \n \"bbbfe62cf15006014e356885fbc7447e3fd37c3743e0522b1f8320ad5c3791c9\", \n \"cf5edcff4053e29cb236d3ed1fe06ca93ae6f64f26e25117d68ee130b9bc60c8\", \n \"d599d7814adbab0f1442f5a10074e00f3a776ce183ea924abcd6154f0d068bb4\", \n \"df5b588f555cccdf4bbf695158b10b5d3a5f463da7e36d26bdf8b7ba0f8ed144\", \n \"f9ad42a9bd9ade188e997845cae1b0587bf496a35c3bffacd20fefe07860a348\")\n or DstIpAddr in (\"103.255.44.56\",\n \"123.1.170.152\",\n \"207.148.102.208\",\n \"88.218.192.128\")\n or TargetFilePath contains \"/Library/LaunchAgents/softwareupdate.plist\"\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for alerts related to DazzleSpy activity, known to affect macOS devices via a MachO binary"
- },
- {
- "name": "tactics",
- "value": "ResourceDevelopment"
- },
- {
- "name": "techniques",
- "value": "T1587,T1587.001"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject1')._huntingQuerycontentId1),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 1",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject1')._huntingQuerycontentId1)]",
- "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject1').huntingQueryVersion1]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - DazzleSpy",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject2').huntingQueryTemplateSpecName2]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_JokerSpy_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_2",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - JokerSpy",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"5fe1790667ee5085e73b054566d548eb4473c20cf962368dd53ba776e9642272\", \n \"39bbc16028fd46bf4ddad49c21439504d3f6f42cccbd30945a2d2fdb4ce393a4\", \n \"aa951c053baf011d08f3a60a10c1d09bbac32f332413db5b38b8737558a08dc1\", \n \"d895075057e491b34b0f8c0392b44e43ade425d19eaaacea6ef8c5c9bd3487d8\", \n \"951039bf66cdf436c240ef206ef7356b1f6c8fffc6cbe55286ec2792bf7fe16c\", \n \"452c832a17436f61ad5f32ee1c97db05575160105ed1dcd0d3c6db9fb5a9aea1\", \n \"6d3eff4e029db9d7b8dc076cfed5e2315fd54cb1ff9c6533954569f9e2397d4c\")\nor DnsQueryName contains \"git-hub.me\"\nor DnsQueryName contains \"app.influmarket.org\"\nor EventMatch contains \"jokerspy\"\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for alerts related to JokerSpy activity, Known to use various back doors to deploy spyware on victims' systems in order to perform reconnaissance and for command and control."
- },
- {
- "name": "tactics",
- "value": "Execution,Masquerading"
- },
- {
- "name": "techniques",
- "value": "T1059,T1036"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject2')._huntingQuerycontentId2),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 2",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject2')._huntingQuerycontentId2)]",
- "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject2').huntingQueryVersion2]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - JokerSpy",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject3').huntingQueryTemplateSpecName3]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_KandyKorn_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_3",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - KandyKorn",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1\",\n \"51dd4efcf714e64b4ad472ea556bf1a017f40a193a647b9e28bf356979651077\")\n or DnsQueryName contains \"tp-globa.xyz\"\n or DstIpAddr in (\"192.119.64.43\", \"23.254.226.90\")\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for activity related to KandyKorn activity, known to affect macOS devices via a MachO binary"
- },
- {
- "name": "tactics",
- "value": "Exfiltration"
- },
- {
- "name": "techniques",
- "value": "T1020"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject3')._huntingQuerycontentId3),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 3",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject3')._huntingQuerycontentId3)]",
- "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject3').huntingQueryVersion3]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - KandyKorn",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject4').huntingQueryTemplateSpecName4]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_PureLand_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_4",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - PureLand",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 has \"0b9a3b00302faf3297b60fff0714f2db87245a613dcd9849645bffa7c4a3df9b\"\n or DstIpAddr contains \"193.168.141.107\"\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for activity related to PureLand activity, known to affect macOS devices via a MachO binary"
- },
- {
- "name": "tactics",
- "value": "Exfiltration"
- },
- {
- "name": "techniques",
- "value": "T1020"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject4')._huntingQuerycontentId4),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 4",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject4')._huntingQuerycontentId4)]",
- "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject4').huntingQueryVersion4]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - PureLand",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject5').huntingQueryTemplateSpecName5]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_RustBucket_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_5",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - RustBucket",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 in (\"e74e8cdf887ae2de25590c55cb52dad66f0135ad4a1df224155f772554ea970c\", \"ac08406818bbf4fe24ea04bfd72f747c89174bdb\", \"72167ec09d62cdfb04698c3f96a6131dceb24a9c\", \"fd1cef5abe3e0c275671916a1f3a566f13489416\")\n or DnsQueryName contains \"cloud.dnx.capital\"\n or DnsQueryName contains \"deck.31ventures.info\"\n or ((TargetBinarySigningAppID contains \"com.apple.pdfViewer\") and (TargetbinarySignerType != \"Apple\"))\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for activity related to RustBucket activity, known to affect macOS devices via a MachO binary"
- },
- {
- "name": "tactics",
- "value": "Exfiltration"
- },
- {
- "name": "techniques",
- "value": "T1020"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject5')._huntingQuerycontentId5),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 5",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject5')._huntingQuerycontentId5)]",
- "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject5').huntingQueryVersion5]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - RustBucket",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject6').huntingQueryTemplateSpecName6]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_Turtle_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_6",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - Turtle",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 has \"a48af4a62358831fe5376aa52db1a3555b0c93c1665b242c0c1f49462f614c56\"\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for activity related to Turtle activity, known to affect macOS devices via a MachO binary"
- },
- {
- "name": "tactics",
- "value": "Exfiltration"
- },
- {
- "name": "techniques",
- "value": "T1020"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject6')._huntingQuerycontentId6),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 6",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject6')._huntingQuerycontentId6)]",
- "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject6').huntingQueryVersion6]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - Turtle",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('huntingQueryObject7').huntingQueryTemplateSpecName7]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_macOS_AtomicStealer_HuntingQueries Hunting Query with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
- "parameters": {},
- "variables": {},
- "resources": [
- {
- "type": "Microsoft.OperationalInsights/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "Jamf_Protect_Hunting_Query_7",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "JamfProtect - macOS - AtomicStealer",
- "category": "Hunting Queries",
- "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"ce3c57e6c025911a916a61a716ff32f2699f3e3a84eb0ebbe892a5d4b8fb9c7a\", \n \"91cca8b573d9bfdbe2d7ff74ce31acee7a3a9f8e0034841af38d96a1d4ad02f4\", \n \"7668dcab16c2f16396dd0d3a580bca89a3675462c1e9f98e79d75d6e7e6c8c1f\")\nor TargetFileSHA256 has \"6b0bde56810f7c0295d57c41ffa746544a5370cedbe514e874cf2cd04582f4b0\"\nor DnsQueryName contains \"app-downloads.org\"\nor DnsQueryName contains \"trabingviews.com\"\nor DstIpAddr contains \"185.106.93.154\"\nor EventMatch contains \"atomicstealer\"\n",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": "Use this query to look for activity related to AtomicStealer activity, known to affect macOS devices via a MachO binary"
- },
- {
- "name": "tactics",
- "value": "Exfiltration"
- },
- {
- "name": "techniques",
- "value": "T1020"
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject7')._huntingQuerycontentId7),'/'))))]",
- "properties": {
- "description": "Jamf Protect Hunting Query 7",
- "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject7')._huntingQuerycontentId7)]",
- "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]",
- "kind": "HuntingQuery",
- "version": "[variables('huntingQueryObject7').huntingQueryVersion7]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]",
- "contentKind": "HuntingQuery",
- "displayName": "JamfProtect - macOS - AtomicStealer",
- "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '1.0.0')))]",
- "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '1.0.0')))]",
- "version": "1.0.0"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('playbookTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_Alert_Status_InProgress Playbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('playbookVersion1')]",
- "parameters": {
- "clientIdentifier": {
- "type": "String",
- "metadata": {
- "description": "The Client ID for the Jamf Protect API Key"
- }
- },
- "clientSecret": {
- "type": "SecureString",
- "metadata": {
- "description": "The Client Secret for the Jamf Protect API Key"
- }
- },
- "jamfProtect_URL": {
- "defaultValue": "https://*.protect.jamfcloud.com",
- "type": "String",
- "metadata": {
- "description": "Enter the Jamf Protect instance URL ex: {https://fakevalue.protect.jamfcloud.com}"
- }
- },
- "PlaybookName": {
- "type": "String",
- "minLength": 1,
- "defaultValue": "JamfProtect_Alert_Status_InProgress",
- "metadata": {
- "description": "Name of the Logic App/Playbook"
- }
- }
- },
- "variables": {
- "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
- "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
- "_connection-1": "[[variables('connection-1')]",
- "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
- "workspace-name": "[parameters('workspace')]",
- "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
- },
- "resources": [
- {
- "type": "Microsoft.Web/connections",
- "apiVersion": "2016-06-01",
- "name": "[[variables('AzureSentinelConnectionName')]",
- "location": "[[variables('workspace-location-inline')]",
- "kind": "V1",
- "properties": {
- "displayName": "[[variables('AzureSentinelConnectionName')]",
- "parameterValueType": "Alternative",
- "api": {
- "id": "[[variables('_connection-1')]"
- }
- }
- },
- {
- "type": "Microsoft.Logic/workflows",
- "apiVersion": "2017-07-01",
- "name": "[[parameters('playbookName')]",
- "location": "[[variables('workspace-location-inline')]",
- "identity": {
- "type": "SystemAssigned"
- },
- "properties": {
- "state": "Enabled",
- "definition": {
- "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
- "contentVersion": "1.0.0.0",
- "parameters": {
- "$connections": {
- "type": "Object"
- },
- "client_ID": {
- "defaultValue": "[[parameters('clientIdentifier')]",
- "type": "String"
- },
- "jamfProtectURL": {
- "defaultValue": "[[parameters('jamfProtect_URL')]",
- "type": "String"
- },
- "password": {
- "defaultValue": "[[parameters('clientSecret')]",
- "type": "SecureString"
- }
- },
- "triggers": {
- "Microsoft_Sentinel_incident": {
- "type": "ApiConnectionWebhook",
- "inputs": {
- "body": {
- "callback_url": "@{listCallbackUrl()}"
- },
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuresentinel']['connectionId']"
- }
- },
- "path": "/incident-creation"
- }
- }
- },
- "actions": {
- "For_each": {
- "foreach": "@triggerBody()?['object']?['properties']?['Alerts']",
- "actions": {
- "Add_comment_to_incident_(V3)": {
- "runAfter": {
- "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": [
- "Succeeded"
- ]
- },
- "type": "ApiConnection",
- "inputs": {
- "body": {
- "incidentArmId": "@triggerBody()?['object']?['id']",
- "message": "Jamf Protect Alert with URL @{outputs('Composing_Jamf_Protect_Alert_URL')} has been set to status In Progress
"
- },
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuresentinel']['connectionId']"
- }
- },
- "method": "post",
- "path": "/Incidents/Comment"
- }
- },
- "Composing_Jamf_Protect_Alert_URL": {
- "type": "Compose",
- "inputs": "@items('For_each')?['properties']?['alertLink']"
- },
- "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": {
- "runAfter": {
- "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": [
- "Succeeded"
- ]
- },
- "type": "Http",
- "inputs": {
- "authentication": {
- "type": "Raw",
- "value": "@variables('accessToken')"
- },
- "body": {
- "operationName": "updateAlert",
- "query": "mutation updateAlert {\n updateAlerts(input: { uuids: [\"@{outputs('Removing_pre-fix_of_URL_and_keeping_Alert_UDID')}\"], status: InProgress })\n {\n items {\n uuid\n status\n }\n }\n}\n"
- },
- "method": "POST",
- "uri": "@{parameters('jamfProtectURL')}/graphql"
- }
- },
- "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": {
- "runAfter": {
- "Composing_Jamf_Protect_Alert_URL": [
- "Succeeded"
- ]
- },
- "type": "Compose",
- "inputs": "@replace(outputs('Composing_Jamf_Protect_Alert_URL'), variables('jamfProtectAlertURL'), '')"
- }
- },
- "runAfter": {
- "Set_accessToken_as_variable": [
- "Succeeded"
- ]
- },
- "type": "Foreach"
- },
- "Generate_Access_Token": {
- "runAfter": {
- "set_jamfProtectAlertURL_as_variable": [
- "Succeeded"
- ]
- },
- "type": "Http",
- "inputs": {
- "body": {
- "client_id": "@{parameters('client_ID')}",
- "password": "@{parameters('password')}"
- },
- "headers": {
- "Content-Type": "application/json"
- },
- "method": "POST",
- "uri": "@{parameters('jamfProtectURL')}/token"
- },
- "runtimeConfiguration": {
- "secureData": {
- "properties": [
- "inputs"
- ]
- }
- }
- },
- "Parse_JSON_Response_from_Access_Token": {
- "runAfter": {
- "Generate_Access_Token": [
- "Succeeded"
- ]
- },
- "type": "ParseJson",
- "inputs": {
- "content": "@body('Generate_Access_Token')",
- "schema": {
- "properties": {
- "access_token": {
- "type": "string"
- },
- "expires_in": {
- "type": "integer"
- },
- "token_type": {
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- },
- "Set_accessToken_as_variable": {
- "runAfter": {
- "Parse_JSON_Response_from_Access_Token": [
- "Succeeded"
- ]
- },
- "type": "InitializeVariable",
- "inputs": {
- "variables": [
- {
- "name": "accessToken",
- "type": "string",
- "value": "@body('Parse_JSON_Response_from_Access_Token')?['access_token']"
- }
- ]
- }
- },
- "set_jamfProtectAlertURL_as_variable": {
- "type": "InitializeVariable",
- "inputs": {
- "variables": [
- {
- "name": "jamfProtectAlertURL",
- "type": "string",
- "value": "@{parameters('jamfProtectURL')}/Alerts/"
- }
- ]
- }
- }
- }
- },
- "parameters": {
- "$connections": {
- "value": {
- "azuresentinel": {
- "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]",
- "connectionName": "[[variables('AzureSentinelConnectionName')]",
- "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
- "connectionProperties": {
- "authentication": {
- "type": "ManagedServiceIdentity"
- }
- }
- }
- }
- }
- }
- },
- "tags": {
- "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]",
- "properties": {
- "parentId": "[variables('playbookId1')]",
- "contentId": "[variables('_playbookContentId1')]",
- "kind": "Playbook",
- "version": "[variables('playbookVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ],
- "metadata": {
- "title": "Jamf Protect - Set Alert to In Progress",
- "description": "This Jamf Protect Playbook can be used manually or in a Automation Rule to change the state of the Alert in Jamf Protect itself, in an automated way you can mirror the state from a Microsoft Sentinel incident back to Jamf Protect.",
- "mainSteps": [
- "1. Fetches the AlertUDID from the Alert of Jamf Protect",
- "2. Generates a Access Token to authenticate against the Jamf Protect GraphQL API",
- "3. Changes the Alert status in Jamf Protect to In Progress"
- ],
- "prerequisites": [
- "1. Generate API Client in Jamf Protect and take note of the CLientID and Password. [learn how](https://learn.jamf.com/bundle/jamf-protect-documentation/page/Jamf_Protect_API.html#ariaid-title3)",
- "2. Use the ClientID and Password during the deployment of this Playbook"
- ],
- "lastUpdateTime": "2023-07-20T00:00:00Z",
- "tags": [
- "Utilities"
- ],
- "source": {
- "type": "solution",
- "name": "Jamf Protect"
- },
- "postDeployment": [
- "** b. Configurations in Sentinel **",
- "1. In Microsoft Sentinel Analytic Rules for Jamf Protect - Alerts should be configured to create an incident",
- "2. Configure the Automation Rules to trigger this playbook once a incident is status is changed to Active"
- ],
- "releaseNotes": [
- {
- "version": "1.0.0",
- "title": "Jamf Protect - Set Alert to In Progress",
- "notes": [
- "Initial version"
- ]
- }
- ]
- }
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_playbookContentId1')]",
- "contentKind": "Playbook",
- "displayName": "JamfProtect_Alert_Status_InProgress",
- "contentProductId": "[variables('_playbookcontentProductId1')]",
- "id": "[variables('_playbookcontentProductId1')]",
- "version": "[variables('playbookVersion1')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('playbookTemplateSpecName2')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_Alert_Status_Resolved Playbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('playbookVersion2')]",
- "parameters": {
- "clientIdentifier": {
- "type": "String",
- "metadata": {
- "description": "The Client ID for the Jamf Protect API Key"
- }
- },
- "clientSecret": {
- "type": "SecureString",
- "metadata": {
- "description": "The Client Secret for the Jamf Protect API Key"
- }
- },
- "jamfProtect_URL": {
- "defaultValue": "https://*.protect.jamfcloud.com",
- "type": "String",
- "metadata": {
- "description": "Enter the Jamf Protect instance URL ex: {https://fakevalue.protect.jamfcloud.com}"
- }
- },
- "PlaybookName": {
- "type": "String",
- "minLength": 1,
- "defaultValue": "JamfProtect_Alert_Status_Resolved",
- "metadata": {
- "description": "Name of the Logic App/Playbook"
- }
- }
- },
- "variables": {
- "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
- "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
- "_connection-1": "[[variables('connection-1')]",
- "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
- "workspace-name": "[parameters('workspace')]",
- "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
- },
- "resources": [
- {
- "type": "Microsoft.Web/connections",
- "apiVersion": "2016-06-01",
- "name": "[[variables('AzureSentinelConnectionName')]",
- "location": "[[variables('workspace-location-inline')]",
- "kind": "V1",
- "properties": {
- "displayName": "[[variables('AzureSentinelConnectionName')]",
- "parameterValueType": "Alternative",
- "api": {
- "id": "[[variables('_connection-1')]"
- }
- }
- },
- {
- "type": "Microsoft.Logic/workflows",
- "apiVersion": "2017-07-01",
- "name": "[[parameters('playbookName')]",
- "location": "[[variables('workspace-location-inline')]",
- "identity": {
- "type": "SystemAssigned"
- },
- "properties": {
- "state": "Enabled",
- "definition": {
- "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
- "contentVersion": "1.0.0.0",
- "parameters": {
- "$connections": {
- "type": "Object"
- },
- "client_ID": {
- "defaultValue": "[[parameters('clientIdentifier')]",
- "type": "String"
- },
- "jamfProtectURL": {
- "defaultValue": "[[parameters('jamfProtect_URL')]",
- "type": "String"
- },
- "password": {
- "defaultValue": "[[parameters('clientSecret')]",
- "type": "SecureString"
- }
- },
- "triggers": {
- "Microsoft_Sentinel_incident": {
- "type": "ApiConnectionWebhook",
- "inputs": {
- "body": {
- "callback_url": "@{listCallbackUrl()}"
- },
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuresentinel']['connectionId']"
- }
- },
- "path": "/incident-creation"
- }
- }
- },
- "actions": {
- "For_each": {
- "foreach": "@triggerBody()?['object']?['properties']?['Alerts']",
- "actions": {
- "Add_comment_to_incident_(V3)": {
- "runAfter": {
- "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": [
- "Succeeded"
- ]
- },
- "type": "ApiConnection",
- "inputs": {
- "body": {
- "incidentArmId": "@triggerBody()?['object']?['id']",
- "message": "Jamf Protect Alert with URL @{outputs('Composing_Jamf_Protect_Alert_URL')} has been set to status Resolved
"
- },
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuresentinel']['connectionId']"
- }
- },
- "method": "post",
- "path": "/Incidents/Comment"
- }
- },
- "Composing_Jamf_Protect_Alert_URL": {
- "type": "Compose",
- "inputs": "@items('For_each')?['properties']?['alertLink']"
- },
- "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": {
- "runAfter": {
- "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": [
- "Succeeded"
- ]
- },
- "type": "Http",
- "inputs": {
- "authentication": {
- "type": "Raw",
- "value": "@variables('accessToken')"
- },
- "body": {
- "operationName": "updateAlert",
- "query": "mutation updateAlert {\n updateAlerts(input: { uuids: [\"@{outputs('Removing_pre-fix_of_URL_and_keeping_Alert_UDID')}\"], status: Resolved })\n {\n items {\n uuid\n status\n }\n }\n}\n"
- },
- "method": "POST",
- "uri": "@{parameters('jamfProtectURL')}/graphql"
- }
- },
- "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": {
- "runAfter": {
- "Composing_Jamf_Protect_Alert_URL": [
- "Succeeded"
- ]
- },
- "type": "Compose",
- "inputs": "@replace(outputs('Composing_Jamf_Protect_Alert_URL'), variables('jamfProtectAlertURL'), '')"
- }
- },
- "runAfter": {
- "Set_accessToken_as_variable": [
- "Succeeded"
- ]
- },
- "type": "Foreach"
- },
- "Generate_Access_Token": {
- "runAfter": {
- "set_jamfProtectAlertURL_as_variable": [
- "Succeeded"
- ]
- },
- "type": "Http",
- "inputs": {
- "body": {
- "client_id": "@{parameters('client_ID')}",
- "password": "@{parameters('password')}"
- },
- "headers": {
- "Content-Type": "application/json"
- },
- "method": "POST",
- "uri": "@{parameters('jamfProtectURL')}/token"
- },
- "runtimeConfiguration": {
- "secureData": {
- "properties": [
- "inputs"
- ]
- }
- }
- },
- "Parse_JSON_Response_from_Access_Token": {
- "runAfter": {
- "Generate_Access_Token": [
- "Succeeded"
- ]
- },
- "type": "ParseJson",
- "inputs": {
- "content": "@body('Generate_Access_Token')",
- "schema": {
- "properties": {
- "access_token": {
- "type": "string"
- },
- "expires_in": {
- "type": "integer"
- },
- "token_type": {
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- },
- "Set_accessToken_as_variable": {
- "runAfter": {
- "Parse_JSON_Response_from_Access_Token": [
- "Succeeded"
- ]
- },
- "type": "InitializeVariable",
- "inputs": {
- "variables": [
- {
- "name": "accessToken",
- "type": "string",
- "value": "@body('Parse_JSON_Response_from_Access_Token')?['access_token']"
- }
- ]
- }
- },
- "set_jamfProtectAlertURL_as_variable": {
- "type": "InitializeVariable",
- "inputs": {
- "variables": [
- {
- "name": "jamfProtectAlertURL",
- "type": "string",
- "value": "@{parameters('jamfProtectURL')}/Alerts/"
- }
- ]
- }
- }
- }
- },
- "parameters": {
- "$connections": {
- "value": {
- "azuresentinel": {
- "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]",
- "connectionName": "[[variables('AzureSentinelConnectionName')]",
- "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
- "connectionProperties": {
- "authentication": {
- "type": "ManagedServiceIdentity"
- }
- }
- }
- }
- }
- }
- },
- "tags": {
- "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]",
- "properties": {
- "parentId": "[variables('playbookId2')]",
- "contentId": "[variables('_playbookContentId2')]",
- "kind": "Playbook",
- "version": "[variables('playbookVersion2')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ],
- "metadata": {
- "title": "Jamf Protect - Set Alert to Resolved",
- "description": "This Jamf Protect Playbook can be used manually or in a Automation Rule to change the state of the Alert in Jamf Protect itself, in an automated way you can mirror the state from a Microsoft Sentinel incident back to Jamf Protect.",
- "mainSteps": [
- "1. Fetches the AlertUDID from the Alert of Jamf Protect",
- "2. Generates a Access Token to authenticate against the Jamf Protect GraphQL API",
- "3. Changes the Alert status in Jamf Protect to Resolved"
- ],
- "prerequisites": [
- "1. Generate API Client in Jamf Protect and take note of the CLientID and Password. [learn how](https://learn.jamf.com/bundle/jamf-protect-documentation/page/Jamf_Protect_API.html#ariaid-title3)",
- "2. Use the ClientID and Password during the deployment of this Playbook"
- ],
- "lastUpdateTime": "2023-07-20T00:00:00Z",
- "tags": [
- "Utilities"
- ],
- "source": {
- "type": "solution",
- "name": "Jamf Protect"
- },
- "postDeployment": [
- "** b. Configurations in Sentinel **",
- "1. In Microsoft Sentinel Analytic Rules for Jamf Protect - Alerts should be configured to create an incident",
- "2. Configure the Automation Rules to trigger this playbook once a incident is status is changed to Active"
- ],
- "releaseNotes": [
- {
- "version": "1.0.0",
- "title": "Jamf Protect - Set Alert to Resolved",
- "notes": [
- "Initial version"
- ]
- }
- ]
- }
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_playbookContentId2')]",
- "contentKind": "Playbook",
- "displayName": "JamfProtect_Alert_Status_Resolved",
- "contentProductId": "[variables('_playbookcontentProductId2')]",
- "id": "[variables('_playbookcontentProductId2')]",
- "version": "[variables('playbookVersion2')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
- "apiVersion": "2023-04-01-preview",
- "name": "[variables('playbookTemplateSpecName3')]",
- "location": "[parameters('workspace-location')]",
- "dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
- ],
- "properties": {
- "description": "JamfProtect_LockComputer_with_JamfPro Playbook with template version 3.1.1",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('playbookVersion3')]",
- "parameters": {
- "jamfProClientID": {
- "type": "String",
- "metadata": {
- "description": "The ClientID for the Jamf Pro"
- }
- },
- "jamfProSecret": {
- "type": "SecureString",
- "metadata": {
- "description": "The secret for the ClientID of Jamf Pro"
- }
- },
- "jamfProURL": {
- "defaultValue": "https://*.jamfcloud.com",
- "type": "String",
- "metadata": {
- "description": "Enter the Jamf Pro instance URL ex: {https://fakevalue.jamfcloud.com}"
- }
- },
- "PlaybookName": {
- "type": "String",
- "minLength": 1,
- "defaultValue": "JamfProtect_LockComputer_with_JamfPro",
- "metadata": {
- "description": "Name of the Logic App/Playbook"
- }
- }
- },
- "variables": {
- "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
- "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
- "_connection-1": "[[variables('connection-1')]",
- "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
- "workspace-name": "[parameters('workspace')]",
- "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
- },
- "resources": [
- {
- "type": "Microsoft.Web/connections",
- "apiVersion": "2016-06-01",
- "name": "[[variables('AzureSentinelConnectionName')]",
- "location": "[[variables('workspace-location-inline')]",
- "kind": "V1",
- "properties": {
- "displayName": "[[variables('AzureSentinelConnectionName')]",
- "parameterValueType": "Alternative",
- "api": {
- "id": "[[variables('_connection-1')]"
- }
- }
- },
- {
- "type": "Microsoft.Logic/workflows",
- "apiVersion": "2017-07-01",
- "name": "[[parameters('playbookName')]",
- "location": "[[variables('workspace-location-inline')]",
- "identity": {
- "type": "SystemAssigned"
- },
- "properties": {
- "state": "Enabled",
- "definition": {
- "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
- "contentVersion": "1.0.0.0",
- "parameters": {
- "$connections": {
- "type": "Object"
- },
- "jamfProSecret": {
- "defaultValue": "[[parameters('jamfProSecret')]",
- "type": "SecureString"
- },
- "jamfProURL": {
- "defaultValue": "[[parameters('jamfProURL')]",
- "type": "String"
- },
- "jamfProClientID": {
- "defaultValue": "[[parameters('jamfProClientID')]",
- "type": "String"
- }
- },
- "triggers": {
- "Microsoft_Sentinel_incident": {
- "type": "ApiConnectionWebhook",
- "inputs": {
- "body": {
- "callback_url": "@{listCallbackUrl()}"
- },
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuresentinel']['connectionId']"
- }
- },
- "path": "/incident-creation"
- }
- }
- },
- "actions": {
- "Filter_array_for_the_entity_kind_Host": {
- "runAfter": {
- "Parse_JSON_Entities_from_the_Incident": [
- "Succeeded"
- ]
- },
- "type": "Query",
- "inputs": {
- "from": "@body('Parse_JSON_Entities_from_the_Incident')",
- "where": "@equals(item()['kind'], 'Host')"
- }
- },
- "For_each_host_send_DeviceLock_command": {
- "foreach": "@body('Filter_array_for_the_entity_kind_Host')",
- "actions": {
- "Add_comment_to_incident_(V3)": {
- "runAfter": {
- "Send_DeviceLock_command_to_given_computers_JSSID": [
- "Succeeded"
- ]
- },
- "type": "ApiConnection",
- "inputs": {
- "body": {
- "incidentArmId": "@triggerBody()?['object']?['id']",
- "message": "Device Lock command has been send to @{body('Parse_JSON_for_given_computer_based_on_managementID')?['general']?['name']} with passcode: @{outputs('Generate_a_randomised_6_digit_value')}
"
- },
- "host": {
- "connection": {
- "name": "@parameters('$connections')['azuresentinel']['connectionId']"
- }
- },
- "method": "post",
- "path": "/Incidents/Comment"
- }
- },
- "Generate_a_randomised_6_digit_value": {
- "runAfter": {
- "Parse_JSON_for_given_computer_based_on_managementID": [
- "Succeeded",
- "Failed"
- ]
- },
- "type": "Compose",
- "inputs": "@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}"
- },
- "Get_JSSID_for_given_computer_in_Jamf_Pro": {
- "type": "Http",
- "inputs": {
- "headers": {
- "Authorization": "Bearer @{variables('accessToken')}",
- "accept": "application/json"
- },
- "method": "GET",
- "uri": "@{parameters('jamfProURL')}/JSSResource/computers/name/@{items('For_each_host_send_DeviceLock_command')?['properties']?['friendlyName']}"
- }
- },
- "Get_managementID_for_given_computer_in_Jamf_Pro": {
- "runAfter": {
- "Parse_JSON_response_for_given_computer": [
- "Succeeded"
- ]
- },
- "type": "Http",
- "inputs": {
- "headers": {
- "Authorization": "Bearer @{variables('accessToken')}",
- "accept": "application/json"
- },
- "method": "GET",
- "uri": "@{parameters('jamfProURL')}/api/v1/computers-inventory/@{body('Parse_JSON_response_for_given_computer')?['computer']?['general']?['id']}?section=GENERAL"
- }
- },
- "Parse_JSON_for_given_computer_based_on_managementID": {
- "runAfter": {
- "Get_managementID_for_given_computer_in_Jamf_Pro": [
- "Succeeded"
- ]
- },
- "type": "ParseJson",
- "inputs": {
- "content": "@body('Get_managementID_for_given_computer_in_Jamf_Pro')",
- "schema": {
- "properties": {
- "general": {
- "properties": {
- "declarativeDeviceManagementEnabled": {
- "type": "boolean"
- },
- "enrolledViaAutomatedDeviceEnrollment": {
- "type": "boolean"
- },
- "initialEntryDate": {
- "type": "string"
- },
- "itunesStoreAccountActive": {
- "type": "boolean"
- },
- "jamfBinaryVersion": {
- "type": "string"
- },
- "lastContactTime": {
- "type": "string"
- },
- "lastEnrolledDate": {
- "type": "string"
- },
- "lastIpAddress": {
- "type": "string"
- },
- "lastReportedIp": {
- "type": "string"
- },
- "managementId": {
- "type": "string"
- },
- "mdmCapable": {
- "properties": {
- "capable": {
- "type": "boolean"
- },
- "capableUsers": {
- "items": {
- "type": "string"
- },
- "type": "array"
- }
- },
- "type": "object"
- },
- "mdmProfileExpiration": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "platform": {
- "type": "string"
- },
- "remoteManagement": {
- "properties": {
- "managed": {
- "type": "boolean"
- }
- },
- "type": "object"
- },
- "reportDate": {
- "type": "string"
- },
- "site": {
- "properties": {
- "id": {
- "type": "string"
- },
- "name": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "supervised": {
- "type": "boolean"
- },
- "userApprovedMdm": {
- "type": "boolean"
- }
- },
- "type": "object"
- },
- "id": {
- "type": "string"
- },
- "udid": {
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- },
- "Parse_JSON_response_for_given_computer": {
- "runAfter": {
- "Get_JSSID_for_given_computer_in_Jamf_Pro": [
- "Succeeded"
- ]
- },
- "type": "ParseJson",
- "inputs": {
- "content": "@body('Get_JSSID_for_given_computer_in_Jamf_Pro')",
- "schema": {
- "properties": {
- "computer": {
- "properties": {
- "certificates": {
- "items": {
- "properties": {
- "common_name": {
- "type": "string"
- },
- "expires_epoch": {
- "type": "integer"
- },
- "expires_utc": {
- "type": "string"
- },
- "identity": {
- "type": "boolean"
- },
- "name": {
- "type": "string"
- }
- },
- "required": [
- "common_name",
- "identity",
- "expires_utc",
- "expires_epoch",
- "name"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "configuration_profiles": {
- "items": {
- "properties": {
- "id": {
- "type": "integer"
- },
- "is_removable": {
- "type": "boolean"
- },
- "name": {
- "type": "string"
- },
- "uuid": {
- "type": "string"
- }
- },
- "required": [
- "id",
- "name",
- "uuid",
- "is_removable"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "extension_attributes": {
- "items": {
- "properties": {
- "id": {
- "type": "integer"
- },
- "multi_value": {
- "type": "boolean"
- },
- "name": {
- "type": "string"
- },
- "type": {
- "type": "string"
- },
- "value": {
- "type": "string"
- }
- },
- "required": [
- "id",
- "name",
- "type",
- "multi_value",
- "value"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "general": {
- "properties": {
- "alt_mac_address": {
- "type": "string"
- },
- "alt_network_adapter_type": {
- "type": "string"
- },
- "asset_tag": {
- "type": "string"
- },
- "barcode_1": {
- "type": "string"
- },
- "barcode_2": {
- "type": "string"
- },
- "distribution_point": {
- "type": "string"
- },
- "id": {
- "type": "integer"
- },
- "initial_entry_date": {
- "type": "string"
- },
- "initial_entry_date_epoch": {
- "type": "integer"
- },
- "initial_entry_date_utc": {
- "type": "string"
- },
- "ip_address": {
- "type": "string"
- },
- "itunes_store_account_is_active": {
- "type": "boolean"
- },
- "jamf_version": {
- "type": "string"
- },
- "last_cloud_backup_date_epoch": {
- "type": "integer"
- },
- "last_cloud_backup_date_utc": {
- "type": "string"
- },
- "last_contact_time": {
- "type": "string"
- },
- "last_contact_time_epoch": {
- "type": "integer"
- },
- "last_contact_time_utc": {
- "type": "string"
- },
- "last_enrolled_date_epoch": {
- "type": "integer"
- },
- "last_enrolled_date_utc": {
- "type": "string"
- },
- "last_reported_ip": {
- "type": "string"
- },
- "mac_address": {
- "type": "string"
- },
- "management_status": {
- "properties": {
- "enrolled_via_dep": {
- "type": "boolean"
- },
- "user_approved_enrollment": {
- "type": "boolean"
- },
- "user_approved_mdm": {
- "type": "boolean"
- }
- },
- "type": "object"
- },
- "mdm_capable": {
- "type": "boolean"
- },
- "mdm_capable_users": {
- "properties": {
- "mdm_capable_user": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "mdm_profile_expiration_epoch": {
- "type": "integer"
- },
- "mdm_profile_expiration_utc": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "network_adapter_type": {
- "type": "string"
- },
- "platform": {
- "type": "string"
- },
- "remote_management": {
- "properties": {
- "managed": {
- "type": "boolean"
- },
- "management_password_sha256": {
- "type": "string"
- },
- "management_username": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "report_date": {
- "type": "string"
- },
- "report_date_epoch": {
- "type": "integer"
- },
- "report_date_utc": {
- "type": "string"
- },
- "serial_number": {
- "type": "string"
- },
- "site": {
- "properties": {
- "id": {
- "type": "integer"
- },
- "name": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "supervised": {
- "type": "boolean"
- },
- "sus": {
- "type": "string"
- },
- "udid": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "groups_accounts": {
- "properties": {
- "computer_group_memberships": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "local_accounts": {
- "items": {
- "properties": {
- "administrator": {
- "type": "boolean"
- },
- "filevault_enabled": {
- "type": "boolean"
- },
- "home": {
- "type": "string"
- },
- "home_size": {
- "type": "string"
- },
- "home_size_mb": {
- "type": "integer"
- },
- "name": {
- "type": "string"
- },
- "realname": {
- "type": "string"
- },
- "uid": {
- "type": "string"
- }
- },
- "required": [
- "name",
- "realname",
- "uid",
- "home",
- "home_size",
- "home_size_mb",
- "administrator",
- "filevault_enabled"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "user_inventories": {
- "properties": {
- "disable_automatic_login": {
- "type": "boolean"
- },
- "user": {
- "properties": {
- "password_history_depth": {
- "type": "string"
- },
- "password_max_age": {
- "type": "string"
- },
- "password_min_complex_characters": {
- "type": "string"
- },
- "password_min_length": {
- "type": "string"
- },
- "password_require_alphanumeric": {
- "type": "string"
- },
- "username": {
- "type": "string"
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- },
- "hardware": {
- "properties": {
- "active_directory_status": {
- "type": "string"
- },
- "available_ram_slots": {
- "type": "integer"
- },
- "battery_capacity": {
- "type": "integer"
- },
- "ble_capable": {
- "type": "boolean"
- },
- "boot_rom": {
- "type": "string"
- },
- "bus_speed": {
- "type": "integer"
- },
- "bus_speed_mhz": {
- "type": "integer"
- },
- "cache_size": {
- "type": "integer"
- },
- "cache_size_kb": {
- "type": "integer"
- },
- "disk_encryption_configuration": {
- "type": "string"
- },
- "filevault2_users": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "gatekeeper_status": {
- "type": "string"
- },
- "institutional_recovery_key": {
- "type": "string"
- },
- "is_apple_silicon": {
- "type": "boolean"
- },
- "make": {
- "type": "string"
- },
- "mapped_printers": {
- "type": "array"
- },
- "model": {
- "type": "string"
- },
- "model_identifier": {
- "type": "string"
- },
- "nic_speed": {
- "type": "string"
- },
- "number_cores": {
- "type": "integer"
- },
- "number_processors": {
- "type": "integer"
- },
- "optical_drive": {
- "type": "string"
- },
- "os_build": {
- "type": "string"
- },
- "os_name": {
- "type": "string"
- },
- "os_version": {
- "type": "string"
- },
- "processor_architecture": {
- "type": "string"
- },
- "processor_speed": {
- "type": "integer"
- },
- "processor_speed_mhz": {
- "type": "integer"
- },
- "processor_type": {
- "type": "string"
- },
- "service_pack": {
- "type": "string"
- },
- "sip_status": {
- "type": "string"
- },
- "smc_version": {
- "type": "string"
- },
- "software_update_device_id": {
- "type": "string"
- },
- "storage": {
- "type": "array"
- },
- "supports_ios_app_installs": {
- "type": "boolean"
- },
- "total_ram": {
- "type": "integer"
- },
- "total_ram_mb": {
- "type": "integer"
- },
- "xprotect_version": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "iphones": {
- "type": "array"
- },
- "location": {
- "properties": {
- "building": {
- "type": "string"
- },
- "department": {
- "type": "string"
- },
- "email_address": {
- "type": "string"
- },
- "phone": {
- "type": "string"
- },
- "phone_number": {
- "type": "string"
- },
- "position": {
- "type": "string"
- },
- "real_name": {
- "type": "string"
- },
- "realname": {
- "type": "string"
- },
- "room": {
- "type": "string"
- },
- "username": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "peripherals": {
- "type": "array"
- },
- "purchasing": {
- "properties": {
- "applecare_id": {
- "type": "string"
- },
- "attachments": {
- "type": "array"
- },
- "is_leased": {
- "type": "boolean"
- },
- "is_purchased": {
- "type": "boolean"
- },
- "lease_expires": {
- "type": "string"
- },
- "lease_expires_epoch": {
- "type": "integer"
- },
- "lease_expires_utc": {
- "type": "string"
- },
- "life_expectancy": {
- "type": "integer"
- },
- "os_applecare_id": {
- "type": "string"
- },
- "os_maintenance_expires": {
- "type": "string"
- },
- "po_date": {
- "type": "string"
- },
- "po_date_epoch": {
- "type": "integer"
- },
- "po_date_utc": {
- "type": "string"
- },
- "po_number": {
- "type": "string"
- },
- "purchase_price": {
- "type": "string"
- },
- "purchasing_account": {
- "type": "string"
- },
- "purchasing_contact": {
- "type": "string"
- },
- "vendor": {
- "type": "string"
- },
- "warranty_expires": {
- "type": "string"
- },
- "warranty_expires_epoch": {
- "type": "integer"
- },
- "warranty_expires_utc": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "security": {
- "properties": {
- "activation_lock": {
- "type": "boolean"
- },
- "external_boot_level": {
- "type": "string"
- },
- "firewall_enabled": {
- "type": "boolean"
- },
- "recovery_lock_enabled": {
- "type": "boolean"
- },
- "secure_boot_level": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "software": {
- "properties": {
- "applications": {
- "items": {
- "properties": {
- "bundle_id": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "path": {
- "type": "string"
- },
- "version": {
- "type": "string"
- }
- },
- "required": [
- "name",
- "path",
- "version",
- "bundle_id"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "available_software_updates": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "available_updates": {
- "properties": {
- "update": {
- "properties": {
- "name": {
- "type": "string"
- },
- "package_name": {
- "type": "string"
- },
- "version": {
- "type": "string"
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- },
- "cached_by_casper": {
- "type": "array"
- },
- "fonts": {
- "type": "array"
- },
- "installed_by_casper": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "installed_by_installer_swu": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "licensed_software": {
- "type": "array"
- },
- "plugins": {
- "type": "array"
- },
- "running_services": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "unix_executables": {
- "type": "array"
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- }
- }
- },
- "Send_DeviceLock_command_to_given_computers_JSSID": {
- "runAfter": {
- "Generate_a_randomised_6_digit_value": [
- "Succeeded"
- ]
- },
- "type": "Http",
- "inputs": {
- "headers": {
- "Authorization": "Bearer @{variables('accessToken')}",
- "accept": "application/json"
- },
- "method": "POST",
- "uri": "@{parameters('jamfProURL')}/JSSResource/computercommands/command/DeviceLock/passcode/@{outputs('Generate_a_randomised_6_digit_value')}/id/@{body('Parse_JSON_for_given_computer_based_on_managementID')?['general']?['site']?['id']}"
- }
- }
- },
- "runAfter": {
- "Filter_array_for_the_entity_kind_Host": [
- "Succeeded"
- ]
- },
- "type": "Foreach"
- },
- "Generate_Access_Token_using_API_Client": {
- "type": "Http",
- "inputs": {
- "body": "client_id=@{parameters('jamfProClientID')}&client_secret=@{parameters('jamfProSecret')}&grant_type=client_credentials",
- "headers": {
- "Content-Type": "application/x-www-form-urlencoded"
- },
- "method": "POST",
- "uri": "@{parameters('jamfProURL')}/api/oauth/token"
- },
- "runtimeConfiguration": {
- "secureData": {
- "properties": [
- "inputs"
- ]
- }
- }
- },
- "Parse_JSON_Entities_from_the_Incident": {
- "runAfter": {
- "Set_accessToken_as_variable": [
- "Succeeded"
- ]
- },
- "type": "ParseJson",
- "inputs": {
- "content": "@triggerBody()?['object']?['properties']?['relatedEntities']",
- "schema": {
- "items": {
- "properties": {
- "id": {
- "type": "string"
- },
- "kind": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "properties": {
- "properties": {
- "address": {
- "type": "string"
- },
- "friendlyName": {
- "type": "string"
- }
- },
- "type": "object"
- },
- "type": {
- "type": "string"
- }
- },
- "required": [
- "id",
- "name",
- "type",
- "kind",
- "properties"
- ],
- "type": "object"
- },
- "type": "array"
- }
- }
- },
- "Parse_JSON_Response_from_Access_Token": {
- "runAfter": {
- "Generate_Access_Token_using_API_Client": [
- "Succeeded"
- ]
- },
- "type": "ParseJson",
- "inputs": {
- "content": "@body('Generate_Access_Token_using_API_Client')",
- "schema": {
- "properties": {
- "access_token": {
- "type": "string"
- },
- "expires_in": {
- "type": "integer"
- },
- "scope": {
- "type": "string"
- },
- "token_type": {
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- },
- "Set_accessToken_as_variable": {
- "runAfter": {
- "Parse_JSON_Response_from_Access_Token": [
- "Succeeded"
- ]
- },
- "type": "InitializeVariable",
- "inputs": {
- "variables": [
- {
- "name": "accessToken",
- "type": "string",
- "value": "@body('Parse_JSON_Response_from_Access_Token')?['access_token']"
- }
- ]
- }
- }
- }
- },
- "parameters": {
- "$connections": {
- "value": {
- "azuresentinel": {
- "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]",
- "connectionName": "[[variables('AzureSentinelConnectionName')]",
- "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
- "connectionProperties": {
- "authentication": {
- "type": "ManagedServiceIdentity"
- }
- }
- }
- }
- }
- }
- },
- "tags": {
- "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]",
- "properties": {
- "parentId": "[variables('playbookId3')]",
- "contentId": "[variables('_playbookContentId3')]",
- "kind": "Playbook",
- "version": "[variables('playbookVersion3')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- }
- }
- }
- ],
- "metadata": {
- "title": "Jamf Protect - Remote lock computer with Jamf Pro",
- "description": "This Playbook can be used manually or in a Automation Rule to send an remote MDM command with Jamf Pro to lock the computer with an randomised 6 digit passcode.",
- "mainSteps": [
- "1. Fetches the Host entity from the Incident created based on event data from Jamf Protect",
- "2. Generates a Access Token using a API Client to authenticate against the Jamf Pro API",
- "3. Retrieves the JSSID and ManagementUUID from Jamf Pro for given computer",
- "4. Sends a remote lock MDM command with a randomised 6 digit passcode",
- "5. Randomised passcode will be stored in the Comments section of the incident itself."
- ],
- "prerequisites": [
- "1. Create an API Client in Jamf Pro that is capable of reading computers and sending remote commands. [learn how](https://learn.jamf.com/bundle/jamf-pro-documentation-current)",
- "2. Use the Client ID and Secret during the deployment of this Playbook"
- ],
- "lastUpdateTime": "2023-07-20T00:00:00Z",
- "tags": [
- "Utilities"
- ],
- "source": {
- "type": "solution",
- "name": "Jamf Protect"
- },
- "postDeployment": [
- "** b. Configurations in Sentinel **",
- "1. This Playbook can be best used as Action while investigating an Incident."
- ],
- "releaseNotes": [
- {
- "version": "1.0.0",
- "title": "Jamf Protect - Remote lock computer with Jamf Pro",
- "notes": [
- "Initial version"
- ]
- }
- ]
- }
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_playbookContentId3')]",
- "contentKind": "Playbook",
- "displayName": "JamfProtect_LockComputer_with_JamfPro",
- "contentProductId": "[variables('_playbookcontentProductId3')]",
- "id": "[variables('_playbookcontentProductId3')]",
- "version": "[variables('playbookVersion3')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
- "apiVersion": "2023-04-01-preview",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "version": "3.1.1",
- "kind": "Solution",
- "contentSchemaVersion": "3.0.0",
- "displayName": "Jamf Protect",
- "publisherDisplayName": "Jamf Software, LLC",
- "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Jamf Protect solution for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.
\nData Connectors: 1, Parsers: 1, Workbooks: 1, Analytic Rules: 3, Hunting Queries: 7, Playbooks: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
- "contentKind": "Solution",
- "contentProductId": "[variables('_solutioncontentProductId')]",
- "id": "[variables('_solutioncontentProductId')]",
- "icon": "
",
- "contentId": "[variables('_solutionId')]",
- "parentId": "[variables('_solutionId')]",
- "source": {
- "kind": "Solution",
- "name": "Jamf Protect",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Thijs Xhaflaire",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Jamf Software, LLC",
- "email": "support@jamf.com",
- "tier": "Partner",
- "link": "https://www.jamf.com/support/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "kind": "DataConnector",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "version": "[variables('dataConnectorVersion1')]"
- },
- {
- "kind": "Parser",
- "contentId": "[variables('parserObject1').parserContentId1]",
- "version": "[variables('parserObject1').parserVersion1]"
- },
- {
- "kind": "Workbook",
- "contentId": "[variables('_workbookContentId1')]",
- "version": "[variables('workbookVersion1')]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
- "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
- "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
- "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
- "version": "[variables('huntingQueryObject1').huntingQueryVersion1]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
- "version": "[variables('huntingQueryObject2').huntingQueryVersion2]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
- "version": "[variables('huntingQueryObject3').huntingQueryVersion3]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
- "version": "[variables('huntingQueryObject4').huntingQueryVersion4]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]",
- "version": "[variables('huntingQueryObject5').huntingQueryVersion5]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]",
- "version": "[variables('huntingQueryObject6').huntingQueryVersion6]"
- },
- {
- "kind": "HuntingQuery",
- "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]",
- "version": "[variables('huntingQueryObject7').huntingQueryVersion7]"
- },
- {
- "kind": "Playbook",
- "contentId": "[variables('_JamfProtect_Alert_Status_InProgress')]",
- "version": "[variables('playbookVersion1')]"
- },
- {
- "kind": "Playbook",
- "contentId": "[variables('_JamfProtect_Alert_Status_Resolved')]",
- "version": "[variables('playbookVersion2')]"
- },
- {
- "kind": "Playbook",
- "contentId": "[variables('_JamfProtect_LockComputer_with_JamfPro')]",
- "version": "[variables('playbookVersion3')]"
- }
- ]
- },
- "firstPublishDate": "2022-10-10",
- "lastPublishDate": "2024-01-12",
- "providers": [
- "Jamf"
- ],
- "categories": {
- "domains": [
- "Security - Threat Protection",
- "Security - Automation (SOAR)"
- ]
- }
- },
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]"
- }
- ],
- "outputs": {}
-}
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "author": "Thijs Xhaflaire - thijs.xhaflaire@jamf.com",
+ "comments": "Solution template for Jamf Protect"
+ },
+ "parameters": {
+ "location": {
+ "type": "string",
+ "minLength": 1,
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
+ }
+ },
+ "workspace-location": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
+ }
+ },
+ "workspace": {
+ "defaultValue": "",
+ "type": "string",
+ "metadata": {
+ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
+ }
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().name]",
+ "metadata": {
+ "description": "resource group name where Microsoft Sentinel is setup"
+ }
+ },
+ "subscription": {
+ "type": "string",
+ "defaultValue": "[last(split(subscription().id, '/'))]",
+ "metadata": {
+ "description": "subscription id where Microsoft Sentinel is setup"
+ }
+ },
+ "workbook1-name": {
+ "type": "string",
+ "defaultValue": "Jamf Protect Workbook",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ }
+ },
+ "variables": {
+ "email": "thijs.xhaflaire@jamf.com",
+ "_email": "[variables('email')]",
+ "_solutionName": "Jamf Protect",
+ "_solutionVersion": "3.2.0",
+ "solutionId": "jamfsoftwareaustraliaptyltd1620360395539.jamf_protect",
+ "_solutionId": "[variables('solutionId')]",
+ "uiConfigId1": "JamfProtect",
+ "_uiConfigId1": "[variables('uiConfigId1')]",
+ "dataConnectorContentId1": "JamfProtect",
+ "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]",
+ "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "_dataConnectorId1": "[variables('dataConnectorId1')]",
+ "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
+ "dataConnectorVersion1": "3.1.0",
+ "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
+ "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
+ "dataConnectorCCPVersion": "1.0.0",
+ "_dataConnectorContentIdConnectorDefinition2": "JamfProtectPush",
+ "dataConnectorTemplateNameConnectorDefinition2": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition2')))]",
+ "_dataConnectorContentIdConnections2": "JamfProtectPushConnections",
+ "dataConnectorTemplateNameConnections2": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnections2')))]",
+ "blanks": "[replace('b', 'b', '')]",
+ "parserObject1": {
+ "_parserName1": "[concat(parameters('workspace'),'/','JamfProtect')]",
+ "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]",
+ "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('JamfProtect-Parser')))]",
+ "parserVersion1": "3.2.0",
+ "parserContentId1": "JamfProtect-Parser"
+ },
+ "workbookVersion1": "2.0.0",
+ "workbookContentId1": "JamfProtectWorkbook",
+ "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
+ "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]",
+ "_workbookContentId1": "[variables('workbookContentId1')]",
+ "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
+ "analyticRuleObject1": {
+ "analyticRuleVersion1": "1.0.5",
+ "_analyticRulecontentId1": "6098daa0-f05e-44d5-b5a0-913e63ba3179",
+ "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '6098daa0-f05e-44d5-b5a0-913e63ba3179')]",
+ "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('6098daa0-f05e-44d5-b5a0-913e63ba3179')))]",
+ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','6098daa0-f05e-44d5-b5a0-913e63ba3179','-', '1.0.5')))]"
+ },
+ "analyticRuleObject2": {
+ "analyticRuleVersion2": "1.0.4",
+ "_analyticRulecontentId2": "44da53c3-f3b0-4b70-afff-f79275cb9442",
+ "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '44da53c3-f3b0-4b70-afff-f79275cb9442')]",
+ "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('44da53c3-f3b0-4b70-afff-f79275cb9442')))]",
+ "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','44da53c3-f3b0-4b70-afff-f79275cb9442','-', '1.0.4')))]"
+ },
+ "analyticRuleObject3": {
+ "analyticRuleVersion3": "1.0.2",
+ "_analyticRulecontentId3": "9eb2f758-003b-4303-83c6-97aed4c03e41",
+ "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '9eb2f758-003b-4303-83c6-97aed4c03e41')]",
+ "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('9eb2f758-003b-4303-83c6-97aed4c03e41')))]",
+ "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','9eb2f758-003b-4303-83c6-97aed4c03e41','-', '1.0.2')))]"
+ },
+ "huntingQueryObject1": {
+ "huntingQueryVersion1": "1.0.0",
+ "_huntingQuerycontentId1": "f0a1bacb-eb6a-4edc-99a9-839a77be3a33",
+ "huntingQueryTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('f0a1bacb-eb6a-4edc-99a9-839a77be3a33')))]"
+ },
+ "huntingQueryObject2": {
+ "huntingQueryVersion2": "1.0.0",
+ "_huntingQuerycontentId2": "8d9a199b-7968-476b-b02b-d030a010609c",
+ "huntingQueryTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('8d9a199b-7968-476b-b02b-d030a010609c')))]"
+ },
+ "huntingQueryObject3": {
+ "huntingQueryVersion3": "1.0.0",
+ "_huntingQuerycontentId3": "60b1269f-374e-49dd-8b10-e4ef85d5bd65",
+ "huntingQueryTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('60b1269f-374e-49dd-8b10-e4ef85d5bd65')))]"
+ },
+ "huntingQueryObject4": {
+ "huntingQueryVersion4": "1.0.0",
+ "_huntingQuerycontentId4": "ec2f21aa-a9c5-42fd-9ee1-c59f30b4fdd6",
+ "huntingQueryTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('ec2f21aa-a9c5-42fd-9ee1-c59f30b4fdd6')))]"
+ },
+ "huntingQueryObject5": {
+ "huntingQueryVersion5": "1.0.0",
+ "_huntingQuerycontentId5": "223f6758-e134-45e8-a9d6-4ca8455799fb",
+ "huntingQueryTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('223f6758-e134-45e8-a9d6-4ca8455799fb')))]"
+ },
+ "huntingQueryObject6": {
+ "huntingQueryVersion6": "1.0.0",
+ "_huntingQuerycontentId6": "09161cb2-f28a-437c-83e3-60b8545dc8f2",
+ "huntingQueryTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('09161cb2-f28a-437c-83e3-60b8545dc8f2')))]"
+ },
+ "huntingQueryObject7": {
+ "huntingQueryVersion7": "1.0.0",
+ "_huntingQuerycontentId7": "2b0ec436-80d6-4e63-b3da-e35048724f37",
+ "huntingQueryTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring('2b0ec436-80d6-4e63-b3da-e35048724f37')))]"
+ },
+ "JamfProtect_Alert_Status_InProgress": "JamfProtect_Alert_Status_InProgress",
+ "_JamfProtect_Alert_Status_InProgress": "[variables('JamfProtect_Alert_Status_InProgress')]",
+ "playbookVersion1": "1.0",
+ "playbookContentId1": "JamfProtect_Alert_Status_InProgress",
+ "_playbookContentId1": "[variables('playbookContentId1')]",
+ "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]",
+ "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]",
+ "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]",
+ "JamfProtect_Alert_Status_Resolved": "JamfProtect_Alert_Status_Resolved",
+ "_JamfProtect_Alert_Status_Resolved": "[variables('JamfProtect_Alert_Status_Resolved')]",
+ "playbookVersion2": "1.0",
+ "playbookContentId2": "JamfProtect_Alert_Status_Resolved",
+ "_playbookContentId2": "[variables('playbookContentId2')]",
+ "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]",
+ "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]",
+ "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]",
+ "JamfProtect_LockComputer_with_JamfPro": "JamfProtect_LockComputer_with_JamfPro",
+ "_JamfProtect_LockComputer_with_JamfPro": "[variables('JamfProtect_LockComputer_with_JamfPro')]",
+ "playbookVersion3": "1.0",
+ "playbookContentId3": "JamfProtect_LockComputer_with_JamfPro",
+ "_playbookContentId3": "[variables('playbookContentId3')]",
+ "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]",
+ "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]",
+ "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]",
+ "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName1')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Jamf Protect data connector with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion1')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId1')]",
+ "title": "Jamf Protect",
+ "publisher": "Jamf",
+ "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Total Activities data received",
+ "legend": "jamfprotect_CL",
+ "baseQuery": "jamfprotect_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Jamf Protect - All events.",
+ "query": "jamfprotect_CL\n | sort by TimeGenerated desc"
+ },
+ {
+ "description": "Jamf Protect - All active endpoints.",
+ "query": "jamfprotect_CL\n | where notempty(input_host_hostname_s) | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | sort by Event desc"
+ },
+ {
+ "description": "Jamf Protect - Top 10 endpoints with Alerts",
+ "query": "jamfprotect_CL\n | where topicType_s == 'alert' and notempty(input_eventType_s) and notempty(input_host_hostname_s)\n | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | top 10 by Event"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "jamfprotect_CL",
+ "lastDataReceivedQuery": "jamfprotect_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "jamfprotect_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": "This connector reads data from the jamfprotect_CL table created by Jamf Protect in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API."
+ }
+ ],
+ "metadata": {
+ "id": "AF74EDD7-5534-46CD-B75D-7119BE1D161D",
+ "version": "3.1.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Jamf Protect for Microsoft Sentinel"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire"
+ },
+ "support": {
+ "tier": "developer",
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "link": "https://jamf.com/support/"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "contentKind": "DataConnector",
+ "displayName": "Jamf Protect",
+ "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
+ "id": "[variables('_dataConnectorcontentProductId1')]",
+ "version": "[variables('dataConnectorVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId1')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "Jamf Protect",
+ "publisher": "Jamf",
+ "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Total Activities data received",
+ "legend": "jamfprotect_CL",
+ "baseQuery": "jamfprotect_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "jamfprotect_CL",
+ "lastDataReceivedQuery": "jamfprotect_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "jamfprotect_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Jamf Protect - All events.",
+ "query": "jamfprotect_CL\n | sort by TimeGenerated desc"
+ },
+ {
+ "description": "Jamf Protect - All active endpoints.",
+ "query": "jamfprotect_CL\n | where notempty(input_host_hostname_s) | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | sort by Event desc"
+ },
+ {
+ "description": "Jamf Protect - Top 10 endpoints with Alerts",
+ "query": "jamfprotect_CL\n | where topicType_s == 'alert' and notempty(input_eventType_s) and notempty(input_host_hostname_s)\n | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | top 10 by Event"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": "This connector reads data from the jamfprotect_CL table created by Jamf Protect in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API."
+ }
+ ],
+ "id": "[variables('_uiConfigId1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnectorDefinition2'), variables('dataConnectorCCPVersion'))]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]",
+ "displayName": "Jamf Protect Push Connector",
+ "contentKind": "DataConnector",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorCCPVersion')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition2'))]",
+ "apiVersion": "2022-09-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
+ "location": "[parameters('workspace-location')]",
+ "kind": "Customizable",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "JamfProtectPush",
+ "title": "Jamf Protect Push Connector",
+ "publisher": "Jamf",
+ "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Telemetry",
+ "legend": "jamfprotecttelemetryv2_CL",
+ "baseQuery": "jamfprotecttelemetryv2_CL"
+ },
+ {
+ "metricName": "Unified Logs",
+ "legend": "jamfprotectunifiedlogs_CL",
+ "baseQuery": "jamfprotectunifiedlogs_CL"
+ },
+ {
+ "metricName": "Telemetry (Legacy)",
+ "legend": "jamfprotecttelemetryv1_CL",
+ "baseQuery": "jamfprotecttelemetryv1_CL"
+ },
+ {
+ "metricName": "Alerts",
+ "legend": "jamfprotectalerts_CL",
+ "baseQuery": "jamfprotectalerts_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Jamf Protect - All Alerts",
+ "query": "jamfprotectalerts_CL\n | sort by TimeGenerated desc"
+ },
+ {
+ "description": "Jamf Protect - All Telemetry events",
+ "query": "jamfprotecttelemetry_CL\n | sort by TimeGenerated desc"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "jamfprotecttelemetryv2_CL",
+ "lastDataReceivedQuery": "jamfprotecttelemetryv2_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotectunifiedlogs_CL",
+ "lastDataReceivedQuery": "jamfprotectunifiedlogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotecttelemetryv1_CL",
+ "lastDataReceivedQuery": "jamfprotecttelemetryv1_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotectalerts_CL",
+ "lastDataReceivedQuery": "jamfprotectalerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriteria": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "jamfprotecttelemetryv2_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotectunifiedlogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotecttelemetryv1_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotectalerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft Entra",
+ "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher."
+ },
+ {
+ "name": "Microsoft Azure",
+ "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Create ARM Resources and Provide the Required Permissions",
+ "description": "This connector reads data from the tables that Jamf Protect uses in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API.",
+ "instructions": [
+ {
+ "type": "Markdown",
+ "parameters": {
+ "content": "#### Automated Configuration and Secure Data Ingestion with Entra Application \nClicking on \"Connect\" will trigger the creation of Log Analytics tables and a Data Collection Rule (DCR). \nIt will then create an Entra application, link the DCR to it, and set the entered secret in the application. This setup enables data to be sent securely to the DCR using an Entra token."
+ }
+ },
+ {
+ "parameters": {
+ "label": "Deploy Jamf Protect connector resources",
+ "applicationDisplayName": "Jamf Protect Connector Application"
+ },
+ "type": "DeployPushConnectorButton"
+ }
+ ]
+ },
+ {
+ "title": "2. Push your logs into the workspace",
+ "description": "Use the following parameters to configure the your machine to send the logs to the workspace.",
+ "instructions": [
+ {
+ "parameters": {
+ "label": "Tenant ID (Directory ID)",
+ "fillWith": [
+ "TenantId"
+ ]
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Entra Application ID",
+ "fillWith": [
+ "ApplicationId"
+ ],
+ "placeholder": "Deploy push connector to get the Application ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Entra Application Secret",
+ "fillWith": [
+ "ApplicationSecret"
+ ],
+ "placeholder": "Deploy push connector to get the Application Secret"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "DCE Uri",
+ "fillWith": [
+ "DataCollectionEndpoint"
+ ],
+ "placeholder": "Deploy push connector to get the DCR Uri"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "DCR Immutable ID",
+ "fillWith": [
+ "DataCollectionRuleId"
+ ],
+ "placeholder": "Deploy push connector to get the DCR ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Telemetry (Legacy) Stream ID",
+ "value": "Custom-jamfprotecttelemetryv1_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Unified Logs Stream ID",
+ "value": "Custom-jamfprotectunifiedlogs_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Telemetry Stream ID",
+ "value": "Custom-jamfprotecttelemetryv2_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Alerts Stream ID",
+ "value": "Custom-jamfprotectalerts_CL"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition2')))]",
+ "apiVersion": "2022-01-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition2'))]",
+ "contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorCCPVersion')]",
+ "source": {
+ "sourceId": "[variables('_solutionId')]",
+ "name": "[variables('_solutionName')]",
+ "kind": "Solution"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ },
+ "dependencies": {
+ "criteria": [
+ {
+ "version": "[variables('dataConnectorCCPVersion')]",
+ "contentId": "[variables('_dataConnectorContentIdConnections2')]",
+ "kind": "ResourcesDataConnector"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "JamfProtectCustomDCR",
+ "apiVersion": "2022-06-01",
+ "type": "Microsoft.Insights/dataCollectionRules",
+ "location": "[parameters('workspace-location')]",
+ "kind": "[variables('blanks')]",
+ "properties": {
+ "streamDeclarations": {
+ "Custom-jamfprotecttelemetryv2": {
+ "columns": [
+ {
+ "name": "action",
+ "type": "dynamic"
+ },
+ {
+ "name": "action_type",
+ "type": "int"
+ },
+ {
+ "name": "deadline",
+ "type": "int"
+ },
+ {
+ "name": "event",
+ "type": "dynamic"
+ },
+ {
+ "name": "event_type",
+ "type": "int"
+ },
+ {
+ "name": "glob_seq_num",
+ "type": "int"
+ },
+ {
+ "name": "host",
+ "type": "dynamic"
+ },
+ {
+ "name": "mach_time",
+ "type": "long"
+ },
+ {
+ "name": "metadata",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "seq_num",
+ "type": "int"
+ },
+ {
+ "name": "thread",
+ "type": "dynamic"
+ },
+ {
+ "name": "time",
+ "type": "datetime"
+ },
+ {
+ "name": "uuid",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "int"
+ }
+ ]
+ },
+ "Custom-jamfprotectunifiedlogs": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "caid",
+ "type": "string"
+ },
+ {
+ "name": "certid",
+ "type": "string"
+ },
+ {
+ "name": "input",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "Custom-jamfprotecttelemetryv1": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "arguments",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain",
+ "type": "dynamic"
+ },
+ {
+ "name": "header",
+ "type": "dynamic"
+ },
+ {
+ "name": "host_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "key",
+ "type": "string"
+ },
+ {
+ "name": "return",
+ "type": "dynamic"
+ },
+ {
+ "name": "subject",
+ "type": "dynamic"
+ },
+ {
+ "name": "identity",
+ "type": "dynamic"
+ },
+ {
+ "name": "texts",
+ "type": "string"
+ },
+ {
+ "name": "metrics",
+ "type": "dynamic"
+ },
+ {
+ "name": "page_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "attributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_child",
+ "type": "dynamic"
+ },
+ {
+ "name": "path",
+ "type": "dynamic"
+ },
+ {
+ "name": "_event_score",
+ "type": "int"
+ },
+ {
+ "name": "contents",
+ "type": "string"
+ },
+ {
+ "name": "file",
+ "type": "dynamic"
+ },
+ {
+ "name": "socket_inet",
+ "type": "dynamic"
+ },
+ {
+ "name": "exit",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_args",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_env",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_parent",
+ "type": "dynamic"
+ },
+ {
+ "name": "architecture",
+ "type": "string"
+ },
+ {
+ "name": "bios_firmware_versions",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "rateLimitingSeconds",
+ "type": "int"
+ }
+ ]
+ },
+ "Custom-jamfprotectalerts": {
+ "columns": [
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "caid",
+ "type": "string"
+ },
+ {
+ "name": "certid",
+ "type": "string"
+ },
+ {
+ "name": "input",
+ "type": "dynamic"
+ }
+ ]
+ }
+ },
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": "[variables('workspaceResourceId')]",
+ "name": "clv2ws1"
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [
+ "Custom-jamfprotecttelemetryv2"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = metadata.vendor,\n EventProduct = metadata.product,\n EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = host.protectVersion,\n EventSeverity = \"Informational\",\n //\n // Jamf Protect - Device Hostnames\n TargetHostname = host.hostname,\n DvcHostname = host.hostname,\n DvcSerial = host.serial,\n DvcIpAddr = host.ips,\n DvcId = host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = host.os,\n SrcDeviceType = \"Computer\"\n| project-rename\n TimeGenerated = ['time'],\n EventOriginalUid = uuid,\n EventOriginalType = event_type,\n EventCount = glob_seq_num\n| project-away\n metadata,\n host,\n seq_num,\n version,\n deadline,\n mach_time,\n action_type\n\n",
+ "outputStream": "Custom-jamfprotecttelemetryv2_CL"
+ },
+ {
+ "streams": [
+ "Custom-jamfprotectunifiedlogs"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Unified Log Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = \"UnifiedLog\",\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.event.name,\n EventResultMessage = input.match.event.composedMessage,\n // EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", input.match.uuid),\n // //\n // // Jamf Protect - Device Hostnames\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n // Jamf Protect - Event Details\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = \"Create\",\n ProcessEventSubType = \"Exec\",\n TargetProcessName = tostring(input.match.event.process),\n TargetProcessId = toreal(input.match.event.processIdentifier),\n TargetProcessGuid = tostring(input.match.event.uuid),\n TargetProcessCommandLine = input.match.event.process.args,\n TargetProcessCurrentDirectory = input.match.event.processImagePath\n| project-away\n caid,\n certid\n\n",
+ "outputStream": "Custom-jamfprotectunifiedlogs_CL"
+ },
+ {
+ "streams": [
+ "Custom-jamfprotecttelemetryv1"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Device Telemetry Stream'\n// Data Field Normalization\n| extend\n EventSeverity = \"Informational\",\n //\n // Jamf Protect Telemetry - Endpoint Information\n //\n TargetModel = metrics.hw_model,\n DvcOsVersion = host_info.osversion,\n TargetHostname = host_info.host_name,\n DvcHostname = host_info.host_name,\n DvcId = host_info.host_uuid,\n // Jamf Protect - Event Types\n EventType = case(\n header.event_name == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header.event_name == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header.event_name == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header.event_name == \"AUE_auth_user\",\n \"Elevate\",\n header.event_name == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header.event_name == \"AUE_CHDIR\",\n \"FolderMoved\",\n header.event_name == \"AUE_CHROOT\",\n \"FolderModified\",\n header.event_name == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_create_group\",\n \"GroupCreated\",\n header.event_name == \"AUE_create_user\",\n \"UserCreated\",\n header.event_name == \"AUE_delete_group\",\n \"GroupDeleted\",\n header.event_name == \"AUE_delete_user\",\n \"UserDeleted\",\n header.event_name == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header.event_name == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_FORK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_GETAUID\",\n \"\",\n header.event_name == \"AUE_KILL\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_logout\",\n \"Logoff\",\n header.event_name == \"AUE_lw_login\",\n \"Logon\",\n header.event_name == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header.event_name == \"AUE_modify_group\",\n \"GroupModified\",\n header.event_name == \"AUE_modify_password\",\n \"PasswordChanged\",\n header.event_name == \"AUE_modify_user\",\n \"UserModified\",\n header.event_name == \"AUE_MOUNT\",\n \"VolumeMount\",\n header.event_name == \"AUE_openssh\",\n \"SshInitiated\",\n header.event_name == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header.event_name == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header.event_name == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_END\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_START\",\n \"Logon\",\n header.event_name == \"AUE_SESSION_UPDATE\",\n \"\",\n header.event_name == \"AUE_SETPRIORITY\",\n \"\",\n header.event_name == \"AUE_SETSOCKOPT\",\n \"\",\n header.event_name == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header.event_name == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header.event_name == \"AUE_SOCKETPAIR\",\n \"\",\n header.event_name == \"AUE_ssauthint\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthmech\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthorize\",\n \"Elevate\",\n header.event_name == \"AUE_TASKFORPID\",\n \"\",\n header.event_name == \"AUE_TASKNAMEFORPID\",\n \"\",\n header.event_name == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header.event_name == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header.event_name == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header.event_name == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n //\n // Jamf Protect Telemetry - Process\n //\n ActingProcessId = toreal(subject.responsible_process_id),\n ActingProcessName = tostring(subject.responsible_process_name),\n ParentProcessName = tostring(subject.parent_path),\n ParentProcessId = toreal(subject.parent_pid),\n ParentProcessGuid = tostring(subject.parent_uuid),\n TargetProcessName = tostring(subject.process_name),\n TargetProcessId = toreal(subject.process_id),\n TargetProcessGuid = tostring(exec_chain.uuid),\n TargetProcessSHA256 = tostring(subject.process_hash),\n TargetUserId = toreal(subject.user_id),\n TargetUsername = tostring(subject.user_name),\n TargetProcessCommandLine = exec_args.args_compiled,\n ActorUsername = tostring(subject.effective_user_name),\n ActorUserId = toreal(subject.audit_user_name),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = tostring(subject.group_name),\n GroupID = toreal(subject.group_id),\n EffectiveGroupName = tostring(subject.effective_group_name),\n EffectiveGroupID = toreal(subject.effective_group_id),\n //\n // Jamf Protect Telemetry - Network\n //\n DstIpAddr = socket_inet.ip_address,\n DstPortNumber = socket_inet.port,\n NetworkProtocolVersion = case(socket_inet.id == 128, \"IPV4\", socket_inet.id == 129, \"IPV6\", \"\"),\n SrcIpAddr = subject.terminal.id.ip.address,\n //\n // Jamf Protect Telemetry - Binaries\n //\n TargetBinarySHA256 = tostring(identity.cd_hash),\n TargetbinarySignerType = case(identity.signer_type == 0, \"Developer\", identity.signer_type == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity.team_id),\n TargetBinarySigningAppID = tostring(identity.signer_id),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = path\n| project-away _event_score\n\n",
+ "outputStream": "Custom-jamfprotecttelemetryv1_CL"
+ },
+ {
+ "streams": [
+ "Custom-jamfprotectalerts"
+ ],
+ "destinations": [
+ "clv2ws1"
+ ],
+ "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Alerts Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = case(\n input.eventType == \"GPClickEvent\",\n \"Click\",\n input.eventType == \"GPDownloadEvent\",\n \"Download\",\n input.eventType == \"GPFSEvent\",\n \"FileSystem\",\n input.eventType == \"GPProcessEvent\",\n \"Process\",\n input.eventType == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input.eventType == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input.eventType == \"GPMRTEvent\",\n \"MRT\",\n input.eventType == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input.eventType == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input.eventType == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input.eventType == \"GPUSBEvent\",\n \"USB\",\n input.eventType == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.facts[0].name,\n EventResultMessage = input.match.facts[0].human,\n //\n // Jamf Protect - Device Hostnames\n //\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input.match.event.type == 0, \"None\", input.match.event.type == 1, \"Create\", input.match.event.type == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input.match.event.subType == 7, \"Exec\", input.match.event.subType == 1, \"Fork\", input.match.event.subType == 23, \"Execve\", input.match.event.subType == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(input.related.processes[array_length(input.related.processes) - 1].path),\n ActingProcessId = toreal(input.related.processes[0].responsiblePID),\n ActingProcessGuid = tostring(input.related.processes[array_length(input.related.processes) - 1].uuid),\n ParentProcessName = todynamic(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].path), \"\")),\n ParentProcessId = iff(array_length(input.related.processes) > 1, toreal(input.related.processes[1].pid), double(null)),\n ParentProcessGuid = tostring(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].uuid), \"\")),\n TargetProcessName = todynamic(input.related.processes[0].name),\n TargetProcessId = input.related.processes[0].pid,\n TargetProcessGuid = input.related.processes[0].uuid,\n TargetProcessSHA1 = tostring(input.related.binaries[0].sha1hex),\n TargetProcessSHA256 = tostring(input.related.binaries[0].sha256hex),\n TargetProcessCommandLine = input.related.processes[0].args,\n TargetProcessCurrentDirectory = tostring(input.related.processes[0].path),\n TargetProcessStatusCode = toreal(input.related.processes[0].exitCode),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = input.related.files[0].path,\n TargetFileSHA1 = input.related.files[0].sha1hex,\n TargetFileSHA256 = input.related.files[0].sha256hex,\n TargetFileSize = input.related.files[0].size,\n TargetFileSigningInfoMessage = input.related.files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(input.related.files[0].signingInfo.signerType == 0, \"Apple\", input.related.files[0].signingInfo.signerType == 1, \"App Store\", input.related.files[0].signingInfo.signerType == 2, \"Developer\", input.related.files[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = input.related.files[0].signingInfo.teamid,\n TargetFileIsDownload = tobool(input.related.files[0].isDownload),\n TargetFileIsAppBundle = tobool(input.related.files[0].isAppBundle),\n TargetFileIsDirectory = tobool(input.related.files[0].isDirectory),\n TargetFileIsScreenshot = tobool(input.related.files[0].isScreenShot),\n TargetFileExtendedAttributes = input.related.files[0].xattrs,\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = input.related.binaries[0].path,\n TargetBinarySHA1 = input.related.binaries[0].sha1hex,\n TargetBinarySHA256 = input.related.binaries[0].sha256hex,\n TargetBinarySigningInfoMessage = input.related.binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(input.related.binaries[0].signingInfo.signerType == 0, \"Apple\", input.related.binaries[0].signingInfo.signerType == 1, \"App Store\", input.related.binaries[0].signingInfo.signerType == 2, \"Developer\", input.related.binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = input.related.binaries[0].signingInfo.teamid,\n TargetBinarySigningAppID = input.related.binaries[0].signingInfo.appid\n| project-away\n caid,\n certid\n",
+ "outputStream": "Custom-jamfprotectalerts_CL"
+ }
+ ],
+ "dataCollectionEndpointId": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]"
+ }
+ },
+ {
+ "name": "jamfprotecttelemetryv2_CL",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "location": "[parameters('workspace-location')]",
+ "kind": null,
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotecttelemetryv2_CL",
+ "columns": [
+ {
+ "name": "action",
+ "type": "dynamic"
+ },
+ {
+ "name": "event",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "int"
+ },
+ {
+ "name": "EventCount",
+ "type": "int"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "thread",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "string"
+ },
+ {
+ "name": "EventVendor",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventProduct",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSchemaVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+ },
+ {
+ "name": "jamfprotectalerts_CL",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "location": "[parameters('workspace-location')]",
+ "kind": null,
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotectalerts_CL",
+ "columns": [
+ {
+ "name": "input",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventVendor",
+ "type": "string"
+ },
+ {
+ "name": "EventProduct",
+ "type": "string"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "EventResult",
+ "type": "string"
+ },
+ {
+ "name": "EventMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventResultMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventSubType",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessName",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessId",
+ "type": "real"
+ },
+ {
+ "name": "ActingProcessGuid",
+ "type": "string"
+ },
+ {
+ "name": "ParentProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessId",
+ "type": "real"
+ },
+ {
+ "name": "ParentProcessGuid",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessSHA1",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessSHA256",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCurrentDirectory",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessStatusCode",
+ "type": "real"
+ },
+ {
+ "name": "TargetFilePath",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSHA1",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSize",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSigningInfoMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileSignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetFileSigningTeamID",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetFileIsDownload",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsAppBundle",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsDirectory",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileIsScreenshot",
+ "type": "boolean"
+ },
+ {
+ "name": "TargetFileExtendedAttributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinaryFilePath",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA1",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySigningInfoMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetbinarySignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningTeamID",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySigningAppID",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+ },
+ {
+ "name": "jamfprotecttelemetryv1_CL",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "location": "[parameters('workspace-location')]",
+ "kind": null,
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotecttelemetryv1_CL",
+ "columns": [
+ {
+ "name": "architecture",
+ "type": "string"
+ },
+ {
+ "name": "arguments",
+ "type": "dynamic"
+ },
+ {
+ "name": "attributes",
+ "type": "dynamic"
+ },
+ {
+ "name": "bios_firmware_versions",
+ "type": "dynamic"
+ },
+ {
+ "name": "contents",
+ "type": "string"
+ },
+ {
+ "name": "exec_args",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_child",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_chain_parent",
+ "type": "dynamic"
+ },
+ {
+ "name": "exec_env",
+ "type": "dynamic"
+ },
+ {
+ "name": "exit",
+ "type": "dynamic"
+ },
+ {
+ "name": "file",
+ "type": "dynamic"
+ },
+ {
+ "name": "header",
+ "type": "dynamic"
+ },
+ {
+ "name": "host_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "identity",
+ "type": "dynamic"
+ },
+ {
+ "name": "key",
+ "type": "string"
+ },
+ {
+ "name": "metrics",
+ "type": "dynamic"
+ },
+ {
+ "name": "page_info",
+ "type": "dynamic"
+ },
+ {
+ "name": "path",
+ "type": "dynamic"
+ },
+ {
+ "name": "process",
+ "type": "dynamic"
+ },
+ {
+ "name": "rateLimitingSeconds",
+ "type": "int"
+ },
+ {
+ "name": "return",
+ "type": "dynamic"
+ },
+ {
+ "name": "socket_inet",
+ "type": "dynamic"
+ },
+ {
+ "name": "subject",
+ "type": "dynamic"
+ },
+ {
+ "name": "texts",
+ "type": "string"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventVendor",
+ "type": "string"
+ },
+ {
+ "name": "EventProduct",
+ "type": "string"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "TargetModel",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "ActingProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActingProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "ParentProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessSHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetUserId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetUsername",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActorUsername",
+ "type": "dynamic"
+ },
+ {
+ "name": "ActorUserId",
+ "type": "dynamic"
+ },
+ {
+ "name": "GroupName",
+ "type": "dynamic"
+ },
+ {
+ "name": "GroupID",
+ "type": "dynamic"
+ },
+ {
+ "name": "EffectiveGroupName",
+ "type": "dynamic"
+ },
+ {
+ "name": "EffectiveGroupID",
+ "type": "dynamic"
+ },
+ {
+ "name": "DstIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DstPortNumber",
+ "type": "dynamic"
+ },
+ {
+ "name": "NetworkProtocolVersion",
+ "type": "string"
+ },
+ {
+ "name": "SrcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetBinarySHA256",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetbinarySignerType",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningTeamID",
+ "type": "string"
+ },
+ {
+ "name": "TargetBinarySigningAppID",
+ "type": "string"
+ },
+ {
+ "name": "TargetFilePath",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+ },
+ {
+ "name": "jamfprotectunifiedlogs_CL",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "location": "[parameters('workspace-location')]",
+ "kind": null,
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "jamfprotectunifiedlogs_CL",
+ "columns": [
+ {
+ "name": "input",
+ "type": "dynamic"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "EventProductVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventSeverity",
+ "type": "string"
+ },
+ {
+ "name": "EventOriginalType",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventOriginalUid",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventType",
+ "type": "string"
+ },
+ {
+ "name": "EventResult",
+ "type": "string"
+ },
+ {
+ "name": "EventMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "EventResultMessage",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcHostname",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcSerial",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcIpAddr",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcId",
+ "type": "dynamic"
+ },
+ {
+ "name": "DvcOs",
+ "type": "string"
+ },
+ {
+ "name": "DvcOsVersion",
+ "type": "dynamic"
+ },
+ {
+ "name": "SrcDeviceType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventType",
+ "type": "string"
+ },
+ {
+ "name": "ProcessEventSubType",
+ "type": "string"
+ },
+ {
+ "name": "TargetProcessName",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessId",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessGuid",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCommandLine",
+ "type": "dynamic"
+ },
+ {
+ "name": "TargetProcessCurrentDirectory",
+ "type": "dynamic"
+ }
+ ]
+ },
+ "totalRetentionInDays": 30
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition2'),'-', variables('dataConnectorCCPVersion'))))]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "version": "[variables('dataConnectorCCPVersion')]"
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition2'))]",
+ "apiVersion": "2022-09-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
+ "location": "[parameters('workspace-location')]",
+ "kind": "Customizable",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "JamfProtectPush",
+ "title": "Jamf Protect Push Connector",
+ "publisher": "Jamf",
+ "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.",
+ "graphQueries": [
+ {
+ "metricName": "Telemetry",
+ "legend": "jamfprotecttelemetryv2_CL",
+ "baseQuery": "jamfprotecttelemetryv2_CL"
+ },
+ {
+ "metricName": "Unified Logs",
+ "legend": "jamfprotectunifiedlogs_CL",
+ "baseQuery": "jamfprotectunifiedlogs_CL"
+ },
+ {
+ "metricName": "Telemetry (Legacy)",
+ "legend": "jamfprotecttelemetryv1_CL",
+ "baseQuery": "jamfprotecttelemetryv1_CL"
+ },
+ {
+ "metricName": "Alerts",
+ "legend": "jamfprotectalerts_CL",
+ "baseQuery": "jamfprotectalerts_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Jamf Protect - All Alerts",
+ "query": "jamfprotectalerts_CL\n | sort by TimeGenerated desc"
+ },
+ {
+ "description": "Jamf Protect - All Telemetry events",
+ "query": "jamfprotecttelemetry_CL\n | sort by TimeGenerated desc"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "jamfprotecttelemetryv2_CL",
+ "lastDataReceivedQuery": "jamfprotecttelemetryv2_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotectunifiedlogs_CL",
+ "lastDataReceivedQuery": "jamfprotectunifiedlogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotecttelemetryv1_CL",
+ "lastDataReceivedQuery": "jamfprotecttelemetryv1_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ },
+ {
+ "name": "jamfprotectalerts_CL",
+ "lastDataReceivedQuery": "jamfprotectalerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriteria": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "jamfprotecttelemetryv2_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotectunifiedlogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotecttelemetryv1_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)",
+ "jamfprotectalerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft Entra",
+ "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher."
+ },
+ {
+ "name": "Microsoft Azure",
+ "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "title": "1. Create ARM Resources and Provide the Required Permissions",
+ "description": "This connector reads data from the tables that Jamf Protect uses in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API.",
+ "instructions": [
+ {
+ "type": "Markdown",
+ "parameters": {
+ "content": "#### Automated Configuration and Secure Data Ingestion with Entra Application \nClicking on \"Connect\" will trigger the creation of Log Analytics tables and a Data Collection Rule (DCR). \nIt will then create an Entra application, link the DCR to it, and set the entered secret in the application. This setup enables data to be sent securely to the DCR using an Entra token."
+ }
+ },
+ {
+ "parameters": {
+ "label": "Deploy Jamf Protect connector resources",
+ "applicationDisplayName": "Jamf Protect Connector Application"
+ },
+ "type": "DeployPushConnectorButton"
+ }
+ ]
+ },
+ {
+ "title": "2. Push your logs into the workspace",
+ "description": "Use the following parameters to configure the your machine to send the logs to the workspace.",
+ "instructions": [
+ {
+ "parameters": {
+ "label": "Tenant ID (Directory ID)",
+ "fillWith": [
+ "TenantId"
+ ]
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Entra Application ID",
+ "fillWith": [
+ "ApplicationId"
+ ],
+ "placeholder": "Deploy push connector to get the Application ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Entra Application Secret",
+ "fillWith": [
+ "ApplicationSecret"
+ ],
+ "placeholder": "Deploy push connector to get the Application Secret"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "DCE Uri",
+ "fillWith": [
+ "DataCollectionEndpoint"
+ ],
+ "placeholder": "Deploy push connector to get the DCR Uri"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "DCR Immutable ID",
+ "fillWith": [
+ "DataCollectionRuleId"
+ ],
+ "placeholder": "Deploy push connector to get the DCR ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Telemetry (Legacy) Stream ID",
+ "value": "Custom-jamfprotecttelemetryv1_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Unified Logs Stream ID",
+ "value": "Custom-jamfprotectunifiedlogs_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Telemetry Stream ID",
+ "value": "Custom-jamfprotecttelemetryv2_CL"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "label": "Alerts Stream ID",
+ "value": "Custom-jamfprotectalerts_CL"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition2')))]",
+ "apiVersion": "2022-01-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition2'))]",
+ "contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorCCPVersion')]",
+ "source": {
+ "sourceId": "[variables('_solutionId')]",
+ "name": "[variables('_solutionName')]",
+ "kind": "Solution"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ },
+ "dependencies": {
+ "criteria": [
+ {
+ "version": "[variables('dataConnectorCCPVersion')]",
+ "contentId": "[variables('_dataConnectorContentIdConnections2')]",
+ "kind": "ResourcesDataConnector"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnections2'), variables('dataConnectorCCPVersion'))]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "contentId": "[variables('_dataConnectorContentIdConnections2')]",
+ "displayName": "Jamf Protect Push Connector",
+ "contentKind": "ResourcesDataConnector",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorCCPVersion')]",
+ "parameters": {
+ "auth": {
+ "type": "object",
+ "defaultValue": {
+ "appId": "[[parameters('auth').appId]]",
+ "servicePrincipalId": "[[parameters('auth').servicePrincipalId]]"
+ }
+ },
+ "connectorDefinitionName": {
+ "defaultValue": "Jamf Protect Push Connector",
+ "type": "string",
+ "minLength": 1
+ },
+ "workspace": {
+ "defaultValue": "[parameters('workspace')]",
+ "type": "string"
+ },
+ "dcrConfig": {
+ "defaultValue": {
+ "dataCollectionEndpoint": "data collection Endpoint",
+ "dataCollectionRuleImmutableId": "data collection rule immutableId"
+ },
+ "type": "object"
+ }
+ },
+ "variables": {
+ "_dataConnectorContentIdConnections2": "[variables('_dataConnectorContentIdConnections2')]"
+ },
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnections2')))]",
+ "apiVersion": "2022-01-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentIdConnections2'))]",
+ "contentId": "[variables('_dataConnectorContentIdConnections2')]",
+ "kind": "ResourcesDataConnector",
+ "version": "[variables('dataConnectorCCPVersion')]",
+ "source": {
+ "sourceId": "[variables('_solutionId')]",
+ "name": "[variables('_solutionName')]",
+ "kind": "Solution"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', 'JamfProtectPushConnectorPolling')]",
+ "apiVersion": "2023-02-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "Push",
+ "properties": {
+ "connectorDefinitionName": "JamfProtectPush",
+ "dcrConfig": {
+ "streamName": "Custom-jamfprotecttelemetryv2",
+ "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]",
+ "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]"
+ },
+ "auth": {
+ "type": "Push",
+ "AppId": "[[parameters('auth').appId]",
+ "ServicePrincipalId": "[[parameters('auth').servicePrincipalId]"
+ },
+ "request": {
+ "RetryCount": 1
+ },
+ "response": {
+ "eventsJsonPaths": [
+ "$.messages"
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','rdc','-', uniqueString(concat(variables('_solutionId'),'-','ResourcesDataConnector','-',variables('_dataConnectorContentIdConnections2'),'-', variables('dataConnectorCCPVersion'))))]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "version": "[variables('dataConnectorCCPVersion')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserObject1').parserTemplateSpecName1]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect Data Parser with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('parserObject1').parserVersion1]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[variables('parserObject1')._parserName1]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "JamfProtect",
+ "query": "let JamfProtectAlerts_view = view () {\njamfprotectalerts_CL\n| extend\n ActingProcessCreationTime = unixtime_seconds_todatetime(tolong(input.related.processes[array_length(input.related.processes) - 1].startTimestamp)),\n ParentProcessCreationTime = iff(\n array_length(input.related.processes) > 1, \n unixtime_seconds_todatetime(tolong(input.related.processes[0].startTimestamp)), \n datetime(null)\n ),\n TargetProcessCreationTime = unixtime_seconds_todatetime(todouble(input.related.processes[0].startTimestamp)),\n TargetUserId = coalesce(input.related.users[1].uid, input.related.users[0].uid),\n TargetUsername = coalesce(input.related.users[1].name, input.related.users[0].name)\n };\nlet JamfProtectUnifiedLog_view = view () {\njamfprotectunifiedlogs_CL\n| extend EventStartTime = unixtime_seconds_todatetime(tolong(input.match.event.timestamp))\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetryv1_view = view () {\njamfprotecttelemetryv1_CL\n| extend\n EventStartTime = unixtime_seconds_todatetime(todouble(header.time_seconds_epoch)),\n EventResult = coalesce(return.description, texts)\n};\nlet JamfProtectTelemetryv2_view = view () {\njamfprotecttelemetryv2_CL\n// Generic Fields\n| extend\n EventExpanded = tostring(parse_json(event)[strcat_array(bag_keys(event), '.')]),\n eventTypeHuman = tostring(bag_keys(event)[0])\n| extend EventResult = iif((event[eventTypeHuman]['success'] == true), \"Success\", dynamic(null))\n| extend\n EventMessage = case(\n eventTypeHuman == \"authentication\",\n \"A user authentication happened\",\n eventTypeHuman == \"authorization_judgement\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"authorization_petition\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"bios_uefi\",\n \"Collection of bios and firmware data\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Apple's Background Task Manager notified that an item has been added\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Apple's Background Task Manager notified that an existing item has been removed\",\n eventTypeHuman == \"chroot\",\n \"Software has changed its apparent root directory in which it's actively operating out of\",\n eventTypeHuman == \"cs_invalidated\",\n \"The system detected that a process has had its code signature marked as invalid\",\n eventTypeHuman == \"exec\",\n \"A new process has been executed\",\n eventTypeHuman == \"kextload\",\n \"A kernel extension (kext) was loaded\",\n eventTypeHuman == \"kextunload\",\n \"A kernel extension (kext) was unloaded\",\n eventTypeHuman == \"login_login\",\n \"A user attempted to log in using /usr/bin/login\",\n eventTypeHuman == \"login_logout\",\n \"A user logged out from /usr/bin/login\",\n eventTypeHuman == \"lw_session_lock\",\n \"A user has locked the screen\",\n eventTypeHuman == \"lw_session_login\",\n \"A user has logged in via the Login Window\",\n eventTypeHuman == \"lw_session_logout\",\n \"A user has logged out of an active graphical session\",\n eventTypeHuman == \"lw_session_unlock\",\n \"A user has unlocked the screen from the Login Window\",\n eventTypeHuman == \"mount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute set on user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute added to a user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute removed from a user or group using Open Directory\",\n eventTypeHuman == \"od_create_group\",\n \"A group has been created using Open Directory\",\n eventTypeHuman == \"od_create_user\",\n \"A user has been created using Open Directory\",\n eventTypeHuman == \"od_delete_group\",\n \"A group has been deleted using Open Directory\",\n eventTypeHuman == \"od_delete_user\",\n \"A user has been deleted using Open Directory\",\n eventTypeHuman == \"od_disable_user\",\n \"A user has been disabled using Open Directory\",\n eventTypeHuman == \"od_enable_user\",\n \"A user has been enabled using Open Directory\",\n eventTypeHuman == \"od_group_add\",\n \"A member has been added to a group using Open Directory\",\n eventTypeHuman == \"od_group_remove\",\n \"A member has been removed from a group using Open Directory\",\n eventTypeHuman == \"od_group_set\",\n \"A group has a member initialised or replaced using Open Directory\",\n eventTypeHuman == \"od_modify_password\",\n \"A user password is modified via Open Directory\",\n eventTypeHuman == \"openssh_login\",\n \"A user has logged into the system via OpenSSH\",\n eventTypeHuman == \"openssh_logout\",\n \"A user has logged out of an OpenSSH session\",\n eventTypeHuman == \"performance\",\n \"Collection of system performance data\",\n eventTypeHuman == \"profile_add\",\n \"A configuration profile is installed on the system\",\n eventTypeHuman == \"profile_remove\",\n \"A configuration profile is removed from the system\",\n eventTypeHuman == \"remount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"A screensharing session has attached to a graphical session\",\n eventTypeHuman == \"screenscharing_detach\",\n \"A screensharing session has detached from a graphical session\",\n eventTypeHuman == \"settime\",\n \"The system time was attempted to be set\",\n eventTypeHuman == \"su\",\n \"A user attempts to start a new shell using a substitute user identity\",\n eventTypeHuman == \"sudo\",\n \"A sudo attempt occured\",\n eventTypeHuman == \"unmount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"Apple's XProtect detected malware on the system\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"Apple's XProtect remediated malware on the system\",\n eventTypeHuman == \"file_collection\",\n \"A crash or diagnostic file has been collected\",\n eventTypeHuman == \"log_collection\",\n \"Entries from a log file have been collected\",\n \"No reason yet defined for this event\"\n ),\n EventType = case(\n eventTypeHuman == \"authentication\",\n \"Logon\",\n eventTypeHuman == \"authorization_judgement\",\n \"ProcessCreated\",\n eventTypeHuman == \"authorization_petition\",\n \"ProcessCreated\",\n eventTypeHuman == \"bios_uefi\",\n \"Hardware\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Create\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Delete\",\n eventTypeHuman == \"chroot\",\n \"Set\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"exec\",\n \"ProcessCreated\",\n eventTypeHuman == \"kextload\",\n \"Create\",\n eventTypeHuman == \"kextunload\",\n \"Delete\",\n eventTypeHuman == \"login_login\",\n \"Logon\",\n eventTypeHuman == \"login_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_lock\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_login\",\n \"Logon\",\n eventTypeHuman == \"lw_session_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Logon\",\n eventTypeHuman == \"mount\",\n \"FileSystemMounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Set\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Create\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Delete\",\n eventTypeHuman == \"od_create_group\",\n \"GroupCreated\",\n eventTypeHuman == \"od_create_user\",\n \"UserCreated\",\n eventTypeHuman == \"od_delete_group\",\n \"GroupDeleted\",\n eventTypeHuman == \"od_delete_user\",\n \"UserDeleted\",\n eventTypeHuman == \"od_disable_user\",\n \"UserDisabled\",\n eventTypeHuman == \"od_enable_user\",\n \"UserEnabled\",\n eventTypeHuman == \"od_group_add\",\n \"UserAddedToGroup\",\n eventTypeHuman == \"od_group_remove\",\n \"UserRemovedFromGroup\",\n eventTypeHuman == \"od_group_set\",\n \"GroupModified\",\n eventTypeHuman == \"od_modify_password\",\n \"PasswordChanged\",\n eventTypeHuman == \"openssh_login\",\n \"Logon\",\n eventTypeHuman == \"openssh_logout\",\n \"Logoff\",\n eventTypeHuman == \"performance\",\n \"PerformanceData\",\n eventTypeHuman == \"profile_add\",\n \"Create\",\n eventTypeHuman == \"profile_remove\",\n \"Delete\",\n eventTypeHuman == \"remount\",\n \"FileSystemRemounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"Logon\",\n eventTypeHuman == \"screenscharing_detach\",\n \"Logoff\",\n eventTypeHuman == \"settime\",\n \"Set\",\n eventTypeHuman == \"su\",\n \"Elevate\",\n eventTypeHuman == \"sudo\",\n \"Elevate\",\n eventTypeHuman == \"unmount\",\n \"FileSystemUnmounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"MalwareDetected\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"MalwareRemediated\",\n \"\"\n ),\n EventSubType = case(\n eventTypeHuman == \"authentication\",\n \"Interactive\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"btm\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"btm\",\n eventTypeHuman == \"chroot\",\n \"Directory\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"kextload\",\n \"System Settings\",\n eventTypeHuman == \"kextunload\",\n \"System Settings\",\n eventTypeHuman == \"login_login\",\n \"Interactive\",\n eventTypeHuman == \"login_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_lock\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_login\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Interactive\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute\",\n eventTypeHuman == \"openssh_login\",\n \"Interactive\",\n eventTypeHuman == \"openssh_logout\",\n \"Interactive\",\n eventTypeHuman == \"profile_add\",\n \"Configuration Profile\",\n eventTypeHuman == \"profile_remove\",\n \"Configuration Profile\",\n eventTypeHuman == \"screenscharing_attach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"screenscharing_detach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"settime\",\n \"System Settings\",\n eventTypeHuman == \"su\",\n \"Interactive\",\n eventTypeHuman == \"sudo\",\n \"Interactive\",\n \"\"\n )\n// Jamf Protect Telemetry - Event Process\n| extend eventContext = \n iif(\n isnotempty(event[eventTypeHuman]['app']['audit_token']),\n event[eventTypeHuman]['app'],\n iif(\n isnotempty(event[eventTypeHuman]['target']['audit_token']),\n event[eventTypeHuman]['target'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['od']['audit_token']),\n event[eventTypeHuman]['data']['od'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['token']['audit_token']),\n event[eventTypeHuman]['data']['token'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['touchid']['audit_token']),\n event[eventTypeHuman]['data']['touchid'],\n iif(\n isnotempty(event[eventTypeHuman]['instigator']['audit_token']),\n event[eventTypeHuman]['instigator'],\n ['process']\n)\n)\n)\n)\n)\n)\n| extend\n TargetProcessName = tostring(eventContext.executable.path),\n TargetProcessId = tostring(eventContext.audit_token.pid),\n TargetProcessGuid = tostring(eventContext.audit_token.uuid),\n TargetProcessCreationTime = tostring(eventContext.start_time),\n TargetProcessSHA1 = tostring(eventContext.executable.sha1),\n TargetProcessSHA256 = tostring(eventContext.executable.sha256),\n TargetProcessCommandLine = event[eventTypeHuman]['args'],\n TargetProcessTTY = tostring(eventContext.tty.path),\n TargetBinarySigningAppID = tostring(eventContext.signing_id),\n TargetBinarySigningTeamID = tostring(eventContext.team_id),\n TargetBinaryCDHash = tostring(eventContext.cdhash),\n TargetBinaryIsESClient = tobool(eventContext.is_es_client),\n TargetBinaryIsPlatformBinary = tobool(eventContext.is_platform_binary),\n TargetUserId = tostring(eventContext.audit_token.euid),\n ActingProcessId = tostring(eventContext.parent_audit_token.pid),\n ActingProcessGuid = tostring(eventContext.parent_audit_token.uuid),\n ActorUserId = tostring(eventContext.parent_audit_token.euid),\n ParentProcessId = tostring(eventContext.responsible_audit_token.pid),\n ParentProcessGuid = tostring(eventContext.responsible_audit_token.uuid)\n// Jamf Protect Telemetry - Revealing Code Signing flags\n| extend TargetProcessCodesignFlags = \n iif(isnotempty(eventContext.codesigning_flags),\n bag_pack(\n \"CS_VALID\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000001) > 0, true, false),\n \"CS_ADHOC\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000002) > 0, true, false),\n \"CS_GET_TASK_ALLOW\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000004) > 0, true, false),\n \"CS_INSTALLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000008) > 0, true, false),\n \"CS_FORCED_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000010) > 0, true, false),\n \"CS_INVALID_ALLOWED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000020) > 0, true, false),\n \"CS_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000100) > 0, true, false),\n \"CS_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000200) > 0, true, false),\n \"CS_CHECK_EXPIRATION\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000400) > 0, true, false),\n \"CS_RESTRICT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000800) > 0, true, false),\n \"CS_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00001000) > 0, true, false),\n \"CS_REQUIRE_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00002000) > 0, true, false),\n \"CS_ENTITLEMENTS_VALIDATED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00004000) > 0, true, false),\n \"CS_NVRAM_UNRESTRICTED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00008000) > 0, true, false),\n \"CS_RUNTIME\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00010000) > 0, true, false),\n \"CS_LINKER_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000) > 0, true, false),\n \"CS_EXEC_SET_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00100000) > 0, true, false),\n \"CS_EXEC_SET_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00200000) > 0, true, false),\n \"CS_EXEC_SET_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00400000) > 0, true, false),\n \"CS_EXEC_INHERIT_SIP\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00800000) > 0, true, false),\n \"CS_KILLED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x01000000) > 0, true, false),\n \"CS_DYLD_PLATFORM\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x02000000) > 0, true, false),\n \"CS_PLATFORM_BINARY\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x04000000) > 0, true, false),\n \"CS_PLATFORM_PATH\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x08000000) > 0, true, false),\n \"CS_DEBUGGED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x10000000) > 0, true, false),\n \"CS_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000000) > 0, true, false),\n \"CS_DEV_CODE\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x40000000) > 0, true, false),\n \"CS_DATAVAULT_CONTROLLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x80000000) > 0, true, false)\n ), \"\")\n// Event Specific - authentication\n| extend TargetUsername =\n iif(\n isnotempty(event[eventTypeHuman]['username']),\n event[eventTypeHuman]['username'],\n iif(\n isnotempty(event[eventTypeHuman]['to_username']),\n event[eventTypeHuman]['to_username'],\n iif(\n isnotempty(event[eventTypeHuman]['account_name']),\n event[eventTypeHuman]['account_name'],\n iif(\n isnotempty(event[eventTypeHuman]['user_name']),\n event[eventTypeHuman]['user_name'],\n iif(\n isnotempty(event[eventTypeHuman]['authentication_username']),\n event[eventTypeHuman]['authentication_username'],\n \"\"\n)\n)\n)\n)\n)\n// Event Specific - authentication\n| extend ActorUsername = \n iif(\n isnotempty(event[eventTypeHuman]['from_username']),\n event[eventTypeHuman]['from_username'],\n iif(\n isnotempty(event[eventTypeHuman]['session_username']),\n event[eventTypeHuman]['session_username'],\n \"\"\n)\n)\n| extend Authentication = iif(\n eventTypeHuman == \"authentication\",\n bag_pack(\n \"authentication_method\",\n iff(isnotempty(event[eventTypeHuman].data), tostring(bag_keys(event[eventTypeHuman].data)[0]), \"\")\n),\n dynamic(null)\n )\n// Event Specific - bios_uefi\n| extend HardwareInformation = iif(\n eventTypeHuman == \"bios_uefi\",\n bag_pack(\n \"host_architecture\",\n iff(isnotempty(event[eventTypeHuman].architecture), event[eventTypeHuman].architecture, \"\"),\n \"firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['firmware-version']), event[eventTypeHuman].bios.['firmware-version'], \"\"),\n \"system_firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['system-firmware-version']), event[eventTypeHuman].bios.['system-firmware-version'], \"\")\n),\n dynamic(null)\n )\n// Event Specific - btm_launch_item_add & btm_launch_item_remove\n| extend BtmItem = iif(\n eventTypeHuman in (\"btm_launch_item_add\", \"btm_launch_item_remove\", \"remount\"),\n bag_pack(\n \"btm_executable_path\",\n iff(isnotempty(event[eventTypeHuman].executable_path), event[eventTypeHuman].executable_path, \"\"),\n \"btm_item_app_url\",\n iff(isnotempty(event[eventTypeHuman].item.app_url), event[eventTypeHuman].item.app_url, \"\"),\n \"btm_item_url\",\n iff(isnotempty(event[eventTypeHuman].item.item_url), event[eventTypeHuman].item.item_url, \"\"),\n \"btm_item_managed\",\n iff(isnotempty(event[eventTypeHuman].item.managed), event[eventTypeHuman].item.managed, \"\"),\n \"btm_item_legacy\",\n iff(isnotempty(event[eventTypeHuman].item.legacy), event[eventTypeHuman].item.legacy, \"\"),\n \"btm_item_uid\",\n iff(isnotempty(event[eventTypeHuman].item.uid), event[eventTypeHuman].item.uid, \"\"),\n \"btm_item_type\",\n iff(\n isnotempty(event[eventTypeHuman].item.item_type),\n case(\n event[eventTypeHuman].item.item_type == 0,\n \"UserItem\",\n event[eventTypeHuman].item.item_type == 1,\n \"App\",\n event[eventTypeHuman].item.item_type == 2,\n \"LoginItem\",\n event[eventTypeHuman].item.item_type == 3,\n \"LaunchAgent\",\n event[eventTypeHuman].item.item_type == 4,\n \"LaunchDaemon\",\n \"Unknown\"\n),\n \"\"\n)\n),\n dynamic(null)\n )\n// Event Specific - chroot\n| extend Chroot = iif(\n eventTypeHuman == \"chroot\",\n bag_pack(\n \"apparent_root_directory\",\n iff(isnotempty(event[eventTypeHuman].target), event[eventTypeHuman].target.path, \"\"),\n \"stats\",\n iff(isnotempty(event[eventTypeHuman].target.stat), event[eventTypeHuman].target.stat, \"\")\n),\n dynamic(null)\n )\n// Event Specific - cs_invalidated\n// Event Specific - exec\n// Event Specific - kextload & kextunload\n| extend KernelExtension = iif(\n eventTypeHuman in (\"kextload\", \"kextunload\"),\n bag_pack(\n \"kext_identifier\",\n iff(isnotempty(event[eventTypeHuman].identifier), event[eventTypeHuman].identifier, \"\")\n),\n dynamic(null)\n )\n// Event Specific - lw_session_lock & lw_session_unlock & lw_session_login & lw_session_logout\n| extend LoginWindowSession = iif(\n eventTypeHuman in (\"lw_session_lock\", \"lw_session_unlock\", \"lw_session_login\", \"lw_session_logout\"),\n bag_pack(\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_session_id), event[eventTypeHuman].graphical_session_id, \"\")\n),\n dynamic(null)\n )\n// Event Specific - mount & remount & unmount\n| extend FileSystem = iif(\n eventTypeHuman in (\"mount\", \"unmount\", \"remount\"),\n bag_pack(\n \"volume_device_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntfromname), event[eventTypeHuman].statfs.f_mntfromname, \"\"),\n \"volume_mount_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntonname), event[eventTypeHuman].statfs.f_mntonname, \"\"),\n \"volume_file_system_type\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_fstypename), event[eventTypeHuman].statfs.f_fstypename, \"\"),\n \"volume_size\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_bsize), event[eventTypeHuman].statfs.f_bsize, \"\")\n),\n dynamic(null)\n )\n// Event Specific - od_attribute_set & od_attribute_value_add & od_attribute_value_remove & od_create_group & od_create_user & od_delete_group & od_delete_user & od_disable_user & od_enable_user\n| extend OpenDirectory = iif(\n eventTypeHuman in (\"od_attribute_set\", \"od_attribute_value_add\", \"od_attribute_value_remove\", \"od_create_group\", \"od_create_user\", \"od_delete_group\", \"od_delete_user\", \"od_disable_user\", \"od_enable_user\"),\n bag_pack(\n \"group_name\",\n iff(isnotempty(event[eventTypeHuman].group_name), event[eventTypeHuman].group_name, \"\"),\n \"member_array\",\n iff(isnotempty(event[eventTypeHuman].members.member_array), event[eventTypeHuman].members.member_array, \"\"),\n \"member_value\",\n iff(isnotempty(event[eventTypeHuman].member.member_value), event[eventTypeHuman].member.member_value, \"\"),\n \"user_name\",\n iff(isnotempty(event[eventTypeHuman].user_name), event[eventTypeHuman].user_name, \"\"),\n \"account_name\",\n iff(isnotempty(event[eventTypeHuman].account_name), event[eventTypeHuman].account_name, \"\"),\n \"db_path\",\n iff(isnotempty(event[eventTypeHuman].db_path), event[eventTypeHuman].db_path, \"\"),\n \"record_name\",\n iff(isnotempty(event[eventTypeHuman].record_name), event[eventTypeHuman].record_name, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\"),\n \"node_name\",\n iff(isnotempty(event[eventTypeHuman].node_name), event[eventTypeHuman].node_name, \"\")\n),\n dynamic(null)\n )\n// Event Specific - openssh_login & openssh_logout\n| extend SSHContext = iif(\n eventTypeHuman in (\"openssh_login\", \"openssh_logout\"),\n bag_pack(\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n),\n \"result_type\", \n iff(\n isnotempty(event[eventTypeHuman].result_type),\n case(\n event[eventTypeHuman].result_type == 0,\n \"Exceeded maximum attempts\",\n event[eventTypeHuman].result_type == 1,\n \"Denied by root\",\n event[eventTypeHuman].result_type == 2,\n \"Success\",\n event[eventTypeHuman].result_type == 3,\n \"No reason\",\n event[eventTypeHuman].result_type == 4,\n \"Password\",\n event[eventTypeHuman].result_type == 5,\n \"kbdint\",\n event[eventTypeHuman].result_type == 6,\n \"Public key\",\n event[eventTypeHuman].result_type == 7,\n \"Host based\",\n event[eventTypeHuman].result_type == 8,\n \"GSS API\",\n event[eventTypeHuman].result_type == 9,\n \"Invalid user\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null) \n )\n// Event Specific - performance\n// Event Specific - profile_add & profile_remove\n| extend Profile = iif(\n eventTypeHuman in (\"profile_add\", \"profile_remove\"),\n bag_pack(\n \"profile_scope\",\n iff(isnotempty(event[eventTypeHuman].profile.scope), event[eventTypeHuman].profile.scope, \"\"),\n \"profile_identifier\",\n iff(isnotempty(event[eventTypeHuman].profile.identifier), event[eventTypeHuman].profile.identifiery, \"\"),\n \"profile_uuid\",\n iff(isnotempty(event[eventTypeHuman].profile.uuid), event[eventTypeHuman].profile.uuid, \"\"),\n \"profile_display_name\",\n iff(isnotempty(event[eventTypeHuman].profile.display_name), event[eventTypeHuman].profile.display_name, \"\"),\n \"profile_organization\",\n iff(isnotempty(event[eventTypeHuman].profile.organization), event[eventTypeHuman].profile.organization, \"\"),\n \"profile_is_updated\",\n iff(isnotempty(event[eventTypeHuman].is_update), event[eventTypeHuman].is_update, \"\"),\n \"profile_install_source\", \n iff(\n isnotempty(event[eventTypeHuman].profile.install_source),\n case(\n event[eventTypeHuman].profile.install_source == 0,\n \"mdm\",\n event[eventTypeHuman].profile.install_source == 1,\n \"manual\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - screenscharing_attach & screensharing_detach\n| extend Screensharing = iif(\n eventTypeHuman in (\"screensharing_attach\", \"screensharing_detach\"),\n bag_pack(\n \"existing_session\",\n iff(isnotempty(event[eventTypeHuman].existing_session), event[eventTypeHuman].existing_session, \"\"),\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_authentication_username), event[eventTypeHuman].graphical_authentication_username, \"\"),\n \"session_username\",\n iff(isnotempty(event[eventTypeHuman].session_username), event[eventTypeHuman].session_username, \"\"),\n \"viewer_appleid\",\n iff(isnotempty(event[eventTypeHuman].viewer_appleid), event[eventTypeHuman].viewer_appleid, \"\"),\n \"authentication_type\",\n iff(isnotempty(event[eventTypeHuman].authentication_type), event[eventTypeHuman].authentication_type, \"\"),\n \"source_address\",\n iff(isnotempty(event[eventTypeHuman].source_address), event[eventTypeHuman].source_address, \"\"),\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - su\n| extend Su = iif(\n eventTypeHuman == \"su\",\n bag_pack(\n \"username\",\n iff(isnotempty(event[eventTypeHuman].username), event[eventTypeHuman].username, \"\"),\n \"uid\",\n iff(isnotempty(event[eventTypeHuman].uid), event[eventTypeHuman].uid, \"\"),\n \"args\",\n iff(isnotempty(event[eventTypeHuman].argv), event[eventTypeHuman].argv, \"\"),\n \"env_vars\",\n iff(isnotempty(event[eventTypeHuman].env), event[eventTypeHuman].env, \"\"),\n \"env_count\",\n iff(isnotempty(event[eventTypeHuman].env_count), event[eventTypeHuman].env_count, \"\"),\n \"from_username\",\n iff(isnotempty(event[eventTypeHuman].from_username), event[eventTypeHuman].from_username, \"\"),\n \"to_username\",\n iff(isnotempty(event[eventTypeHuman].to_username), event[eventTypeHuman].to_username, \"\"),\n \"failure_message\",\n iff(isnotempty(event[eventTypeHuman].failure_reason), event[eventTypeHuman].failure_reason, \"\")\n),\n dynamic(null)\n )\n// Event Specific - sudo\n| extend Sudo = iif(\n eventTypeHuman == \"sudo\",\n bag_pack(\n \"TargetProcessCommandLine\",\n iff(isnotempty(event[eventTypeHuman].command), event[eventTypeHuman].command, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\")\n),\n dynamic(null)\n )\n// Event Specific - xp_malware_detected & xp_malware_remediated\n| extend Xprotect = iif(\n eventTypeHuman in (\"xp_malware_detected\", \"xp_malware_remediated\"),\n bag_pack(\n \"detected_path\",\n iff(isnotempty(event[eventTypeHuman].detected_path), event[eventTypeHuman].detected_path, \"\"),\n \"remediated_path\",\n iff(isnotempty(event[eventTypeHuman].remediated_path), event[eventTypeHuman].remediated_path, \"\"),\n \"malware_identifier\",\n iff(isnotempty(event[eventTypeHuman].malware_identifier), event[eventTypeHuman].malware_identifier, \"\"),\n \"signature_version\",\n iff(isnotempty(event[eventTypeHuman].signature_version), event[eventTypeHuman].signature_version, \"\")\n),\n dynamic(null)\n )\n| project-away\naction,\nevent,\nprocess\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n// //\n// // Jamf Protect - Threat Events\n// //\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectTelemetryv1_view, JamfProtectTelemetryv2_view, JamfProtectNetworkTraffic_view, JamfProtectThreatEvents_view\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
+ "source": {
+ "name": "Jamf Protect",
+ "kind": "Solution",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "contentKind": "Parser",
+ "displayName": "JamfProtect",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.2.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.2.0')))]",
+ "version": "[variables('parserObject1').parserVersion1]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('parserObject1')._parserName1]",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "JamfProtect",
+ "query": "let JamfProtectAlerts_view = view () {\njamfprotectalerts_CL\n| extend\n ActingProcessCreationTime = unixtime_seconds_todatetime(tolong(input.related.processes[array_length(input.related.processes) - 1].startTimestamp)),\n ParentProcessCreationTime = iff(\n array_length(input.related.processes) > 1, \n unixtime_seconds_todatetime(tolong(input.related.processes[0].startTimestamp)), \n datetime(null)\n ),\n TargetProcessCreationTime = unixtime_seconds_todatetime(todouble(input.related.processes[0].startTimestamp)),\n TargetUserId = coalesce(input.related.users[1].uid, input.related.users[0].uid),\n TargetUsername = coalesce(input.related.users[1].name, input.related.users[0].name)\n };\nlet JamfProtectUnifiedLog_view = view () {\njamfprotectunifiedlogs_CL\n| extend EventStartTime = unixtime_seconds_todatetime(tolong(input.match.event.timestamp))\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetryv1_view = view () {\njamfprotecttelemetryv1_CL\n| extend\n EventStartTime = unixtime_seconds_todatetime(todouble(header.time_seconds_epoch)),\n EventResult = coalesce(return.description, texts)\n};\nlet JamfProtectTelemetryv2_view = view () {\njamfprotecttelemetryv2_CL\n// Generic Fields\n| extend\n EventExpanded = tostring(parse_json(event)[strcat_array(bag_keys(event), '.')]),\n eventTypeHuman = tostring(bag_keys(event)[0])\n| extend EventResult = iif((event[eventTypeHuman]['success'] == true), \"Success\", dynamic(null))\n| extend\n EventMessage = case(\n eventTypeHuman == \"authentication\",\n \"A user authentication happened\",\n eventTypeHuman == \"authorization_judgement\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"authorization_petition\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"bios_uefi\",\n \"Collection of bios and firmware data\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Apple's Background Task Manager notified that an item has been added\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Apple's Background Task Manager notified that an existing item has been removed\",\n eventTypeHuman == \"chroot\",\n \"Software has changed its apparent root directory in which it's actively operating out of\",\n eventTypeHuman == \"cs_invalidated\",\n \"The system detected that a process has had its code signature marked as invalid\",\n eventTypeHuman == \"exec\",\n \"A new process has been executed\",\n eventTypeHuman == \"kextload\",\n \"A kernel extension (kext) was loaded\",\n eventTypeHuman == \"kextunload\",\n \"A kernel extension (kext) was unloaded\",\n eventTypeHuman == \"login_login\",\n \"A user attempted to log in using /usr/bin/login\",\n eventTypeHuman == \"login_logout\",\n \"A user logged out from /usr/bin/login\",\n eventTypeHuman == \"lw_session_lock\",\n \"A user has locked the screen\",\n eventTypeHuman == \"lw_session_login\",\n \"A user has logged in via the Login Window\",\n eventTypeHuman == \"lw_session_logout\",\n \"A user has logged out of an active graphical session\",\n eventTypeHuman == \"lw_session_unlock\",\n \"A user has unlocked the screen from the Login Window\",\n eventTypeHuman == \"mount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute set on user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute added to a user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute removed from a user or group using Open Directory\",\n eventTypeHuman == \"od_create_group\",\n \"A group has been created using Open Directory\",\n eventTypeHuman == \"od_create_user\",\n \"A user has been created using Open Directory\",\n eventTypeHuman == \"od_delete_group\",\n \"A group has been deleted using Open Directory\",\n eventTypeHuman == \"od_delete_user\",\n \"A user has been deleted using Open Directory\",\n eventTypeHuman == \"od_disable_user\",\n \"A user has been disabled using Open Directory\",\n eventTypeHuman == \"od_enable_user\",\n \"A user has been enabled using Open Directory\",\n eventTypeHuman == \"od_group_add\",\n \"A member has been added to a group using Open Directory\",\n eventTypeHuman == \"od_group_remove\",\n \"A member has been removed from a group using Open Directory\",\n eventTypeHuman == \"od_group_set\",\n \"A group has a member initialised or replaced using Open Directory\",\n eventTypeHuman == \"od_modify_password\",\n \"A user password is modified via Open Directory\",\n eventTypeHuman == \"openssh_login\",\n \"A user has logged into the system via OpenSSH\",\n eventTypeHuman == \"openssh_logout\",\n \"A user has logged out of an OpenSSH session\",\n eventTypeHuman == \"performance\",\n \"Collection of system performance data\",\n eventTypeHuman == \"profile_add\",\n \"A configuration profile is installed on the system\",\n eventTypeHuman == \"profile_remove\",\n \"A configuration profile is removed from the system\",\n eventTypeHuman == \"remount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"A screensharing session has attached to a graphical session\",\n eventTypeHuman == \"screenscharing_detach\",\n \"A screensharing session has detached from a graphical session\",\n eventTypeHuman == \"settime\",\n \"The system time was attempted to be set\",\n eventTypeHuman == \"su\",\n \"A user attempts to start a new shell using a substitute user identity\",\n eventTypeHuman == \"sudo\",\n \"A sudo attempt occured\",\n eventTypeHuman == \"unmount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"Apple's XProtect detected malware on the system\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"Apple's XProtect remediated malware on the system\",\n eventTypeHuman == \"file_collection\",\n \"A crash or diagnostic file has been collected\",\n eventTypeHuman == \"log_collection\",\n \"Entries from a log file have been collected\",\n \"No reason yet defined for this event\"\n ),\n EventType = case(\n eventTypeHuman == \"authentication\",\n \"Logon\",\n eventTypeHuman == \"authorization_judgement\",\n \"ProcessCreated\",\n eventTypeHuman == \"authorization_petition\",\n \"ProcessCreated\",\n eventTypeHuman == \"bios_uefi\",\n \"Hardware\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Create\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Delete\",\n eventTypeHuman == \"chroot\",\n \"Set\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"exec\",\n \"ProcessCreated\",\n eventTypeHuman == \"kextload\",\n \"Create\",\n eventTypeHuman == \"kextunload\",\n \"Delete\",\n eventTypeHuman == \"login_login\",\n \"Logon\",\n eventTypeHuman == \"login_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_lock\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_login\",\n \"Logon\",\n eventTypeHuman == \"lw_session_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Logon\",\n eventTypeHuman == \"mount\",\n \"FileSystemMounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Set\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Create\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Delete\",\n eventTypeHuman == \"od_create_group\",\n \"GroupCreated\",\n eventTypeHuman == \"od_create_user\",\n \"UserCreated\",\n eventTypeHuman == \"od_delete_group\",\n \"GroupDeleted\",\n eventTypeHuman == \"od_delete_user\",\n \"UserDeleted\",\n eventTypeHuman == \"od_disable_user\",\n \"UserDisabled\",\n eventTypeHuman == \"od_enable_user\",\n \"UserEnabled\",\n eventTypeHuman == \"od_group_add\",\n \"UserAddedToGroup\",\n eventTypeHuman == \"od_group_remove\",\n \"UserRemovedFromGroup\",\n eventTypeHuman == \"od_group_set\",\n \"GroupModified\",\n eventTypeHuman == \"od_modify_password\",\n \"PasswordChanged\",\n eventTypeHuman == \"openssh_login\",\n \"Logon\",\n eventTypeHuman == \"openssh_logout\",\n \"Logoff\",\n eventTypeHuman == \"performance\",\n \"PerformanceData\",\n eventTypeHuman == \"profile_add\",\n \"Create\",\n eventTypeHuman == \"profile_remove\",\n \"Delete\",\n eventTypeHuman == \"remount\",\n \"FileSystemRemounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"Logon\",\n eventTypeHuman == \"screenscharing_detach\",\n \"Logoff\",\n eventTypeHuman == \"settime\",\n \"Set\",\n eventTypeHuman == \"su\",\n \"Elevate\",\n eventTypeHuman == \"sudo\",\n \"Elevate\",\n eventTypeHuman == \"unmount\",\n \"FileSystemUnmounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"MalwareDetected\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"MalwareRemediated\",\n \"\"\n ),\n EventSubType = case(\n eventTypeHuman == \"authentication\",\n \"Interactive\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"btm\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"btm\",\n eventTypeHuman == \"chroot\",\n \"Directory\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"kextload\",\n \"System Settings\",\n eventTypeHuman == \"kextunload\",\n \"System Settings\",\n eventTypeHuman == \"login_login\",\n \"Interactive\",\n eventTypeHuman == \"login_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_lock\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_login\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Interactive\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute\",\n eventTypeHuman == \"openssh_login\",\n \"Interactive\",\n eventTypeHuman == \"openssh_logout\",\n \"Interactive\",\n eventTypeHuman == \"profile_add\",\n \"Configuration Profile\",\n eventTypeHuman == \"profile_remove\",\n \"Configuration Profile\",\n eventTypeHuman == \"screenscharing_attach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"screenscharing_detach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"settime\",\n \"System Settings\",\n eventTypeHuman == \"su\",\n \"Interactive\",\n eventTypeHuman == \"sudo\",\n \"Interactive\",\n \"\"\n )\n// Jamf Protect Telemetry - Event Process\n| extend eventContext = \n iif(\n isnotempty(event[eventTypeHuman]['app']['audit_token']),\n event[eventTypeHuman]['app'],\n iif(\n isnotempty(event[eventTypeHuman]['target']['audit_token']),\n event[eventTypeHuman]['target'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['od']['audit_token']),\n event[eventTypeHuman]['data']['od'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['token']['audit_token']),\n event[eventTypeHuman]['data']['token'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['touchid']['audit_token']),\n event[eventTypeHuman]['data']['touchid'],\n iif(\n isnotempty(event[eventTypeHuman]['instigator']['audit_token']),\n event[eventTypeHuman]['instigator'],\n ['process']\n)\n)\n)\n)\n)\n)\n| extend\n TargetProcessName = tostring(eventContext.executable.path),\n TargetProcessId = tostring(eventContext.audit_token.pid),\n TargetProcessGuid = tostring(eventContext.audit_token.uuid),\n TargetProcessCreationTime = tostring(eventContext.start_time),\n TargetProcessSHA1 = tostring(eventContext.executable.sha1),\n TargetProcessSHA256 = tostring(eventContext.executable.sha256),\n TargetProcessCommandLine = event[eventTypeHuman]['args'],\n TargetProcessTTY = tostring(eventContext.tty.path),\n TargetBinarySigningAppID = tostring(eventContext.signing_id),\n TargetBinarySigningTeamID = tostring(eventContext.team_id),\n TargetBinaryCDHash = tostring(eventContext.cdhash),\n TargetBinaryIsESClient = tobool(eventContext.is_es_client),\n TargetBinaryIsPlatformBinary = tobool(eventContext.is_platform_binary),\n TargetUserId = tostring(eventContext.audit_token.euid),\n ActingProcessId = tostring(eventContext.parent_audit_token.pid),\n ActingProcessGuid = tostring(eventContext.parent_audit_token.uuid),\n ActorUserId = tostring(eventContext.parent_audit_token.euid),\n ParentProcessId = tostring(eventContext.responsible_audit_token.pid),\n ParentProcessGuid = tostring(eventContext.responsible_audit_token.uuid)\n// Jamf Protect Telemetry - Revealing Code Signing flags\n| extend TargetProcessCodesignFlags = \n iif(isnotempty(eventContext.codesigning_flags),\n bag_pack(\n \"CS_VALID\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000001) > 0, true, false),\n \"CS_ADHOC\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000002) > 0, true, false),\n \"CS_GET_TASK_ALLOW\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000004) > 0, true, false),\n \"CS_INSTALLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000008) > 0, true, false),\n \"CS_FORCED_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000010) > 0, true, false),\n \"CS_INVALID_ALLOWED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000020) > 0, true, false),\n \"CS_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000100) > 0, true, false),\n \"CS_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000200) > 0, true, false),\n \"CS_CHECK_EXPIRATION\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000400) > 0, true, false),\n \"CS_RESTRICT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000800) > 0, true, false),\n \"CS_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00001000) > 0, true, false),\n \"CS_REQUIRE_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00002000) > 0, true, false),\n \"CS_ENTITLEMENTS_VALIDATED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00004000) > 0, true, false),\n \"CS_NVRAM_UNRESTRICTED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00008000) > 0, true, false),\n \"CS_RUNTIME\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00010000) > 0, true, false),\n \"CS_LINKER_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000) > 0, true, false),\n \"CS_EXEC_SET_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00100000) > 0, true, false),\n \"CS_EXEC_SET_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00200000) > 0, true, false),\n \"CS_EXEC_SET_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00400000) > 0, true, false),\n \"CS_EXEC_INHERIT_SIP\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00800000) > 0, true, false),\n \"CS_KILLED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x01000000) > 0, true, false),\n \"CS_DYLD_PLATFORM\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x02000000) > 0, true, false),\n \"CS_PLATFORM_BINARY\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x04000000) > 0, true, false),\n \"CS_PLATFORM_PATH\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x08000000) > 0, true, false),\n \"CS_DEBUGGED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x10000000) > 0, true, false),\n \"CS_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000000) > 0, true, false),\n \"CS_DEV_CODE\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x40000000) > 0, true, false),\n \"CS_DATAVAULT_CONTROLLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x80000000) > 0, true, false)\n ), \"\")\n// Event Specific - authentication\n| extend TargetUsername =\n iif(\n isnotempty(event[eventTypeHuman]['username']),\n event[eventTypeHuman]['username'],\n iif(\n isnotempty(event[eventTypeHuman]['to_username']),\n event[eventTypeHuman]['to_username'],\n iif(\n isnotempty(event[eventTypeHuman]['account_name']),\n event[eventTypeHuman]['account_name'],\n iif(\n isnotempty(event[eventTypeHuman]['user_name']),\n event[eventTypeHuman]['user_name'],\n iif(\n isnotempty(event[eventTypeHuman]['authentication_username']),\n event[eventTypeHuman]['authentication_username'],\n \"\"\n)\n)\n)\n)\n)\n// Event Specific - authentication\n| extend ActorUsername = \n iif(\n isnotempty(event[eventTypeHuman]['from_username']),\n event[eventTypeHuman]['from_username'],\n iif(\n isnotempty(event[eventTypeHuman]['session_username']),\n event[eventTypeHuman]['session_username'],\n \"\"\n)\n)\n| extend Authentication = iif(\n eventTypeHuman == \"authentication\",\n bag_pack(\n \"authentication_method\",\n iff(isnotempty(event[eventTypeHuman].data), tostring(bag_keys(event[eventTypeHuman].data)[0]), \"\")\n),\n dynamic(null)\n )\n// Event Specific - bios_uefi\n| extend HardwareInformation = iif(\n eventTypeHuman == \"bios_uefi\",\n bag_pack(\n \"host_architecture\",\n iff(isnotempty(event[eventTypeHuman].architecture), event[eventTypeHuman].architecture, \"\"),\n \"firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['firmware-version']), event[eventTypeHuman].bios.['firmware-version'], \"\"),\n \"system_firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['system-firmware-version']), event[eventTypeHuman].bios.['system-firmware-version'], \"\")\n),\n dynamic(null)\n )\n// Event Specific - btm_launch_item_add & btm_launch_item_remove\n| extend BtmItem = iif(\n eventTypeHuman in (\"btm_launch_item_add\", \"btm_launch_item_remove\", \"remount\"),\n bag_pack(\n \"btm_executable_path\",\n iff(isnotempty(event[eventTypeHuman].executable_path), event[eventTypeHuman].executable_path, \"\"),\n \"btm_item_app_url\",\n iff(isnotempty(event[eventTypeHuman].item.app_url), event[eventTypeHuman].item.app_url, \"\"),\n \"btm_item_url\",\n iff(isnotempty(event[eventTypeHuman].item.item_url), event[eventTypeHuman].item.item_url, \"\"),\n \"btm_item_managed\",\n iff(isnotempty(event[eventTypeHuman].item.managed), event[eventTypeHuman].item.managed, \"\"),\n \"btm_item_legacy\",\n iff(isnotempty(event[eventTypeHuman].item.legacy), event[eventTypeHuman].item.legacy, \"\"),\n \"btm_item_uid\",\n iff(isnotempty(event[eventTypeHuman].item.uid), event[eventTypeHuman].item.uid, \"\"),\n \"btm_item_type\",\n iff(\n isnotempty(event[eventTypeHuman].item.item_type),\n case(\n event[eventTypeHuman].item.item_type == 0,\n \"UserItem\",\n event[eventTypeHuman].item.item_type == 1,\n \"App\",\n event[eventTypeHuman].item.item_type == 2,\n \"LoginItem\",\n event[eventTypeHuman].item.item_type == 3,\n \"LaunchAgent\",\n event[eventTypeHuman].item.item_type == 4,\n \"LaunchDaemon\",\n \"Unknown\"\n),\n \"\"\n)\n),\n dynamic(null)\n )\n// Event Specific - chroot\n| extend Chroot = iif(\n eventTypeHuman == \"chroot\",\n bag_pack(\n \"apparent_root_directory\",\n iff(isnotempty(event[eventTypeHuman].target), event[eventTypeHuman].target.path, \"\"),\n \"stats\",\n iff(isnotempty(event[eventTypeHuman].target.stat), event[eventTypeHuman].target.stat, \"\")\n),\n dynamic(null)\n )\n// Event Specific - cs_invalidated\n// Event Specific - exec\n// Event Specific - kextload & kextunload\n| extend KernelExtension = iif(\n eventTypeHuman in (\"kextload\", \"kextunload\"),\n bag_pack(\n \"kext_identifier\",\n iff(isnotempty(event[eventTypeHuman].identifier), event[eventTypeHuman].identifier, \"\")\n),\n dynamic(null)\n )\n// Event Specific - lw_session_lock & lw_session_unlock & lw_session_login & lw_session_logout\n| extend LoginWindowSession = iif(\n eventTypeHuman in (\"lw_session_lock\", \"lw_session_unlock\", \"lw_session_login\", \"lw_session_logout\"),\n bag_pack(\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_session_id), event[eventTypeHuman].graphical_session_id, \"\")\n),\n dynamic(null)\n )\n// Event Specific - mount & remount & unmount\n| extend FileSystem = iif(\n eventTypeHuman in (\"mount\", \"unmount\", \"remount\"),\n bag_pack(\n \"volume_device_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntfromname), event[eventTypeHuman].statfs.f_mntfromname, \"\"),\n \"volume_mount_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntonname), event[eventTypeHuman].statfs.f_mntonname, \"\"),\n \"volume_file_system_type\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_fstypename), event[eventTypeHuman].statfs.f_fstypename, \"\"),\n \"volume_size\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_bsize), event[eventTypeHuman].statfs.f_bsize, \"\")\n),\n dynamic(null)\n )\n// Event Specific - od_attribute_set & od_attribute_value_add & od_attribute_value_remove & od_create_group & od_create_user & od_delete_group & od_delete_user & od_disable_user & od_enable_user\n| extend OpenDirectory = iif(\n eventTypeHuman in (\"od_attribute_set\", \"od_attribute_value_add\", \"od_attribute_value_remove\", \"od_create_group\", \"od_create_user\", \"od_delete_group\", \"od_delete_user\", \"od_disable_user\", \"od_enable_user\"),\n bag_pack(\n \"group_name\",\n iff(isnotempty(event[eventTypeHuman].group_name), event[eventTypeHuman].group_name, \"\"),\n \"member_array\",\n iff(isnotempty(event[eventTypeHuman].members.member_array), event[eventTypeHuman].members.member_array, \"\"),\n \"member_value\",\n iff(isnotempty(event[eventTypeHuman].member.member_value), event[eventTypeHuman].member.member_value, \"\"),\n \"user_name\",\n iff(isnotempty(event[eventTypeHuman].user_name), event[eventTypeHuman].user_name, \"\"),\n \"account_name\",\n iff(isnotempty(event[eventTypeHuman].account_name), event[eventTypeHuman].account_name, \"\"),\n \"db_path\",\n iff(isnotempty(event[eventTypeHuman].db_path), event[eventTypeHuman].db_path, \"\"),\n \"record_name\",\n iff(isnotempty(event[eventTypeHuman].record_name), event[eventTypeHuman].record_name, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\"),\n \"node_name\",\n iff(isnotempty(event[eventTypeHuman].node_name), event[eventTypeHuman].node_name, \"\")\n),\n dynamic(null)\n )\n// Event Specific - openssh_login & openssh_logout\n| extend SSHContext = iif(\n eventTypeHuman in (\"openssh_login\", \"openssh_logout\"),\n bag_pack(\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n),\n \"result_type\", \n iff(\n isnotempty(event[eventTypeHuman].result_type),\n case(\n event[eventTypeHuman].result_type == 0,\n \"Exceeded maximum attempts\",\n event[eventTypeHuman].result_type == 1,\n \"Denied by root\",\n event[eventTypeHuman].result_type == 2,\n \"Success\",\n event[eventTypeHuman].result_type == 3,\n \"No reason\",\n event[eventTypeHuman].result_type == 4,\n \"Password\",\n event[eventTypeHuman].result_type == 5,\n \"kbdint\",\n event[eventTypeHuman].result_type == 6,\n \"Public key\",\n event[eventTypeHuman].result_type == 7,\n \"Host based\",\n event[eventTypeHuman].result_type == 8,\n \"GSS API\",\n event[eventTypeHuman].result_type == 9,\n \"Invalid user\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null) \n )\n// Event Specific - performance\n// Event Specific - profile_add & profile_remove\n| extend Profile = iif(\n eventTypeHuman in (\"profile_add\", \"profile_remove\"),\n bag_pack(\n \"profile_scope\",\n iff(isnotempty(event[eventTypeHuman].profile.scope), event[eventTypeHuman].profile.scope, \"\"),\n \"profile_identifier\",\n iff(isnotempty(event[eventTypeHuman].profile.identifier), event[eventTypeHuman].profile.identifiery, \"\"),\n \"profile_uuid\",\n iff(isnotempty(event[eventTypeHuman].profile.uuid), event[eventTypeHuman].profile.uuid, \"\"),\n \"profile_display_name\",\n iff(isnotempty(event[eventTypeHuman].profile.display_name), event[eventTypeHuman].profile.display_name, \"\"),\n \"profile_organization\",\n iff(isnotempty(event[eventTypeHuman].profile.organization), event[eventTypeHuman].profile.organization, \"\"),\n \"profile_is_updated\",\n iff(isnotempty(event[eventTypeHuman].is_update), event[eventTypeHuman].is_update, \"\"),\n \"profile_install_source\", \n iff(\n isnotempty(event[eventTypeHuman].profile.install_source),\n case(\n event[eventTypeHuman].profile.install_source == 0,\n \"mdm\",\n event[eventTypeHuman].profile.install_source == 1,\n \"manual\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - screenscharing_attach & screensharing_detach\n| extend Screensharing = iif(\n eventTypeHuman in (\"screensharing_attach\", \"screensharing_detach\"),\n bag_pack(\n \"existing_session\",\n iff(isnotempty(event[eventTypeHuman].existing_session), event[eventTypeHuman].existing_session, \"\"),\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_authentication_username), event[eventTypeHuman].graphical_authentication_username, \"\"),\n \"session_username\",\n iff(isnotempty(event[eventTypeHuman].session_username), event[eventTypeHuman].session_username, \"\"),\n \"viewer_appleid\",\n iff(isnotempty(event[eventTypeHuman].viewer_appleid), event[eventTypeHuman].viewer_appleid, \"\"),\n \"authentication_type\",\n iff(isnotempty(event[eventTypeHuman].authentication_type), event[eventTypeHuman].authentication_type, \"\"),\n \"source_address\",\n iff(isnotempty(event[eventTypeHuman].source_address), event[eventTypeHuman].source_address, \"\"),\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - su\n| extend Su = iif(\n eventTypeHuman == \"su\",\n bag_pack(\n \"username\",\n iff(isnotempty(event[eventTypeHuman].username), event[eventTypeHuman].username, \"\"),\n \"uid\",\n iff(isnotempty(event[eventTypeHuman].uid), event[eventTypeHuman].uid, \"\"),\n \"args\",\n iff(isnotempty(event[eventTypeHuman].argv), event[eventTypeHuman].argv, \"\"),\n \"env_vars\",\n iff(isnotempty(event[eventTypeHuman].env), event[eventTypeHuman].env, \"\"),\n \"env_count\",\n iff(isnotempty(event[eventTypeHuman].env_count), event[eventTypeHuman].env_count, \"\"),\n \"from_username\",\n iff(isnotempty(event[eventTypeHuman].from_username), event[eventTypeHuman].from_username, \"\"),\n \"to_username\",\n iff(isnotempty(event[eventTypeHuman].to_username), event[eventTypeHuman].to_username, \"\"),\n \"failure_message\",\n iff(isnotempty(event[eventTypeHuman].failure_reason), event[eventTypeHuman].failure_reason, \"\")\n),\n dynamic(null)\n )\n// Event Specific - sudo\n| extend Sudo = iif(\n eventTypeHuman == \"sudo\",\n bag_pack(\n \"TargetProcessCommandLine\",\n iff(isnotempty(event[eventTypeHuman].command), event[eventTypeHuman].command, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\")\n),\n dynamic(null)\n )\n// Event Specific - xp_malware_detected & xp_malware_remediated\n| extend Xprotect = iif(\n eventTypeHuman in (\"xp_malware_detected\", \"xp_malware_remediated\"),\n bag_pack(\n \"detected_path\",\n iff(isnotempty(event[eventTypeHuman].detected_path), event[eventTypeHuman].detected_path, \"\"),\n \"remediated_path\",\n iff(isnotempty(event[eventTypeHuman].remediated_path), event[eventTypeHuman].remediated_path, \"\"),\n \"malware_identifier\",\n iff(isnotempty(event[eventTypeHuman].malware_identifier), event[eventTypeHuman].malware_identifier, \"\"),\n \"signature_version\",\n iff(isnotempty(event[eventTypeHuman].signature_version), event[eventTypeHuman].signature_version, \"\")\n),\n dynamic(null)\n )\n| project-away\naction,\nevent,\nprocess\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n// //\n// // Jamf Protect - Threat Events\n// //\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectTelemetryv1_view, JamfProtectTelemetryv2_view, JamfProtectNetworkTraffic_view, JamfProtectThreatEvents_view\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('workbookTemplateSpecName1')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtectDashboard Workbook with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('workbookVersion1')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId1')]",
+ "location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "This Jamf Protect Workbook for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel.\n Providing reports into all alerts, device controls and Unfied Logs."
+ },
+ "properties": {
+ "displayName": "[parameters('workbook1-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"b608e714-b3ec-4380-b666-1aa781513ab4\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Subscription\",\"type\":6,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"includeAll\":false},\"label\":\"☁️ Subscription\"},{\"id\":\"f408f1cf-dbcb-4f57-9409-272374bd3cd4\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Workspace\",\"type\":5,\"isRequired\":true,\"query\":\"Resources | where type =~ \\\"microsoft.operationalinsights/workspaces\\\" | order by name | project id, name, selected=row_number()==1, group=resourceGroup\",\"crossComponentResources\":[\"{Subscription}\"],\"queryType\":1,\"resourceType\":\"microsoft.resourcegraph/resources\",\"label\":\"🗂️ Workspace\",\"value\":\"\"},{\"id\":\"397d983f-ea80-4aa5-8c65-547d40cb312b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_timetoken\",\"label\":\"⏱️ Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"value\":{\"durationMs\":172800000}},{\"id\":\"d716fb1e-0d71-4e99-9406-18ae7df6e037\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"changelog\",\"label\":\"📖 Changelog\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\": \\\"Yes\\\", \\\"label\\\": \\\"Yes\\\"},\\r\\n {\\\"value\\\": \\\"No\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"Parameters Picker\"},{\"type\":1,\"content\":{\"json\":\"## Jamf Protect for Microsoft Sentinel!\\n\\nThe [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) for Microsoft Sentinel solution creates detailed event data from macOS endpoints into a Microsoft Sentinel workspace in a simple and easy workflow. The solution provides you with full visibility into Apple Endpoint Security by leveraging Workbooks containing [Alert](https://docs.jamf.com/jamf-protect/documentation/Alerts.html) and [Unified Logging](https://docs.jamf.com/jamf-protect/documentation/Unified_Logging.html) events captured by Jamf Protect and the [macOS built-in security events](https://support.apple.com/en-gb/guide/security/sec469d47bd8/web) that occurred across the protected organisational endpoints\\n\\n\\n#### Changelog\\n\\n**v2.2.0**\\n\\n***Workbook***\\n - Added System Performance Metrics\\n - Includes Energy Impact\\n - Added Network Traffic Stream\\n - Updated Workbook to make use of the newly added parser\\n - Added and tweaked querys and graphs\\n\\n ***Parser***\\n - Added JamfProtect parser for parsing and mapping all incoming raw data.\\n\\n ***Analytic Rules***\\n - Updated Analytic Rules to make use of the newly added parser. \\n\\t\\n**v2.1**\\n\\n***Workbook***\\n - Added Endpoint Telemetry\\n - Includes graphs and visualisations\\n\\t- Includes Endpoint Information\\n\\t- Includes Jamf Pro log parser\\n- Added Network Threat Events\\n \\t- Includes graphs and visualisations\\n- Added new Pickers\\n - Allows selecting different Log Analytic Workspaces\\n - Changed TimeRanger picker\\n- Added Changelog\\n\\n**Analytic Rules**\\n\\n- Added Analytic Rules\\n\\t- Jamf Protect - Alerts\\n\\t- Jamf Protect - Unified Logs\\n\\t- Jamf Protect - Network Threat Events\\n\\n\\n **v2.0**\\n \\n- Initial release of the solution containing a basic Workbook\\n\"},\"conditionalVisibility\":{\"parameterName\":\"changelog\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"Text - Changelog\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Threat Hunting {_timetoken:value}\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"Set an type and provide values to search on File hash, CVE numbers or report on Alerts mapped to the MITRE framework or display latest alerts for a single endpoint.\",\"style\":\"info\"},\"name\":\"Text - Threat Hunting\",\"styleSettings\":{\"showBorder\":true}},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"5f5886d0-e83e-4ffc-a48c-bfed7370aa66\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_type\",\"label\":\"Type\",\"type\":2,\"description\":\"Please choose the type\",\"isGlobal\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\n { \\\"value\\\":\\\"filehash\\\", \\\"label\\\":\\\"File Hash\\\" },\\n { \\\"value\\\":\\\"CVE\\\", \\\"label\\\":\\\"CVE\\\" },\\n { \\\"value\\\":\\\"mitre\\\", \\\"label\\\":\\\"Framework: MITRE\\\" },\\n { \\\"value\\\":\\\"endpointalerts\\\", \\\"label\\\":\\\"Latest alerts for a single endpoint\\\" }\\n]\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"15\",\"name\":\"Picker - Threat Hunting Type\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"{Workspace}\"],\"parameters\":[{\"id\":\"49255f47-8f93-4746-8260-aad07befdb06\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_hostnamealert\",\"label\":\"Hostname\",\"type\":2,\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n | project-keep DvcHostname\\n| project-rename Hostname = DvcHostname\\n| summarize by Hostname\",\"crossComponentResources\":[\"{Workspace}\"],\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"conditionalVisibilities\":[{\"parameterName\":\"_type\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"endpointalerts\"}],\"name\":\"Picker - Threat Hunting Hostname\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"bcdd945e-4dfe-47d6-9489-f76ce012c224\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_filehash\",\"label\":\"File Hash\",\"type\":1,\"description\":\"Thish value can be used for searching all alerts for a certain hash\",\"isRequired\":true,\"isGlobal\":true,\"value\":\"5e54bccbd4d93447e79cda0558b0b308a186c2be571c739e5460a3cb6ef665c0\"}],\"style\":\"formHorizontal\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"conditionalVisibility\":{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"filehash\"},\"name\":\"Search - Threat Hunting Hash\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"0344768b-16c4-44ec-a4ac-73a8bc83d0e2\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_CVE\",\"label\":\"CVE Number\",\"type\":1,\"description\":\"Please search on the CVE number\",\"isRequired\":true,\"isGlobal\":true,\"value\":\"T15\"}],\"style\":\"formHorizontal\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"conditionalVisibility\":{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"CVE\"},\"name\":\"Search - Threat Hunting CVE\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"ProcessPrevented\\\" or EventType == \\\"ProcessCreated\\\"\\n| where TargetProcessSHA1 has \\\"{_filehash:value}\\\" or TargetBinarySHA256 has \\\"{_filehash:value}\\\"\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\",\"size\":4,\"title\":\"Matches on FileHash\",\"noDataMessage\":\"No matches found based on the hash value\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to navigate to original event in Jamf Protect\"}}]}},\"conditionalVisibilities\":[{\"parameterName\":\"_filehash\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"filehash\"}],\"name\":\"Query - Threat Hunting Hash\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where Match_tags contains \\\"{_CVE:value}\\\"\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n Match_tags,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventMatch,\\n Match_tags,\\n EventSeverity,\\n EventMatchType,\\n TargetProcessCommandLine,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\",\"size\":1,\"title\":\"Matches on CVE\",\"noDataMessage\":\"No matches found based on the _CVE:value CVE number\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to nagivate to original event in Jamf Protect\"}}]}},\"conditionalVisibilities\":[{\"parameterName\":\"_cve\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"CVE\"}],\"name\":\"Query - Threat Hunting CVE\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where Match_tags contains \\\"MITREattack\\\"\\n| extend\\n Tactics = case(Match_tags has \\\"Execution\\\", \\\"Execution\\\", Match_tags has \\\"Visibility\\\", \\\"Visibility\\\", Match_tags has \\\"Persistence\\\", \\\"Persistence\\\", Match_tags has \\\"LateralMovement\\\", \\\"Lateral Movement\\\", Match_tags has \\\"CredentialAccess\\\", \\\"Credential Acccess\\\", Match_tags has \\\"DefenseEvasion\\\", \\\"Defense Evasion\\\", Match_tags has \\\"PrivilegeEscalation\\\", \\\"Privilege Escalation\\\", Match_tags has \\\"Impact\\\", \\\"Impact\\\", Match_tags has \\\"CommandAndControl\\\", \\\"Command and Control\\\", Match_tags has \\\"Discovery\\\", \\\"Discovery\\\", Match_tags has \\\"InitialAccess\\\", \\\"Initial Access\\\", \\\"\\\"),\\n Techniques = extract(@\\\"[A-Za-z]\\\\d{4}\\\", 0, tostring(Match_tags))\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Tactics,\\n Techniques,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Tactics,\\n Techniques,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\",\"size\":1,\"title\":\"Alerts mapped to MITRE\",\"noDataMessage\":\"No alerts found that are mapped to the MITRE framework\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to navigate to original event in Jamf Protect\"}}],\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"conditionalVisibilities\":[{\"parameterName\":\"_type\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"mitre\"}],\"name\":\"Query - Threat Hunting MITRE\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where DvcHostname contains \\\"{_hostnamealert:value}\\\"\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\" and isnotempty(EventType)\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| project-reorder\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n EventMessage,\\n EventDescription,\\n Match_tags,\\n EventSeverity,\\n DvcHostname,\\n EventReportUrl\\n| sort by TimeGenerated\\n| limit 10\",\"size\":1,\"title\":\"Recent 10 alerts in the past {_timetoken:value} for {_hostnamealert:value}\",\"noDataMessage\":\"No alerts found\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to nagivage to original event in Jamf Protect\"}}],\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"conditionalVisibilities\":[{\"parameterName\":\"_type\",\"comparison\":\"isNotEqualTo\",\"value\":\"null\"},{\"parameterName\":\"_type\",\"comparison\":\"isEqualTo\",\"value\":\"endpointalerts\"},{\"parameterName\":\"_hostnamealert\",\"comparison\":\"isNotEqualTo\",\"value\":\"\"}],\"name\":\"Query - Threat Hunting 10 Recent Alerts Endpoint\"}]},\"customWidth\":\"100\",\"name\":\"Group - Threat Hunting\",\"styleSettings\":{\"margin\":\"200\",\"padding\":\"200\",\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| where EventSeverity != \\\"Informational\\\"\\n| sort by EventStartTime\\n| limit 10\",\"size\":0,\"title\":\"Recent 10 alerts in the past {_timetoken:value}\",\"noDataMessage\":\"No alerts found\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"EventReportUrl\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\",\"linkLabel\":\"Click to navigate to Alert in Jamf Protect\"}},{\"columnMatch\":\"AlertURL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"TimeGenerated\",\"sortOrder\":1}]},\"name\":\"Query - 10 Recent Alerts\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"datatable (Count: long, severity: string) [\\n 0, \\\"Informational\\\",\\n 0, \\\"Low\\\",\\n 0, \\\"Medium\\\",\\n 0, \\\"High\\\"\\n]\\n| union\\n (\\n JamfProtect\\n | where EventProduct == \\\"Jamf Protect - Alerts\\\" \\n and isnotempty(EventType)\\n and EventSeverity != \\\"True\\\"\\n | summarize Count = count() by EventSeverity\\n )\\n| where isnotempty(EventSeverity)\\n| summarize Count=sum(Count) by EventSeverity\",\"size\":3,\"title\":\"All Alerts {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"EventSeverity\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"==\",\"thresholdValue\":\"Informational\",\"representation\":\"green\",\"text\":\"{0}{1}\"},{\"operator\":\"==\",\"thresholdValue\":\"Low\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"},{\"operator\":\"==\",\"thresholdValue\":\"Medium\",\"representation\":\"orange\",\"text\":\"{0}{1}\"},{\"operator\":\"==\",\"thresholdValue\":\"High\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"green\",\"text\":\"{0}{1}\"}],\"compositeBarSettings\":{\"labelText\":\"\"}}},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumSignificantDigits\":1,\"maximumSignificantDigits\":3},\"emptyValCustomText\":\"0\"}},\"showBorder\":true,\"sortCriteriaField\":\"Count\",\"sortOrderField\":2}},\"name\":\"Datatable - Alerts per Severity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n and isnotempty(EventType)\\n| where EventSeverity != \\\"True\\\"\\n| summarize count() by EventSeverity, bin(TimeGenerated,{_timetoken:grain})\\n| render areachart \",\"size\":0,\"title\":\"Events Detected (Count By Severity) {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"chartSettings\":{\"showLegend\":true,\"seriesLabelSettings\":[{\"seriesName\":\"0\",\"label\":\"Informational\"},{\"seriesName\":\"1\",\"label\":\"Low\"},{\"seriesName\":\"2\",\"label\":\"Medium\"},{\"seriesName\":\"3\",\"label\":\"High\"}]}},\"customWidth\":\"50\",\"name\":\"Query - Events detected by Severity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"UnifiedLog\\\"\\n| summarize count() by tostring(EventDescription), bin(TimeGenerated,{_timetoken:grain})\\n| render areachart \",\"size\":0,\"title\":\"Unified Logging Events {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Unified Logs\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\" \\n and isnotempty(EventType)\\n and isnotempty(DvcHostname)\\n| summarize Event = count() by DvcHostname\\n| sort by Event desc\",\"size\":3,\"title\":\"Most Active Endpoints (Total, last {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"table\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"HostName\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Event\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"HostName\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Event\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"100\",\"name\":\"Query - Most active endpoints with Alerts\",\"styleSettings\":{\"maxWidth\":\"100\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n and isnotempty(EventType)\\n| summarize Events = count() by EventProduct, bin(TimeGenerated,{_timetoken:grain})\\n| render columnchart \",\"size\":0,\"title\":\"Events detected (Total by date, {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"jamfprotect_CL\",\"label\":\"Jamf Protect\"}]}},\"customWidth\":\"50\",\"name\":\"Query - Total events detected\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| summarize Events = count() by EventType, bin(EventStartTime,{_timetoken:grain})\\n| render areachart with(kind=stacked)\\n\",\"size\":0,\"title\":\"Events Detected (Count by Type, {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"areachart\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Events\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Events\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"Query - Events detected counted by Type\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Event Types\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| summarize Events = count() by EventType\\n| render piechart\",\"size\":3,\"showAnalytics\":true,\"title\":\"Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - Events by Type\",\"styleSettings\":{\"maxWidth\":\"100\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"FileSystem\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"File System Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - File System Events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"Process\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \\n\",\"size\":3,\"showAnalytics\":true,\"title\":\"Process Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - Process Event Types\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"USB\\\"\\nor EventType == \\\"UsbBlock\\\" and EventMessage == \\\"USBWrite\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"USB Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - USB Event Types\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"Gatekeeper\\\"\\n| summarize count() by tostring(EventMessage)\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"Gatekeeper Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"GatekeeperBlockedSigned\",\"label\":\"Signed\"},{\"seriesName\":\"GatekeeperBlockedRevoked\",\"label\":\"Revoked\"},{\"seriesName\":\"GatekeeperBlockedUnsignedOrUnknown\",\"label\":\"UnsignedOrUnknown\"}]}},\"customWidth\":\"33\",\"name\":\"Query - GateKeeper Events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"ProcessPrevented\\\"\\n| summarize Threat = count() by EventMatch\\n| render piechart \",\"size\":3,\"showAnalytics\":true,\"title\":\"Threat Prevention Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"33\",\"name\":\"Query - Threat Prevention Types\"}]},\"name\":\"Group - Event Types\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Alerts\\\"\\n| where isnotempty(EventType)\\n| summarize count() by tostring(EventType), tostring(EventMessage)\\n| project-rename Count = count_\\n| sort by Count desc\\n| limit 10\\n\",\"size\":3,\"showAnalytics\":true,\"title\":\"Top 10 Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 Events\",\"styleSettings\":{\"maxWidth\":\"50\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"ProcessDenied\\\"\\n| where isnotempty(DvcHostname)\\n| summarize Count= count() by TargetProcessName, EventMatch, TargetBinarySigningAppID, TargetBinarySigningTeamID\\n| sort by Count asc nulls first\\n| limit 25\",\"size\":0,\"showAnalytics\":true,\"title\":\"Process Blocked by Custom Prevent List {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Process Blocked by Custom Prevent List\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"macOS Built-In Security Tools\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"Gatekeeper\\\"\\n| summarize count() by tostring(EventMessage), TargetFilePath\\n| project-rename BlockType = EventMessage, Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":3,\"showAnalytics\":true,\"title\":\"Top Gatekeeper Blocked Items {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"Query - Top Blocked GateKeepers events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Unified Log\\\"\\n| where input_match_event_subsystem_s == \\\"com.apple.XProtectFramework.PluginAPI\\\"\\n| where tostring(parse_json(input_match_event_composedMessage_s).status_message) <> \\\"[]\\\"\\n| extend status_message_ = tostring(parse_json(input_match_event_composedMessage_s).status_message)\\n| extend execution_duration_ = tostring(parse_json(input_match_event_composedMessage_s).execution_duration)\\n| project \\n EventStartTime, \\n DvcHostname, \\n Status=status_message_, \\n Module=input_match_event_process_s, \\n Execution_Duration=execution_duration_\\n| sort by EventStartTime desc\\n| limit 25\",\"size\":0,\"showAnalytics\":true,\"title\":\"XProtect Remediator Scans {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - XProtect Remediator Activity\"}]},\"name\":\"macOS Built-In Security Tools Group\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Device Controls\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"UsbBlock\\\"\\n| where EventMessage == \\\"EnforcedRemovableDevicePolicy\\\"\\n| extend EventMessage = replace_string(tostring(EventMessage), \\\"EnforcedRemovableDevicePolicy\\\", \\\"Blocked\\\")\\n| summarize count() by tostring(EventMessage)\\n\\n\",\"size\":2,\"title\":\"Device Controls Blocked {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"piechart\",\"tileSettings\":{\"titleContent\":{\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"icons\",\"thresholdsGrid\":[{\"thresholdValue\":\"Alerts\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"Notifications\",\"text\":\"Devices Blocked\"}]}},\"leftContent\":{\"columnMatch\":\"count_\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":true,\"sortOrderField\":2},\"graphSettings\":{\"type\":0,\"centerContent\":{\"columnMatch\":\"count_\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"showMetrics\":false},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"count_\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"count_\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"count_\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"25\",\"name\":\"Query - Blocked USB Events\",\"styleSettings\":{\"maxWidth\":\"25\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"UsbBlock\\\"\\n| where EventMessage == \\\"EnforcedRemovableDevicePolicy\\\"\\n| extend device_ = strcat(input_match_event_device_vendorName_s, \\\" \\\",input_match_event_device_productName_s)\\n| summarize count() by DvcHostname, device_\\n| project-rename Hostname = DvcHostname, Device = device_, Count = count_\\n| sort by Count desc\\n\\n\",\"size\":0,\"title\":\"Device Controls Endpoint {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"65\",\"name\":\"Query - Blocked USB Devices\",\"styleSettings\":{\"maxWidth\":\"100\"}}]},\"name\":\"Group - Device Controls\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Endpoint Telemetry\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where identity_signer_id_s == \\\"com.apple.sudo\\\"\\n and ParentProcessName == \\\"/usr/bin/sudo\\\"\\n and ActorUsername == \\\"root\\\"\\n and ActorUserId != \\\"-1\\\"\\n| extend Compiled_Arguments = replace_string(TargetProcessCommandLine, \\\",\\\", \\\" \\\")\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n DvcHostname,\\n ActorUserId,\\n Compiled_Arguments\\n| project-rename Hostname = DvcHostname, Elevated_User = ActorUserId\\n| limit 50\\n| sort by EventStartTime\",\"size\":0,\"title\":\"Succesful sudo events {_timetoken:value}\",\"noDataMessage\":\"No events occured\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Compiled_Arguments\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"69.5714ch\"}}],\"sortBy\":[{\"itemKey\":\"EventStartTime\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"EventStartTime\",\"sortOrder\":2}]},\"name\":\"Query - Successful sudo events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n//| where SrcIpAddr != \\\"0.0.0.0\\\" and EventType != \\\"AUE_SESSION_START\\\" and EventType != \\\"PLAINTEXT_LOG_COLLECTION_EVENT\\\" and EventType != \\\"BIOS_FIRMWARE_VERSIONS\\\" and EventType != \\\"SYSTEM_PERFORMANCE_METRICS\\\" and EventType != \\\"RATE_LIMITING_APPLIED\\\"\\n| where SrcIpAddr != \\\"0.0.0.0\\\" and EventType == \\\"ProcessCreated\\\"\\n or SrcIpAddr != \\\"0.0.0.0\\\" and EventType == \\\"Logoff\\\"\\n or SrcIpAddr != \\\"0.0.0.0\\\" and EventType == \\\"SshInitiated\\\"\\n| where isnotempty(DvcHostname)\\n| where isnotempty(EventType)\\n| where EventProduct != \\\"Jamf Protect - Alerts\\\"\\n//| extend binary=parse_json(path_s)[0]\\n| extend Compiled_Arguments = replace_string(TargetProcessCommandLine, \\\",\\\", \\\" \\\")\\n| project-keep\\n TimeGenerated,\\n EventStartTime,\\n EventType,\\n return_description_s,\\n TargetProcessName,\\n DvcHostname,\\n SrcIpAddr,\\n ActorUsername,\\n ActorUserId,\\n Compiled_Arguments\\n| project-rename\\n EventName = EventType,\\n Description = return_description_s,\\n Hostname = DvcHostname,\\n Process_Name = TargetProcessName,\\n IP_Adress = SrcIpAddr,\\n Elevated_User = ActorUserId\\n| limit 15\\n| sort by EventStartTime\",\"size\":0,\"title\":\"Remotely Controlled Commands (Outbound) {_timetoken:value}\",\"noDataMessage\":\"No events occured\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"name\":\"Query - Remotely Controlled Commands\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n| where isnotempty(TargetProcessName)\\n| project-keep TimeGenerated, ParentProcessName, TargetProcessName\\n| summarize Rare_Process_Count = count() by TargetProcessName, ParentProcessName\\n| sort by Rare_Process_Count asc nulls first\\n| limit 200\",\"size\":0,\"title\":\"Rare Process Executions (All Executions) {_timetoken:value}\",\"noDataMessage\":\"No events occured\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Rare_Process_Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Rare_Process_Count\",\"sortOrder\":1}]},\"customWidth\":\"100\",\"name\":\"Query - Rare Process Executions\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n and isnotempty(ParentProcessName)\\n| project\\n DvcHostname,\\n TargetProcessName,\\n ParentProcessName,\\n ParentProcessGuid,\\n exec_chain_thread_uuid_g\\n| summarize\\n thread_uuid = make_set(exec_chain_thread_uuid_g, 128),\\n Hostnames = make_set(DvcHostname, 128),\\n process = make_set(TargetProcessName, 128)\\n by ParentProcessName\\n| project \\n Hostnames,\\n process,\\n parent_process=ParentProcessName,\\n thread_uuid\",\"size\":0,\"title\":\"Parent/child process with thread uuid {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"100\",\"name\":\"Query - Parent and Child Process UUID\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Endpoint Information\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"SystemPerformanceMetrics\\\"\\n| extend metrics = parse_json(metrics_tasks_s)\\n| project-keep DvcHostname, metrics, TimeGenerated\\n| project-reorder DvcHostname, metrics\\n| mv-expand metrics\\n| extend energy_impact = metrics.energy_impact\\n| extend process_name = metrics.name\\n| project-rename\\n Hostname = DvcHostname\\n| extend avg = toreal(energy_impact)\\n| summarize Average = avg(avg) by tostring(process_name), bin(TimeGenerated,{_timetoken:grain})\\n| render timechart\\n\\n\\n\\n\",\"size\":0,\"aggregation\":3,\"title\":\"Overall System Energy Impact on all endpoints {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"tileSettings\":{\"showBorder\":false},\"graphSettings\":{\"type\":0,\"nodeIdField\":\"Hostname\",\"sourceIdField\":\"Hostname\",\"targetIdField\":\"Hostname\",\"graphOrientation\":3,\"showOrientationToggles\":false,\"staticNodeSize\":100,\"hivesMargin\":5},\"chartSettings\":{\"group\":\"process_name\",\"createOtherGroup\":15,\"showLegend\":true},\"mapSettings\":{\"locInfo\":\"LatLong\"}},\"customWidth\":\"100\",\"name\":\"Query - System Performance Metrics - Energy Impact\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Log Parser {_timetoken:value}\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"Please select a hostname in order to show the collected plain-text log files.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"_hostnamelogparser\",\"comparison\":\"isEqualTo\"},\"name\":\"Text - Jamf Log Parser Note\",\"styleSettings\":{\"showBorder\":true}},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"{Workspace}\"],\"parameters\":[{\"id\":\"f747e125-851e-45f7-b500-5d22049da6a6\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_hostnamelogparser\",\"label\":\"Hostname\",\"type\":2,\"isRequired\":true,\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n and EventType == \\\"LogFileCollected\\\"\\n| project-keep DvcHostname\\n| project-rename Hostname = DvcHostname\\n| summarize by Hostname\",\"crossComponentResources\":[\"{Workspace}\"],\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"7d123ad2-1768-4d22-b438-565ab483c044\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_logselectlogparser\",\"label\":\"Available Log File\",\"type\":2,\"isRequired\":true,\"query\":\"JamfProtect\\n| where EventType == \\\"LogFileCollected\\\"\\n and DvcHostname == \\\"{_hostnamelogparser:value}\\\"\\n| project-keep TargetFilePath\\n| project-keep TargetFilePath\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"[\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"]\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, '\\\"', \\\"\\\")\\n| summarize by TargetFilePath\",\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":7776000000},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"/var/log/jamf.log\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"40\",\"name\":\"Picker - Hostname\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"LogFileCollected\\\"\\n and DvcHostname == \\\"{_hostnamelogparser:value}\\\"\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"[\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, \\\"]\\\", \\\"\\\")\\n| extend TargetFilePath = replace_string(TargetFilePath, '\\\"', \\\"\\\")\\n| where TargetFilePath == \\\"{_logselectlogparser:escapejson}\\\"\\n| project EventResult, EventStartTime\\n| project-rename Logs = EventResult\\n| project-reorder EventStartTime, Logs\\n| mv-expand parse_json(Logs)\\n| sort by EventStartTime desc\\n| limit 50\",\"size\":0,\"showAnalytics\":true,\"title\":\"Log File Collection on \\\"{_hostnamelogparser:value}\\\"\",\"noDataMessage\":\"No matches found based on the hostname\",\"timeContextFromParameter\":\"_timetoken\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Logs\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"150ch\"}}]}},\"conditionalVisibility\":{\"parameterName\":\"_hostnamelogparser\",\"comparison\":\"isNotEqualTo\"},\"name\":\"Query - Parse Logs\"}]},\"customWidth\":\"100\",\"name\":\"Group - Log Parser\",\"styleSettings\":{\"margin\":\"200\",\"padding\":\"200\",\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Endpoint System Performance {_timetoken:value}\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"Please select a hostname in order to show the system performance metrics.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"_hostnamelogparser\",\"comparison\":\"isEqualTo\"},\"name\":\"Text - Jamf Log Parser Note\",\"styleSettings\":{\"showBorder\":true}},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"crossComponentResources\":[\"{Workspace}\"],\"parameters\":[{\"id\":\"f747e125-851e-45f7-b500-5d22049da6a6\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"_hostname\",\"label\":\"Hostname\",\"type\":2,\"query\":\"JamfProtect\\n| where isnotempty(DvcHostname)\\n and EventType == \\\"SystemPerformanceMetrics\\\"\\n| project-keep DvcHostname\\n| project-rename Hostname = DvcHostname\\n| summarize by Hostname\",\"crossComponentResources\":[\"{Workspace}\"],\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"LMAC-ZW0GTLVDL\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"40\",\"name\":\"Picker - Hostname\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventType == \\\"SystemPerformanceMetrics\\\"\\n and DvcHostname == \\\"{_hostname:value}\\\"\\n| extend metrics = parse_json(metrics_tasks_s)\\n| project-keep DvcHostname, metrics, TimeGenerated\\n| project-reorder DvcHostname, metrics\\n| mv-expand metrics\\n| extend energy_impact = metrics.energy_impact\\n| extend process_name = metrics.name\\n| project-rename\\n Hostname = DvcHostname\\n| extend avg = toreal(energy_impact)\\n| summarize Average = avg(avg) by tostring(process_name), bin(TimeGenerated,{_timetoken:grain})\\n| render timechart\",\"size\":0,\"aggregation\":3,\"title\":\"Energy Impact on {_hostname:value}\",\"noDataMessage\":\"No metrics found based on the hostname\",\"timeContextFromParameter\":\"_timetoken\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"TimeGenerated\",\"formatter\":5},{\"columnMatch\":\"JamfLogs\",\"formatter\":1,\"formatOptions\":{\"customColumnWidthSetting\":\"100ch\"}}]},\"chartSettings\":{\"group\":\"process_name\",\"createOtherGroup\":15,\"showLegend\":true}},\"conditionalVisibility\":{\"parameterName\":\"_hostname\",\"comparison\":\"isNotEqualTo\"},\"name\":\"Query - Endpoint System Performance - Energy Impact\"}]},\"customWidth\":\"100\",\"name\":\"Group - Endpoint System Performance\",\"styleSettings\":{\"margin\":\"200\",\"padding\":\"200\",\"showBorder\":true}}]},\"name\":\"Group - Endpoint Information\"}]},\"name\":\"Group - Telemetry\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Network Threat Events\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and EventResult == \\\"Blocked\\\"\\n| extend blocks = case(EventResult == \\\"Blocked\\\", \\\"Blocked\\\", \\\"True\\\")\\n| summarize arg_max(EventResult, *) by EventStartTime\\n| summarize Count = count() by blocks\\n\\n\",\"size\":4,\"title\":\"Threats blocked by NTP {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"],\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Count\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"==\",\"thresholdValue\":\"0\",\"representation\":\"green\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\"<\",\"thresholdValue\":\"15\",\"representation\":\"gray\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\"<\",\"thresholdValue\":\"30\",\"representation\":\"orange\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\">\",\"thresholdValue\":\"50\",\"representation\":\"redBright\",\"text\":\"Threats blocked by NTP\"},{\"operator\":\"Default\",\"representation\":\"gray\",\"text\":\"Threats blocked by NTP\"}],\"compositeBarSettings\":{\"labelText\":\"\"}}},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true,\"minimumSignificantDigits\":1,\"maximumSignificantDigits\":3},\"emptyValCustomText\":\"0\"}},\"showBorder\":true,\"sortCriteriaField\":\"blocks\",\"sortOrderField\":1,\"size\":\"auto\"}},\"name\":\"Query - Threats blocked by NTP\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n| where isnotempty(EventSeverity)\\n| summarize arg_max(EventSeverity, *) by EventStartTime\\n| summarize count() by EventSeverity, bin(TimeGenerated,{_timetoken:grain})\\n| render areachart\",\"size\":0,\"title\":\"Network Events Detected (Count By Severity) {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Network Events by Severity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and isnotempty(DvcHostname)\\n| summarize arg_max(DvcHostname, *) by EventStartTime\\n| summarize Event = count() by DvcHostname\\n| sort by Event desc\",\"size\":0,\"title\":\"Most Active Endpoints (Total, last {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Most Active Endoints with Alerts\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and isnotempty(ThreatCategory)\\n| summarize arg_max(ThreatCategory, *) by EventStartTime\\n| summarize Events = count() by ThreatCategory, bin(EventStartTime, {_timetoken:grain})\\n| render areachart with(kind=stacked)\",\"size\":0,\"title\":\"Network Events Detected (Count by Type, {_timetoken:value})\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Network Events by Category\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\"\\n and isnotempty(ThreatCategory)\\n| summarize arg_max(ThreatCategory, *) by EventStartTime\\n| summarize Events = count() by ThreatCategory\\n| render piechart\",\"size\":0,\"title\":\"Event Types {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Network Events by Description\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\" \\n and notempty(ThreatCategory) and notempty(DnsQueryName)\\n| extend name_ = ThreatCategory\\n| summarize arg_max(DnsQueryName, *) by EventStartTime\\n| summarize count() by DnsQueryName, ThreatCategory\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 Blocked destinations {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 blocked destinations\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Threat Events Stream\\\" \\n and notempty(ThreatCategory)\\n and notempty(DstIpAddr)\\n| extend name_ = ThreatCategory\\n| summarize arg_max(DstIpAddr, *) by EventStartTime\\n| summarize count() by DstIpAddr\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 Blocked IPs {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 Blocked IPs\"}]},\"name\":\"Network Threat Events - Group\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Network Traffic\",\"expandable\":true,\"expanded\":true,\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Network Traffic Stream\\\"\\n and isnotempty(DnsQuery)\\n| summarize arg_max(DnsQuery, *) by EventStartTime\\n| summarize count() by DnsQuery, DnsQueryTypeName\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 resolved destinations {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 resolved destinations\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"JamfProtect\\n| where EventProduct == \\\"Jamf Protect - Network Traffic Stream\\\"\\n and isnotempty(DstIpAddr) and DstIpAddr != \\\"[]\\\"\\n| summarize arg_max(DstIpAddr, *) by EventStartTime\\n| summarize count() by DstIpAddr\\n| project-rename\\n Count = count_\\n| sort by Count desc\\n| limit 10\",\"size\":0,\"title\":\"Top 10 Resolved IPs {_timetoken:value}\",\"timeContextFromParameter\":\"_timetoken\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{Workspace}\"]},\"customWidth\":\"50\",\"name\":\"Query - Top 10 Resolved IPs\"}]},\"name\":\"Network Traffic - Group\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-JamfProtectDashboard\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
+ "properties": {
+ "description": "@{workbookKey=JamfProtectWorkbook; logoFileName=jamf_logo.svg; description=This Jamf Protect Workbook for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel.\n Providing reports into all alerts, device controls and Unfied Logs.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0.0; title=Jamf Protect Workbook; templateRelativePath=JamfProtectDashboard.json; subtitle=; provider=Jamf Software, LLC}.description",
+ "parentId": "[variables('workbookId1')]",
+ "contentId": "[variables('_workbookContentId1')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "jamfprotect_CL",
+ "kind": "DataType"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId1')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook1-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId1')]",
+ "id": "[variables('_workbookcontentProductId1')]",
+ "version": "[variables('workbookVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtectAlerts_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "NRT",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "Creates an incident based on Jamf Protect Alert data in Microsoft Sentinel",
+ "displayName": "Jamf Protect - Alerts",
+ "enabled": false,
+ "query": "JamfProtect\n| where EventProduct == \"Jamf Protect - Alerts\"\n and isnotempty(EventSeverity)\n| extend\n algorithm = \"SHA256\",\n Host_IPs = tostring(parse_json(DvcIpAddr)[0]),\n Tags = tostring(Match_facts[0].tags),\n Tactics = case(Match_tags has \"Execution\", \"Execution\", Match_tags has \"Visibility\", \"Visibility\", Match_tags has \"Persistence\", \"Persistence\", Match_tags has \"LateralMovement\", \"LateralMovement\", Match_tags has \"CredentialAccess\", \"CredentialAcccess\", Match_tags has \"DefenseEvasion\", \"DefenseEvasion\", Match_tags has \"PrivilegeEscalation\", \"PrivilegeEscalation\", Match_tags has \"Impact\", \"Impact\", Match_tags has \"CommandAndControl\", \"CommandandControl\", Match_tags has \"Discovery\", \"Discovery\", Match_tags has \"InitialAccess\", \"InitialAccess\", \"\"),\n Techniques = pack_array(extract(@\"[A-Za-z]\\d{4}\", 0, tostring(Match_tags))),\n JamfPro = case(Match_actions has \"SmartGroup\", \"Workflow with Jamf Pro\", Match_actions has \"Prevented\", \"No workflow, Prevented by Protect\", \"No workflow\")\n",
+ "severity": "High",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "jamfprotect_CL"
+ ],
+ "connectorId": "JamfProtect"
+ }
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "DvcHostname",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DvcOs",
+ "identifier": "OSFamily"
+ },
+ {
+ "columnName": "DvcOsVersion",
+ "identifier": "OSVersion"
+ }
+ ],
+ "entityType": "Host"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "Host_IPs",
+ "identifier": "Address"
+ }
+ ],
+ "entityType": "IP"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "TargetUsername",
+ "identifier": "Name"
+ }
+ ],
+ "entityType": "Account"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "TargetProcessCurrentDirectory",
+ "identifier": "CommandLine"
+ },
+ {
+ "columnName": "TargetProcessId",
+ "identifier": "ProcessId"
+ }
+ ],
+ "entityType": "Process"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "algorithm",
+ "identifier": "Algorithm"
+ },
+ {
+ "columnName": "TargetBinarySHA256",
+ "identifier": "Value"
+ }
+ ],
+ "entityType": "FileHash"
+ }
+ ],
+ "eventGroupingSettings": {
+ "aggregationKind": "AlertPerResult"
+ },
+ "customDetails": {
+ "Related_Binaries": "TargetBinaryFilePath",
+ "Related_File_hash": "TargetBinarySHA256",
+ "Protect_Tags": "Tags",
+ "Protect_Analytic": "EventMessage",
+ "Protect_Event_Type": "EventType",
+ "TargetbinarySign": "TargetbinarySignerType",
+ "JamfPro_Status": "JamfPro",
+ "TargetBinarySignMsg": "TargetBinarySigningInfoMessage",
+ "TargetBinarySigner": "TargetBinarySigningTeamID"
+ },
+ "alertDetailsOverride": {
+ "alertDisplayNameFormat": "{{EventMessage}} detected on {{DvcHostname}}",
+ "alertDescriptionFormat": "{{EventDescription}} - Please investigate",
+ "alertDynamicProperties": [
+ {
+ "alertProperty": "AlertLink",
+ "value": "EventReportUrl"
+ },
+ {
+ "alertProperty": "ProviderName",
+ "value": "EventVendor"
+ },
+ {
+ "alertProperty": "ProductName",
+ "value": "EventProduct"
+ },
+ {
+ "alertProperty": "Techniques",
+ "value": "Techniques"
+ }
+ ],
+ "alertTacticsColumnName": "Tactics",
+ "alertSeverityColumnName": "EventSeverity"
+ },
+ "incidentConfiguration": {
+ "groupingConfiguration": {
+ "lookbackDuration": "PT5H",
+ "matchingMethod": "AllEntities",
+ "enabled": false,
+ "reopenClosedIncident": false
+ },
+ "createIncident": true
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Analytics Rule 1",
+ "parentId": "[variables('analyticRuleObject1').analyticRuleId1]",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Jamf Protect - Alerts",
+ "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtectNetworkThreats_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "NRT",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "Creates an incident based based on Jamf Protect's Network Threat Event Stream alerts.",
+ "displayName": "Jamf Protect - Network Threats",
+ "enabled": false,
+ "query": "JamfProtect\n| where EventProduct == \"Jamf Protect - Threat Events Stream\"\n and EventResult == \"Blocked\"\n and isnotempty(EventSeverity)\n| extend Tactics = \"Initial Access\"\n| extend Techniques = \"T1566\"\n",
+ "severity": "Informational",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "jamfprotect_CL"
+ ],
+ "connectorId": "JamfProtect"
+ }
+ ],
+ "tactics": [
+ "InitialAccess"
+ ],
+ "techniques": [
+ "T1133"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "Hostname",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DvcOs",
+ "identifier": "OSFamily"
+ }
+ ],
+ "entityType": "Host"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "DstIpAddr",
+ "identifier": "Address"
+ }
+ ],
+ "entityType": "IP"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "SrcUsermail",
+ "identifier": "AadUserId"
+ },
+ {
+ "columnName": "SrcUsername",
+ "identifier": "FullName"
+ }
+ ],
+ "entityType": "Account"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "DnsQueryName",
+ "identifier": "Url"
+ }
+ ],
+ "entityType": "URL"
+ }
+ ],
+ "eventGroupingSettings": {
+ "aggregationKind": "AlertPerResult"
+ },
+ "customDetails": {
+ "Category": "ThreatCategory"
+ },
+ "alertDetailsOverride": {
+ "alertDisplayNameFormat": "Network Threat detected on {{DvcHostname}}",
+ "alertDescriptionFormat": "A Network Threat has been {{EventResult}} on {{DvcHostname}}",
+ "alertDynamicProperties": [
+ {
+ "alertProperty": "AlertLink",
+ "value": "EventReportUrl"
+ },
+ {
+ "alertProperty": "ProviderName",
+ "value": "EventVendor"
+ },
+ {
+ "alertProperty": "ProductName",
+ "value": "EventProduct"
+ },
+ {
+ "alertProperty": "RemediationSteps",
+ "value": "EventResult"
+ },
+ {
+ "alertProperty": "Techniques",
+ "value": "Techniques"
+ }
+ ],
+ "alertTacticsColumnName": "Tactics",
+ "alertSeverityColumnName": "EventSeverity"
+ },
+ "incidentConfiguration": {
+ "groupingConfiguration": {
+ "lookbackDuration": "PT5H",
+ "matchingMethod": "AllEntities",
+ "enabled": false,
+ "reopenClosedIncident": false
+ },
+ "createIncident": true
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Analytics Rule 2",
+ "parentId": "[variables('analyticRuleObject2').analyticRuleId2]",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Jamf Protect - Network Threats",
+ "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtectUnifiedLogs_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "NRT",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "Creates an informational incident based on Jamf Protect Unified Log data in Microsoft Sentinel",
+ "displayName": "Jamf Protect - Unified Logs",
+ "enabled": false,
+ "query": "JamfProtect\n| where EventType == \"UnifiedLog\"\n| where isnotempty(EventSeverity)\n| extend Host_IPs = tostring(parse_json(DvcIpAddr)[0])\n",
+ "severity": "Informational",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "jamfprotect_CL"
+ ],
+ "connectorId": "JamfProtect"
+ }
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "DvcHostname",
+ "identifier": "HostName"
+ }
+ ],
+ "entityType": "Host"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "Host_IPs",
+ "identifier": "Address"
+ }
+ ],
+ "entityType": "IP"
+ }
+ ],
+ "eventGroupingSettings": {
+ "aggregationKind": "AlertPerResult"
+ },
+ "customDetails": {
+ "Tags": "Match_tags",
+ "Unified_Log": "EventDescription",
+ "Event_Process": "TargetProcessName",
+ "Protect_Event_Type": "EventType"
+ },
+ "alertDetailsOverride": {
+ "alertDisplayNameFormat": "{{EventDescription}} on {{DvcHostname}}",
+ "alertDescriptionFormat": "{{EventDescription}} has been captured in the unified logs",
+ "alertDynamicProperties": [
+ {
+ "alertProperty": "ProviderName",
+ "value": "EventVendor"
+ },
+ {
+ "alertProperty": "ProductName",
+ "value": "EventProduct"
+ }
+ ],
+ "alertSeverityColumnName": "EventSeverity"
+ },
+ "incidentConfiguration": {
+ "groupingConfiguration": {
+ "lookbackDuration": "PT5H",
+ "matchingMethod": "AllEntities",
+ "enabled": false,
+ "reopenClosedIncident": false
+ },
+ "createIncident": true
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Analytics Rule 3",
+ "parentId": "[variables('analyticRuleObject3').analyticRuleId3]",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Jamf Protect - Unified Logs",
+ "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject1').huntingQueryTemplateSpecName1]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_DazzleSpy_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_1",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - DazzleSpy",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"341bc86bc9b76ac69dca0a48a328fd37d74c96c2e37210304cfa66ccdbe72b27\", \n \"4c67717fdf1ba588c8be62b6137c92d344a7d4f46b24fa525e5eaa3de330b16c\", \n \"570cd76bf49cf52e0cb347a68bdcf0590b2eaece134e1b1eba7e8d66261bdbe6\", \n \"623f99cbe20af8b79cbfea7f485d47d3462d927153d24cac4745d7043c15619a\", \n \"8fae0d5860aa44b5c7260ef7a0b277bcddae8c02cea7d3a9c19f1a40388c223f\", \n \"9b71fad3280cf36501fe110e022845b29c1fb1343d5250769eada7c36bc45f70\", \n \"a63466d09c3a6a2596a98de36083b6d268f393a27f7b781e52eeb98ae055af97\", \n \"bbbfe62cf15006014e356885fbc7447e3fd37c3743e0522b1f8320ad5c3791c9\", \n \"cf5edcff4053e29cb236d3ed1fe06ca93ae6f64f26e25117d68ee130b9bc60c8\", \n \"d599d7814adbab0f1442f5a10074e00f3a776ce183ea924abcd6154f0d068bb4\", \n \"df5b588f555cccdf4bbf695158b10b5d3a5f463da7e36d26bdf8b7ba0f8ed144\", \n \"f9ad42a9bd9ade188e997845cae1b0587bf496a35c3bffacd20fefe07860a348\")\n or DstIpAddr in (\"103.255.44.56\",\n \"123.1.170.152\",\n \"207.148.102.208\",\n \"88.218.192.128\")\n or TargetFilePath contains \"/Library/LaunchAgents/softwareupdate.plist\"\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for alerts related to DazzleSpy activity, known to affect macOS devices via a MachO binary"
+ },
+ {
+ "name": "tactics",
+ "value": "ResourceDevelopment"
+ },
+ {
+ "name": "techniques",
+ "value": "T1587,T1587.001"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject1')._huntingQuerycontentId1),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 1",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject1')._huntingQuerycontentId1)]",
+ "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject1').huntingQueryVersion1]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - DazzleSpy",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject2').huntingQueryTemplateSpecName2]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_JokerSpy_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_2",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - JokerSpy",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"5fe1790667ee5085e73b054566d548eb4473c20cf962368dd53ba776e9642272\", \n \"39bbc16028fd46bf4ddad49c21439504d3f6f42cccbd30945a2d2fdb4ce393a4\", \n \"aa951c053baf011d08f3a60a10c1d09bbac32f332413db5b38b8737558a08dc1\", \n \"d895075057e491b34b0f8c0392b44e43ade425d19eaaacea6ef8c5c9bd3487d8\", \n \"951039bf66cdf436c240ef206ef7356b1f6c8fffc6cbe55286ec2792bf7fe16c\", \n \"452c832a17436f61ad5f32ee1c97db05575160105ed1dcd0d3c6db9fb5a9aea1\", \n \"6d3eff4e029db9d7b8dc076cfed5e2315fd54cb1ff9c6533954569f9e2397d4c\")\nor DnsQueryName contains \"git-hub.me\"\nor DnsQueryName contains \"app.influmarket.org\"\nor EventMatch contains \"jokerspy\"\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for alerts related to JokerSpy activity, Known to use various back doors to deploy spyware on victims' systems in order to perform reconnaissance and for command and control."
+ },
+ {
+ "name": "tactics",
+ "value": "Execution,Masquerading"
+ },
+ {
+ "name": "techniques",
+ "value": "T1059,T1036"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject2')._huntingQuerycontentId2),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 2",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject2')._huntingQuerycontentId2)]",
+ "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject2').huntingQueryVersion2]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - JokerSpy",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject3').huntingQueryTemplateSpecName3]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_KandyKorn_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_3",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - KandyKorn",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1\",\n \"51dd4efcf714e64b4ad472ea556bf1a017f40a193a647b9e28bf356979651077\")\n or DnsQueryName contains \"tp-globa.xyz\"\n or DstIpAddr in (\"192.119.64.43\", \"23.254.226.90\")\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for activity related to KandyKorn activity, known to affect macOS devices via a MachO binary"
+ },
+ {
+ "name": "tactics",
+ "value": "Exfiltration"
+ },
+ {
+ "name": "techniques",
+ "value": "T1020"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject3')._huntingQuerycontentId3),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 3",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject3')._huntingQuerycontentId3)]",
+ "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject3').huntingQueryVersion3]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - KandyKorn",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject4').huntingQueryTemplateSpecName4]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_PureLand_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_4",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - PureLand",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 has \"0b9a3b00302faf3297b60fff0714f2db87245a613dcd9849645bffa7c4a3df9b\"\n or DstIpAddr contains \"193.168.141.107\"\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for activity related to PureLand activity, known to affect macOS devices via a MachO binary"
+ },
+ {
+ "name": "tactics",
+ "value": "Exfiltration"
+ },
+ {
+ "name": "techniques",
+ "value": "T1020"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject4')._huntingQuerycontentId4),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 4",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject4')._huntingQuerycontentId4)]",
+ "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject4').huntingQueryVersion4]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - PureLand",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject5').huntingQueryTemplateSpecName5]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_RustBucket_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_5",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - RustBucket",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 in (\"e74e8cdf887ae2de25590c55cb52dad66f0135ad4a1df224155f772554ea970c\", \"ac08406818bbf4fe24ea04bfd72f747c89174bdb\", \"72167ec09d62cdfb04698c3f96a6131dceb24a9c\", \"fd1cef5abe3e0c275671916a1f3a566f13489416\")\n or DnsQueryName contains \"cloud.dnx.capital\"\n or DnsQueryName contains \"deck.31ventures.info\"\n or ((TargetBinarySigningAppID contains \"com.apple.pdfViewer\") and (TargetbinarySignerType != \"Apple\"))\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for activity related to RustBucket activity, known to affect macOS devices via a MachO binary"
+ },
+ {
+ "name": "tactics",
+ "value": "Exfiltration"
+ },
+ {
+ "name": "techniques",
+ "value": "T1020"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject5')._huntingQuerycontentId5),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 5",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject5')._huntingQuerycontentId5)]",
+ "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject5').huntingQueryVersion5]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - RustBucket",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject6').huntingQueryTemplateSpecName6]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_Turtle_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_6",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - Turtle",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 has \"a48af4a62358831fe5376aa52db1a3555b0c93c1665b242c0c1f49462f614c56\"\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for activity related to Turtle activity, known to affect macOS devices via a MachO binary"
+ },
+ {
+ "name": "tactics",
+ "value": "Exfiltration"
+ },
+ {
+ "name": "techniques",
+ "value": "T1020"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject6')._huntingQuerycontentId6),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 6",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject6')._huntingQuerycontentId6)]",
+ "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject6').huntingQueryVersion6]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - Turtle",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('huntingQueryObject7').huntingQueryTemplateSpecName7]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_macOS_AtomicStealer_HuntingQueries Hunting Query with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "Jamf_Protect_Hunting_Query_7",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "JamfProtect - macOS - AtomicStealer",
+ "category": "Hunting Queries",
+ "query": "JamfProtect\n| where TargetProcessSHA256 in (\n \"ce3c57e6c025911a916a61a716ff32f2699f3e3a84eb0ebbe892a5d4b8fb9c7a\", \n \"91cca8b573d9bfdbe2d7ff74ce31acee7a3a9f8e0034841af38d96a1d4ad02f4\", \n \"7668dcab16c2f16396dd0d3a580bca89a3675462c1e9f98e79d75d6e7e6c8c1f\")\nor TargetFileSHA256 has \"6b0bde56810f7c0295d57c41ffa746544a5370cedbe514e874cf2cd04582f4b0\"\nor DnsQueryName contains \"app-downloads.org\"\nor DnsQueryName contains \"trabingviews.com\"\nor DstIpAddr contains \"185.106.93.154\"\nor EventMatch contains \"atomicstealer\"\n",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": "Use this query to look for activity related to AtomicStealer activity, known to affect macOS devices via a MachO binary"
+ },
+ {
+ "name": "tactics",
+ "value": "Exfiltration"
+ },
+ {
+ "name": "techniques",
+ "value": "T1020"
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject7')._huntingQuerycontentId7),'/'))))]",
+ "properties": {
+ "description": "Jamf Protect Hunting Query 7",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('huntingQueryObject7')._huntingQuerycontentId7)]",
+ "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]",
+ "kind": "HuntingQuery",
+ "version": "[variables('huntingQueryObject7').huntingQueryVersion7]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]",
+ "contentKind": "HuntingQuery",
+ "displayName": "JamfProtect - macOS - AtomicStealer",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '1.0.0')))]",
+ "version": "1.0.0"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName1')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_Alert_Status_InProgress Playbook with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion1')]",
+ "parameters": {
+ "clientIdentifier": {
+ "type": "String",
+ "metadata": {
+ "description": "The Client ID for the Jamf Protect API Key"
+ }
+ },
+ "clientSecret": {
+ "type": "SecureString",
+ "metadata": {
+ "description": "The Client Secret for the Jamf Protect API Key"
+ }
+ },
+ "jamfProtect_URL": {
+ "defaultValue": "https://*.protect.jamfcloud.com",
+ "type": "String",
+ "metadata": {
+ "description": "Enter the Jamf Protect instance URL ex: {https://fakevalue.protect.jamfcloud.com}"
+ }
+ },
+ "PlaybookName": {
+ "type": "String",
+ "minLength": 1,
+ "defaultValue": "JamfProtect_Alert_Status_InProgress",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ }
+ },
+ "variables": {
+ "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
+ "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "_connection-1": "[[variables('connection-1')]",
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('AzureSentinelConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "kind": "V1",
+ "properties": {
+ "displayName": "[[variables('AzureSentinelConnectionName')]",
+ "parameterValueType": "Alternative",
+ "api": {
+ "id": "[[variables('_connection-1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2017-07-01",
+ "name": "[[parameters('playbookName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "$connections": {
+ "type": "Object"
+ },
+ "client_ID": {
+ "defaultValue": "[[parameters('clientIdentifier')]",
+ "type": "String"
+ },
+ "jamfProtectURL": {
+ "defaultValue": "[[parameters('jamfProtect_URL')]",
+ "type": "String"
+ },
+ "password": {
+ "defaultValue": "[[parameters('clientSecret')]",
+ "type": "SecureString"
+ }
+ },
+ "triggers": {
+ "Microsoft_Sentinel_incident": {
+ "type": "ApiConnectionWebhook",
+ "inputs": {
+ "body": {
+ "callback_url": "@{listCallbackUrl()}"
+ },
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['azuresentinel']['connectionId']"
+ }
+ },
+ "path": "/incident-creation"
+ }
+ }
+ },
+ "actions": {
+ "For_each": {
+ "foreach": "@triggerBody()?['object']?['properties']?['Alerts']",
+ "actions": {
+ "Add_comment_to_incident_(V3)": {
+ "runAfter": {
+ "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": [
+ "Succeeded"
+ ]
+ },
+ "type": "ApiConnection",
+ "inputs": {
+ "body": {
+ "incidentArmId": "@triggerBody()?['object']?['id']",
+ "message": "Jamf Protect Alert with URL @{outputs('Composing_Jamf_Protect_Alert_URL')} has been set to status In Progress
"
+ },
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['azuresentinel']['connectionId']"
+ }
+ },
+ "method": "post",
+ "path": "/Incidents/Comment"
+ }
+ },
+ "Composing_Jamf_Protect_Alert_URL": {
+ "type": "Compose",
+ "inputs": "@items('For_each')?['properties']?['alertLink']"
+ },
+ "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": {
+ "runAfter": {
+ "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "authentication": {
+ "type": "Raw",
+ "value": "@variables('accessToken')"
+ },
+ "body": {
+ "operationName": "updateAlert",
+ "query": "mutation updateAlert {\n updateAlerts(input: { uuids: [\"@{outputs('Removing_pre-fix_of_URL_and_keeping_Alert_UDID')}\"], status: InProgress })\n {\n items {\n uuid\n status\n }\n }\n}\n"
+ },
+ "method": "POST",
+ "uri": "@{parameters('jamfProtectURL')}/graphql"
+ }
+ },
+ "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": {
+ "runAfter": {
+ "Composing_Jamf_Protect_Alert_URL": [
+ "Succeeded"
+ ]
+ },
+ "type": "Compose",
+ "inputs": "@replace(outputs('Composing_Jamf_Protect_Alert_URL'), variables('jamfProtectAlertURL'), '')"
+ }
+ },
+ "runAfter": {
+ "Set_accessToken_as_variable": [
+ "Succeeded"
+ ]
+ },
+ "type": "Foreach"
+ },
+ "Generate_Access_Token": {
+ "runAfter": {
+ "set_jamfProtectAlertURL_as_variable": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "body": {
+ "client_id": "@{parameters('client_ID')}",
+ "password": "@{parameters('password')}"
+ },
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "method": "POST",
+ "uri": "@{parameters('jamfProtectURL')}/token"
+ },
+ "runtimeConfiguration": {
+ "secureData": {
+ "properties": [
+ "inputs"
+ ]
+ }
+ }
+ },
+ "Parse_JSON_Response_from_Access_Token": {
+ "runAfter": {
+ "Generate_Access_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Generate_Access_Token')",
+ "schema": {
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "expires_in": {
+ "type": "integer"
+ },
+ "token_type": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ },
+ "Set_accessToken_as_variable": {
+ "runAfter": {
+ "Parse_JSON_Response_from_Access_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "accessToken",
+ "type": "string",
+ "value": "@body('Parse_JSON_Response_from_Access_Token')?['access_token']"
+ }
+ ]
+ }
+ },
+ "set_jamfProtectAlertURL_as_variable": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "jamfProtectAlertURL",
+ "type": "string",
+ "value": "@{parameters('jamfProtectURL')}/Alerts/"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "parameters": {
+ "$connections": {
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]",
+ "connectionName": "[[variables('AzureSentinelConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "connectionProperties": {
+ "authentication": {
+ "type": "ManagedServiceIdentity"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId1')]",
+ "contentId": "[variables('_playbookContentId1')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "Jamf Protect - Set Alert to In Progress",
+ "description": "This Jamf Protect Playbook can be used manually or in a Automation Rule to change the state of the Alert in Jamf Protect itself, in an automated way you can mirror the state from a Microsoft Sentinel incident back to Jamf Protect.",
+ "mainSteps": [
+ "1. Fetches the AlertUDID from the Alert of Jamf Protect",
+ "2. Generates a Access Token to authenticate against the Jamf Protect GraphQL API",
+ "3. Changes the Alert status in Jamf Protect to In Progress"
+ ],
+ "prerequisites": [
+ "1. Generate API Client in Jamf Protect and take note of the CLientID and Password. [learn how](https://learn.jamf.com/bundle/jamf-protect-documentation/page/Jamf_Protect_API.html#ariaid-title3)",
+ "2. Use the ClientID and Password during the deployment of this Playbook"
+ ],
+ "lastUpdateTime": "2023-07-20T00:00:00Z",
+ "tags": [
+ "Utilities"
+ ],
+ "source": {
+ "type": "solution",
+ "name": "Jamf Protect"
+ },
+ "postDeployment": [
+ "** b. Configurations in Sentinel **",
+ "1. In Microsoft Sentinel Analytic Rules for Jamf Protect - Alerts should be configured to create an incident",
+ "2. Configure the Automation Rules to trigger this playbook once a incident is status is changed to Active"
+ ],
+ "releaseNotes": [
+ {
+ "version": "1.0.0",
+ "title": "Jamf Protect - Set Alert to In Progress",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ ]
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId1')]",
+ "contentKind": "Playbook",
+ "displayName": "JamfProtect_Alert_Status_InProgress",
+ "contentProductId": "[variables('_playbookcontentProductId1')]",
+ "id": "[variables('_playbookcontentProductId1')]",
+ "version": "[variables('playbookVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName2')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_Alert_Status_Resolved Playbook with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion2')]",
+ "parameters": {
+ "clientIdentifier": {
+ "type": "String",
+ "metadata": {
+ "description": "The Client ID for the Jamf Protect API Key"
+ }
+ },
+ "clientSecret": {
+ "type": "SecureString",
+ "metadata": {
+ "description": "The Client Secret for the Jamf Protect API Key"
+ }
+ },
+ "jamfProtect_URL": {
+ "defaultValue": "https://*.protect.jamfcloud.com",
+ "type": "String",
+ "metadata": {
+ "description": "Enter the Jamf Protect instance URL ex: {https://fakevalue.protect.jamfcloud.com}"
+ }
+ },
+ "PlaybookName": {
+ "type": "String",
+ "minLength": 1,
+ "defaultValue": "JamfProtect_Alert_Status_Resolved",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ }
+ },
+ "variables": {
+ "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
+ "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "_connection-1": "[[variables('connection-1')]",
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('AzureSentinelConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "kind": "V1",
+ "properties": {
+ "displayName": "[[variables('AzureSentinelConnectionName')]",
+ "parameterValueType": "Alternative",
+ "api": {
+ "id": "[[variables('_connection-1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2017-07-01",
+ "name": "[[parameters('playbookName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "$connections": {
+ "type": "Object"
+ },
+ "client_ID": {
+ "defaultValue": "[[parameters('clientIdentifier')]",
+ "type": "String"
+ },
+ "jamfProtectURL": {
+ "defaultValue": "[[parameters('jamfProtect_URL')]",
+ "type": "String"
+ },
+ "password": {
+ "defaultValue": "[[parameters('clientSecret')]",
+ "type": "SecureString"
+ }
+ },
+ "triggers": {
+ "Microsoft_Sentinel_incident": {
+ "type": "ApiConnectionWebhook",
+ "inputs": {
+ "body": {
+ "callback_url": "@{listCallbackUrl()}"
+ },
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['azuresentinel']['connectionId']"
+ }
+ },
+ "path": "/incident-creation"
+ }
+ }
+ },
+ "actions": {
+ "For_each": {
+ "foreach": "@triggerBody()?['object']?['properties']?['Alerts']",
+ "actions": {
+ "Add_comment_to_incident_(V3)": {
+ "runAfter": {
+ "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": [
+ "Succeeded"
+ ]
+ },
+ "type": "ApiConnection",
+ "inputs": {
+ "body": {
+ "incidentArmId": "@triggerBody()?['object']?['id']",
+ "message": "Jamf Protect Alert with URL @{outputs('Composing_Jamf_Protect_Alert_URL')} has been set to status Resolved
"
+ },
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['azuresentinel']['connectionId']"
+ }
+ },
+ "method": "post",
+ "path": "/Incidents/Comment"
+ }
+ },
+ "Composing_Jamf_Protect_Alert_URL": {
+ "type": "Compose",
+ "inputs": "@items('For_each')?['properties']?['alertLink']"
+ },
+ "HTTP_POST_-_Change_Alert_Status_using_Jamf_Protect's_GraphQL_API_Endpoint": {
+ "runAfter": {
+ "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "authentication": {
+ "type": "Raw",
+ "value": "@variables('accessToken')"
+ },
+ "body": {
+ "operationName": "updateAlert",
+ "query": "mutation updateAlert {\n updateAlerts(input: { uuids: [\"@{outputs('Removing_pre-fix_of_URL_and_keeping_Alert_UDID')}\"], status: Resolved })\n {\n items {\n uuid\n status\n }\n }\n}\n"
+ },
+ "method": "POST",
+ "uri": "@{parameters('jamfProtectURL')}/graphql"
+ }
+ },
+ "Removing_pre-fix_of_URL_and_keeping_Alert_UDID": {
+ "runAfter": {
+ "Composing_Jamf_Protect_Alert_URL": [
+ "Succeeded"
+ ]
+ },
+ "type": "Compose",
+ "inputs": "@replace(outputs('Composing_Jamf_Protect_Alert_URL'), variables('jamfProtectAlertURL'), '')"
+ }
+ },
+ "runAfter": {
+ "Set_accessToken_as_variable": [
+ "Succeeded"
+ ]
+ },
+ "type": "Foreach"
+ },
+ "Generate_Access_Token": {
+ "runAfter": {
+ "set_jamfProtectAlertURL_as_variable": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "body": {
+ "client_id": "@{parameters('client_ID')}",
+ "password": "@{parameters('password')}"
+ },
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "method": "POST",
+ "uri": "@{parameters('jamfProtectURL')}/token"
+ },
+ "runtimeConfiguration": {
+ "secureData": {
+ "properties": [
+ "inputs"
+ ]
+ }
+ }
+ },
+ "Parse_JSON_Response_from_Access_Token": {
+ "runAfter": {
+ "Generate_Access_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Generate_Access_Token')",
+ "schema": {
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "expires_in": {
+ "type": "integer"
+ },
+ "token_type": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ },
+ "Set_accessToken_as_variable": {
+ "runAfter": {
+ "Parse_JSON_Response_from_Access_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "accessToken",
+ "type": "string",
+ "value": "@body('Parse_JSON_Response_from_Access_Token')?['access_token']"
+ }
+ ]
+ }
+ },
+ "set_jamfProtectAlertURL_as_variable": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "jamfProtectAlertURL",
+ "type": "string",
+ "value": "@{parameters('jamfProtectURL')}/Alerts/"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "parameters": {
+ "$connections": {
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]",
+ "connectionName": "[[variables('AzureSentinelConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "connectionProperties": {
+ "authentication": {
+ "type": "ManagedServiceIdentity"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId2')]",
+ "contentId": "[variables('_playbookContentId2')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion2')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "Jamf Protect - Set Alert to Resolved",
+ "description": "This Jamf Protect Playbook can be used manually or in a Automation Rule to change the state of the Alert in Jamf Protect itself, in an automated way you can mirror the state from a Microsoft Sentinel incident back to Jamf Protect.",
+ "mainSteps": [
+ "1. Fetches the AlertUDID from the Alert of Jamf Protect",
+ "2. Generates a Access Token to authenticate against the Jamf Protect GraphQL API",
+ "3. Changes the Alert status in Jamf Protect to Resolved"
+ ],
+ "prerequisites": [
+ "1. Generate API Client in Jamf Protect and take note of the CLientID and Password. [learn how](https://learn.jamf.com/bundle/jamf-protect-documentation/page/Jamf_Protect_API.html#ariaid-title3)",
+ "2. Use the ClientID and Password during the deployment of this Playbook"
+ ],
+ "lastUpdateTime": "2023-07-20T00:00:00Z",
+ "tags": [
+ "Utilities"
+ ],
+ "source": {
+ "type": "solution",
+ "name": "Jamf Protect"
+ },
+ "postDeployment": [
+ "** b. Configurations in Sentinel **",
+ "1. In Microsoft Sentinel Analytic Rules for Jamf Protect - Alerts should be configured to create an incident",
+ "2. Configure the Automation Rules to trigger this playbook once a incident is status is changed to Active"
+ ],
+ "releaseNotes": [
+ {
+ "version": "1.0.0",
+ "title": "Jamf Protect - Set Alert to Resolved",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ ]
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId2')]",
+ "contentKind": "Playbook",
+ "displayName": "JamfProtect_Alert_Status_Resolved",
+ "contentProductId": "[variables('_playbookcontentProductId2')]",
+ "id": "[variables('_playbookcontentProductId2')]",
+ "version": "[variables('playbookVersion2')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName3')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "JamfProtect_LockComputer_with_JamfPro Playbook with template version 3.2.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion3')]",
+ "parameters": {
+ "jamfProClientID": {
+ "type": "String",
+ "metadata": {
+ "description": "The ClientID for the Jamf Pro"
+ }
+ },
+ "jamfProSecret": {
+ "type": "SecureString",
+ "metadata": {
+ "description": "The secret for the ClientID of Jamf Pro"
+ }
+ },
+ "jamfProURL": {
+ "defaultValue": "https://*.jamfcloud.com",
+ "type": "String",
+ "metadata": {
+ "description": "Enter the Jamf Pro instance URL ex: {https://fakevalue.jamfcloud.com}"
+ }
+ },
+ "PlaybookName": {
+ "type": "String",
+ "minLength": 1,
+ "defaultValue": "JamfProtect_LockComputer_with_JamfPro",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ }
+ },
+ "variables": {
+ "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]",
+ "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "_connection-1": "[[variables('connection-1')]",
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('AzureSentinelConnectionName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "kind": "V1",
+ "properties": {
+ "displayName": "[[variables('AzureSentinelConnectionName')]",
+ "parameterValueType": "Alternative",
+ "api": {
+ "id": "[[variables('_connection-1')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2017-07-01",
+ "name": "[[parameters('playbookName')]",
+ "location": "[[variables('workspace-location-inline')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "$connections": {
+ "type": "Object"
+ },
+ "jamfProSecret": {
+ "defaultValue": "[[parameters('jamfProSecret')]",
+ "type": "SecureString"
+ },
+ "jamfProURL": {
+ "defaultValue": "[[parameters('jamfProURL')]",
+ "type": "String"
+ },
+ "jamfProClientID": {
+ "defaultValue": "[[parameters('jamfProClientID')]",
+ "type": "String"
+ }
+ },
+ "triggers": {
+ "Microsoft_Sentinel_incident": {
+ "type": "ApiConnectionWebhook",
+ "inputs": {
+ "body": {
+ "callback_url": "@{listCallbackUrl()}"
+ },
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['azuresentinel']['connectionId']"
+ }
+ },
+ "path": "/incident-creation"
+ }
+ }
+ },
+ "actions": {
+ "Filter_array_for_the_entity_kind_Host": {
+ "runAfter": {
+ "Parse_JSON_Entities_from_the_Incident": [
+ "Succeeded"
+ ]
+ },
+ "type": "Query",
+ "inputs": {
+ "from": "@body('Parse_JSON_Entities_from_the_Incident')",
+ "where": "@equals(item()['kind'], 'Host')"
+ }
+ },
+ "For_each_host_send_DeviceLock_command": {
+ "foreach": "@body('Filter_array_for_the_entity_kind_Host')",
+ "actions": {
+ "Add_comment_to_incident_(V3)": {
+ "runAfter": {
+ "Send_DeviceLock_command_to_given_computers_JSSID": [
+ "Succeeded"
+ ]
+ },
+ "type": "ApiConnection",
+ "inputs": {
+ "body": {
+ "incidentArmId": "@triggerBody()?['object']?['id']",
+ "message": "Device Lock command has been send to @{body('Parse_JSON_for_given_computer_based_on_managementID')?['general']?['name']} with passcode: @{outputs('Generate_a_randomised_6_digit_value')}
"
+ },
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['azuresentinel']['connectionId']"
+ }
+ },
+ "method": "post",
+ "path": "/Incidents/Comment"
+ }
+ },
+ "Generate_a_randomised_6_digit_value": {
+ "runAfter": {
+ "Parse_JSON_for_given_computer_based_on_managementID": [
+ "Succeeded",
+ "Failed"
+ ]
+ },
+ "type": "Compose",
+ "inputs": "@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}@{rand(0, 9)}"
+ },
+ "Get_JSSID_for_given_computer_in_Jamf_Pro": {
+ "type": "Http",
+ "inputs": {
+ "headers": {
+ "Authorization": "Bearer @{variables('accessToken')}",
+ "accept": "application/json"
+ },
+ "method": "GET",
+ "uri": "@{parameters('jamfProURL')}/JSSResource/computers/name/@{items('For_each_host_send_DeviceLock_command')?['properties']?['friendlyName']}"
+ }
+ },
+ "Get_managementID_for_given_computer_in_Jamf_Pro": {
+ "runAfter": {
+ "Parse_JSON_response_for_given_computer": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "headers": {
+ "Authorization": "Bearer @{variables('accessToken')}",
+ "accept": "application/json"
+ },
+ "method": "GET",
+ "uri": "@{parameters('jamfProURL')}/api/v1/computers-inventory/@{body('Parse_JSON_response_for_given_computer')?['computer']?['general']?['id']}?section=GENERAL"
+ }
+ },
+ "Parse_JSON_for_given_computer_based_on_managementID": {
+ "runAfter": {
+ "Get_managementID_for_given_computer_in_Jamf_Pro": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Get_managementID_for_given_computer_in_Jamf_Pro')",
+ "schema": {
+ "properties": {
+ "general": {
+ "properties": {
+ "declarativeDeviceManagementEnabled": {
+ "type": "boolean"
+ },
+ "enrolledViaAutomatedDeviceEnrollment": {
+ "type": "boolean"
+ },
+ "initialEntryDate": {
+ "type": "string"
+ },
+ "itunesStoreAccountActive": {
+ "type": "boolean"
+ },
+ "jamfBinaryVersion": {
+ "type": "string"
+ },
+ "lastContactTime": {
+ "type": "string"
+ },
+ "lastEnrolledDate": {
+ "type": "string"
+ },
+ "lastIpAddress": {
+ "type": "string"
+ },
+ "lastReportedIp": {
+ "type": "string"
+ },
+ "managementId": {
+ "type": "string"
+ },
+ "mdmCapable": {
+ "properties": {
+ "capable": {
+ "type": "boolean"
+ },
+ "capableUsers": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "mdmProfileExpiration": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "platform": {
+ "type": "string"
+ },
+ "remoteManagement": {
+ "properties": {
+ "managed": {
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+ },
+ "reportDate": {
+ "type": "string"
+ },
+ "site": {
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "supervised": {
+ "type": "boolean"
+ },
+ "userApprovedMdm": {
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+ },
+ "id": {
+ "type": "string"
+ },
+ "udid": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ },
+ "Parse_JSON_response_for_given_computer": {
+ "runAfter": {
+ "Get_JSSID_for_given_computer_in_Jamf_Pro": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Get_JSSID_for_given_computer_in_Jamf_Pro')",
+ "schema": {
+ "properties": {
+ "computer": {
+ "properties": {
+ "certificates": {
+ "items": {
+ "properties": {
+ "common_name": {
+ "type": "string"
+ },
+ "expires_epoch": {
+ "type": "integer"
+ },
+ "expires_utc": {
+ "type": "string"
+ },
+ "identity": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "common_name",
+ "identity",
+ "expires_utc",
+ "expires_epoch",
+ "name"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "configuration_profiles": {
+ "items": {
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "is_removable": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "uuid": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "uuid",
+ "is_removable"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "extension_attributes": {
+ "items": {
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "multi_value": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "type",
+ "multi_value",
+ "value"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "general": {
+ "properties": {
+ "alt_mac_address": {
+ "type": "string"
+ },
+ "alt_network_adapter_type": {
+ "type": "string"
+ },
+ "asset_tag": {
+ "type": "string"
+ },
+ "barcode_1": {
+ "type": "string"
+ },
+ "barcode_2": {
+ "type": "string"
+ },
+ "distribution_point": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "initial_entry_date": {
+ "type": "string"
+ },
+ "initial_entry_date_epoch": {
+ "type": "integer"
+ },
+ "initial_entry_date_utc": {
+ "type": "string"
+ },
+ "ip_address": {
+ "type": "string"
+ },
+ "itunes_store_account_is_active": {
+ "type": "boolean"
+ },
+ "jamf_version": {
+ "type": "string"
+ },
+ "last_cloud_backup_date_epoch": {
+ "type": "integer"
+ },
+ "last_cloud_backup_date_utc": {
+ "type": "string"
+ },
+ "last_contact_time": {
+ "type": "string"
+ },
+ "last_contact_time_epoch": {
+ "type": "integer"
+ },
+ "last_contact_time_utc": {
+ "type": "string"
+ },
+ "last_enrolled_date_epoch": {
+ "type": "integer"
+ },
+ "last_enrolled_date_utc": {
+ "type": "string"
+ },
+ "last_reported_ip": {
+ "type": "string"
+ },
+ "mac_address": {
+ "type": "string"
+ },
+ "management_status": {
+ "properties": {
+ "enrolled_via_dep": {
+ "type": "boolean"
+ },
+ "user_approved_enrollment": {
+ "type": "boolean"
+ },
+ "user_approved_mdm": {
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+ },
+ "mdm_capable": {
+ "type": "boolean"
+ },
+ "mdm_capable_users": {
+ "properties": {
+ "mdm_capable_user": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "mdm_profile_expiration_epoch": {
+ "type": "integer"
+ },
+ "mdm_profile_expiration_utc": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "network_adapter_type": {
+ "type": "string"
+ },
+ "platform": {
+ "type": "string"
+ },
+ "remote_management": {
+ "properties": {
+ "managed": {
+ "type": "boolean"
+ },
+ "management_password_sha256": {
+ "type": "string"
+ },
+ "management_username": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "report_date": {
+ "type": "string"
+ },
+ "report_date_epoch": {
+ "type": "integer"
+ },
+ "report_date_utc": {
+ "type": "string"
+ },
+ "serial_number": {
+ "type": "string"
+ },
+ "site": {
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "supervised": {
+ "type": "boolean"
+ },
+ "sus": {
+ "type": "string"
+ },
+ "udid": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "groups_accounts": {
+ "properties": {
+ "computer_group_memberships": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "local_accounts": {
+ "items": {
+ "properties": {
+ "administrator": {
+ "type": "boolean"
+ },
+ "filevault_enabled": {
+ "type": "boolean"
+ },
+ "home": {
+ "type": "string"
+ },
+ "home_size": {
+ "type": "string"
+ },
+ "home_size_mb": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "realname": {
+ "type": "string"
+ },
+ "uid": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "realname",
+ "uid",
+ "home",
+ "home_size",
+ "home_size_mb",
+ "administrator",
+ "filevault_enabled"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "user_inventories": {
+ "properties": {
+ "disable_automatic_login": {
+ "type": "boolean"
+ },
+ "user": {
+ "properties": {
+ "password_history_depth": {
+ "type": "string"
+ },
+ "password_max_age": {
+ "type": "string"
+ },
+ "password_min_complex_characters": {
+ "type": "string"
+ },
+ "password_min_length": {
+ "type": "string"
+ },
+ "password_require_alphanumeric": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "hardware": {
+ "properties": {
+ "active_directory_status": {
+ "type": "string"
+ },
+ "available_ram_slots": {
+ "type": "integer"
+ },
+ "battery_capacity": {
+ "type": "integer"
+ },
+ "ble_capable": {
+ "type": "boolean"
+ },
+ "boot_rom": {
+ "type": "string"
+ },
+ "bus_speed": {
+ "type": "integer"
+ },
+ "bus_speed_mhz": {
+ "type": "integer"
+ },
+ "cache_size": {
+ "type": "integer"
+ },
+ "cache_size_kb": {
+ "type": "integer"
+ },
+ "disk_encryption_configuration": {
+ "type": "string"
+ },
+ "filevault2_users": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "gatekeeper_status": {
+ "type": "string"
+ },
+ "institutional_recovery_key": {
+ "type": "string"
+ },
+ "is_apple_silicon": {
+ "type": "boolean"
+ },
+ "make": {
+ "type": "string"
+ },
+ "mapped_printers": {
+ "type": "array"
+ },
+ "model": {
+ "type": "string"
+ },
+ "model_identifier": {
+ "type": "string"
+ },
+ "nic_speed": {
+ "type": "string"
+ },
+ "number_cores": {
+ "type": "integer"
+ },
+ "number_processors": {
+ "type": "integer"
+ },
+ "optical_drive": {
+ "type": "string"
+ },
+ "os_build": {
+ "type": "string"
+ },
+ "os_name": {
+ "type": "string"
+ },
+ "os_version": {
+ "type": "string"
+ },
+ "processor_architecture": {
+ "type": "string"
+ },
+ "processor_speed": {
+ "type": "integer"
+ },
+ "processor_speed_mhz": {
+ "type": "integer"
+ },
+ "processor_type": {
+ "type": "string"
+ },
+ "service_pack": {
+ "type": "string"
+ },
+ "sip_status": {
+ "type": "string"
+ },
+ "smc_version": {
+ "type": "string"
+ },
+ "software_update_device_id": {
+ "type": "string"
+ },
+ "storage": {
+ "type": "array"
+ },
+ "supports_ios_app_installs": {
+ "type": "boolean"
+ },
+ "total_ram": {
+ "type": "integer"
+ },
+ "total_ram_mb": {
+ "type": "integer"
+ },
+ "xprotect_version": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "iphones": {
+ "type": "array"
+ },
+ "location": {
+ "properties": {
+ "building": {
+ "type": "string"
+ },
+ "department": {
+ "type": "string"
+ },
+ "email_address": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "phone_number": {
+ "type": "string"
+ },
+ "position": {
+ "type": "string"
+ },
+ "real_name": {
+ "type": "string"
+ },
+ "realname": {
+ "type": "string"
+ },
+ "room": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "peripherals": {
+ "type": "array"
+ },
+ "purchasing": {
+ "properties": {
+ "applecare_id": {
+ "type": "string"
+ },
+ "attachments": {
+ "type": "array"
+ },
+ "is_leased": {
+ "type": "boolean"
+ },
+ "is_purchased": {
+ "type": "boolean"
+ },
+ "lease_expires": {
+ "type": "string"
+ },
+ "lease_expires_epoch": {
+ "type": "integer"
+ },
+ "lease_expires_utc": {
+ "type": "string"
+ },
+ "life_expectancy": {
+ "type": "integer"
+ },
+ "os_applecare_id": {
+ "type": "string"
+ },
+ "os_maintenance_expires": {
+ "type": "string"
+ },
+ "po_date": {
+ "type": "string"
+ },
+ "po_date_epoch": {
+ "type": "integer"
+ },
+ "po_date_utc": {
+ "type": "string"
+ },
+ "po_number": {
+ "type": "string"
+ },
+ "purchase_price": {
+ "type": "string"
+ },
+ "purchasing_account": {
+ "type": "string"
+ },
+ "purchasing_contact": {
+ "type": "string"
+ },
+ "vendor": {
+ "type": "string"
+ },
+ "warranty_expires": {
+ "type": "string"
+ },
+ "warranty_expires_epoch": {
+ "type": "integer"
+ },
+ "warranty_expires_utc": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "security": {
+ "properties": {
+ "activation_lock": {
+ "type": "boolean"
+ },
+ "external_boot_level": {
+ "type": "string"
+ },
+ "firewall_enabled": {
+ "type": "boolean"
+ },
+ "recovery_lock_enabled": {
+ "type": "boolean"
+ },
+ "secure_boot_level": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "software": {
+ "properties": {
+ "applications": {
+ "items": {
+ "properties": {
+ "bundle_id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "path",
+ "version",
+ "bundle_id"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "available_software_updates": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "available_updates": {
+ "properties": {
+ "update": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "package_name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "cached_by_casper": {
+ "type": "array"
+ },
+ "fonts": {
+ "type": "array"
+ },
+ "installed_by_casper": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "installed_by_installer_swu": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "licensed_software": {
+ "type": "array"
+ },
+ "plugins": {
+ "type": "array"
+ },
+ "running_services": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "unix_executables": {
+ "type": "array"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ }
+ }
+ },
+ "Send_DeviceLock_command_to_given_computers_JSSID": {
+ "runAfter": {
+ "Generate_a_randomised_6_digit_value": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "headers": {
+ "Authorization": "Bearer @{variables('accessToken')}",
+ "accept": "application/json"
+ },
+ "method": "POST",
+ "uri": "@{parameters('jamfProURL')}/JSSResource/computercommands/command/DeviceLock/passcode/@{outputs('Generate_a_randomised_6_digit_value')}/id/@{body('Parse_JSON_for_given_computer_based_on_managementID')?['general']?['site']?['id']}"
+ }
+ }
+ },
+ "runAfter": {
+ "Filter_array_for_the_entity_kind_Host": [
+ "Succeeded"
+ ]
+ },
+ "type": "Foreach"
+ },
+ "Generate_Access_Token_using_API_Client": {
+ "type": "Http",
+ "inputs": {
+ "body": "client_id=@{parameters('jamfProClientID')}&client_secret=@{parameters('jamfProSecret')}&grant_type=client_credentials",
+ "headers": {
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ "method": "POST",
+ "uri": "@{parameters('jamfProURL')}/api/oauth/token"
+ },
+ "runtimeConfiguration": {
+ "secureData": {
+ "properties": [
+ "inputs"
+ ]
+ }
+ }
+ },
+ "Parse_JSON_Entities_from_the_Incident": {
+ "runAfter": {
+ "Set_accessToken_as_variable": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@triggerBody()?['object']?['properties']?['relatedEntities']",
+ "schema": {
+ "items": {
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "properties": {
+ "properties": {
+ "address": {
+ "type": "string"
+ },
+ "friendlyName": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "type": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "type",
+ "kind",
+ "properties"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ }
+ }
+ },
+ "Parse_JSON_Response_from_Access_Token": {
+ "runAfter": {
+ "Generate_Access_Token_using_API_Client": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Generate_Access_Token_using_API_Client')",
+ "schema": {
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "expires_in": {
+ "type": "integer"
+ },
+ "scope": {
+ "type": "string"
+ },
+ "token_type": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ },
+ "Set_accessToken_as_variable": {
+ "runAfter": {
+ "Parse_JSON_Response_from_Access_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "accessToken",
+ "type": "string",
+ "value": "@body('Parse_JSON_Response_from_Access_Token')?['access_token']"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "parameters": {
+ "$connections": {
+ "value": {
+ "azuresentinel": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]",
+ "connectionName": "[[variables('AzureSentinelConnectionName')]",
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]",
+ "connectionProperties": {
+ "authentication": {
+ "type": "ManagedServiceIdentity"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId3')]",
+ "contentId": "[variables('_playbookContentId3')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion3')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "Jamf Protect - Remote lock computer with Jamf Pro",
+ "description": "This Playbook can be used manually or in a Automation Rule to send an remote MDM command with Jamf Pro to lock the computer with an randomised 6 digit passcode.",
+ "mainSteps": [
+ "1. Fetches the Host entity from the Incident created based on event data from Jamf Protect",
+ "2. Generates a Access Token using a API Client to authenticate against the Jamf Pro API",
+ "3. Retrieves the JSSID and ManagementUUID from Jamf Pro for given computer",
+ "4. Sends a remote lock MDM command with a randomised 6 digit passcode",
+ "5. Randomised passcode will be stored in the Comments section of the incident itself."
+ ],
+ "prerequisites": [
+ "1. Create an API Client in Jamf Pro that is capable of reading computers and sending remote commands. [learn how](https://learn.jamf.com/bundle/jamf-pro-documentation-current)",
+ "2. Use the Client ID and Secret during the deployment of this Playbook"
+ ],
+ "lastUpdateTime": "2023-07-20T00:00:00Z",
+ "tags": [
+ "Utilities"
+ ],
+ "source": {
+ "type": "solution",
+ "name": "Jamf Protect"
+ },
+ "postDeployment": [
+ "** b. Configurations in Sentinel **",
+ "1. This Playbook can be best used as Action while investigating an Incident."
+ ],
+ "releaseNotes": [
+ {
+ "version": "1.0.0",
+ "title": "Jamf Protect - Remote lock computer with Jamf Pro",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ ]
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId3')]",
+ "contentKind": "Playbook",
+ "displayName": "JamfProtect_LockComputer_with_JamfPro",
+ "contentProductId": "[variables('_playbookcontentProductId3')]",
+ "id": "[variables('_playbookcontentProductId3')]",
+ "version": "[variables('playbookVersion3')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
+ "apiVersion": "2023-04-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "version": "3.2.0",
+ "kind": "Solution",
+ "contentSchemaVersion": "3.0.0",
+ "displayName": "Jamf Protect",
+ "publisherDisplayName": "Jamf Software, LLC",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Jamf Protect solution for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.
\nData Connectors: 2, Parsers: 1, Workbooks: 1, Analytic Rules: 3, Hunting Queries: 7, Playbooks: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "contentKind": "Solution",
+ "contentProductId": "[variables('_solutioncontentProductId')]",
+ "id": "[variables('_solutioncontentProductId')]",
+ "icon": "
",
+ "contentId": "[variables('_solutionId')]",
+ "parentId": "[variables('_solutionId')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Jamf Protect",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Thijs Xhaflaire",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Jamf Software, LLC",
+ "email": "support@jamf.com",
+ "tier": "Partner",
+ "link": "https://www.jamf.com/support/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "kind": "DataConnector",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "version": "[variables('dataConnectorVersion1')]"
+ },
+ {
+ "kind": "DataConnector",
+ "contentId": "[variables('_dataConnectorContentIdConnections2')]",
+ "version": "[variables('dataConnectorCCPVersion')]"
+ },
+ {
+ "kind": "Parser",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "version": "[variables('parserObject1').parserVersion1]"
+ },
+ {
+ "kind": "Workbook",
+ "contentId": "[variables('_workbookContentId1')]",
+ "version": "[variables('workbookVersion1')]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
+ "version": "[variables('huntingQueryObject1').huntingQueryVersion1]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
+ "version": "[variables('huntingQueryObject2').huntingQueryVersion2]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
+ "version": "[variables('huntingQueryObject3').huntingQueryVersion3]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
+ "version": "[variables('huntingQueryObject4').huntingQueryVersion4]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject5')._huntingQuerycontentId5]",
+ "version": "[variables('huntingQueryObject5').huntingQueryVersion5]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject6')._huntingQuerycontentId6]",
+ "version": "[variables('huntingQueryObject6').huntingQueryVersion6]"
+ },
+ {
+ "kind": "HuntingQuery",
+ "contentId": "[variables('huntingQueryObject7')._huntingQuerycontentId7]",
+ "version": "[variables('huntingQueryObject7').huntingQueryVersion7]"
+ },
+ {
+ "kind": "Playbook",
+ "contentId": "[variables('_JamfProtect_Alert_Status_InProgress')]",
+ "version": "[variables('playbookVersion1')]"
+ },
+ {
+ "kind": "Playbook",
+ "contentId": "[variables('_JamfProtect_Alert_Status_Resolved')]",
+ "version": "[variables('playbookVersion2')]"
+ },
+ {
+ "kind": "Playbook",
+ "contentId": "[variables('_JamfProtect_LockComputer_with_JamfPro')]",
+ "version": "[variables('playbookVersion3')]"
+ }
+ ]
+ },
+ "firstPublishDate": "2022-10-10",
+ "lastPublishDate": "2024-01-12",
+ "providers": [
+ "Jamf"
+ ],
+ "categories": {
+ "domains": [
+ "Security - Threat Protection",
+ "Security - Automation (SOAR)"
+ ]
+ }
+ },
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]"
+ }
+ ],
+ "outputs": {}
+}
diff --git a/Solutions/Jamf Protect/Package/testParameters.json b/Solutions/Jamf Protect/Package/testParameters.json
index 3f390a145a5..52529e16dab 100644
--- a/Solutions/Jamf Protect/Package/testParameters.json
+++ b/Solutions/Jamf Protect/Package/testParameters.json
@@ -21,6 +21,20 @@
"description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
}
},
+ "resourceGroupName": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().name]",
+ "metadata": {
+ "description": "resource group name where Microsoft Sentinel is setup"
+ }
+ },
+ "subscription": {
+ "type": "string",
+ "defaultValue": "[last(split(subscription().id, '/'))]",
+ "metadata": {
+ "description": "subscription id where Microsoft Sentinel is setup"
+ }
+ },
"workbook1-name": {
"type": "string",
"defaultValue": "Jamf Protect Workbook",
diff --git a/Solutions/Jamf Protect/Parsers/JamfProtect.yaml b/Solutions/Jamf Protect/Parsers/JamfProtect.yaml
index 75d977b1529..5d4cef74efb 100644
--- a/Solutions/Jamf Protect/Parsers/JamfProtect.yaml
+++ b/Solutions/Jamf Protect/Parsers/JamfProtect.yaml
@@ -1,816 +1,852 @@
id: d941b837-88fa-4c77-a4d8-76af0044cac0
Function:
Title: Parser for JamfProtect
- Version: '3.1.0'
- LastUpdated: '2024-01-12'
+ Version: '3.2.0'
+ LastUpdated: '2025-01-06'
Category: Microsoft Sentinel Parser
FunctionName: JamfProtect
FunctionAlias: JamfProtect
FunctionQuery: |
- let JamfProtectAlerts_view = view () {
- jamfprotect_CL
- | where topicType_s == "alert"
- and input_eventType_s <> "GPUnifiedLogEvent"
- and isnotempty(input_match_severity_d)
- // JSON Parsing at earliest stage
- | extend
- Related_users = parse_json(input_related_users_s),
- Related_files = parse_json(input_related_files_s),
- Related_binaries = parse_json(input_related_binaries_s),
- Related_groups = parse_json(input_related_groups_s),
- Related_processes = parse_json(input_related_processes_s),
- Match_facts = parse_json(input_match_facts_s),
- Match_tags = parse_json(input_match_tags_s),
- Match_actions = parse_json(input_match_actions_s),
- Match_context = parse_json(input_match_context_s),
- Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)
- // ASIM - Common Fields
- | extend EventVendor = 'Jamf'
- | extend EventProduct = 'Jamf Protect - Alerts'
- | project-rename
- EventOriginalUid = input_match_uuid_g
- | extend
- // Jamf Protect - Common Fields
- EventType = case(
- input_eventType_s == "GPClickEvent",
- "Click",
- input_eventType_s == "GPDownloadEvent",
- "Download",
- input_eventType_s == "GPFSEvent",
- "FileSystem",
- input_eventType_s == "GPProcessEvent",
- "Process",
- input_eventType_s == "GPKeylogRegisterEvent",
- "Keylog",
- input_eventType_s == "GPGatekeeperEvent",
- "Gatekeeper",
- input_eventType_s == "GPMRTEvent",
- "MRT",
- input_eventType_s == "GPPreventedExecutionEvent",
- "ProcessDenied",
- input_eventType_s == "GPThreatMatchExecEvent",
- "ProcessPrevented",
- input_eventType_s == "GPUnifiedLogEvent",
- "UnifiedLog",
- input_eventType_s == "GPUSBEvent",
- "USB",
- input_eventType_s == "auth-mount",
- "UsbBlock",
- "Unknown"
- ),
- EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),
- EventMessage = coalesce(Match_facts[1].name, Match_facts[0].name),
- EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),
- EventResult = case(Match_actions has "Prevented", "Prevented", "Allowed"),
- EventProductVersion = column_ifexists("input_host_protectVersion_s", ""),
- //
- // Jamf Protect - Alert details
- //
- EventSeverity = case(input_match_severity_d == 0, "Informational", input_match_severity_d == 1, "Low", input_match_severity_d == 2, "Medium", input_match_severity_d == 3, "High", "Informational"),
- EventMatch = column_ifexists("input_match_event_matchValue_s", ""),
- EventMatchType = column_ifexists("input_match_event_matchType_s", ""),
- EventReportUrl = strcat("https://", context_identity_claims_hd_s, ".jamfcloud.com/Alerts/", EventOriginalUid),
- //
- // Jamf Protect - Source User
- SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),
- //
- // Jamf Protect - Source Device Hostnames
- //
- TargetHostname = column_ifexists("input_host_hostname_s", ""),
- DvcHostname = column_ifexists("input_host_hostname_s", ""),
- DvcIpAddr = column_ifexists("input_host_ips_s", ""),
- DvcId = column_ifexists("input_host_provisioningUDID_g", ""),
- DvcOs="macOS",
- SrcDeviceType="Computer",
- //
- // Jamf Protect Alerts - Process
- //
- ProcessEventType = case(input_match_event_type_d == 0, "None", input_match_event_type_d == 1, "Create", input_match_event_type_d == 2, "Exit", ""),
- ProcessEventSubType = case(input_match_event_subType_d == 7, "Exec", input_match_event_subType_d == 1, "Fork", input_match_event_subType_d == 23, "Execve", input_match_event_subType_d == 43190, "Posix Spawn", ""),
- ActingProcessName = tostring(Related_processes[array_length(Related_processes) - 1].path),
- ActingProcessCreationTime = format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[array_length(Related_processes) - 1].startTimestamp)), 'HH:mm:ss'),
- ActingProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].responsiblePID)),
- ActingProcessGuid = tostring(Related_processes[array_length(Related_processes) - 1].uuid),
- ParentProcessName = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].path), ""),
- ParentProcessCreationTime = iff(array_length(Related_processes) > 1, format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[1].startTimestamp)), 'HH:mm:ss'), ""),
- ParentProcessId = iff(array_length(Related_processes) > 1, toreal(Related_processes[1].pid), double(null)),
- ParentProcessGuid = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].uuid), ""),
- TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),
- TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),
- TargetProcessGuid = tostring(Related_processes[0].uuid),
- TargetProcessSHA1 = Related_binaries[0].sha1hex,
- TargetProcessSHA256 = Related_binaries[0].sha256hex,
- TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),
- TargetProcessCommandLine = column_ifexists("input_match_event_process_args_s", ""),
- TargetProcessCurrentDirectory = column_ifexists("input_match_event_process_path_s", ""),
- //TargetProcessStatusCode = column_ifexists(Related_processes[0].exitCode, ""),
- TargetUserId = toreal(coalesce(Related_users[1].uid, Related_processes[0].uid)),
- TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].uid)),
- //
- // Jamf Protect Alerts - Files
- //
- TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),
- TargetFileSHA1 = Related_files[0].sha1hex,
- TargetFileSHA256 = Related_files[0].sha256hex,
- TargetFileSize = Related_files[0].size,
- TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,
- TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, "Apple", Related_files[0].signingInfo.signerType == 1, "App Store", Related_files[0].signingInfo.signerType == 2, "Developer", Related_files[0].signingInfo.signerType == 3, "Ad Hoc", Related_files[0].signingInfo.signerType == 4, "Unsigned", ""),
- TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,
- TargetFileIsDownload = case(Related_files[0].isDownload == "true", "true", Related_files[0].isDownload == "false", "false", ""),
- TargetFileIsAppBundle = case(Related_files[0].isAppBundle == "true", "true", Related_files[0].isAppBundle == "false", "false", ""),
- TargetFileIsDirectory = case(Related_files[0].isDirectory == "true", "true", Related_files[0].isDirectory == "false", "false", ""),
- TargetFileIsScreenshot = case(Related_files[0].isScreenShot == "true", "true", Related_files[0].isScreenShot == "false", "false", ""),
- //
- // Jamf Protect Alerts - Binaries
- TargetBinaryFilePath = Related_binaries[0].path,
- TargetBinarySHA1 = tostring(Related_binaries[0].sha1hex),
- TargetBinarySHA256 = tostring(Related_binaries[0].sha256hex),
- TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,
- TargetbinarySignerType = case(Related_binaries[0].signingInfo.signerType == 0, "Apple", Related_binaries[0].signingInfo.signerType == 1, "App Store", Related_binaries[0].signingInfo.signerType == 2, "Developer", Related_binaries[0].signingInfo.signerType == 3, "Ad Hoc", Related_binaries[0].signingInfo.signerType == 4, "Unsigned", ""),
- TargetBinarySigningTeamID = tostring(Related_binaries[0].signingInfo.teamid),
- TargetBinarySigningAppID = tostring(Related_binaries[0].signingInfo.appid)
- | project-reorder
- TimeGenerated,
- EventStartTime,
- EventVendor,
- EventProduct,
- EventType,
- EventDescription,
- EventMessage,
- EventSeverity,
- EventMatch,
- EventMatchType,
- EventResult,
- EventProductVersion,
- EventReportUrl,
- TargetHostname,
- DvcHostname,
- DvcId,
- DvcOs,
- DvcIpAddr,
- SrcDeviceType,
- SrcUsername,
- ProcessEventType,
- ProcessEventSubType,
- ActingProcessName,
- ActingProcessCreationTime,
- ActingProcessId,
- ActingProcessGuid,
- ParentProcessName,
- ParentProcessCreationTime,
- ParentProcessId,
- ParentProcessGuid,
- TargetProcessName,
- TargetProcessId,
- TargetProcessGuid,
- TargetProcessSHA1,
- TargetProcessSHA256,
- TargetProcessCreationTime,
- TargetProcessCommandLine,
- TargetProcessCurrentDirectory,
- //TargetProcessStatusCode,
- TargetUsername,
- TargetUserId,
- TargetFilePath,
- TargetFileSHA1,
- TargetFileSHA256,
- TargetFileSize,
- TargetFileSigningInfoMessage,
- TargetFileSignerType,
- TargetFileSigningTeamID,
- TargetFileIsAppBundle,
- TargetFileIsDirectory,
- TargetFileIsDownload,
- TargetFileIsScreenshot,
- TargetBinaryFilePath,
- TargetBinarySHA1,
- TargetBinarySHA256,
- TargetBinarySigningInfoMessage,
- TargetbinarySignerType,
- TargetBinarySigningTeamID,
- TargetBinarySigningAppID,
- Related_users,
- Related_files,
- Related_binaries,
- Related_groups,
- Related_processes,
- Match_event_process_signing,
- Match_facts,
- Match_actions,
- Match_tags,
- *input_match_event_*
- | project-keep
- TimeGenerated,
- EventStartTime,
- EventVendor,
- EventProduct,
- EventType,
- EventDescription,
- EventMessage,
- EventProductVersion,
- EventSeverity,
- EventMatch,
- EventMatchType,
- EventResult,
- EventReportUrl,
- TargetHostname,
- DvcHostname,
- DvcId,
- DvcOs,
- DvcIpAddr,
- SrcDeviceType,
- SrcUsername,
- ProcessEventType,
- ProcessEventSubType,
- ActingProcessName,
- ActingProcessCreationTime,
- ActingProcessId,
- ActingProcessGuid,
- ParentProcessName,
- ParentProcessCreationTime,
- ParentProcessId,
- ParentProcessGuid,
- TargetProcessName,
- TargetProcessId,
- TargetProcessGuid,
- TargetProcessSHA1,
- TargetProcessSHA256,
- TargetProcessCreationTime,
- TargetProcessCommandLine,
- TargetProcessCurrentDirectory,
- //TargetProcessStatusCode,
- TargetUsername,
- TargetUserId,
- TargetFilePath,
- TargetFileSHA1,
- TargetFileSHA256,
- TargetFileSize,
- TargetFileSigningInfoMessage,
- TargetFileSignerType,
- TargetFileSigningTeamID,
- TargetFileIsAppBundle,
- TargetFileIsDirectory,
- TargetFileIsDownload,
- TargetFileIsScreenshot,
- TargetBinaryFilePath,
- TargetBinarySHA1,
- TargetBinarySHA256,
- TargetBinarySigningInfoMessage,
- TargetbinarySignerType,
- TargetBinarySigningTeamID,
- TargetBinarySigningAppID,
- Related_users,
- Related_files,
- Related_binaries,
- Related_groups,
- Related_processes,
- Match_event_process_signing,
- Match_facts,
- Match_actions,
- Match_tags,
- *input_match_event_*
- };
- //
- // Jamf Protect - Unified Logs
- //
- let JamfProtectUnifiedLog_view = view () {
- jamfprotect_CL
- | where input_eventType_s == "GPUnifiedLogEvent"
- and isnotempty(input_match_severity_d)
- // JSON Parsing at earliest stage
- | extend
- Related_users = parse_json(input_related_users_s),
- Related_files = parse_json(input_related_files_s),
- Related_binaries = parse_json(input_related_binaries_s),
- Related_groups = parse_json(input_related_groups_s),
- Related_processes = parse_json(input_related_processes_s),
- Match_facts = parse_json(input_match_facts_s),
- Match_tags = parse_json(input_match_tags_s),
- Match_actions = parse_json(input_match_actions_s),
- Match_context = parse_json(input_match_context_s),
- Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)
- // ASIM - Common Fields
- | extend EventVendor = 'Jamf'
- | extend EventProduct = 'Jamf Protect - Unified Log'
- | project-rename
- EventOriginalUid = input_match_uuid_g
- | extend
- // Jamf Protect - Common Fields
- EventType = case(
- input_eventType_s == "GPClickEvent",
- "Click",
- input_eventType_s == "GPDownloadEvent",
- "Download",
- input_eventType_s == "GPFSEvent",
- "FileSystem",
- input_eventType_s == "GPProcessEvent",
- "Process",
- input_eventType_s == "GPKeylogRegisterEvent",
- "Keylog",
- input_eventType_s == "GPGatekeeperEvent",
- "Gatekeeper",
- input_eventType_s == "GPMRTEvent",
- "MRT",
- input_eventType_s == "GPPreventedExecutionEvent",
- "ProcessDenied",
- input_eventType_s == "GPThreatMatchExecEvent",
- "ProcessPrevented",
- input_eventType_s == "GPUnifiedLogEvent",
- "UnifiedLog",
- input_eventType_s == "GPUSBEvent",
- "USB",
- input_eventType_s == "Auth-mount",
- "UsbBlock",
- "Unknown"
- ),
- EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),
- EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),
- EventResult = case(Match_actions has "Prevented", "Prevented", "Allowed"),
- //
- // Jamf Protect - Unified Logs details
- //
- EventSeverity = case(input_match_severity_d == 0, "Informational", input_match_severity_d == 1, "Low", input_match_severity_d == 2, "Medium", input_match_severity_d == 3, "High", "Informational"),
- EventMatch = column_ifexists("input_match_event_matchValue_s", ""),
- EventMatchType = column_ifexists("input_match_event_matchType_s", ""),
- EventReportUrl = strcat("https://", context_identity_claims_hd_s, ".jamfcloud.com/Alerts/", EventOriginalUid),
- //
- // Jamf Protect - Source User
- SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),
- //
- // Jamf Protect - Source Device Hostnames
- //
- TargetHostname = column_ifexists("input_host_hostname_s", ""),
- DvcHostname = column_ifexists("input_host_hostname_s", ""),
- DvcIpAddr = column_ifexists("input_host_ips_s", ""),
- DvcId = column_ifexists("input_host_provisioningUDID_g", ""),
- DvcOs="macOS",
- SrcDeviceType="Computer",
- //
- // Jamf Protect Unified Logs - Process
- //
- //ParentProcessName = coalesce(input_match_event_process_ppid_d, parse_json('input_related_processes_s')[0].ppid), //column_ifexists("exec_chain_child_parent_path_s", ""), coalesce('input.match.event.process.ppid', mvindex('input.related.processes{}.ppid', 0))
- ProcessEventType = case(input_match_event_type_d == 0, "None", input_match_event_type_d == 1, "Create", input_match_event_type_d == 2, "Exit", ""),
- ProcessEventSubType = case(input_match_event_subType_d == 7, "Exec", input_match_event_subType_d == 1, "Fork", input_match_event_subType_d == 23, "Execve", input_match_event_subType_d == 43190, "Posix Spawn", ""),
- ParentProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].ppid)),
- ParentProcessGuid = tostring(coalesce(input_match_event_process_pgid_d, toreal(Related_processes[0].pgid))),
- TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),
- TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),
- TargetProcessGuid = tostring(Related_processes[0].uuid),
- TargetProcessSHA1 = Related_binaries[0].sha1hex,
- TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),
- TargetProcessCommandLine = column_ifexists("input_match_event_process_args_s", ""),
- TargetProcessCurrentDirectory = column_ifexists("input_match_event_process_path_s", ""),
- TargetUserId = toreal(coalesce(Related_users[1].uid, Related_users[0].uid)),
- TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),
- //
- // Jamf Protect Unified Logs - Files
- //
- TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),
- TargetFileSHA1 = Related_files[0].sha1hex,
- TargetFileSHA256 = Related_files[0].sha256hex,
- TargetFileSize = Related_files[0].size,
- TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,
- TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, "Apple", Related_files[0].signingInfo.signerType == 1, "App Store", Related_files[0].signingInfo.signerType == 2, "Developer", Related_files[0].signingInfo.signerType == 3, "Ad Hoc", Related_files[0].signingInfo.signerType == 4, "Unsigned", ""),
- TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,
- TargetFileIsDownload = case(Related_files[0].isDownload == "true", "true", Related_files[0].isDownload == "false", "false", ""),
- TargetFileIsAppBundle = case(Related_files[0].isAppBundle == "true", "true", Related_files[0].isAppBundle == "false", "false", ""),
- TargetFileIsDirectory = case(Related_files[0].isDirectory == "true", "true", Related_files[0].isDirectory == "false", "false", ""),
- TargetFileIsScreenshot = case(Related_files[0].isScreenShot == "true", "true", Related_files[0].isScreenShot == "false", "false", "")
- | project-reorder
- TimeGenerated,
- EventStartTime,
- EventVendor,
- EventProduct,
- EventType,
- EventDescription,
- EventSeverity,
- EventMatch,
- EventMatchType,
- EventResult,
- EventReportUrl,
- TargetHostname,
- DvcHostname,
- DvcId,
- DvcOs,
- DvcIpAddr,
- SrcDeviceType,
- SrcUsername,
- ProcessEventType,
- ProcessEventSubType,
- ParentProcessId,
- ParentProcessGuid,
- TargetProcessName,
- TargetProcessId,
- TargetProcessGuid,
- TargetProcessSHA1,
- TargetProcessCreationTime,
- TargetProcessCommandLine,
- TargetProcessCurrentDirectory,
- TargetUsername,
- TargetUserId,
- TargetFilePath,
- TargetFileSHA1,
- TargetFileSHA256,
- TargetFileSize,
- TargetFileSigningInfoMessage,
- TargetFileSignerType,
- TargetFileSigningTeamID,
- TargetFileIsAppBundle,
- TargetFileIsDirectory,
- TargetFileIsDownload,
- TargetFileIsScreenshot,
- Related_users,
- Related_files,
- Related_binaries,
- Related_groups,
- Related_processes,
- Match_event_process_signing,
- Match_facts,
- Match_actions,
- Match_tags
- | project-keep
- TimeGenerated,
- EventStartTime,
- EventVendor,
- EventProduct,
- EventType,
- EventDescription,
- EventSeverity,
- EventMatch,
- EventMatchType,
- EventResult,
- EventReportUrl,
- TargetHostname,
- DvcHostname,
- DvcId,
- DvcOs,
- DvcIpAddr,
- SrcDeviceType,
- SrcUsername,
- ProcessEventType,
- ProcessEventSubType,
- ParentProcessId,
- ParentProcessGuid,
- TargetProcessName,
- TargetProcessId,
- TargetProcessGuid,
- TargetProcessSHA1,
- TargetProcessCreationTime,
- TargetProcessCommandLine,
- TargetProcessCurrentDirectory,
- TargetUsername,
- TargetUserId,
- TargetFilePath,
- TargetFileSHA1,
- TargetFileSHA256,
- TargetFileSize,
- TargetFileSigningInfoMessage,
- TargetFileSignerType,
- TargetFileSigningTeamID,
- TargetFileIsAppBundle,
- TargetFileIsDirectory,
- TargetFileIsDownload,
- TargetFileIsScreenshot,
- Related_users,
- Related_files,
- Related_binaries,
- Related_groups,
- Related_processes,
- Match_event_process_signing,
- Match_facts,
- Match_actions,
- Match_tags,
- *input_match_event*
- };
- //
- // Jamf Protect - Network Traffic
- //
- let JamfProtectNetworkTraffic_view = view () {
- jamfprotect_CL
- | where event_metadata_product_s == "Network Traffic Stream"
- // ASIM - Common Fields
- | extend EventVendor = 'Jamf'
- | extend EventProduct = 'Jamf Protect - Network Traffic Stream'
- | project-rename
- | extend
- // Jamf Protect - Common Fields
- EventType = "query",
- EventSubType = "request",
- EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),
- EventResult = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Prevented", ''),
- // Jamf Protect - Source User
- SrcUsermail=column_ifexists('event_user_email_s', ''),
- SrcUsername = column_ifexists('event_user_name_s', ''),
- // Jamf Protect - Source Device Hostnames
- DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),
- DvcIpAddr = column_ifexists("event_source_ip_s", ""),
- DvcId = column_ifexists("event_device_externalId_g", ""),
- DvcOs = case(event_device_osType_s == "MAC_OS", "macOS", event_device_osType_s == "IOS", "iOS", event_device_osType_s == "ANDROID", "Android", "Other"),
- SrcDeviceType = case(event_device_osType_s == "MAC_OS", "Computer", event_device_osType_s == "IOS", "Mobile Device", event_device_osType_s == "ANDROID", "Mobile Device", "Other"),
- // Jamf Protect - DNS Specific
- DnsQuery = column_ifexists('event_hostName_s', ''),
- DvcAction = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''),
- DnsQueryName = column_ifexists('event_domain_s', ''),
- DstIpAddr = column_ifexists('event_destination_ips_s', ''),
- ThreatCategory = column_ifexists('event_eventType_description_s', ''),
- DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),
- DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),
- ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')
- | project-keep
- TimeGenerated,
- EventVendor,
- EventProduct,
- EventType,
- EventSubType,
- EventStartTime,
- EventResult,
- DvcHostname,
- DvcIpAddr,
- DvcId,
- DvcOs,
- SrcDeviceType,
- SrcUsermail,
- SrcUsername,
- DnsQuery,
- DnsQueryName,
- DstIpAddr,
- DnsQueryTypeName,
- DvcAction,
- DnsResponseName,
- ThreatOriginalRiskLevel
- };
- //
- // Jamf Protect - Endpoint Telemetry
- //
- let JamfProtectTelemetry_view = view () {
- jamfprotect_CL
- | where header_event_name_s startswith "AUE_"
- or header_event_name_s == "PLAINTEXT_LOG_COLLECTION_EVENT"
- or header_event_name_s == "SYSTEM_PERFORMANCE_METRICS"
- // ASIM - Common Fields
- | extend EventVendor = 'Jamf'
- | extend EventProduct = 'Jamf Protect - Telemetry'
- // Data Field Normalization
- //| project-rename
- // DvcIpAddr = input_host_ips_s,
- // DvcId = context_identity_claims_clientid_g
- | extend
- // Jamf Protect Alerts - Generic Information
- EventSeverity = case(
- input_match_severity_d == 0,
- "Informational",
- input_match_severity_d == 1,
- "Low",
- input_match_severity_d == 2,
- "Medium",
- input_match_severity_d == 3,
- "High",
- "Informational"
- ),
- EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),
- EventResult = coalesce(return_description_s, texts_s),
- // Jamf Protect Telemetry - Endpoint Information
- TargetModel = column_ifexists("metrics_hw_model_s", ""),
- DvcOsVersion = column_ifexists("host_info_osversion_s", ""),
- TargetHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),
- DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),
- DvcIpAddr = column_ifexists("input_host_ips_s", ""),
- DvcId = column_ifexists("context_identity_claims_clientid_g", ""),
- // Jamf Protect - Event Types
- EventType = case(
- header_event_name_s == "AUE_add_to_group",
- "UserAddedToGroup",
- header_event_name_s == "AUE_AUDITCTL",
- "AuditEvent",
- header_event_name_s == "AUE_AUDITON_SPOLICY",
- "AuditEvent",
- header_event_name_s == "AUE_auth_user",
- "Elevate",
- header_event_name_s == "AUE_BIND",
- "EndpointNetworkSession",
- header_event_name_s == "AUE_BIOS_FIRMWARE_VERSIONS",
- "SystemInformation",
- header_event_name_s == "AUE_CHDIR",
- "FolderMoved",
- header_event_name_s == "AUE_CHROOT",
- "FolderModified",
- header_event_name_s == "AUE_CONNECT",
- "EndpointNetworkSession",
- header_event_name_s == "AUE_create_group",
- "GroupCreated",
- header_event_name_s == "AUE_create_user",
- "UserCreated",
- header_event_name_s == "AUE_delete_group",
- "GroupDeleted",
- header_event_name_s == "AUE_delete_user",
- "UserDeleted",
- header_event_name_s == "AUE_EXECVE",
- "ProcessCreated",
- header_event_name_s == "AUE_EXIT",
- "ProcessTerminated",
- header_event_name_s == "AUE_FORK",
- "ProcessCreated",
- header_event_name_s == "AUE_GETAUID",
- "",
- header_event_name_s == "AUE_KILL",
- "ProcessTerminated",
- header_event_name_s == "AUE_LISTEN",
- "EndpointNetworkSession",
- header_event_name_s == "AUE_logout",
- "Logoff",
- header_event_name_s == "AUE_lw_login",
- "Logon",
- header_event_name_s == "AUE_MAC_SET_PROC",
- "AuditEvent",
- header_event_name_s == "AUE_modify_group",
- "GroupModified",
- header_event_name_s == "AUE_modify_password",
- "PasswordChanged",
- header_event_name_s == "AUE_modify_user",
- "UserModified",
- header_event_name_s == "AUE_MOUNT",
- "VolumeMount",
- header_event_name_s == "AUE_openssh",
- "SshInitiated",
- header_event_name_s == "AUE_PIDFORTASK",
- "ProcessCreated",
- header_event_name_s == "AUE_POSIX_SPAWN",
- "ProcessCreated",
- header_event_name_s == "AUE_remove_from_group",
- "UserRemovedFromGroup",
- header_event_name_s == "AUE_SESSION_CLOSE",
- "Logoff",
- header_event_name_s == "AUE_SESSION_END",
- "Logoff",
- header_event_name_s == "AUE_SESSION_START",
- "Logon",
- header_event_name_s == "AUE_SESSION_UPDATE",
- "",
- header_event_name_s == "AUE_SETPRIORITY",
- "",
- header_event_name_s == "AUE_SETSOCKOPT",
- "",
- header_event_name_s == "AUE_SETTIMEOFDAY",
- "SystemChange",
- header_event_name_s == "AUE_shutdown",
- "ShutdownInitiated",
- header_event_name_s == "AUE_SOCKETPAIR",
- "",
- header_event_name_s == "AUE_ssauthint",
- "Elevate",
- header_event_name_s == "AUE_ssauthmech",
- "Elevate",
- header_event_name_s == "AUE_ssauthorize",
- "Elevate",
- header_event_name_s == "AUE_TASKFORPID",
- "",
- header_event_name_s == "AUE_TASKNAMEFORPID",
- "",
- header_event_name_s == "AUE_UNMOUNT",
- "VolumeUnmount",
- header_event_name_s == "AUE_WAIT4",
- "ProcessTerminated",
- header_event_name_s == "PLAINTEXT_LOG_COLLECTION_EVENT",
- "LogFileCollected",
- header_event_name_s == "SYSTEM_PERFORMANCE_METRICS",
- "SystemPerformanceMetrics",
- "Unknown"
- ),
- // Jamf Protect Telemetry - Process
- ParentProcessName = column_ifexists("subject_responsible_process_name_s", ""),
- ParentProcessId = column_ifexists("subject_responsible_process_id_d", ""),
- ParentProcessGuid = column_ifexists("exec_chain_child_parent_uuid_g", ""),
- TargetProcessName = column_ifexists("subject_process_name_s", ""),
- TargetProcessId = column_ifexists("subject_process_id_d", ""),
- TargetProcessGuid = column_ifexists("exec_chain_thread_uuid_g", ""),
- TargetProcessSHA256 = todynamic(column_ifexists("subject_process_hash_s", "")),
- TargetUserId = toreal(column_ifexists("subject_user_id_d", "")),
- TargetUsername = tostring(column_ifexists("subject_user_name_s", "")),
- TargetProcessCommandLine = column_ifexists("exec_args_args_compiled_s", ""),
- ActorUsername = tostring(column_ifexists("subject_effective_user_name_s", "")),
- ActorUserId = column_ifexists("subject_audit_user_name_s", ""),
- //column_ifexists("application_name_s", ""),
- //
- // Jamf Protect Telemetry - Audit/Group
- //
- GroupName = todynamic(column_ifexists("subject_group_name_s", "")),
- // Jamf Protect Telemetry - Network
- DstIpAddr = column_ifexists("socket_inet_ip_address_s", ""),
- DstPortNumber = column_ifexists("socket_inet_port_d", ""),
- NetworkProtocolVersion = case(socket_inet_id_d == 128, "IPV4", socket_inet_id_d == 129, "IPV6", ""),
- SrcIpAddr = column_ifexists("subject_terminal_id_ip_address_s", ""),
- //
- // Jamf Protect Telemetry - Binaries
- //
- // TargetBinaryFilePath = todynamic(Related_binaries[0].path),
- TargetBinarySHA256 = tostring(identity_cd_hash_s),
- // TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,
- TargetbinarySignerType = case(identity_signer_type_d == 0, "Developer", identity_signer_type_d == 1, "Apple", ""),
- TargetBinarySigningTeamID = tostring(identity_team_id_s),
- TargetBinarySigningAppID = tostring(identity_signer_id_s),
- //
- // Jamf Protect Telemetry - Log File Collection
- //
- TargetFilePath = tostring(parse_json(path_s))
- | project-reorder
- EventStartTime,
- EventVendor,
- EventProduct,
- EventType,
- EventSeverity,
- EventResult,
- TargetHostname,
- DvcHostname,
- DvcId,
- DvcOsVersion,
- DvcIpAddr,
- TargetModel,
- TargetUserId,
- TargetUsername,
- ParentProcessName,
- ParentProcessId,
- ParentProcessGuid,
- TargetProcessName,
- TargetProcessId,
- TargetProcessGuid,
- TargetProcessSHA256,
- TargetProcessCommandLine,
- ActorUsername,
- ActorUserId,
- TargetBinarySHA256,
- TargetbinarySignerType,
- TargetBinarySigningTeamID,
- TargetBinarySigningAppID,
- GroupName,
- SrcIpAddr,
- DstIpAddr,
- DstPortNumber,
- NetworkProtocolVersion,
- TargetFilePath
- | project-away
- arguments_sflags_d,
- arguments_am_failure_d,
- arguments_am_success_d
- };
- //
- // Jamf Protect - Threat Events
- //
- let JamfProtectThreatEvents_view = view () {
- jamfprotect_CL
- | where event_metadata_product_s == "Threat Events Stream"
- // ASIM - Common Fields
- | extend EventVendor = 'Jamf'
- | extend EventProduct = 'Jamf Protect - Threat Events Stream'
- | project-rename
- | extend
- // Jamf Protect - Common Fields
- EventStartTime = column_ifexists("event_timestamp_t", ""),
- EventResult=case(event_action_s == "Blocked", "Blocked", event_action_s == "Detected", "Detected", ''),
- EventReportUrl = column_ifexists("event_eventUrl_s", ""),
- // Jamf Protect - Alert Details
- EventSeverity = case(event_severity_d == 2, "Informational", event_severity_d == 4, "Low", event_severity_d == 6, "Medium", event_severity_d == 8, "High", event_severity_d == 10, "High", "Informational"),
- // Jamf Protect - Source User
- SrcUsermail=column_ifexists('event_user_email_s', ''),
- SrcUsername=column_ifexists('event_user_name_s', ''),
- // Jamf Protect - Source Device Hostnames
- DvcHostname = column_ifexists("event_device_userDeviceName_s", ""),
- DvcIpAddr = column_ifexists("event_source_ip_s", ""),
- DvcId = column_ifexists("event_device_externalId_g", ""),
- DvcOs=case(event_device_os_s has "MAC_OS", "macOS", event_device_os_s has "IOS", "iOS", event_device_os_s has "ANDROID", "Android", "Other"),
- SrcDeviceType=case(event_device_os_s has "MAC_OS", "Computer", event_device_os_s has "IOS", "Mobile Device", event_device_os_s has "ANDROID", "Mobile Device", "Other"),
- // Jamf Protect - DNS Specific
- DnsQuery=column_ifexists('event_hostName_s', ''),
- DvcAction=case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''),
- DnsQueryName=column_ifexists('event_destination_name_s', ''),
- DstIpAddr=column_ifexists('event_destination_ip_s', ''),
- ThreatCategory=column_ifexists('event_eventType_description_s', ''),
- ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),
- // Jamf Protect - App Specific
- TargetFileName = column_ifexists("event_app_name_s", ""),
- TargetFileSHA1 = column_ifexists("event_app_sha1_s", ""),
- TargetFileSHA256 = column_ifexists("event_app_sha256_s", "")
- | project-keep
- TimeGenerated,
- EventVendor,
- EventProduct,
- EventStartTime,
- EventResult,
- EventReportUrl,
- EventSeverity,
- DvcHostname,
- DvcIpAddr,
- DvcId,
- SrcDeviceType,
- SrcUsermail,
- SrcUsername,
- DnsQuery,
- DnsQueryName,
- DstIpAddr,
- ThreatCategory,
- DvcAction,
- ThreatOriginalRiskLevel,
- TargetFileName,
- TargetFileSHA1,
- TargetFileSHA256
- };
- union isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectNetworkTraffic_view, JamfProtectTelemetry_view, JamfProtectThreatEvents_view
+ let JamfProtectAlerts_view = view () {
+ jamfprotectalerts_CL
+ | extend
+ ActingProcessCreationTime = unixtime_seconds_todatetime(tolong(input.related.processes[array_length(input.related.processes) - 1].startTimestamp)),
+ ParentProcessCreationTime = iff(
+ array_length(input.related.processes) > 1,
+ unixtime_seconds_todatetime(tolong(input.related.processes[0].startTimestamp)),
+ datetime(null)
+ ),
+ TargetProcessCreationTime = unixtime_seconds_todatetime(todouble(input.related.processes[0].startTimestamp)),
+ TargetUserId = coalesce(input.related.users[1].uid, input.related.users[0].uid),
+ TargetUsername = coalesce(input.related.users[1].name, input.related.users[0].name)
+ };
+ let JamfProtectUnifiedLog_view = view () {
+ jamfprotectunifiedlogs_CL
+ | extend EventStartTime = unixtime_seconds_todatetime(tolong(input.match.event.timestamp))
+ };
+ //
+ // Jamf Protect - Endpoint Telemetry
+ //
+ let JamfProtectTelemetryv1_view = view () {
+ jamfprotecttelemetryv1_CL
+ | extend
+ EventStartTime = unixtime_seconds_todatetime(todouble(header.time_seconds_epoch)),
+ EventResult = coalesce(return.description, texts)
+ };
+ let JamfProtectTelemetryv2_view = view () {
+ jamfprotecttelemetryv2_CL
+ // Generic Fields
+ | extend
+ EventExpanded = tostring(parse_json(event)[strcat_array(bag_keys(event), '.')]),
+ eventTypeHuman = tostring(bag_keys(event)[0])
+ | extend EventResult = iif((event[eventTypeHuman]['success'] == true), "Success", dynamic(null))
+ | extend
+ EventMessage = case(
+ eventTypeHuman == "authentication",
+ "A user authentication happened",
+ eventTypeHuman == "authorization_judgement",
+ "A process has its rights petition judged",
+ eventTypeHuman == "authorization_petition",
+ "A process has its rights petition judged",
+ eventTypeHuman == "bios_uefi",
+ "Collection of bios and firmware data",
+ eventTypeHuman == "btm_launch_item_add",
+ "Apple's Background Task Manager notified that an item has been added",
+ eventTypeHuman == "btm_launch_item_remove",
+ "Apple's Background Task Manager notified that an existing item has been removed",
+ eventTypeHuman == "chroot",
+ "Software has changed its apparent root directory in which it's actively operating out of",
+ eventTypeHuman == "cs_invalidated",
+ "The system detected that a process has had its code signature marked as invalid",
+ eventTypeHuman == "exec",
+ "A new process has been executed",
+ eventTypeHuman == "kextload",
+ "A kernel extension (kext) was loaded",
+ eventTypeHuman == "kextunload",
+ "A kernel extension (kext) was unloaded",
+ eventTypeHuman == "login_login",
+ "A user attempted to log in using /usr/bin/login",
+ eventTypeHuman == "login_logout",
+ "A user logged out from /usr/bin/login",
+ eventTypeHuman == "lw_session_lock",
+ "A user has locked the screen",
+ eventTypeHuman == "lw_session_login",
+ "A user has logged in via the Login Window",
+ eventTypeHuman == "lw_session_logout",
+ "A user has logged out of an active graphical session",
+ eventTypeHuman == "lw_session_unlock",
+ "A user has unlocked the screen from the Login Window",
+ eventTypeHuman == "mount",
+ "A file system has been mounted",
+ eventTypeHuman == "od_attribute_set",
+ "Attribute set on user or group using Open Directory",
+ eventTypeHuman == "od_attribute_value_add",
+ "Attribute added to a user or group using Open Directory",
+ eventTypeHuman == "od_attribute_value_remove",
+ "Attribute removed from a user or group using Open Directory",
+ eventTypeHuman == "od_create_group",
+ "A group has been created using Open Directory",
+ eventTypeHuman == "od_create_user",
+ "A user has been created using Open Directory",
+ eventTypeHuman == "od_delete_group",
+ "A group has been deleted using Open Directory",
+ eventTypeHuman == "od_delete_user",
+ "A user has been deleted using Open Directory",
+ eventTypeHuman == "od_disable_user",
+ "A user has been disabled using Open Directory",
+ eventTypeHuman == "od_enable_user",
+ "A user has been enabled using Open Directory",
+ eventTypeHuman == "od_group_add",
+ "A member has been added to a group using Open Directory",
+ eventTypeHuman == "od_group_remove",
+ "A member has been removed from a group using Open Directory",
+ eventTypeHuman == "od_group_set",
+ "A group has a member initialised or replaced using Open Directory",
+ eventTypeHuman == "od_modify_password",
+ "A user password is modified via Open Directory",
+ eventTypeHuman == "openssh_login",
+ "A user has logged into the system via OpenSSH",
+ eventTypeHuman == "openssh_logout",
+ "A user has logged out of an OpenSSH session",
+ eventTypeHuman == "performance",
+ "Collection of system performance data",
+ eventTypeHuman == "profile_add",
+ "A configuration profile is installed on the system",
+ eventTypeHuman == "profile_remove",
+ "A configuration profile is removed from the system",
+ eventTypeHuman == "remount",
+ "A file system has been mounted",
+ eventTypeHuman == "screenscharing_attach",
+ "A screensharing session has attached to a graphical session",
+ eventTypeHuman == "screenscharing_detach",
+ "A screensharing session has detached from a graphical session",
+ eventTypeHuman == "settime",
+ "The system time was attempted to be set",
+ eventTypeHuman == "su",
+ "A user attempts to start a new shell using a substitute user identity",
+ eventTypeHuman == "sudo",
+ "A sudo attempt occured",
+ eventTypeHuman == "unmount",
+ "A file system has been mounted",
+ eventTypeHuman == "xp_malware_detected",
+ "Apple's XProtect detected malware on the system",
+ eventTypeHuman == "xp_malware_remediated",
+ "Apple's XProtect remediated malware on the system",
+ eventTypeHuman == "file_collection",
+ "A crash or diagnostic file has been collected",
+ eventTypeHuman == "log_collection",
+ "Entries from a log file have been collected",
+ "No reason yet defined for this event"
+ ),
+ EventType = case(
+ eventTypeHuman == "authentication",
+ "Logon",
+ eventTypeHuman == "authorization_judgement",
+ "ProcessCreated",
+ eventTypeHuman == "authorization_petition",
+ "ProcessCreated",
+ eventTypeHuman == "bios_uefi",
+ "Hardware",
+ eventTypeHuman == "btm_launch_item_add",
+ "Create",
+ eventTypeHuman == "btm_launch_item_remove",
+ "Delete",
+ eventTypeHuman == "chroot",
+ "Set",
+ eventTypeHuman == "cs_invalidated",
+ "Other",
+ eventTypeHuman == "exec",
+ "ProcessCreated",
+ eventTypeHuman == "kextload",
+ "Create",
+ eventTypeHuman == "kextunload",
+ "Delete",
+ eventTypeHuman == "login_login",
+ "Logon",
+ eventTypeHuman == "login_logout",
+ "Logoff",
+ eventTypeHuman == "lw_session_lock",
+ "Logoff",
+ eventTypeHuman == "lw_session_login",
+ "Logon",
+ eventTypeHuman == "lw_session_logout",
+ "Logoff",
+ eventTypeHuman == "lw_session_unlock",
+ "Logon",
+ eventTypeHuman == "mount",
+ "FileSystemMounted",
+ eventTypeHuman == "od_attribute_set",
+ "Set",
+ eventTypeHuman == "od_attribute_value_add",
+ "Create",
+ eventTypeHuman == "od_attribute_value_remove",
+ "Delete",
+ eventTypeHuman == "od_create_group",
+ "GroupCreated",
+ eventTypeHuman == "od_create_user",
+ "UserCreated",
+ eventTypeHuman == "od_delete_group",
+ "GroupDeleted",
+ eventTypeHuman == "od_delete_user",
+ "UserDeleted",
+ eventTypeHuman == "od_disable_user",
+ "UserDisabled",
+ eventTypeHuman == "od_enable_user",
+ "UserEnabled",
+ eventTypeHuman == "od_group_add",
+ "UserAddedToGroup",
+ eventTypeHuman == "od_group_remove",
+ "UserRemovedFromGroup",
+ eventTypeHuman == "od_group_set",
+ "GroupModified",
+ eventTypeHuman == "od_modify_password",
+ "PasswordChanged",
+ eventTypeHuman == "openssh_login",
+ "Logon",
+ eventTypeHuman == "openssh_logout",
+ "Logoff",
+ eventTypeHuman == "performance",
+ "PerformanceData",
+ eventTypeHuman == "profile_add",
+ "Create",
+ eventTypeHuman == "profile_remove",
+ "Delete",
+ eventTypeHuman == "remount",
+ "FileSystemRemounted",
+ eventTypeHuman == "screenscharing_attach",
+ "Logon",
+ eventTypeHuman == "screenscharing_detach",
+ "Logoff",
+ eventTypeHuman == "settime",
+ "Set",
+ eventTypeHuman == "su",
+ "Elevate",
+ eventTypeHuman == "sudo",
+ "Elevate",
+ eventTypeHuman == "unmount",
+ "FileSystemUnmounted",
+ eventTypeHuman == "xp_malware_detected",
+ "MalwareDetected",
+ eventTypeHuman == "xp_malware_remediated",
+ "MalwareRemediated",
+ ""
+ ),
+ EventSubType = case(
+ eventTypeHuman == "authentication",
+ "Interactive",
+ eventTypeHuman == "btm_launch_item_add",
+ "btm",
+ eventTypeHuman == "btm_launch_item_remove",
+ "btm",
+ eventTypeHuman == "chroot",
+ "Directory",
+ eventTypeHuman == "cs_invalidated",
+ "Other",
+ eventTypeHuman == "kextload",
+ "System Settings",
+ eventTypeHuman == "kextunload",
+ "System Settings",
+ eventTypeHuman == "login_login",
+ "Interactive",
+ eventTypeHuman == "login_logout",
+ "Interactive",
+ eventTypeHuman == "lw_session_lock",
+ "Interactive",
+ eventTypeHuman == "lw_session_login",
+ "Interactive",
+ eventTypeHuman == "lw_session_logout",
+ "Interactive",
+ eventTypeHuman == "lw_session_unlock",
+ "Interactive",
+ eventTypeHuman == "od_attribute_set",
+ "Attribute",
+ eventTypeHuman == "od_attribute_value_add",
+ "Attribute",
+ eventTypeHuman == "od_attribute_value_remove",
+ "Attribute",
+ eventTypeHuman == "openssh_login",
+ "Interactive",
+ eventTypeHuman == "openssh_logout",
+ "Interactive",
+ eventTypeHuman == "profile_add",
+ "Configuration Profile",
+ eventTypeHuman == "profile_remove",
+ "Configuration Profile",
+ eventTypeHuman == "screenscharing_attach",
+ "RemoteInteractive",
+ eventTypeHuman == "screenscharing_detach",
+ "RemoteInteractive",
+ eventTypeHuman == "settime",
+ "System Settings",
+ eventTypeHuman == "su",
+ "Interactive",
+ eventTypeHuman == "sudo",
+ "Interactive",
+ ""
+ )
+ // Jamf Protect Telemetry - Event Process
+ | extend eventContext =
+ iif(
+ isnotempty(event[eventTypeHuman]['app']['audit_token']),
+ event[eventTypeHuman]['app'],
+ iif(
+ isnotempty(event[eventTypeHuman]['target']['audit_token']),
+ event[eventTypeHuman]['target'],
+ iif(
+ isnotempty(event[eventTypeHuman]['data']['od']['audit_token']),
+ event[eventTypeHuman]['data']['od'],
+ iif(
+ isnotempty(event[eventTypeHuman]['data']['token']['audit_token']),
+ event[eventTypeHuman]['data']['token'],
+ iif(
+ isnotempty(event[eventTypeHuman]['data']['touchid']['audit_token']),
+ event[eventTypeHuman]['data']['touchid'],
+ iif(
+ isnotempty(event[eventTypeHuman]['instigator']['audit_token']),
+ event[eventTypeHuman]['instigator'],
+ ['process']
+ )
+ )
+ )
+ )
+ )
+ )
+ | extend
+ TargetProcessName = tostring(eventContext.executable.path),
+ TargetProcessId = tostring(eventContext.audit_token.pid),
+ TargetProcessGuid = tostring(eventContext.audit_token.uuid),
+ TargetProcessCreationTime = tostring(eventContext.start_time),
+ TargetProcessSHA1 = tostring(eventContext.executable.sha1),
+ TargetProcessSHA256 = tostring(eventContext.executable.sha256),
+ TargetProcessCommandLine = event[eventTypeHuman]['args'],
+ TargetProcessTTY = tostring(eventContext.tty.path),
+ TargetBinarySigningAppID = tostring(eventContext.signing_id),
+ TargetBinarySigningTeamID = tostring(eventContext.team_id),
+ TargetBinaryCDHash = tostring(eventContext.cdhash),
+ TargetBinaryIsESClient = tobool(eventContext.is_es_client),
+ TargetBinaryIsPlatformBinary = tobool(eventContext.is_platform_binary),
+ TargetUserId = tostring(eventContext.audit_token.euid),
+ ActingProcessId = tostring(eventContext.parent_audit_token.pid),
+ ActingProcessGuid = tostring(eventContext.parent_audit_token.uuid),
+ ActorUserId = tostring(eventContext.parent_audit_token.euid),
+ ParentProcessId = tostring(eventContext.responsible_audit_token.pid),
+ ParentProcessGuid = tostring(eventContext.responsible_audit_token.uuid)
+ // Jamf Protect Telemetry - Revealing Code Signing flags
+ | extend TargetProcessCodesignFlags =
+ iif(isnotempty(eventContext.codesigning_flags),
+ bag_pack(
+ "CS_VALID",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000001) > 0, true, false),
+ "CS_ADHOC",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000002) > 0, true, false),
+ "CS_GET_TASK_ALLOW",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000004) > 0, true, false),
+ "CS_INSTALLER",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000008) > 0, true, false),
+ "CS_FORCED_LV",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000010) > 0, true, false),
+ "CS_INVALID_ALLOWED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000020) > 0, true, false),
+ "CS_HARD",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000100) > 0, true, false),
+ "CS_KILL",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000200) > 0, true, false),
+ "CS_CHECK_EXPIRATION",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000400) > 0, true, false),
+ "CS_RESTRICT",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00000800) > 0, true, false),
+ "CS_ENFORCEMENT",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00001000) > 0, true, false),
+ "CS_REQUIRE_LV",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00002000) > 0, true, false),
+ "CS_ENTITLEMENTS_VALIDATED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00004000) > 0, true, false),
+ "CS_NVRAM_UNRESTRICTED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00008000) > 0, true, false),
+ "CS_RUNTIME",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00010000) > 0, true, false),
+ "CS_LINKER_SIGNED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x20000) > 0, true, false),
+ "CS_EXEC_SET_HARD",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00100000) > 0, true, false),
+ "CS_EXEC_SET_KILL",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00200000) > 0, true, false),
+ "CS_EXEC_SET_ENFORCEMENT",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00400000) > 0, true, false),
+ "CS_EXEC_INHERIT_SIP",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x00800000) > 0, true, false),
+ "CS_KILLED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x01000000) > 0, true, false),
+ "CS_DYLD_PLATFORM",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x02000000) > 0, true, false),
+ "CS_PLATFORM_BINARY",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x04000000) > 0, true, false),
+ "CS_PLATFORM_PATH",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x08000000) > 0, true, false),
+ "CS_DEBUGGED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x10000000) > 0, true, false),
+ "CS_SIGNED",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x20000000) > 0, true, false),
+ "CS_DEV_CODE",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x40000000) > 0, true, false),
+ "CS_DATAVAULT_CONTROLLER",
+ iff(binary_and(toint(eventContext.codesigning_flags), 0x80000000) > 0, true, false)
+ ), "")
+ // Event Specific - authentication
+ | extend TargetUsername =
+ iif(
+ isnotempty(event[eventTypeHuman]['username']),
+ event[eventTypeHuman]['username'],
+ iif(
+ isnotempty(event[eventTypeHuman]['to_username']),
+ event[eventTypeHuman]['to_username'],
+ iif(
+ isnotempty(event[eventTypeHuman]['account_name']),
+ event[eventTypeHuman]['account_name'],
+ iif(
+ isnotempty(event[eventTypeHuman]['user_name']),
+ event[eventTypeHuman]['user_name'],
+ iif(
+ isnotempty(event[eventTypeHuman]['authentication_username']),
+ event[eventTypeHuman]['authentication_username'],
+ ""
+ )
+ )
+ )
+ )
+ )
+ // Event Specific - authentication
+ | extend ActorUsername =
+ iif(
+ isnotempty(event[eventTypeHuman]['from_username']),
+ event[eventTypeHuman]['from_username'],
+ iif(
+ isnotempty(event[eventTypeHuman]['session_username']),
+ event[eventTypeHuman]['session_username'],
+ ""
+ )
+ )
+ | extend Authentication = iif(
+ eventTypeHuman == "authentication",
+ bag_pack(
+ "authentication_method",
+ iff(isnotempty(event[eventTypeHuman].data), tostring(bag_keys(event[eventTypeHuman].data)[0]), "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - bios_uefi
+ | extend HardwareInformation = iif(
+ eventTypeHuman == "bios_uefi",
+ bag_pack(
+ "host_architecture",
+ iff(isnotempty(event[eventTypeHuman].architecture), event[eventTypeHuman].architecture, ""),
+ "firmware_version",
+ iff(isnotempty(event[eventTypeHuman].bios.['firmware-version']), event[eventTypeHuman].bios.['firmware-version'], ""),
+ "system_firmware_version",
+ iff(isnotempty(event[eventTypeHuman].bios.['system-firmware-version']), event[eventTypeHuman].bios.['system-firmware-version'], "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - btm_launch_item_add & btm_launch_item_remove
+ | extend BtmItem = iif(
+ eventTypeHuman in ("btm_launch_item_add", "btm_launch_item_remove", "remount"),
+ bag_pack(
+ "btm_executable_path",
+ iff(isnotempty(event[eventTypeHuman].executable_path), event[eventTypeHuman].executable_path, ""),
+ "btm_item_app_url",
+ iff(isnotempty(event[eventTypeHuman].item.app_url), event[eventTypeHuman].item.app_url, ""),
+ "btm_item_url",
+ iff(isnotempty(event[eventTypeHuman].item.item_url), event[eventTypeHuman].item.item_url, ""),
+ "btm_item_managed",
+ iff(isnotempty(event[eventTypeHuman].item.managed), event[eventTypeHuman].item.managed, ""),
+ "btm_item_legacy",
+ iff(isnotempty(event[eventTypeHuman].item.legacy), event[eventTypeHuman].item.legacy, ""),
+ "btm_item_uid",
+ iff(isnotempty(event[eventTypeHuman].item.uid), event[eventTypeHuman].item.uid, ""),
+ "btm_item_type",
+ iff(
+ isnotempty(event[eventTypeHuman].item.item_type),
+ case(
+ event[eventTypeHuman].item.item_type == 0,
+ "UserItem",
+ event[eventTypeHuman].item.item_type == 1,
+ "App",
+ event[eventTypeHuman].item.item_type == 2,
+ "LoginItem",
+ event[eventTypeHuman].item.item_type == 3,
+ "LaunchAgent",
+ event[eventTypeHuman].item.item_type == 4,
+ "LaunchDaemon",
+ "Unknown"
+ ),
+ ""
+ )
+ ),
+ dynamic(null)
+ )
+ // Event Specific - chroot
+ | extend Chroot = iif(
+ eventTypeHuman == "chroot",
+ bag_pack(
+ "apparent_root_directory",
+ iff(isnotempty(event[eventTypeHuman].target), event[eventTypeHuman].target.path, ""),
+ "stats",
+ iff(isnotempty(event[eventTypeHuman].target.stat), event[eventTypeHuman].target.stat, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - cs_invalidated
+ // Event Specific - exec
+ // Event Specific - kextload & kextunload
+ | extend KernelExtension = iif(
+ eventTypeHuman in ("kextload", "kextunload"),
+ bag_pack(
+ "kext_identifier",
+ iff(isnotempty(event[eventTypeHuman].identifier), event[eventTypeHuman].identifier, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - lw_session_lock & lw_session_unlock & lw_session_login & lw_session_logout
+ | extend LoginWindowSession = iif(
+ eventTypeHuman in ("lw_session_lock", "lw_session_unlock", "lw_session_login", "lw_session_logout"),
+ bag_pack(
+ "graphical_session_id",
+ iff(isnotempty(event[eventTypeHuman].graphical_session_id), event[eventTypeHuman].graphical_session_id, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - mount & remount & unmount
+ | extend FileSystem = iif(
+ eventTypeHuman in ("mount", "unmount", "remount"),
+ bag_pack(
+ "volume_device_name",
+ iff(isnotempty(event[eventTypeHuman].statfs.f_mntfromname), event[eventTypeHuman].statfs.f_mntfromname, ""),
+ "volume_mount_name",
+ iff(isnotempty(event[eventTypeHuman].statfs.f_mntonname), event[eventTypeHuman].statfs.f_mntonname, ""),
+ "volume_file_system_type",
+ iff(isnotempty(event[eventTypeHuman].statfs.f_fstypename), event[eventTypeHuman].statfs.f_fstypename, ""),
+ "volume_size",
+ iff(isnotempty(event[eventTypeHuman].statfs.f_bsize), event[eventTypeHuman].statfs.f_bsize, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - od_attribute_set & od_attribute_value_add & od_attribute_value_remove & od_create_group & od_create_user & od_delete_group & od_delete_user & od_disable_user & od_enable_user
+ | extend OpenDirectory = iif(
+ eventTypeHuman in ("od_attribute_set", "od_attribute_value_add", "od_attribute_value_remove", "od_create_group", "od_create_user", "od_delete_group", "od_delete_user", "od_disable_user", "od_enable_user"),
+ bag_pack(
+ "group_name",
+ iff(isnotempty(event[eventTypeHuman].group_name), event[eventTypeHuman].group_name, ""),
+ "member_array",
+ iff(isnotempty(event[eventTypeHuman].members.member_array), event[eventTypeHuman].members.member_array, ""),
+ "member_value",
+ iff(isnotempty(event[eventTypeHuman].member.member_value), event[eventTypeHuman].member.member_value, ""),
+ "user_name",
+ iff(isnotempty(event[eventTypeHuman].user_name), event[eventTypeHuman].user_name, ""),
+ "account_name",
+ iff(isnotempty(event[eventTypeHuman].account_name), event[eventTypeHuman].account_name, ""),
+ "db_path",
+ iff(isnotempty(event[eventTypeHuman].db_path), event[eventTypeHuman].db_path, ""),
+ "record_name",
+ iff(isnotempty(event[eventTypeHuman].record_name), event[eventTypeHuman].record_name, ""),
+ "attribute_name",
+ iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, ""),
+ "attribute_value",
+ iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, ""),
+ "node_name",
+ iff(isnotempty(event[eventTypeHuman].node_name), event[eventTypeHuman].node_name, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - openssh_login & openssh_logout
+ | extend SSHContext = iif(
+ eventTypeHuman in ("openssh_login", "openssh_logout"),
+ bag_pack(
+ "source_address_type",
+ iff(
+ isnotempty(event[eventTypeHuman].source_address_type),
+ case(
+ event[eventTypeHuman].source_address_type == 0,
+ "Unknown",
+ event[eventTypeHuman].source_address_type == 1,
+ "IPv4",
+ event[eventTypeHuman].source_address_type == 2,
+ "IPv6",
+ event[eventTypeHuman].source_address_type == 3,
+ "UNIX Socket",
+ "Unknown"
+ ),
+ ""
+ ),
+ "result_type",
+ iff(
+ isnotempty(event[eventTypeHuman].result_type),
+ case(
+ event[eventTypeHuman].result_type == 0,
+ "Exceeded maximum attempts",
+ event[eventTypeHuman].result_type == 1,
+ "Denied by root",
+ event[eventTypeHuman].result_type == 2,
+ "Success",
+ event[eventTypeHuman].result_type == 3,
+ "No reason",
+ event[eventTypeHuman].result_type == 4,
+ "Password",
+ event[eventTypeHuman].result_type == 5,
+ "kbdint",
+ event[eventTypeHuman].result_type == 6,
+ "Public key",
+ event[eventTypeHuman].result_type == 7,
+ "Host based",
+ event[eventTypeHuman].result_type == 8,
+ "GSS API",
+ event[eventTypeHuman].result_type == 9,
+ "Invalid user",
+ "Unknown"
+ ),
+ ""
+ )
+ ),
+ dynamic(null)
+ )
+ // Event Specific - performance
+ // Event Specific - profile_add & profile_remove
+ | extend Profile = iif(
+ eventTypeHuman in ("profile_add", "profile_remove"),
+ bag_pack(
+ "profile_scope",
+ iff(isnotempty(event[eventTypeHuman].profile.scope), event[eventTypeHuman].profile.scope, ""),
+ "profile_identifier",
+ iff(isnotempty(event[eventTypeHuman].profile.identifier), event[eventTypeHuman].profile.identifiery, ""),
+ "profile_uuid",
+ iff(isnotempty(event[eventTypeHuman].profile.uuid), event[eventTypeHuman].profile.uuid, ""),
+ "profile_display_name",
+ iff(isnotempty(event[eventTypeHuman].profile.display_name), event[eventTypeHuman].profile.display_name, ""),
+ "profile_organization",
+ iff(isnotempty(event[eventTypeHuman].profile.organization), event[eventTypeHuman].profile.organization, ""),
+ "profile_is_updated",
+ iff(isnotempty(event[eventTypeHuman].is_update), event[eventTypeHuman].is_update, ""),
+ "profile_install_source",
+ iff(
+ isnotempty(event[eventTypeHuman].profile.install_source),
+ case(
+ event[eventTypeHuman].profile.install_source == 0,
+ "mdm",
+ event[eventTypeHuman].profile.install_source == 1,
+ "manual",
+ "Unknown"
+ ),
+ ""
+ )
+ ),
+ dynamic(null)
+ )
+ // Event Specific - screenscharing_attach & screensharing_detach
+ | extend Screensharing = iif(
+ eventTypeHuman in ("screensharing_attach", "screensharing_detach"),
+ bag_pack(
+ "existing_session",
+ iff(isnotempty(event[eventTypeHuman].existing_session), event[eventTypeHuman].existing_session, ""),
+ "graphical_session_id",
+ iff(isnotempty(event[eventTypeHuman].graphical_authentication_username), event[eventTypeHuman].graphical_authentication_username, ""),
+ "session_username",
+ iff(isnotempty(event[eventTypeHuman].session_username), event[eventTypeHuman].session_username, ""),
+ "viewer_appleid",
+ iff(isnotempty(event[eventTypeHuman].viewer_appleid), event[eventTypeHuman].viewer_appleid, ""),
+ "authentication_type",
+ iff(isnotempty(event[eventTypeHuman].authentication_type), event[eventTypeHuman].authentication_type, ""),
+ "source_address",
+ iff(isnotempty(event[eventTypeHuman].source_address), event[eventTypeHuman].source_address, ""),
+ "source_address_type",
+ iff(
+ isnotempty(event[eventTypeHuman].source_address_type),
+ case(
+ event[eventTypeHuman].source_address_type == 0,
+ "Unknown",
+ event[eventTypeHuman].source_address_type == 1,
+ "IPv4",
+ event[eventTypeHuman].source_address_type == 2,
+ "IPv6",
+ event[eventTypeHuman].source_address_type == 3,
+ "UNIX Socket",
+ "Unknown"
+ ),
+ ""
+ )
+ ),
+ dynamic(null)
+ )
+ // Event Specific - su
+ | extend Su = iif(
+ eventTypeHuman == "su",
+ bag_pack(
+ "username",
+ iff(isnotempty(event[eventTypeHuman].username), event[eventTypeHuman].username, ""),
+ "uid",
+ iff(isnotempty(event[eventTypeHuman].uid), event[eventTypeHuman].uid, ""),
+ "args",
+ iff(isnotempty(event[eventTypeHuman].argv), event[eventTypeHuman].argv, ""),
+ "env_vars",
+ iff(isnotempty(event[eventTypeHuman].env), event[eventTypeHuman].env, ""),
+ "env_count",
+ iff(isnotempty(event[eventTypeHuman].env_count), event[eventTypeHuman].env_count, ""),
+ "from_username",
+ iff(isnotempty(event[eventTypeHuman].from_username), event[eventTypeHuman].from_username, ""),
+ "to_username",
+ iff(isnotempty(event[eventTypeHuman].to_username), event[eventTypeHuman].to_username, ""),
+ "failure_message",
+ iff(isnotempty(event[eventTypeHuman].failure_reason), event[eventTypeHuman].failure_reason, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - sudo
+ | extend Sudo = iif(
+ eventTypeHuman == "sudo",
+ bag_pack(
+ "TargetProcessCommandLine",
+ iff(isnotempty(event[eventTypeHuman].command), event[eventTypeHuman].command, ""),
+ "attribute_name",
+ iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, ""),
+ "attribute_value",
+ iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, "")
+ ),
+ dynamic(null)
+ )
+ // Event Specific - xp_malware_detected & xp_malware_remediated
+ | extend Xprotect = iif(
+ eventTypeHuman in ("xp_malware_detected", "xp_malware_remediated"),
+ bag_pack(
+ "detected_path",
+ iff(isnotempty(event[eventTypeHuman].detected_path), event[eventTypeHuman].detected_path, ""),
+ "remediated_path",
+ iff(isnotempty(event[eventTypeHuman].remediated_path), event[eventTypeHuman].remediated_path, ""),
+ "malware_identifier",
+ iff(isnotempty(event[eventTypeHuman].malware_identifier), event[eventTypeHuman].malware_identifier, ""),
+ "signature_version",
+ iff(isnotempty(event[eventTypeHuman].signature_version), event[eventTypeHuman].signature_version, "")
+ ),
+ dynamic(null)
+ )
+ | project-away
+ action,
+ event,
+ process
+ };
+ //
+ // Jamf Protect - Network Traffic
+ //
+ let JamfProtectNetworkTraffic_view = view () {
+ jamfprotect_CL
+ | where event_metadata_product_s == "Network Traffic Stream"
+ // ASIM - Common Fields
+ | extend EventVendor = 'Jamf'
+ | extend EventProduct = 'Jamf Protect - Network Traffic Stream'
+ | project-rename
+ | extend
+ // Jamf Protect - Common Fields
+ EventType = "query",
+ EventSubType = "request",
+ EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),
+ EventResult = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Prevented", ''),
+ // Jamf Protect - Source User
+ SrcUsermail=column_ifexists('event_user_email_s', ''),
+ SrcUsername = column_ifexists('event_user_name_s', ''),
+ // Jamf Protect - Source Device Hostnames
+ DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),
+ DvcIpAddr = column_ifexists("event_source_ip_s", ""),
+ DvcId = column_ifexists("event_device_externalId_g", ""),
+ DvcOs = case(event_device_osType_s == "MAC_OS", "macOS", event_device_osType_s == "IOS", "iOS", event_device_osType_s == "ANDROID", "Android", "Other"),
+ SrcDeviceType = case(event_device_osType_s == "MAC_OS", "Computer", event_device_osType_s == "IOS", "Mobile Device", event_device_osType_s == "ANDROID", "Mobile Device", "Other"),
+ // Jamf Protect - DNS Specific
+ DnsQuery = column_ifexists('event_hostName_s', ''),
+ DvcAction = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''),
+ DnsQueryName = column_ifexists('event_domain_s', ''),
+ DstIpAddr = column_ifexists('event_destination_ips_s', ''),
+ ThreatCategory = column_ifexists('event_eventType_description_s', ''),
+ DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),
+ DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),
+ ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')
+ | project-keep
+ TimeGenerated,
+ EventVendor,
+ EventProduct,
+ EventType,
+ EventSubType,
+ EventStartTime,
+ EventResult,
+ DvcHostname,
+ DvcIpAddr,
+ DvcId,
+ DvcOs,
+ SrcDeviceType,
+ SrcUsermail,
+ SrcUsername,
+ DnsQuery,
+ DnsQueryName,
+ DstIpAddr,
+ DnsQueryTypeName,
+ DvcAction,
+ DnsResponseName,
+ ThreatOriginalRiskLevel
+ };
+ // //
+ // // Jamf Protect - Threat Events
+ // //
+ let JamfProtectThreatEvents_view = view () {
+ jamfprotect_CL
+ | where event_metadata_product_s == "Threat Events Stream"
+ // ASIM - Common Fields
+ | extend EventVendor = 'Jamf'
+ | extend EventProduct = 'Jamf Protect - Threat Events Stream'
+ | project-rename
+ | extend
+ // Jamf Protect - Common Fields
+ EventStartTime = column_ifexists("event_timestamp_t", ""),
+ EventResult=case(event_action_s == "Blocked", "Blocked", event_action_s == "Detected", "Detected", ''),
+ EventReportUrl = column_ifexists("event_eventUrl_s", ""),
+ // Jamf Protect - Alert Details
+ EventSeverity = case(event_severity_d == 2, "Informational", event_severity_d == 4, "Low", event_severity_d == 6, "Medium", event_severity_d == 8, "High", event_severity_d == 10, "High", "Informational"),
+ // Jamf Protect - Source User
+ SrcUsermail=column_ifexists('event_user_email_s', ''),
+ SrcUsername=column_ifexists('event_user_name_s', ''),
+ // Jamf Protect - Source Device Hostnames
+ DvcHostname = column_ifexists("event_device_userDeviceName_s", ""),
+ DvcIpAddr = column_ifexists("event_source_ip_s", ""),
+ DvcId = column_ifexists("event_device_externalId_g", ""),
+ DvcOs=case(event_device_os_s has "MAC_OS", "macOS", event_device_os_s has "IOS", "iOS", event_device_os_s has "ANDROID", "Android", "Other"),
+ SrcDeviceType=case(event_device_os_s has "MAC_OS", "Computer", event_device_os_s has "IOS", "Mobile Device", event_device_os_s has "ANDROID", "Mobile Device", "Other"),
+ // Jamf Protect - DNS Specific
+ DnsQuery=column_ifexists('event_hostName_s', ''),
+ DvcAction=case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''),
+ DnsQueryName=column_ifexists('event_destination_name_s', ''),
+ DstIpAddr=column_ifexists('event_destination_ip_s', ''),
+ ThreatCategory=column_ifexists('event_eventType_description_s', ''),
+ ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),
+ // Jamf Protect - App Specific
+ TargetFileName = column_ifexists("event_app_name_s", ""),
+ TargetFileSHA1 = column_ifexists("event_app_sha1_s", ""),
+ TargetFileSHA256 = column_ifexists("event_app_sha256_s", "")
+ | project-keep
+ TimeGenerated,
+ EventVendor,
+ EventProduct,
+ EventStartTime,
+ EventResult,
+ EventReportUrl,
+ EventSeverity,
+ DvcHostname,
+ DvcIpAddr,
+ DvcId,
+ SrcDeviceType,
+ SrcUsermail,
+ SrcUsername,
+ DnsQuery,
+ DnsQueryName,
+ DstIpAddr,
+ ThreatCategory,
+ DvcAction,
+ ThreatOriginalRiskLevel,
+ TargetFileName,
+ TargetFileSHA1,
+ TargetFileSHA256
+ };
+ union isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectTelemetryv1_view, JamfProtectTelemetryv2_view, JamfProtectNetworkTraffic_view, JamfProtectThreatEvents_view
diff --git a/Solutions/Jamf Protect/ReleaseNotes.md b/Solutions/Jamf Protect/ReleaseNotes.md
index 45c27296513..b8c7b85ba43 100644
--- a/Solutions/Jamf Protect/ReleaseNotes.md
+++ b/Solutions/Jamf Protect/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.2.0 | 04-02-2025 | Added new CCP **Data Connector** to the Solution.
| 3.1.1 | 30-04-2024 | Repackaged for parser issue fix while reinstall.
| 3.1.0 | 12-01-2024 | Improved data normalization in the parser JamfProtect, ParentProcess is better mapped now, productVersion has been added and more. Added new macOS Hunting Queries including recent malware IOCs.
| 3.0.1 | 05-12-2023 | Minor tweak to parser related to signerType
diff --git a/Solutions/Microsoft 365/Analytic Rules/MailItemsAccessedTimeSeries.yaml b/Solutions/Microsoft 365/Analytic Rules/MailItemsAccessedTimeSeries.yaml
index bfd73e4c4ef..03a770a12e9 100644
--- a/Solutions/Microsoft 365/Analytic Rules/MailItemsAccessedTimeSeries.yaml
+++ b/Solutions/Microsoft 365/Analytic Rules/MailItemsAccessedTimeSeries.yaml
@@ -5,7 +5,7 @@ description: |
The query leverages KQL built-in anomaly detection algorithms to find large deviations from baseline patterns.
Sudden increases in execution frequency of sensitive actions should be further investigated for malicious activity.
Manually change scorethreshold from 1.5 to 3 or higher to reduce the noise based on outliers flagged from the query criteria.
- Read more about MailItemsAccessed- https://docs.microsoft.com/microsoft-365/compliance/advanced-audit?view=o365-worldwide#mailitemsaccessed'
+ Read more about MailItemsAccessed- https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts'
severity: Medium
status: Available
requiredDataConnectors:
@@ -76,5 +76,5 @@ entityMappings:
fieldMappings:
- identifier: Address
columnName: SourceIPMax
-version: 2.0.5
-kind: Scheduled
\ No newline at end of file
+version: 2.0.6
+kind: Scheduled
diff --git a/Solutions/Microsoft 365/Data/Solution_Office365.json b/Solutions/Microsoft 365/Data/Solution_Office365.json
index 82a72354d43..6ef075eafef 100644
--- a/Solutions/Microsoft 365/Data/Solution_Office365.json
+++ b/Solutions/Microsoft 365/Data/Solution_Office365.json
@@ -52,7 +52,7 @@
"Analytic Rules/sharepoint_file_transfer_above_threshold.yaml"
],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Microsoft 365",
- "Version": "3.0.3",
+ "Version": "3.0.5",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"StaticDataConnectorIds": [
diff --git a/Solutions/Microsoft 365/Package/3.0.5.zip b/Solutions/Microsoft 365/Package/3.0.5.zip
new file mode 100644
index 00000000000..bdd62805976
Binary files /dev/null and b/Solutions/Microsoft 365/Package/3.0.5.zip differ
diff --git a/Solutions/Microsoft 365/Package/createUiDefinition.json b/Solutions/Microsoft 365/Package/createUiDefinition.json
index daed1e6ff9b..e74f1f292dc 100644
--- a/Solutions/Microsoft 365/Package/createUiDefinition.json
+++ b/Solutions/Microsoft 365/Package/createUiDefinition.json
@@ -208,7 +208,7 @@
"name": "analytic3-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "Identifies anomalous increases in Exchange mail items accessed operations.\nThe query leverages KQL built-in anomaly detection algorithms to find large deviations from baseline patterns.\nSudden increases in execution frequency of sensitive actions should be further investigated for malicious activity.\nManually change scorethreshold from 1.5 to 3 or higher to reduce the noise based on outliers flagged from the query criteria.\nRead more about MailItemsAccessed- https://docs.microsoft.com/microsoft-365/compliance/advanced-audit?view=o365-worldwide#mailitemsaccessed"
+ "text": "Identifies anomalous increases in Exchange mail items accessed operations.\nThe query leverages KQL built-in anomaly detection algorithms to find large deviations from baseline patterns.\nSudden increases in execution frequency of sensitive actions should be further investigated for malicious activity.\nManually change scorethreshold from 1.5 to 3 or higher to reduce the noise based on outliers flagged from the query criteria.\nRead more about MailItemsAccessed- https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts"
}
}
]
diff --git a/Solutions/Microsoft 365/Package/mainTemplate.json b/Solutions/Microsoft 365/Package/mainTemplate.json
index 0b9ecc066fb..1db3d788322 100644
--- a/Solutions/Microsoft 365/Package/mainTemplate.json
+++ b/Solutions/Microsoft 365/Package/mainTemplate.json
@@ -57,7 +57,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Microsoft 365",
- "_solutionVersion": "3.0.4",
+ "_solutionVersion": "3.0.5",
"solutionId": "azuresentinel.azure-sentinel-solution-office365",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "Office365",
@@ -208,11 +208,11 @@
"_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','bff093b2-500e-4ae5-bb49-a5b1423cbd5b','-', '2.1.3')))]"
},
"analyticRuleObject3": {
- "analyticRuleVersion3": "2.0.5",
+ "analyticRuleVersion3": "2.0.6",
"_analyticRulecontentId3": "b4ceb583-4c44-4555-8ecf-39f572e827ba",
"analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'b4ceb583-4c44-4555-8ecf-39f572e827ba')]",
"analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('b4ceb583-4c44-4555-8ecf-39f572e827ba')))]",
- "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b4ceb583-4c44-4555-8ecf-39f572e827ba','-', '2.0.5')))]"
+ "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b4ceb583-4c44-4555-8ecf-39f572e827ba','-', '2.0.6')))]"
},
"analyticRuleObject4": {
"analyticRuleVersion4": "2.0.4",
@@ -292,11 +292,11 @@
"_analyticRulecontentProductId14": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','8a547285-801c-4290-aa2e-5e7e20ca157d','-', '1.0.6')))]"
},
"analyticRuleObject15": {
- "analyticRuleVersion15": "1.0.5",
+ "analyticRuleVersion15": "1.0.6",
"_analyticRulecontentId15": "8b4f03e7-3460-4401-824d-e65a8dd464f0",
"analyticRuleId15": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '8b4f03e7-3460-4401-824d-e65a8dd464f0')]",
"analyticRuleTemplateSpecName15": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('8b4f03e7-3460-4401-824d-e65a8dd464f0')))]",
- "_analyticRulecontentProductId15": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','8b4f03e7-3460-4401-824d-e65a8dd464f0','-', '1.0.5')))]"
+ "_analyticRulecontentProductId15": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','8b4f03e7-3460-4401-824d-e65a8dd464f0','-', '1.0.6')))]"
},
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
@@ -310,7 +310,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft 365 data connector with template version 3.0.4",
+ "description": "Microsoft 365 data connector with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -505,7 +505,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SharePointAndOneDrive Workbook with template version 3.0.4",
+ "description": "SharePointAndOneDrive Workbook with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -593,7 +593,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Office365 Workbook with template version 3.0.4",
+ "description": "Office365 Workbook with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -681,7 +681,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeOnline Workbook with template version 3.0.4",
+ "description": "ExchangeOnline Workbook with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -769,7 +769,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AnomolousUserAccessingOtherUsersMailbox_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "AnomolousUserAccessingOtherUsersMailbox_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
@@ -854,7 +854,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExternalUserAddedRemovedInTeams_HuntVersion_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "ExternalUserAddedRemovedInTeams_HuntVersion_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
@@ -939,7 +939,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExternalUserFromNewOrgAddedToTeams_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "ExternalUserFromNewOrgAddedToTeams_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
@@ -1024,7 +1024,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Mail_redirect_via_ExO_transport_rule_hunting_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "Mail_redirect_via_ExO_transport_rule_hunting_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
@@ -1109,7 +1109,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MultiTeamBot_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "MultiTeamBot_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
@@ -1194,7 +1194,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MultiTeamOwner_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "MultiTeamOwner_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
@@ -1279,7 +1279,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MultipleTeamsDeletes_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "MultipleTeamsDeletes_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
@@ -1364,7 +1364,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "NewBotAddedToTeams_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "NewBotAddedToTeams_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]",
@@ -1449,7 +1449,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "New_WindowsReservedFileNamesOnOfficeFileServices_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "New_WindowsReservedFileNamesOnOfficeFileServices_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]",
@@ -1534,7 +1534,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "OfficeMailForwarding_hunting_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "OfficeMailForwarding_hunting_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]",
@@ -1619,7 +1619,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "TeamsFilesUploaded_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "TeamsFilesUploaded_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject11').huntingQueryVersion11]",
@@ -1704,7 +1704,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "UserAddToTeamsAndUploadsFile_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "UserAddToTeamsAndUploadsFile_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject12').huntingQueryVersion12]",
@@ -1789,7 +1789,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "WindowsReservedFileNamesOnOfficeFileServices_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "WindowsReservedFileNamesOnOfficeFileServices_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject13').huntingQueryVersion13]",
@@ -1874,7 +1874,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "double_file_ext_exes_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "double_file_ext_exes_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject14').huntingQueryVersion14]",
@@ -1959,7 +1959,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "new_adminaccountactivity_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "new_adminaccountactivity_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject15').huntingQueryVersion15]",
@@ -2044,7 +2044,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "new_sharepoint_downloads_by_IP_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "new_sharepoint_downloads_by_IP_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject16').huntingQueryVersion16]",
@@ -2129,7 +2129,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "new_sharepoint_downloads_by_UserAgent_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "new_sharepoint_downloads_by_UserAgent_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject17').huntingQueryVersion17]",
@@ -2214,7 +2214,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "nonowner_MailboxLogin_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "nonowner_MailboxLogin_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject18').huntingQueryVersion18]",
@@ -2299,7 +2299,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "powershell_or_nonbrowser_MailboxLogin_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "powershell_or_nonbrowser_MailboxLogin_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject19').huntingQueryVersion19]",
@@ -2384,7 +2384,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "sharepoint_downloads_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "sharepoint_downloads_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject20').huntingQueryVersion20]",
@@ -2469,7 +2469,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MultipleUsersEmailForwardedToSameDestination_HuntingQueries Hunting Query with template version 3.0.4",
+ "description": "MultipleUsersEmailForwardedToSameDestination_HuntingQueries Hunting Query with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject21').huntingQueryVersion21]",
@@ -2554,7 +2554,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "External User added to Team and immediately uploads file_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "External User added to Team and immediately uploads file_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -2602,64 +2602,64 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "MemberAdded"
+ "columnName": "MemberAdded",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "MemberAddedAccountName"
+ "columnName": "MemberAddedAccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "MemberAddedAccountUPNSuffix"
+ "columnName": "MemberAddedAccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserWhoAdded"
+ "columnName": "UserWhoAdded",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "UserWhoAddedAccountName"
+ "columnName": "UserWhoAddedAccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UserWhoAddedAccountUPNSuffix"
+ "columnName": "UserWhoAddedAccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserWhoDeleted"
+ "columnName": "UserWhoDeleted",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "UserWhoDeletedAccountName"
+ "columnName": "UserWhoDeletedAccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UserWhoDeletedAccountUPNSuffix"
+ "columnName": "UserWhoDeletedAccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -2715,7 +2715,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExternalUserAddedRemovedInTeams_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "ExternalUserAddedRemovedInTeams_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -2757,64 +2757,64 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "MemberAdded_Removed"
+ "columnName": "MemberAdded_Removed",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "MemberAdded_RemovedAccountName"
+ "columnName": "MemberAdded_RemovedAccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "MemberAdded_RemovedAccountUPNSuffix"
+ "columnName": "MemberAdded_RemovedAccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserWhoAdded"
+ "columnName": "UserWhoAdded",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "UserWhoAddedAccountName"
+ "columnName": "UserWhoAddedAccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UserWhoAddedAccountUPNSuffix"
+ "columnName": "UserWhoAddedAccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserWhoDeleted"
+ "columnName": "UserWhoDeleted",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "UserWhoDeletedAccountName"
+ "columnName": "UserWhoDeletedAccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UserWhoDeletedAccountUPNSuffix"
+ "columnName": "UserWhoDeletedAccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -2870,7 +2870,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MailItemsAccessedTimeSeries_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "MailItemsAccessedTimeSeries_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -2884,7 +2884,7 @@
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
- "description": "Identifies anomalous increases in Exchange mail items accessed operations.\nThe query leverages KQL built-in anomaly detection algorithms to find large deviations from baseline patterns.\nSudden increases in execution frequency of sensitive actions should be further investigated for malicious activity.\nManually change scorethreshold from 1.5 to 3 or higher to reduce the noise based on outliers flagged from the query criteria.\nRead more about MailItemsAccessed- https://docs.microsoft.com/microsoft-365/compliance/advanced-audit?view=o365-worldwide#mailitemsaccessed",
+ "description": "Identifies anomalous increases in Exchange mail items accessed operations.\nThe query leverages KQL built-in anomaly detection algorithms to find large deviations from baseline patterns.\nSudden increases in execution frequency of sensitive actions should be further investigated for malicious activity.\nManually change scorethreshold from 1.5 to 3 or higher to reduce the noise based on outliers flagged from the query criteria.\nRead more about MailItemsAccessed- https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts",
"displayName": "Exchange workflow MailItemsAccessed operation anomaly",
"enabled": false,
"query": "let starttime = 14d;\nlet endtime = 1d;\nlet timeframe = 1h;\nlet scorethreshold = 1.5;\nlet percentthreshold = 50;\n// Preparing the time series data aggregated hourly count of MailItemsAccessd Operation in the form of multi-value array to use with time series anomaly function.\nlet TimeSeriesData =\nOfficeActivity\n| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime)))\n| where OfficeWorkload=~ \"Exchange\" and Operation =~ \"MailItemsAccessed\" and ResultStatus =~ \"Succeeded\"\n| project TimeGenerated, Operation, MailboxOwnerUPN\n| make-series Total=count() on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe;\nlet TimeSeriesAlerts = TimeSeriesData\n| extend (anomalies, score, baseline) = series_decompose_anomalies(Total, scorethreshold, -1, 'linefit')\n| mv-expand Total to typeof(double), TimeGenerated to typeof(datetime), anomalies to typeof(double), score to typeof(double), baseline to typeof(long)\n| where anomalies > 0\n| project TimeGenerated, Total, baseline, anomalies, score;\n// Joining the flagged outlier from the previous step with the original dataset to present contextual information\n// during the anomalyhour to analysts to conduct investigation or informed decisions.\nTimeSeriesAlerts | where TimeGenerated > ago(2d)\n// Join against base logs since specified timeframe to retrive records associated with the hour of anomoly\n| join kind=innerunique (\n OfficeActivity\n | where TimeGenerated > ago(2d)\n | extend DateHour = bin(TimeGenerated, 1h)\n | where OfficeWorkload=~ \"Exchange\" and Operation =~ \"MailItemsAccessed\" and ResultStatus =~ \"Succeeded\"\n | summarize HourlyCount=count(), TimeGeneratedMax = arg_max(TimeGenerated, *), IPAdressList = make_set(Client_IPAddress, 1000), SourceIPMax= arg_max(Client_IPAddress, *), ClientInfoStringList= make_set(ClientInfoString, 1000) by MailboxOwnerUPN, Logon_Type, TenantId, UserType, TimeGenerated = bin(TimeGenerated, 1h)\n | where HourlyCount > 25 // Only considering operations with more than 25 hourly count to reduce False Positivies\n | order by HourlyCount desc\n) on TimeGenerated\n| extend PercentofTotal = round(HourlyCount/Total, 2) * 100\n| where PercentofTotal > percentthreshold // Filter Users with count of less than 5 percent of TotalEvents per Hour to remove FPs/ users with very low count of MailItemsAccessed events\n| order by PercentofTotal desc\n| project-reorder TimeGeneratedMax, Type, OfficeWorkload, Operation, UserId, SourceIPMax, IPAdressList, ClientInfoStringList, HourlyCount, PercentofTotal, Total, baseline, score, anomalies\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n",
@@ -2912,39 +2912,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "Client_IPAddress"
+ "columnName": "Client_IPAddress",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "SourceIPMax"
+ "columnName": "SourceIPMax",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -3000,7 +3000,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Mail_redirect_via_ExO_transport_rule_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "Mail_redirect_via_ExO_transport_rule_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -3044,30 +3044,30 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "IPAddress"
+ "columnName": "IPAddress",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -3123,7 +3123,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Malicious_Inbox_Rule_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "Malicious_Inbox_Rule_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -3167,39 +3167,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "OriginatingServerName"
+ "columnName": "OriginatingServerName",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIPAddress"
+ "columnName": "ClientIPAddress",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -3255,7 +3255,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MultipleTeamsDeletes_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "MultipleTeamsDeletes_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -3298,21 +3298,21 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
}
]
}
@@ -3368,7 +3368,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Office_MailForwarding_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "Office_MailForwarding_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -3412,30 +3412,30 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -3491,7 +3491,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Office_Uploaded_Executables_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "Office_Uploaded_Executables_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -3535,48 +3535,48 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Site_Url"
+ "columnName": "Site_Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
},
{
- "entityType": "File",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "FileNames"
+ "columnName": "FileNames",
+ "identifier": "Name"
}
- ]
+ ],
+ "entityType": "File"
}
]
}
@@ -3632,7 +3632,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RareOfficeOperations_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "RareOfficeOperations_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -3676,39 +3676,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "CloudApplication",
"fieldMappings": [
{
- "identifier": "AppId",
- "columnName": "AppId"
+ "columnName": "AppId",
+ "identifier": "AppId"
}
- ]
+ ],
+ "entityType": "CloudApplication"
}
]
}
@@ -3764,7 +3764,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SharePoint_Downloads_byNewIP_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "SharePoint_Downloads_byNewIP_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]",
@@ -3806,39 +3806,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Site_Url"
+ "columnName": "Site_Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -3894,7 +3894,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SharePoint_Downloads_byNewUserAgent_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "SharePoint_Downloads_byNewUserAgent_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject11').analyticRuleVersion11]",
@@ -3936,39 +3936,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "UserIdName"
+ "columnName": "UserIdName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UserIdUPNSuffix"
+ "columnName": "UserIdUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Site_Url"
+ "columnName": "Site_Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -4024,7 +4024,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "exchange_auditlogdisabled_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "exchange_auditlogdisabled_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject12').analyticRuleVersion12]",
@@ -4066,39 +4066,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "AccountNTDomain"
+ "columnName": "AccountNTDomain",
+ "identifier": "Name"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -4154,7 +4154,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "office_policytampering_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "office_policytampering_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject13').analyticRuleVersion13]",
@@ -4198,30 +4198,30 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -4277,7 +4277,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "sharepoint_file_transfer_folders_above_threshold_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "sharepoint_file_transfer_folders_above_threshold_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject14').analyticRuleVersion14]",
@@ -4319,39 +4319,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "File",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "DirSample"
+ "columnName": "DirSample",
+ "identifier": "Name"
}
- ]
+ ],
+ "entityType": "File"
}
],
"customDetails": {
@@ -4361,13 +4361,13 @@
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
- "matchingMethod": "Selected",
- "enabled": true,
- "reopenClosedIncident": false,
- "lookbackDuration": "PT5H",
"groupByEntities": [
"Account"
- ]
+ ],
+ "matchingMethod": "Selected",
+ "lookbackDuration": "PT5H",
+ "enabled": true,
+ "reopenClosedIncident": false
}
}
}
@@ -4423,7 +4423,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "sharepoint_file_transfer_above_threshold_AnalyticalRules Analytics Rule with template version 3.0.4",
+ "description": "sharepoint_file_transfer_above_threshold_AnalyticalRules Analytics Rule with template version 3.0.5",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject15').analyticRuleVersion15]",
@@ -4465,39 +4465,39 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "UserId"
+ "columnName": "UserId",
+ "identifier": "FullName"
},
{
- "identifier": "Name",
- "columnName": "AccountName"
+ "columnName": "AccountName",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "AccountUPNSuffix"
+ "columnName": "AccountUPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "ClientIP"
+ "columnName": "ClientIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "File",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "FileSample"
+ "columnName": "FileSample",
+ "identifier": "Name"
}
- ]
+ ],
+ "entityType": "File"
}
],
"customDetails": {
@@ -4507,13 +4507,13 @@
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
- "matchingMethod": "Selected",
- "enabled": true,
- "reopenClosedIncident": false,
- "lookbackDuration": "PT5H",
"groupByEntities": [
"Account"
- ]
+ ],
+ "matchingMethod": "Selected",
+ "lookbackDuration": "PT5H",
+ "enabled": true,
+ "reopenClosedIncident": false
}
}
}
@@ -4565,7 +4565,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.4",
+ "version": "3.0.5",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Microsoft 365",
diff --git a/Solutions/Microsoft 365/ReleaseNotes.md b/Solutions/Microsoft 365/ReleaseNotes.md
index 7d00a51ab90..4a29eaff3de 100644
--- a/Solutions/Microsoft 365/ReleaseNotes.md
+++ b/Solutions/Microsoft 365/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.0.5 | 04-02-2025 | Updated **Analytic Rule** MailItemsAccessedTimeSeries.yaml |
| 3.0.4 | 27-08-2024 | Updated **Analytic Rule** for Same names |
| 3.0.3 | 12-06-2024 | Updated **Analytic Rule** for Bug Fixes ExternalUserAddedRemovedInTeams.yaml |
| 3.0.2 | 09-05-2024 | Updated **Analytic Rule** to get expected result and Entity Mapping exchange_auditlogdisabled.yaml and fixed typo description in **Analytic Rules** ExternalUserAddedRemovedInTeams.yaml |
diff --git a/Solutions/Microsoft Entra ID/Analytic Rules/NRT_AuthenticationMethodsChangedforVIPUsers.yaml b/Solutions/Microsoft Entra ID/Analytic Rules/NRT_AuthenticationMethodsChangedforVIPUsers.yaml
index 14932813fe4..986b5ace21c 100644
--- a/Solutions/Microsoft Entra ID/Analytic Rules/NRT_AuthenticationMethodsChangedforVIPUsers.yaml
+++ b/Solutions/Microsoft Entra ID/Analytic Rules/NRT_AuthenticationMethodsChangedforVIPUsers.yaml
@@ -15,7 +15,7 @@ tags:
- AADSecOpsGuide
query: |
let security_info_actions = dynamic(["User registered security info", "User changed default security info", "User deleted security info", "Admin updated security info", "User reviewed security info", "Admin deleted security info", "Admin registered security info"]);
- let VIPUsers = (_GetWatchlist('VIPUsers') | distinct "User Principal Name");
+ let VIPUsers = (_GetWatchlist('VIPUsers') | distinct ["User Principal Name"]);
AuditLogs
| where Category =~ "UserManagement"
| where ActivityDisplayName in (security_info_actions)
@@ -62,5 +62,5 @@ entityMappings:
fieldMappings:
- identifier: Address
columnName: InitiatingIpAddress
-version: 1.0.3
+version: 1.0.4
kind: NRT
diff --git a/Solutions/Okta Single Sign-On/Package/3.1.2.zip b/Solutions/Okta Single Sign-On/Package/3.1.2.zip
index 4d1ab12f470..aaf3128782b 100644
Binary files a/Solutions/Okta Single Sign-On/Package/3.1.2.zip and b/Solutions/Okta Single Sign-On/Package/3.1.2.zip differ
diff --git a/Solutions/Okta Single Sign-On/Package/3.1.3.zip b/Solutions/Okta Single Sign-On/Package/3.1.3.zip
new file mode 100644
index 00000000000..11d7e6b7470
Binary files /dev/null and b/Solutions/Okta Single Sign-On/Package/3.1.3.zip differ
diff --git a/Solutions/Okta Single Sign-On/Package/mainTemplate.json b/Solutions/Okta Single Sign-On/Package/mainTemplate.json
index 946b694f161..ea77899b10a 100644
--- a/Solutions/Okta Single Sign-On/Package/mainTemplate.json
+++ b/Solutions/Okta Single Sign-On/Package/mainTemplate.json
@@ -55,7 +55,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Okta Single Sign-On",
- "_solutionVersion": "3.1.2",
+ "_solutionVersion": "3.1.3",
"solutionId": "azuresentinel.azure-sentinel-solution-okta",
"_solutionId": "[variables('solutionId')]",
"analyticRuleObject1": {
@@ -248,7 +248,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "FailedLoginsFromUnknownOrInvalidUser_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "FailedLoginsFromUnknownOrInvalidUser_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -296,22 +296,22 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "FullName",
"columnName": "actor_alternateId_s"
}
- ],
- "entityType": "Account"
+ ]
},
{
+ "entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "ClientIP"
}
- ],
- "entityType": "IP"
+ ]
}
]
}
@@ -367,7 +367,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "LoginfromUsersfromDifferentCountrieswithin3hours_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "LoginfromUsersfromDifferentCountrieswithin3hours_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -418,13 +418,13 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "FullName",
"columnName": "actor_alternateId_s"
}
- ],
- "entityType": "Account"
+ ]
}
]
}
@@ -480,7 +480,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "PasswordSpray_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "PasswordSpray_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -531,13 +531,13 @@
],
"entityMappings": [
{
+ "entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "client_ipAddress_s"
}
- ],
- "entityType": "IP"
+ ]
}
]
}
@@ -593,7 +593,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "PhishingDetection_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "PhishingDetection_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -641,6 +641,7 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "Name",
@@ -650,17 +651,16 @@
"identifier": "DisplayName",
"columnName": "actor_displayName_s"
}
- ],
- "entityType": "Account"
+ ]
},
{
+ "entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "client_ipAddress_s"
}
- ],
- "entityType": "IP"
+ ]
}
],
"customDetails": {
@@ -720,7 +720,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "NewDeviceLocationCriticalOperation_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "NewDeviceLocationCriticalOperation_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -770,6 +770,7 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "Name",
@@ -779,17 +780,16 @@
"identifier": "DisplayName",
"columnName": "actor_displayName_s"
}
- ],
- "entityType": "Account"
+ ]
},
{
+ "entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "client_ipAddress_s"
}
- ],
- "entityType": "IP"
+ ]
}
],
"customDetails": {
@@ -797,8 +797,8 @@
"SessionId": "[variables('_SessionId')]"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "This query identifies users seen login from new geo location/country {{Location}} as well as a new device and performing critical operations\n",
- "alertDisplayNameFormat": "New Device/Location {{Location}} sign-in along with critical operation"
+ "alertDisplayNameFormat": "New Device/Location {{Location}} sign-in along with critical operation",
+ "alertDescriptionFormat": "This query identifies users seen login from new geo location/country {{Location}} as well as a new device and performing critical operations\n"
}
}
},
@@ -853,7 +853,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MFAFatigue_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "MFAFatigue_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -901,6 +901,7 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "Name",
@@ -910,8 +911,7 @@
"identifier": "DisplayName",
"columnName": "actor_displayName_s"
}
- ],
- "entityType": "Account"
+ ]
}
]
}
@@ -967,7 +967,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "HighRiskAdminActivity_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "HighRiskAdminActivity_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -1015,6 +1015,7 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "Name",
@@ -1024,17 +1025,16 @@
"identifier": "DisplayName",
"columnName": "actor_displayName_s"
}
- ],
- "entityType": "Account"
+ ]
},
{
+ "entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "client_ipAddress_s"
}
- ],
- "entityType": "IP"
+ ]
}
],
"customDetails": {
@@ -1093,7 +1093,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "DeviceRegistrationMaliciousIP_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "DeviceRegistrationMaliciousIP_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -1141,6 +1141,7 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "Name",
@@ -1150,17 +1151,16 @@
"identifier": "DisplayName",
"columnName": "actor_displayName_s"
}
- ],
- "entityType": "Account"
+ ]
},
{
+ "entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "client_ipAddress_s"
}
- ],
- "entityType": "IP"
+ ]
}
]
}
@@ -1216,7 +1216,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "UserSessionImpersonation_AnalyticalRules Analytics Rule with template version 3.1.2",
+ "description": "UserSessionImpersonation_AnalyticalRules Analytics Rule with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -1268,6 +1268,7 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
"identifier": "Name",
@@ -1277,8 +1278,7 @@
"identifier": "DisplayName",
"columnName": "actor_displayName_s"
}
- ],
- "entityType": "Account"
+ ]
}
]
}
@@ -1334,7 +1334,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Okta Single Sign-On data connector with template version 3.1.2",
+ "description": "Okta Single Sign-On data connector with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -2560,16 +2560,20 @@
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorCCPVersion')]",
"parameters": {
- "apikey": {
- "defaultValue": "-NA-",
- "type": "securestring",
- "minLength": 1
+ "innerWorkspace": {
+ "defaultValue": "[parameters('workspace')]",
+ "type": "string"
},
"domainname": {
"defaultValue": "Enter domainname value",
"type": "string",
"minLength": 1
},
+ "apikey": {
+ "defaultValue": "-NA-",
+ "type": "securestring",
+ "minLength": 4
+ },
"connectorDefinitionName": {
"defaultValue": "Okta Single Sign-On",
"type": "string",
@@ -2618,7 +2622,7 @@
}
},
{
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', '{{innerWorkspace}}/Microsoft.SecurityInsights/OktaDCV1_{{domainname}}')]",
+ "name": "[[concat(parameters('innerWorkspace'), '/Microsoft.SecurityInsights', '/OktaDCV1_', parameters('domainname'))]",
"apiVersion": "2023-02-01-preview",
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
"location": "[parameters('workspace-location')]",
@@ -2686,7 +2690,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "AdminPrivilegeGrant_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "AdminPrivilegeGrant_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
@@ -2771,7 +2775,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "CreateAPIToken_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "CreateAPIToken_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
@@ -2856,7 +2860,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ImpersonationSession_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "ImpersonationSession_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
@@ -2941,7 +2945,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RareMFAOperation_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "RareMFAOperation_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
@@ -3026,7 +3030,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "UserPasswordReset_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "UserPasswordReset_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
@@ -3111,7 +3115,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "NewDeviceRegistration_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "NewDeviceRegistration_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
@@ -3196,7 +3200,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "LoginsVPSProvider_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "LoginsVPSProvider_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
@@ -3281,7 +3285,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "LoginNordVPN_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "LoginNordVPN_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]",
@@ -3366,7 +3370,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "LoginFromMultipleLocations_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "LoginFromMultipleLocations_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]",
@@ -3451,7 +3455,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "LegacyAuthentication_HuntingQueries Hunting Query with template version 3.1.2",
+ "description": "LegacyAuthentication_HuntingQueries Hunting Query with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]",
@@ -3536,7 +3540,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "OktaCustomConnector Playbook with template version 3.1.2",
+ "description": "OktaCustomConnector Playbook with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion1')]",
@@ -4799,7 +4803,7 @@
],
"metadata": {
"comments": "This OKTA connector uses okta API to perform different actions on the user accounts.",
- "lastUpdateTime": "2025-01-06T15:31:31.854Z",
+ "lastUpdateTime": "2025-01-30T12:53:51.440Z",
"releaseNotes": {
"version": "1.0",
"title": "[variables('blanks')]",
@@ -4831,7 +4835,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Okta-EnrichIncidentWithUserDetails Playbook with template version 3.1.2",
+ "description": "Okta-EnrichIncidentWithUserDetails Playbook with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion2')]",
@@ -5190,7 +5194,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Okta-PromptUser Playbook with template version 3.1.2",
+ "description": "Okta-PromptUser Playbook with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion3')]",
@@ -5641,7 +5645,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Okta-ResponseFromTeams Playbook with template version 3.1.2",
+ "description": "Okta-ResponseFromTeams Playbook with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion4')]",
@@ -6148,7 +6152,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "OktaSingleSignOn Workbook with template version 3.1.2",
+ "description": "OktaSingleSignOn Workbook with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -6244,7 +6248,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "OktaSSO Data Parser with template version 3.1.2",
+ "description": "OktaSSO Data Parser with template version 3.1.3",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -6372,7 +6376,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.1.2",
+ "version": "3.1.3",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Okta Single Sign-On",
diff --git a/Solutions/Palo Alto Cortex XDR CCP/Data Connectors/CortexXDR_ccp/DataConnectorDefinition.json b/Solutions/Palo Alto Cortex XDR CCP/Data Connectors/CortexXDR_ccp/DataConnectorDefinition.json
index 4d73813fae2..26bcd2701a5 100644
--- a/Solutions/Palo Alto Cortex XDR CCP/Data Connectors/CortexXDR_ccp/DataConnectorDefinition.json
+++ b/Solutions/Palo Alto Cortex XDR CCP/Data Connectors/CortexXDR_ccp/DataConnectorDefinition.json
@@ -7,7 +7,7 @@
"properties": {
"connectorUiConfig": {
"id": "CortexXDRDataConnector",
- "title": "Palo Alto Cortex XDR (Preview)",
+ "title": "Palo Alto Cortex XDR",
"publisher": "Microsoft",
"descriptionMarkdown": "The [Palo Alto Cortex XDR](https://cortex-panw.stoplight.io/docs/cortex-xdr/branches/main/09agw06t5dpvw-cortex-xdr-rest-api) data connector allows ingesting logs from the Palo Alto Cortex XDR API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the Palo Alto Cortex XDR API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
diff --git a/Solutions/Palo Alto Cortex XDR CCP/Package/3.0.2.zip b/Solutions/Palo Alto Cortex XDR CCP/Package/3.0.2.zip
new file mode 100644
index 00000000000..3181e4e4ba9
Binary files /dev/null and b/Solutions/Palo Alto Cortex XDR CCP/Package/3.0.2.zip differ
diff --git a/Solutions/Palo Alto Cortex XDR CCP/Package/createUiDefinition.json b/Solutions/Palo Alto Cortex XDR CCP/Package/createUiDefinition.json
index 88649dfffc5..1a502aa6784 100644
--- a/Solutions/Palo Alto Cortex XDR CCP/Package/createUiDefinition.json
+++ b/Solutions/Palo Alto Cortex XDR CCP/Package/createUiDefinition.json
@@ -64,7 +64,7 @@
}
},
{
- "name": "dataconnectors-link2",
+ "name": "dataconnectors-link1",
"type": "Microsoft.Common.TextBlock",
"options": {
"link": {
diff --git a/Solutions/Palo Alto Cortex XDR CCP/Package/mainTemplate.json b/Solutions/Palo Alto Cortex XDR CCP/Package/mainTemplate.json
index c91006517cf..34fa0b38e6c 100644
--- a/Solutions/Palo Alto Cortex XDR CCP/Package/mainTemplate.json
+++ b/Solutions/Palo Alto Cortex XDR CCP/Package/mainTemplate.json
@@ -45,7 +45,7 @@
},
"variables": {
"_solutionName": "Palo Alto Cortex XDR CCP",
- "_solutionVersion": "3.0.1",
+ "_solutionVersion": "3.0.2",
"solutionId": "azuresentinel.azure-sentinel-solution-cortexccp",
"_solutionId": "[variables('solutionId')]",
"workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
@@ -68,7 +68,7 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnectorDefinition1')]",
- "displayName": "Palo Alto Cortex XDR (Preview)",
+ "displayName": "Palo Alto Cortex XDR",
"contentKind": "DataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -85,7 +85,7 @@
"properties": {
"connectorUiConfig": {
"id": "CortexXDRDataConnector",
- "title": "Palo Alto Cortex XDR (Preview)",
+ "title": "Palo Alto Cortex XDR",
"publisher": "Microsoft",
"descriptionMarkdown": "The [Palo Alto Cortex XDR](https://cortex-panw.stoplight.io/docs/cortex-xdr/branches/main/09agw06t5dpvw-cortex-xdr-rest-api) data connector allows ingesting logs from the Palo Alto Cortex XDR API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the Palo Alto Cortex XDR API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
@@ -2156,7 +2156,7 @@
"properties": {
"connectorUiConfig": {
"id": "CortexXDRDataConnector",
- "title": "Palo Alto Cortex XDR (Preview)",
+ "title": "Palo Alto Cortex XDR",
"publisher": "Microsoft",
"descriptionMarkdown": "The [Palo Alto Cortex XDR](https://cortex-panw.stoplight.io/docs/cortex-xdr/branches/main/09agw06t5dpvw-cortex-xdr-rest-api) data connector allows ingesting logs from the Palo Alto Cortex XDR API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the Palo Alto Cortex XDR API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
@@ -2362,14 +2362,14 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnections1')]",
- "displayName": "Palo Alto Cortex XDR (Preview)",
+ "displayName": "Palo Alto Cortex XDR",
"contentKind": "ResourcesDataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorCCPVersion')]",
"parameters": {
"connectorDefinitionName": {
- "defaultValue": "Palo Alto Cortex XDR (Preview)",
+ "defaultValue": "Palo Alto Cortex XDR",
"type": "string",
"minLength": 1
},
@@ -2664,7 +2664,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.1",
+ "version": "3.0.2",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Palo Alto Cortex XDR CCP",
diff --git a/Solutions/Palo Alto Cortex XDR CCP/ReleaseNotes.md b/Solutions/Palo Alto Cortex XDR CCP/ReleaseNotes.md
index 84bd3f02018..0372f0c651b 100644
--- a/Solutions/Palo Alto Cortex XDR CCP/ReleaseNotes.md
+++ b/Solutions/Palo Alto Cortex XDR CCP/ReleaseNotes.md
@@ -1,4 +1,5 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------------------------|
+| 3.0.2 | 10-02-2025 | Advancing CCP **Data Connector** from Public preview to Global Availability.|
| 3.0.1 | 22-01-2025 | Added Preview tag to **Data Connector** |
| 3.0.0 | 17-12-2024 | Initial Solution Release |
diff --git a/Solutions/ProofPointTap/Analytic Rules/MalwareLinkClicked.yaml b/Solutions/ProofPointTap/Analytic Rules/MalwareLinkClicked.yaml
index 7edba047c2c..2eaf0e59dcd 100644
--- a/Solutions/ProofPointTap/Analytic Rules/MalwareLinkClicked.yaml
+++ b/Solutions/ProofPointTap/Analytic Rules/MalwareLinkClicked.yaml
@@ -19,6 +19,7 @@ relevantTechniques:
query: |
ProofPointTAPClicksPermitted_CL
| where classification_s =~ "malware"
+ | where threatStatus_s != "cleared"
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by TimeGenerated, Sender = sender_s, SenderIPAddress = senderIP_s, Recipient = recipient_s, TimeClicked = clickTime_t, URLClicked = url_s
| extend RecipientName = tostring(split(Recipient, "@")[0]), RecipientUPNSuffix = tostring(split(Recipient, "@")[1])
| extend SenderName = tostring(split(Sender, "@")[0]), SenderUPNSuffix = tostring(split(Sender, "@")[1])
@@ -47,5 +48,5 @@ entityMappings:
fieldMappings:
- identifier: Url
columnName: URLClicked
-version: 1.0.4
+version: 1.0.5
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/ProofPointTap/Package/3.0.5.zip b/Solutions/ProofPointTap/Package/3.0.5.zip
index 6d75662b5fe..b8656e28bce 100644
Binary files a/Solutions/ProofPointTap/Package/3.0.5.zip and b/Solutions/ProofPointTap/Package/3.0.5.zip differ
diff --git a/Solutions/ProofPointTap/Package/createUiDefinition.json b/Solutions/ProofPointTap/Package/createUiDefinition.json
index a71ee4cc44b..b9413c513de 100644
--- a/Solutions/ProofPointTap/Package/createUiDefinition.json
+++ b/Solutions/ProofPointTap/Package/createUiDefinition.json
@@ -71,7 +71,7 @@
}
},
{
- "name": "dataconnectors-link2",
+ "name": "dataconnectors-link1",
"type": "Microsoft.Common.TextBlock",
"options": {
"link": {
diff --git a/Solutions/ProofPointTap/Package/mainTemplate.json b/Solutions/ProofPointTap/Package/mainTemplate.json
index 51dffaf9d9e..7d358267a82 100644
--- a/Solutions/ProofPointTap/Package/mainTemplate.json
+++ b/Solutions/ProofPointTap/Package/mainTemplate.json
@@ -68,11 +68,11 @@
"_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','0558155e-4556-447e-9a22-828f2a7de06b','-', '1.0.4')))]"
},
"analyticRuleObject2": {
- "analyticRuleVersion2": "1.0.4",
+ "analyticRuleVersion2": "1.0.5",
"_analyticRulecontentId2": "8675dd7a-795e-4d56-a79c-fc848c5ee61c",
"analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '8675dd7a-795e-4d56-a79c-fc848c5ee61c')]",
"analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('8675dd7a-795e-4d56-a79c-fc848c5ee61c')))]",
- "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','8675dd7a-795e-4d56-a79c-fc848c5ee61c','-', '1.0.4')))]"
+ "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','8675dd7a-795e-4d56-a79c-fc848c5ee61c','-', '1.0.5')))]"
},
"workbookVersion1": "1.0.0",
"workbookContentId1": "ProofPointTAPWorkbook",
@@ -756,10 +756,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "ProofpointTAP",
"dataTypes": [
"ProofPointTAPMessagesDelivered_CL"
- ],
- "connectorId": "ProofpointTAP"
+ ]
}
],
"tactics": [
@@ -773,7 +773,6 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
"columnName": "Recipient",
@@ -787,10 +786,10 @@
"columnName": "RecipientUPNSuffix",
"identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
"columnName": "Sender",
@@ -804,16 +803,17 @@
"columnName": "SenderUPNSuffix",
"identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
"columnName": "SenderIPAddress",
"identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -886,7 +886,7 @@
"description": "This query identifies a user clicking on an email link whose threat category is classified as a malware",
"displayName": "Malware Link Clicked",
"enabled": false,
- "query": "ProofPointTAPClicksPermitted_CL\n| where classification_s =~ \"malware\"\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by TimeGenerated, Sender = sender_s, SenderIPAddress = senderIP_s, Recipient = recipient_s, TimeClicked = clickTime_t, URLClicked = url_s\n| extend RecipientName = tostring(split(Recipient, \"@\")[0]), RecipientUPNSuffix = tostring(split(Recipient, \"@\")[1])\n| extend SenderName = tostring(split(Sender, \"@\")[0]), SenderUPNSuffix = tostring(split(Sender, \"@\")[1])\n",
+ "query": "ProofPointTAPClicksPermitted_CL\n| where classification_s =~ \"malware\"\n| where threatStatus_s != \"cleared\"\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by TimeGenerated, Sender = sender_s, SenderIPAddress = senderIP_s, Recipient = recipient_s, TimeClicked = clickTime_t, URLClicked = url_s\n| extend RecipientName = tostring(split(Recipient, \"@\")[0]), RecipientUPNSuffix = tostring(split(Recipient, \"@\")[1])\n| extend SenderName = tostring(split(Sender, \"@\")[0]), SenderUPNSuffix = tostring(split(Sender, \"@\")[1])\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "Medium",
@@ -897,10 +897,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "ProofpointTAP",
"dataTypes": [
"ProofPointTAPClicksPermitted_CL"
- ],
- "connectorId": "ProofpointTAP"
+ ]
}
],
"tactics": [
@@ -914,7 +914,6 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
"columnName": "Recipient",
@@ -928,10 +927,10 @@
"columnName": "RecipientUPNSuffix",
"identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
"columnName": "Sender",
@@ -945,25 +944,26 @@
"columnName": "SenderUPNSuffix",
"identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
"columnName": "SenderIPAddress",
"identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
"columnName": "URLClicked",
"identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
diff --git a/Solutions/ProofPointTap/ReleaseNotes.md b/Solutions/ProofPointTap/ReleaseNotes.md
index d999f259a19..d67b88f6a8d 100644
--- a/Solutions/ProofPointTap/ReleaseNotes.md
+++ b/Solutions/ProofPointTap/ReleaseNotes.md
@@ -1,8 +1,8 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------------|
-| 3.0.5 | 05-07-2024 | Updated **Analytic Rules** MalwareAttachmentDelivered.yaml and MalwareLinkClicked.yaml |
-| 3.0.4 | 26-04-2024 | Repackaged for fix on parser in maintemplate to have old parsername and parentid |
-| 3.0.3 | 16-04-2024 | Repackaged for parser issue in maintemplate |
+| 3.0.5 | 12-01-2025 | Updated **Analytic Rule** MalwareLinkClicked.yaml |
+| 3.0.4 | 26-04-2024 | Repackaged for fix on parser in maintemplate to have old parsername and parentid |
+| 3.0.3 | 16-04-2024 | Repackaged for parser issue in maintemplate |
| 3.0.2 | 10-04-2024 | Added Azure Deploy button for government portal deployments |
| 3.0.1 | 10-10-2023 | Manual deployment instructions updated for **Data Connector**|
| 3.0.0 | 01-08-2023 | Updated solution logo with Microsoft Sentinel logo |
diff --git a/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConn.zip b/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConn.zip
index 2453a889be9..e653127d442 100644
Binary files a/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConn.zip and b/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConn.zip differ
diff --git a/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConnector/__init__.py b/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConnector/__init__.py
index 74bccfd07c4..8702ec89714 100644
--- a/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConnector/__init__.py
+++ b/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/ProofpointSentinelConnector/__init__.py
@@ -21,15 +21,15 @@
cluster_id = os.environ['ProofpointClusterID']
_token = os.environ['ProofpointToken']
time_delay_minutes = 60
-event_types = ["maillog","message"]
+event_types = ["maillog", "message"]
logAnalyticsUri = os.environ.get('logAnalyticsUri')
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
-match = re.match(pattern,str(logAnalyticsUri))
-if(not match):
+match = re.match(pattern, str(logAnalyticsUri))
+if not match:
raise Exception("ProofpointPOD: Invalid Log Analytics Uri.")
def main(mytimer: func.TimerRequest) -> None:
@@ -55,10 +55,33 @@ def gen_timeframe(self, time_delay_minutes):
before_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=time_delay_minutes)
self.before_time = before_time.strftime("%Y-%m-%dT%H:59:59.999999")
self.after_time = before_time.strftime("%Y-%m-%dT%H:00:00.000000")
+
+ def check_and_split_msgParts(self, msg_parts, max_size=32000):
+ # If msg_parts is a list or dictionary, convert it to a string (JSON format)
+ if isinstance(msg_parts, (dict, list)):
+ msg_parts = json.dumps(msg_parts)
+
+ # Calculate the length of the message in bytes
+ msglen = len(msg_parts.encode('utf-8'))
+
+ # If the message size exceeds the max size, split it
+ if msglen > max_size:
+ split_point = len(msg_parts) // 2
+ part1 = msg_parts[:split_point]
+ part2 = msg_parts[split_point:]
+
+ # Recursively split both parts if they are still too large
+ split_parts = []
+ split_parts.extend(self.check_and_split_msgParts(part1, max_size)) # Corrected
+ split_parts.extend(self.check_and_split_msgParts(part2, max_size)) # Corrected
+
+ return split_parts
+ else:
+ return [msg_parts]
def set_websocket_conn(self, event_type):
+ max_retries = 3
url = f"wss://logstream.proofpoint.com:443/v1/stream?cid={self.cluster_id}&type={event_type}&sinceTime={self.after_time}&toTime={self.before_time}"
- logging.info('Opening Websocket logstream {}'.format(url))
# defining headers for websocket connection (do not change this)
header = {
"Connection": "Upgrade",
@@ -72,21 +95,26 @@ def set_websocket_conn(self, event_type):
'ca_certs': certifi.where(),
'check_hostname': True
}
- try:
- ws = websocket.create_connection(url, header=header, sslopt=sslopt)
- ws.settimeout(20)
- time.sleep(2)
- logging.info(
- 'Websocket connection established to cluster_id={}, event_type={}'.format(self.cluster_id, event_type))
- print(
- 'Websocket connection established to cluster_id={}, event_type={}'.format(self.cluster_id, event_type))
- return ws
- except Exception as err:
- logging.error('Error while connectiong to websocket {}'.format(err))
- print('Error while connectiong to websocket {}'.format(err))
- return None
-
- def gen_chunks_to_object(self,data,chunksize=100):
+ for attempt in range(max_retries):
+ try:
+ logging.info('Opening Websocket logstream {}'.format(url))
+ ws = websocket.create_connection(url, header=header, sslopt=sslopt)
+ ws.settimeout(20)
+ time.sleep(2)
+ logging.info(
+ 'Websocket connection established to cluster_id={}, event_type={}'.format(self.cluster_id, event_type))
+ print('Websocket connection established to cluster_id={}, event_type={}'.format(self.cluster_id, event_type))
+ return ws
+ except Exception as err:
+ logging.error('Error while connectiong to websocket {}'.format(err))
+ print('Error while connectiong to websocket {}'.format(err))
+ if attempt < max_retries - 1:
+ logging.info('Retrying connection in 5 seconds...')
+ time.sleep(5) # Wait for a while before retrying
+ else:
+ return None
+
+ def gen_chunks_to_object(self, data, chunksize=100):
chunk = []
for index, line in enumerate(data):
if (index % chunksize == 0 and index > 0):
@@ -95,15 +123,26 @@ def gen_chunks_to_object(self,data,chunksize=100):
chunk.append(line)
yield chunk
- def gen_chunks(self,data,event_type):
+ def gen_chunks(self, data, event_type):
for chunk in self.gen_chunks_to_object(data, chunksize=10000):
print(len(chunk))
obj_array = []
for row in chunk:
if row != None and row != '':
y = json.loads(row)
+ #logging.info(f'json row : {y}')
y.update({'event_type': event_type})
+ if 'msgParts' in y:
+ msg_parts = y['msgParts']
+ split_parts = self.check_and_split_msgParts(msg_parts)
+ if len(split_parts) == 1: # No splitting required
+ y["msgParts"] = split_parts[0]
+ else: # Splitting required
+ for i, part in enumerate(split_parts, start=1):
+ y[f"msgParts{i}"] = part
+ del y["msgParts"]
obj_array.append(y)
+ #logging.info(f'Response Object array : {obj_array}')
sentinel = AzureSentinelConnector(
log_analytics_uri=logAnalyticsUri,
@@ -113,6 +152,7 @@ def gen_chunks(self,data,event_type):
queue_size=5000
)
for event in obj_array:
+ #logging.info(f'Response event : {event}')
sentinel.send(event)
sentinel.flush()
@@ -128,7 +168,7 @@ def get_data(self, event_type=None):
events.append(data)
sent_events += 1
if len(events) > 500:
- self.gen_chunks(events,event_type)
+ self.gen_chunks(events, event_type)
events = []
except websocket._exceptions.WebSocketTimeoutException:
break
@@ -142,10 +182,10 @@ def get_data(self, event_type=None):
logging.error('Error while closing socket: {}'.format(err))
print('Error while closing socket: {}'.format(err))
if sent_events > 0:
- self.gen_chunks(events,event_type)
+ self.gen_chunks(events, event_type)
logging.info('Total events sent: {}. Type: {}. Period(UTC): {} - {}'.format(sent_events, event_type,
self.after_time,
self.before_time))
print('Total events sent: {}. Type: {}. Period(UTC): {} - {}'.format(sent_events, event_type,
self.after_time,
- self.before_time))
\ No newline at end of file
+ self.before_time))
diff --git a/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/host.json b/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/host.json
index a9b836982df..f8f3efaf0e7 100644
--- a/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/host.json
+++ b/Solutions/Proofpoint On demand(POD) Email Security/Data Connectors/host.json
@@ -1,15 +1,16 @@
{
- "version": "2.0",
- "logging": {
- "applicationInsights": {
- "samplingSettings": {
- "isEnabled": true,
- "excludedTypes": "Request"
- }
+ "version": "2.0",
+ "functionTimeout": "00:10:00",
+ "logging": {
+ "applicationInsights": {
+ "samplingSettings": {
+ "isEnabled": true,
+ "excludedTypes": "Request"
}
- },
- "extensionBundle": {
- "id": "Microsoft.Azure.Functions.ExtensionBundle",
- "version": "[3.*, 4.0.0)"
}
- }
\ No newline at end of file
+ },
+ "extensionBundle": {
+ "id": "Microsoft.Azure.Functions.ExtensionBundle",
+ "version": "[3.*, 4.0.0)"
+ }
+}
\ No newline at end of file
diff --git a/Solutions/QualysVM/Data Connectors/azuredeploy_QualysVM_API_FunctionApp_V2.json b/Solutions/QualysVM/Data Connectors/azuredeploy_QualysVM_API_FunctionApp_V2.json
index 778b1f512e4..b6e9414cf03 100644
--- a/Solutions/QualysVM/Data Connectors/azuredeploy_QualysVM_API_FunctionApp_V2.json
+++ b/Solutions/QualysVM/Data Connectors/azuredeploy_QualysVM_API_FunctionApp_V2.json
@@ -8,6 +8,13 @@
"maxLength": 11,
"type": "string"
},
+ "hostingPlan": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "The name of the Azure App Service Plan where this function app will run."
+ }
+ },
"WorkspaceID": {
"type": "string",
"defaultValue": ""
@@ -45,6 +52,7 @@
},
"variables": {
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
+ "HostingPlanName": "[parameters('hostingPlan')]",
"StorageSuffix":"[environment().suffixes.storage]",
"LogAnaltyicsUri":"[replace(environment().portal, 'https://portal', concat('https://', toLower(parameters('WorkspaceID')), '.ods.opinsights'))]"
},
@@ -100,18 +108,24 @@
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
- "name": "[variables('FunctionName')]",
+ "name": "[variables('HostingPlanName')]",
"location": "[resourceGroup().location]",
"sku": {
- "name": "Y1",
- "tier": "Dynamic"
+ "name": "Y1",
+ "tier": "Dynamic",
+ "size": "Y1",
+ "family": "Y",
+ "capacity": 0
},
"kind": "functionapp",
"properties": {
- "name": "[variables('FunctionName')]",
- "workerSize": "0",
- "workerSizeId": "0",
- "numberOfWorkers": "1"
+ "name": "[variables('HostingPlanName')]",
+ "computeMode": "Dynamic",
+ "kind": "functionapp",
+ "reserved": false,
+ "isXenon": false,
+ "hyperV": false,
+ "azBalancing": false
}
},
{
@@ -160,7 +174,7 @@
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
- "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "[resourceId('Microsoft.Web/serverfarms', variables('HostingPlanName'))]",
"[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
],
"kind": "functionapp",
@@ -169,7 +183,7 @@
},
"properties": {
"name": "[variables('FunctionName')]",
- "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
+ "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('HostingPlanName'))]",
"httpsOnly": true,
"clientAffinityEnabled": true,
"alwaysOn": true,
@@ -243,4 +257,4 @@
}
}
]
- }
+}
diff --git a/Solutions/Recorded Future/Data/Solution_RecordedFuture.json b/Solutions/Recorded Future/Data/Solution_RecordedFuture.json
index e1e31bb5a00..4f381ead999 100644
--- a/Solutions/Recorded Future/Data/Solution_RecordedFuture.json
+++ b/Solutions/Recorded Future/Data/Solution_RecordedFuture.json
@@ -42,7 +42,7 @@
"Workbooks/RecordedFutureMalwareThreatHunting.json"
],
"BasePath": "Users\\emangsten\\git\\github\\Azure-Sentinel\\Solutions\\Recorded Future",
- "Version": "3.2.13",
+ "Version": "3.2.14",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1Pconnector": false
diff --git a/Solutions/Recorded Future/Package/3.2.14.zip b/Solutions/Recorded Future/Package/3.2.14.zip
new file mode 100644
index 00000000000..3576be79131
Binary files /dev/null and b/Solutions/Recorded Future/Package/3.2.14.zip differ
diff --git a/Solutions/Recorded Future/Package/mainTemplate.json b/Solutions/Recorded Future/Package/mainTemplate.json
index 7c145142245..aa717494332 100644
--- a/Solutions/Recorded Future/Package/mainTemplate.json
+++ b/Solutions/Recorded Future/Package/mainTemplate.json
@@ -97,7 +97,7 @@
"email": "support@recordedfuture.com",
"_email": "[variables('email')]",
"_solutionName": "Recorded Future",
- "_solutionVersion": "3.2.13",
+ "_solutionVersion": "3.2.14",
"solutionId": "recordedfuture1605638642586.recorded_future_sentinel_solution",
"_solutionId": "[variables('solutionId')]",
"analyticRuleObject1": {
@@ -206,7 +206,7 @@
"_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]",
"RecordedFuture-Domain-IndicatorImport": "RecordedFuture-Domain-IndicatorImport",
"_RecordedFuture-Domain-IndicatorImport": "[variables('RecordedFuture-Domain-IndicatorImport')]",
- "playbookVersion5": "1.0",
+ "playbookVersion5": "1.2",
"playbookContentId5": "RecordedFuture-Domain-IndicatorImport",
"_playbookContentId5": "[variables('playbookContentId5')]",
"playbookId5": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId5'))]",
@@ -214,7 +214,7 @@
"_playbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId5'),'-', variables('playbookVersion5'))))]",
"RecordedFuture-Hash-IndicatorImport": "RecordedFuture-Hash-IndicatorImport",
"_RecordedFuture-Hash-IndicatorImport": "[variables('RecordedFuture-Hash-IndicatorImport')]",
- "playbookVersion6": "1.0",
+ "playbookVersion6": "1.2",
"playbookContentId6": "RecordedFuture-Hash-IndicatorImport",
"_playbookContentId6": "[variables('playbookContentId6')]",
"playbookId6": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId6'))]",
@@ -222,7 +222,7 @@
"_playbookcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId6'),'-', variables('playbookVersion6'))))]",
"RecordedFuture-IP-IndicatorImport": "RecordedFuture-IP-IndicatorImport",
"_RecordedFuture-IP-IndicatorImport": "[variables('RecordedFuture-IP-IndicatorImport')]",
- "playbookVersion7": "1.0",
+ "playbookVersion7": "1.2",
"playbookContentId7": "RecordedFuture-IP-IndicatorImport",
"_playbookContentId7": "[variables('playbookContentId7')]",
"playbookId7": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId7'))]",
@@ -230,7 +230,7 @@
"_playbookcontentProductId7": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId7'),'-', variables('playbookVersion7'))))]",
"RecordedFuture-URL-IndicatorImport": "RecordedFuture-URL-IndicatorImport",
"_RecordedFuture-URL-IndicatorImport": "[variables('RecordedFuture-URL-IndicatorImport')]",
- "playbookVersion8": "1.0",
+ "playbookVersion8": "1.2",
"playbookContentId8": "RecordedFuture-URL-IndicatorImport",
"_playbookContentId8": "[variables('playbookContentId8')]",
"playbookId8": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId8'))]",
@@ -344,7 +344,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureDomainMalwareC2inDNSEvents_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureDomainMalwareC2inDNSEvents_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -483,7 +483,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureDomainMalwareC2inSyslogEvents_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureDomainMalwareC2inSyslogEvents_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -623,7 +623,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureHashObservedInUndergroundinCommonSecurityLog_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureHashObservedInUndergroundinCommonSecurityLog_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -779,7 +779,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureIPMalwareC2inAzureActivityEvents_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureIPMalwareC2inAzureActivityEvents_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -910,7 +910,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureIPMalwareC2inDNSEvents_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureIPMalwareC2inDNSEvents_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -1055,7 +1055,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureUrlReportedbyInsiktGroupinSyslogEvents_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureUrlReportedbyInsiktGroupinSyslogEvents_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -1184,7 +1184,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureThreatHuntingHashAllActors_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureThreatHuntingHashAllActors_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -1321,7 +1321,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureThreatHuntingIPAllActors_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureThreatHuntingIPAllActors_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -1452,7 +1452,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureThreatHuntingDomainAllActors_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureThreatHuntingDomainAllActors_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -1583,7 +1583,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureThreatHuntingUrlAllActors_AnalyticalRules Analytics Rule with template version 3.2.13",
+ "description": "RecordedFutureThreatHuntingUrlAllActors_AnalyticalRules Analytics Rule with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]",
@@ -1712,7 +1712,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-IOC_Enrichment Playbook with template version 3.2.13",
+ "description": "RecordedFuture-IOC_Enrichment Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion1')]",
@@ -2386,7 +2386,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-Playbook-Alert-Importer Playbook with template version 3.2.13",
+ "description": "RecordedFuture-Playbook-Alert-Importer Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion2')]",
@@ -2756,7 +2756,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-AlertImporter Playbook with template version 3.2.13",
+ "description": "RecordedFuture-AlertImporter Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion3')]",
@@ -3218,7 +3218,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-ThreatIntelligenceImport Playbook with template version 3.2.13",
+ "description": "RecordedFuture-ThreatIntelligenceImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion4')]",
@@ -3447,7 +3447,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-Domain-IndicatorImport Playbook with template version 3.2.13",
+ "description": "RecordedFuture-Domain-IndicatorImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion5')]",
@@ -3554,7 +3554,7 @@
}
}
},
- "RecordedFuture-ImportToSentinel": {
+ "RecordedFuture-ThreatIntelligenceImport": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
@@ -3637,7 +3637,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-Domain-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0",
+ "hidden-SentinelTemplateVersion": "1.2",
"hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
},
"dependsOn": [
@@ -3694,7 +3694,7 @@
"postDeployment": [
"After deployment, open the playbook to configure all connections and press save."
],
- "lastUpdateTime": "2024-01-12T00:00:00Z",
+ "lastUpdateTime": "2025-01-29T00:00:00Z",
"tags": [
"Threat Intelligence"
],
@@ -3712,6 +3712,13 @@
"notes": [
"API connection rename."
]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [
+ "Rename logic app block for consistency."
+ ]
}
]
}
@@ -3738,7 +3745,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-Hash-IndicatorImport Playbook with template version 3.2.13",
+ "description": "RecordedFuture-Hash-IndicatorImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion6')]",
@@ -3845,7 +3852,7 @@
}
}
},
- "RecordedFuture-ImportToSentinel": {
+ "RecordedFuture-ThreatIntelligenceImport": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
@@ -3928,7 +3935,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-Hash-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0",
+ "hidden-SentinelTemplateVersion": "1.2",
"hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
},
"dependsOn": [
@@ -3985,7 +3992,7 @@
"postDeployment": [
"After deployment, open the playbook to configure all connections and press save."
],
- "lastUpdateTime": "2024-01-12T00:00:00Z",
+ "lastUpdateTime": "2025-01-30T00:00:00Z",
"tags": [
"Threat Intelligence"
],
@@ -4003,6 +4010,13 @@
"notes": [
"API connection rename."
]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [
+ "Rename logic app block for consistency."
+ ]
}
]
}
@@ -4029,7 +4043,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-IP-IndicatorImport Playbook with template version 3.2.13",
+ "description": "RecordedFuture-IP-IndicatorImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion7')]",
@@ -4220,7 +4234,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-IP-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0",
+ "hidden-SentinelTemplateVersion": "1.2",
"hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
},
"dependsOn": [
@@ -4278,7 +4292,7 @@
"postDeployment": [
"After deployment, open the playbook to configure all connections and press save."
],
- "lastUpdateTime": "2024-01-12T17:00:00Z",
+ "lastUpdateTime": "2025-01-30T17:00:00Z",
"tags": [
"Threat Intelligence"
],
@@ -4296,6 +4310,13 @@
"notes": [
"API connection rename."
]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [
+ "Rename logic app block for consistency."
+ ]
}
]
}
@@ -4322,7 +4343,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-URL-IndicatorImport Playbook with template version 3.2.13",
+ "description": "RecordedFuture-URL-IndicatorImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion8')]",
@@ -4429,7 +4450,7 @@
}
}
},
- "RecordedFuture-ImportToSentinel": {
+ "RecordedFuture-ThreatIntelligenceImport": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
@@ -4512,7 +4533,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-URL-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0",
+ "hidden-SentinelTemplateVersion": "1.2",
"hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
},
"dependsOn": [
@@ -4569,7 +4590,7 @@
"postDeployment": [
"After deployment, open the playbook to configure all connections and press save."
],
- "lastUpdateTime": "2024-01-12T00:00:00Z",
+ "lastUpdateTime": "2025-01-30T00:00:00Z",
"tags": [
"Threat Intelligence"
],
@@ -4587,6 +4608,13 @@
"notes": [
"API connection rename."
]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [
+ "Rename logic app block for consistency."
+ ]
}
]
}
@@ -4613,7 +4641,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-Sandbox_Enrichment-Url Playbook with template version 3.2.13",
+ "description": "RecordedFuture-Sandbox_Enrichment-Url Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion9')]",
@@ -4998,7 +5026,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-CustomConnector Playbook with template version 3.2.13",
+ "description": "RecordedFuture-CustomConnector Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion10')]",
@@ -5083,7 +5111,7 @@
"url": "https://support.recordedfuture.com",
"email": "support@recordedfuture.com"
},
- "version": "1.0"
+ "version": "1.1"
},
"host": "api.recordedfuture.com",
"basePath": "/gw/azure",
@@ -5229,7 +5257,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -5516,7 +5544,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -5659,7 +5687,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -5808,7 +5836,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -5955,7 +5983,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -6572,7 +6600,7 @@
}
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -7626,7 +7654,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-ThreatMap-Importer Playbook with template version 3.2.13",
+ "description": "RecordedFuture-ThreatMap-Importer Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion11')]",
@@ -8005,7 +8033,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuture-MalwareThreatMap-Importer Playbook with template version 3.2.13",
+ "description": "RecordedFuture-MalwareThreatMap-Importer Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion12')]",
@@ -8380,7 +8408,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ActorThreatHunt-IndicatorImport Playbook with template version 3.2.13",
+ "description": "ActorThreatHunt-IndicatorImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion13')]",
@@ -8616,7 +8644,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MalwareThreatHunt-IndicatorImport Playbook with template version 3.2.13",
+ "description": "MalwareThreatHunt-IndicatorImport Playbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion14')]",
@@ -8853,7 +8881,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFuturePlaybookAlertOverview Workbook with template version 3.2.13",
+ "description": "RecordedFuturePlaybookAlertOverview Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -8937,7 +8965,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureAlertOverview Workbook with template version 3.2.13",
+ "description": "RecordedFutureAlertOverview Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -9021,7 +9049,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureDomainCorrelation Workbook with template version 3.2.13",
+ "description": "RecordedFutureDomainCorrelation Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -9105,7 +9133,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureHashCorrelation Workbook with template version 3.2.13",
+ "description": "RecordedFutureHashCorrelation Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion4')]",
@@ -9189,7 +9217,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureIPCorrelation Workbook with template version 3.2.13",
+ "description": "RecordedFutureIPCorrelation Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion5')]",
@@ -9273,7 +9301,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureURLCorrelation Workbook with template version 3.2.13",
+ "description": "RecordedFutureURLCorrelation Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion6')]",
@@ -9357,7 +9385,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureThreatActorHunting Workbook with template version 3.2.13",
+ "description": "RecordedFutureThreatActorHunting Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion7')]",
@@ -9441,7 +9469,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "RecordedFutureMalwareThreatHunting Workbook with template version 3.2.13",
+ "description": "RecordedFutureMalwareThreatHunting Workbook with template version 3.2.14",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion8')]",
@@ -9521,7 +9549,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.2.13",
+ "version": "3.2.14",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Recorded Future",
diff --git a/Solutions/Recorded Future/Playbooks/Alerts/pba_categories.png b/Solutions/Recorded Future/Playbooks/Alerts/pba_categories.png
new file mode 100644
index 00000000000..23a86c056ff
Binary files /dev/null and b/Solutions/Recorded Future/Playbooks/Alerts/pba_categories.png differ
diff --git a/Solutions/Recorded Future/Playbooks/Alerts/readme.md b/Solutions/Recorded Future/Playbooks/Alerts/readme.md
index 8cb0b31d24d..b8b8ba8addf 100644
--- a/Solutions/Recorded Future/Playbooks/Alerts/readme.md
+++ b/Solutions/Recorded Future/Playbooks/Alerts/readme.md
@@ -8,14 +8,15 @@ Included in Recorded Future Intelligence Solution: **Yes**\
Requires **/recordedfuturev2** API keys as described in the [Connector authorization](../readme.md#connectors-authorization) section. \
Connectors used: ***recordedfuturev2***, ***azuresentinel***, ***azureloganalyticsdatacollector*** and ***azuremonitorlogs*** see [Connector authorization](../readme.md#connectors-authorization) for guidance.
+
+
+
Retrieves Alerts and stores them in a custom log in the Log Analytic Workspace. More information on Alerts (requires Recorded Future login)
The Alert importer playbook can create sentinel incidents when receiving alerts. Its possible to turn off incident generation by setting the logic app parameter create_incident to false.

-
-
## RecordedFuture-Playbook-Alert-Importer
@@ -24,11 +25,24 @@ Included in Recorded Future Intelligence Solution: **Yes**\
Requires **/recordedfuturev2** API keys as described in the [Connector authorization](#connectors-authorization) section. \
Connectors used: ***recordedfuturev2***, ***azuresentinel*** and ***azureloganalyticsdatacollector*** see [Connector authorization](../readme.md#connectors-authorization) for guidance.
+
+
+
Retrieves Playbook Alerts and stores them in a custom log in the Log Analytic Workspace. More information on Playbook Alerts (requires Recorded Future login)
The Playbook Alert importer playbook can create sentinel incidents when receiving alerts. Its possible to turn off incident generation by setting the logic app parameter create_incident to false.

-
-
+
+### Limiting Playbook Alert categories
+If you want to import only specific Playbook Alert categories, you can edit the `Search Playbook Alerts` step within the logic app and specify `Categories`:
+
+
+
+The currently supported Playbook Alert categories are:
+- `code_repo_leakage`
+- `domain_abuse`
+- `identity_novel_exposures`
+- `third_party_risk`
+- `cyber_vulnerability`
diff --git a/Solutions/Recorded Future/Playbooks/Connectors/RecordedFuture-CustomConnector/azuredeploy.json b/Solutions/Recorded Future/Playbooks/Connectors/RecordedFuture-CustomConnector/azuredeploy.json
index 4645396cf10..7e29e0f9323 100644
--- a/Solutions/Recorded Future/Playbooks/Connectors/RecordedFuture-CustomConnector/azuredeploy.json
+++ b/Solutions/Recorded Future/Playbooks/Connectors/RecordedFuture-CustomConnector/azuredeploy.json
@@ -1,6 +1,6 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
+ "contentVersion": "1.1.0.0",
"parameters": {
"ConnectorName": {
"defaultValue": "RecordedFuture-CustomConnector",
@@ -48,7 +48,7 @@
"url": "https://support.recordedfuture.com",
"email": "support@recordedfuture.com"
},
- "version": "1.0"
+ "version": "1.1"
},
"host": "api.recordedfuture.com",
"basePath": "/gw/azure",
@@ -194,7 +194,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -481,7 +481,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -624,7 +624,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -773,7 +773,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -920,7 +920,7 @@
"x-ms-visibility": "internal"
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
@@ -1537,7 +1537,7 @@
}
},
{
- "name": "IntelligenceCloudTracking",
+ "name": "IntelligenceCloud",
"in": "query",
"required": false,
"type": "boolean",
diff --git a/Solutions/Recorded Future/Playbooks/Enrichment/readme.md b/Solutions/Recorded Future/Playbooks/Enrichment/readme.md
index be84a60d6ea..39f1c5cc094 100644
--- a/Solutions/Recorded Future/Playbooks/Enrichment/readme.md
+++ b/Solutions/Recorded Future/Playbooks/Enrichment/readme.md
@@ -41,7 +41,7 @@ This will trigger the Recorded Future playbook to run when any incident is creat
The Recorded Future Collective Insights aggregates data related to Sigma Rules and other indicators, driving collective insights to better identify threats. Anonymized, unattributable data is collected for analytical purposes to identify trends and insights with the Collective Insights. The **RecordedFuture-IOC_Enrichment** playbook gives end users the ability to contribute collective insights to the Collective Insights.
Click here to learn more (requires Recorded Future Login)
-To opt-out from Collective insights by setting the CollectiveInsights parameter to [false]
+To opt-out from Collective insights by setting the IntelligenceCloud parameter to [false]

diff --git a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Domain-IndicatorImport/azuredeploy.json b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Domain-IndicatorImport/azuredeploy.json
index 9275d111e5c..adfe5b324b5 100644
--- a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Domain-IndicatorImport/azuredeploy.json
+++ b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Domain-IndicatorImport/azuredeploy.json
@@ -1,6 +1,6 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
+ "contentVersion": "1.2.0.0",
"metadata": {
"title": "RecordedFuture-Domain-IndicatorImport",
"description": "This playbook imports Domain risk lists from Recorded Future and stores them as Threat Intelligence Indicators in Microsoft Sentinel, for detection purposes.\n\nThis playbook depends on RecordedFuture-ThreatIntelligenceImport that need to be installed **manually** before installing this playbook.",
@@ -12,7 +12,7 @@
"After deployment, open the playbook to configure all connections and press save."
],
"prerequisitesDeployTemplateFile": "../RecordedFuture-ThreatIntelligenceImport/azuredeploy.json",
- "lastUpdateTime": "2024-01-12T00:00:00.000Z",
+ "lastUpdateTime": "2025-01-29T00:00:00.000Z",
"entities": [],
"tags": [ "Threat Intelligence" ],
"support": {
@@ -28,10 +28,15 @@
"title": "RecordedFuture-Domain-IndicatorImport",
"notes": [ "Initial version" ]
},
- {
+ {
"version": "1.1",
"title": "API Connectors",
"notes": [ "API connection rename." ]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [ "Rename logic app block for consistency." ]
}
]
},
@@ -135,7 +140,7 @@
}
}
},
- "RecordedFuture-ImportToSentinel": {
+ "RecordedFuture-ThreatIntelligenceImport": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
@@ -220,7 +225,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-Domain-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0"
+ "hidden-SentinelTemplateVersion": "1.2"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('RecordedfutureConnectionName'))]"
diff --git a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Hash-IndicatorImport/azuredeploy.json b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Hash-IndicatorImport/azuredeploy.json
index e852edc8748..2d3547e4680 100644
--- a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Hash-IndicatorImport/azuredeploy.json
+++ b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-Hash-IndicatorImport/azuredeploy.json
@@ -1,6 +1,6 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
+ "contentVersion": "1.2.0.0",
"metadata": {
"title": "RecordedFuture-Hash-IndicatorImport",
"description": "This playbook imports Hash risk lists from Recorded Future and stores them as Threat Intelligence Indicators in Microsoft Sentinel, for detection purposes.\n\nThis playbook depends on RecordedFuture-ThreatIntelligenceImport that need to be installed **manually** before installing this playbook.",
@@ -12,7 +12,7 @@
"After deployment, open the playbook to configure all connections and press save."
],
"prerequisitesDeployTemplateFile": "../RecordedFuture-ThreatIntelligenceImport/azuredeploy.json",
- "lastUpdateTime": "2024-01-12T00:00:00.000Z",
+ "lastUpdateTime": "2025-01-30T00:00:00.000Z",
"entities": [],
"tags": [ "Threat Intelligence" ],
"support": {
@@ -28,10 +28,15 @@
"title": "RecordedFuture-Hash-IndicatorImport",
"notes": [ "Initial version" ]
},
- {
+ {
"version": "1.1",
"title": "API Connectors",
"notes": [ "API connection rename." ]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [ "Rename logic app block for consistency." ]
}
]
},
@@ -136,7 +141,7 @@
}
}
},
- "RecordedFuture-ImportToSentinel": {
+ "RecordedFuture-ThreatIntelligenceImport": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
@@ -221,7 +226,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-Hash-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0"
+ "hidden-SentinelTemplateVersion": "1.2"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('RecordedfutureConnectionName'))]"
diff --git a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-IP-IndicatorImport/azuredeploy.json b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-IP-IndicatorImport/azuredeploy.json
index e84cd310f62..7d9cfb1d239 100644
--- a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-IP-IndicatorImport/azuredeploy.json
+++ b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-IP-IndicatorImport/azuredeploy.json
@@ -1,6 +1,6 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
+ "contentVersion": "1.2.0.0",
"metadata": {
"title": "RecordedFuture-IP-IndicatorImport",
"description": "This playbook imports IP risk lists from Recorded Future and stores them as Threat Intelligence Indicators in Microsoft Sentinel, for detection purposes.\n\nThis playbook depends on RecordedFuture-ThreatIntelligenceImport that need to be installed **manually** before installing this playbook.",
@@ -13,7 +13,7 @@
"After deployment, open the playbook to configure all connections and press save."
],
"prerequisitesDeployTemplateFile": "../RecordedFuture-ThreatIntelligenceImport/azuredeploy.json",
- "lastUpdateTime": "2024-01-12T17:00:00.000Z",
+ "lastUpdateTime": "2025-01-30T17:00:00.000Z",
"entities": [],
"tags": [ "Threat Intelligence" ],
"support": {
@@ -28,10 +28,15 @@
"title": "RecordedFuture-IP-IndicatorImport",
"notes": [ "Initial version" ]
},
- {
+ {
"version": "1.1",
"title": "API Connectors",
"notes": [ "API connection rename." ]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [ "Rename logic app block for consistency." ]
}
]
},
@@ -221,7 +226,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-IP-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0"
+ "hidden-SentinelTemplateVersion": "1.2"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('RecordedfutureConnectionName'))]"
diff --git a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-URL-IndicatorImport/azuredeploy.json b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-URL-IndicatorImport/azuredeploy.json
index 6c8adf3f8e5..df4afab4958 100644
--- a/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-URL-IndicatorImport/azuredeploy.json
+++ b/Solutions/Recorded Future/Playbooks/IndicatorImport/RecordedFuture-URL-IndicatorImport/azuredeploy.json
@@ -1,6 +1,6 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "1.0.0.0",
+ "contentVersion": "1.2.0.0",
"metadata": {
"title": "RecordedFuture-URL-IndicatorImport",
"description": "This playbook imports URL risk lists from Recorded Future and stores them as Threat Intelligence Indicators in Microsoft Sentinel, for detection purposes.\n\nThis playbook depends on RecordedFuture-ThreatIntelligenceImport that need to be installed **manually** before installing this playbook.",
@@ -12,7 +12,7 @@
"After deployment, open the playbook to configure all connections and press save."
],
"prerequisitesDeployTemplateFile": "../RecordedFuture-ThreatIntelligenceImport/azuredeploy.json",
- "lastUpdateTime": "2024-01-12T00:00:00.000Z",
+ "lastUpdateTime": "2025-01-30T00:00:00.000Z",
"entities": [],
"tags": [ "Threat Intelligence" ],
"support": {
@@ -32,6 +32,11 @@
"version": "1.1",
"title": "API Connectors",
"notes": [ "API connection rename." ]
+ },
+ {
+ "version": "1.2",
+ "title": "Minor rename",
+ "notes": [ "Rename logic app block for consistency." ]
}
]
},
@@ -135,7 +140,7 @@
}
}
},
- "RecordedFuture-ImportToSentinel": {
+ "RecordedFuture-ThreatIntelligenceImport": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
@@ -220,7 +225,7 @@
"apiVersion": "2017-07-01",
"tags": {
"hidden-SentinelTemplateName": "RecordedFuture-URL-IndicatorImport",
- "hidden-SentinelTemplateVersion": "1.0"
+ "hidden-SentinelTemplateVersion": "1.2"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('RecordedfutureConnectionName'))]"
diff --git a/Solutions/Recorded Future/ReleaseNotes.md b/Solutions/Recorded Future/ReleaseNotes.md
index e84c2ea2d57..26243709066 100644
--- a/Solutions/Recorded Future/ReleaseNotes.md
+++ b/Solutions/Recorded Future/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.2.14 | 30-01-2025 | Fix the name of `IntelligenceCloud` parameter in `RecordedFuture-CustomConnector` + other minor renames |
| 3.2.13 | 08-01-2025 | Removed Custom Entity mappings from **Analytic rules** |
| 3.2.12 | 28-11-2024 | Fix API connection bug in RecordedFuture-AlertImporter |
| 3.2.11 | 31-10-2024 | Fix API connection bug in RecordedFuture-ThreatMap-Importer, documentation improvements |
diff --git a/Solutions/SailPointIdentityNow/Data Connectors/SearchEvent.zip b/Solutions/SailPointIdentityNow/Data Connectors/SearchEvent.zip
index d57e82027a7..81b4ddbf209 100644
Binary files a/Solutions/SailPointIdentityNow/Data Connectors/SearchEvent.zip and b/Solutions/SailPointIdentityNow/Data Connectors/SearchEvent.zip differ
diff --git a/Solutions/SailPointIdentityNow/Data Connectors/requirements.txt b/Solutions/SailPointIdentityNow/Data Connectors/requirements.txt
index e158df1caa4..9890f748c9f 100644
--- a/Solutions/SailPointIdentityNow/Data Connectors/requirements.txt
+++ b/Solutions/SailPointIdentityNow/Data Connectors/requirements.txt
@@ -9,5 +9,5 @@ azure-storage==0.36.0
azure-data-tables==12.1.0
azure-cosmos==4.2.0
azure-cosmosdb-table==1.0.6
-cryptography==43.0.1
+cryptography==44.0.1
cffi==1.14.6
\ No newline at end of file
diff --git a/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-BruteForce.yaml b/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-BruteForce.yaml
index 4e9671a385a..4beb903745a 100644
--- a/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-BruteForce.yaml
+++ b/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-BruteForce.yaml
@@ -9,8 +9,8 @@ requiredDataConnectors:
- connectorId: SalesforceServiceCloud
dataTypes:
- SalesforceServiceCloud
-queryFrequency: 20m
-queryPeriod: 20m
+queryFrequency: 1h
+queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
@@ -48,5 +48,5 @@ entityMappings:
fieldMappings:
- identifier: FullName
columnName: User
-version: 1.0.2
+version: 1.0.3
kind: Scheduled
diff --git a/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-PasswordSpray.yaml b/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-PasswordSpray.yaml
index 87e876cc6f4..c0f529eb24e 100644
--- a/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-PasswordSpray.yaml
+++ b/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-PasswordSpray.yaml
@@ -1,15 +1,15 @@
id: 64d16e62-1a17-4a35-9ea7-2b9fe6f07118
name: Potential Password Spray Attack
description: |
- 'This query searches for failed attempts to log in from more than 15 various users within a 5 minute timeframe from the same source. This is a potential indication of a password spray attack.'
+ 'This query searches for failed attempts to log in from more than 15 various users within a 5 minutes timeframe from the same source. This is a potential indication of a password spray attack.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: SalesforceServiceCloud
dataTypes:
- SalesforceServiceCloud
-queryFrequency: 5m
-queryPeriod: 5m
+queryFrequency: 1h
+queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
@@ -30,5 +30,5 @@ entityMappings:
fieldMappings:
- identifier: Address
columnName: ClientIp
-version: 1.0.1
+version: 1.0.2
kind: Scheduled
diff --git a/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-SigninsMultipleCountries.yaml b/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-SigninsMultipleCountries.yaml
index ab5110384cf..be83c9a9b72 100644
--- a/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-SigninsMultipleCountries.yaml
+++ b/Solutions/Salesforce Service Cloud/Analytic Rules/Salesforce-SigninsMultipleCountries.yaml
@@ -1,15 +1,15 @@
id: 3094e036-e5ae-4d6e-8626-b0f86ebc71f2
name: User Sign in from different countries
description: |
- 'This query searches for successful user logins from different countries within 30min.'
+ 'This query searches for successful user logins from different countries within 30 mins.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: SalesforceServiceCloud
dataTypes:
- SalesforceServiceCloud
-queryFrequency: 30m
-queryPeriod: 30m
+queryFrequency: 1h
+queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
@@ -37,5 +37,5 @@ entityMappings:
fieldMappings:
- identifier: AadUserId
columnName: User
-version: 1.0.1
+version: 1.0.2
kind: Scheduled
diff --git a/Solutions/Salesforce Service Cloud/Data/Solution_TSalesforceCloudtemplateSpec.json b/Solutions/Salesforce Service Cloud/Data/Solution_TSalesforceCloudtemplateSpec.json
index 5ea02a1e7c2..abc268eef29 100644
--- a/Solutions/Salesforce Service Cloud/Data/Solution_TSalesforceCloudtemplateSpec.json
+++ b/Solutions/Salesforce Service Cloud/Data/Solution_TSalesforceCloudtemplateSpec.json
@@ -18,7 +18,7 @@
"Workbooks/SalesforceServiceCloud.json"
],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Salesforce Service Cloud",
- "Version": "3.0.0",
+ "Version": "3.0.1",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1PConnector": false
diff --git a/Solutions/Salesforce Service Cloud/Package/3.0.1.zip b/Solutions/Salesforce Service Cloud/Package/3.0.1.zip
new file mode 100644
index 00000000000..dce111c4e42
Binary files /dev/null and b/Solutions/Salesforce Service Cloud/Package/3.0.1.zip differ
diff --git a/Solutions/Salesforce Service Cloud/Package/createUiDefinition.json b/Solutions/Salesforce Service Cloud/Package/createUiDefinition.json
index 09c7fec5421..e530e25d63f 100644
--- a/Solutions/Salesforce Service Cloud/Package/createUiDefinition.json
+++ b/Solutions/Salesforce Service Cloud/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \r \n • Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Salesforce%20Service%20Cloud/ReleaseNotes.md)\r \n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Salesforce Service Cloud](https://www.salesforce.com/in/products/service-cloud/overview/) solution for Microsoft Sentinel enables you to ingest Service Cloud events into Microsoft Sentinel.\r\n \r\n **Underlying Microsoft Technologies used:** \r\n\r\n This solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\r\n\n a. [Azure Monitor HTTP Data Collector API](https://docs.microsoft.com/azure/azure-monitor/logs/data-collector-api)\r\n\n b. [Azure Functions](https://azure.microsoft.com/services/functions/#overview)\n\n**Data Connectors:** 1, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Salesforce%20Service%20Cloud/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Salesforce Service Cloud](https://www.salesforce.com/in/products/service-cloud/overview/) solution for Microsoft Sentinel enables you to ingest Service Cloud events into Microsoft Sentinel.\r\n \r\n **Underlying Microsoft Technologies used:** \r\n\r\n This solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\r\n\n a. [Azure Monitor HTTP Data Collector API](https://docs.microsoft.com/azure/azure-monitor/logs/data-collector-api)\r\n\n b. [Azure Functions](https://azure.microsoft.com/services/functions/#overview)\n\n**Data Connectors:** 1, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
@@ -60,14 +60,14 @@
"name": "dataconnectors1-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "The Salesforce Service Cloud data connector provides the capability to ingest information about your Salesforce operational events into Microsoft Sentinel through the REST API. The connector provides the ability to review events in your org on an accelerated basis and get event log files in hourly increments for recent activity. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ "text": "This Solution installs the data connector for Salesforce Service Cloud. You can get Salesforce Service Cloud custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
}
},
{
"name": "dataconnectors-parser-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "The solution installs a parser that transforms ingested data. The transformed logs can be accessed using the SalesforceServiceCloud Kusto Function alias."
+ "text": "The Solution installs a parser that transforms the ingested data into Microsoft Sentinel normalized format. The normalized format enables better correlation of different types of data from different data sources to drive end-to-end outcomes seamlessly in security monitoring, hunting, incident investigation and response scenarios in Microsoft Sentinel."
}
},
{
@@ -159,7 +159,7 @@
"name": "analytic1-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "Identifies evidence of brute force activity against a user based on multiple authentication failures \nand at least one successful authentication within a given time window. This query limits IPAddresses to 100 and may not potentially cover all IPAddresses\nThe default failure threshold is 10, success threshold is 1, and the default time window is 20 minutes."
+ "text": "Identifies evidence of brute force activity against a user based on multiple authentication failures and at least one successful authentication within a given time window. This query limits IPAddresses to 100 and may not potentially cover all IPAddresses.\nThe default failure threshold is 10, success threshold is 1, and the default time window is 20 minutes."
}
}
]
@@ -173,7 +173,7 @@
"name": "analytic2-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "This query searches for failed attempts to log in from more than 15 various users within a 5 minute timeframe from the same source. This is a potential indication of a password spray attack."
+ "text": "This query searches for failed attempts to log in from more than 15 various users within a 5 minutes timeframe from the same source. This is a potential indication of a password spray attack."
}
}
]
@@ -187,7 +187,7 @@
"name": "analytic3-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "This query searches for successful user logins from different countries within 30min."
+ "text": "This query searches for successful user logins from different countries within 30 mins."
}
}
]
diff --git a/Solutions/Salesforce Service Cloud/Package/mainTemplate.json b/Solutions/Salesforce Service Cloud/Package/mainTemplate.json
index b114a3242f1..22b044525a9 100644
--- a/Solutions/Salesforce Service Cloud/Package/mainTemplate.json
+++ b/Solutions/Salesforce Service Cloud/Package/mainTemplate.json
@@ -38,12 +38,33 @@
}
},
"variables": {
- "solutionId": "azuresentinel.azure-sentinel-solution-salesforceservicecloud",
- "_solutionId": "[variables('solutionId')]",
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Salesforce Service Cloud",
- "_solutionVersion": "3.0.0",
+ "_solutionVersion": "3.0.1",
+ "solutionId": "azuresentinel.azure-sentinel-solution-salesforceservicecloud",
+ "_solutionId": "[variables('solutionId')]",
+ "analyticRuleObject1": {
+ "analyticRuleVersion1": "1.0.3",
+ "_analyticRulecontentId1": "5a6ce089-e756-40fb-b022-c8e8864a973a",
+ "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '5a6ce089-e756-40fb-b022-c8e8864a973a')]",
+ "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('5a6ce089-e756-40fb-b022-c8e8864a973a')))]",
+ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','5a6ce089-e756-40fb-b022-c8e8864a973a','-', '1.0.3')))]"
+ },
+ "analyticRuleObject2": {
+ "analyticRuleVersion2": "1.0.2",
+ "_analyticRulecontentId2": "64d16e62-1a17-4a35-9ea7-2b9fe6f07118",
+ "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '64d16e62-1a17-4a35-9ea7-2b9fe6f07118')]",
+ "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('64d16e62-1a17-4a35-9ea7-2b9fe6f07118')))]",
+ "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','64d16e62-1a17-4a35-9ea7-2b9fe6f07118','-', '1.0.2')))]"
+ },
+ "analyticRuleObject3": {
+ "analyticRuleVersion3": "1.0.2",
+ "_analyticRulecontentId3": "3094e036-e5ae-4d6e-8626-b0f86ebc71f2",
+ "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '3094e036-e5ae-4d6e-8626-b0f86ebc71f2')]",
+ "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('3094e036-e5ae-4d6e-8626-b0f86ebc71f2')))]",
+ "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','3094e036-e5ae-4d6e-8626-b0f86ebc71f2','-', '1.0.2')))]"
+ },
"uiConfigId1": "SalesforceServiceCloud",
"_uiConfigId1": "[variables('uiConfigId1')]",
"dataConnectorContentId1": "SalesforceServiceCloud",
@@ -53,15 +74,13 @@
"dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
"dataConnectorVersion1": "1.0.0",
"_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
- "parserName1": "SalesforceServiceCloud",
- "_parserName1": "[concat(parameters('workspace'),'/',variables('parserName1'))]",
- "parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
- "_parserId1": "[variables('parserId1')]",
- "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId1'))))]",
- "parserVersion1": "1.0.0",
- "parserContentId1": "SalesforceServiceCloud-Parser",
- "_parserContentId1": "[variables('parserContentId1')]",
- "_parsercontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId1'),'-', variables('parserVersion1'))))]",
+ "parserObject1": {
+ "_parserName1": "[concat(parameters('workspace'),'/','SalesforceServiceCloud')]",
+ "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'SalesforceServiceCloud')]",
+ "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('SalesforceServiceCloud-Parser')))]",
+ "parserVersion1": "1.0.0",
+ "parserContentId1": "SalesforceServiceCloud-Parser"
+ },
"workbookVersion1": "1.0.0",
"workbookContentId1": "SalesforceServiceCloudWorkbook",
"workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
@@ -69,209 +88,86 @@
"_workbookContentId1": "[variables('workbookContentId1')]",
"workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
"_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
- "analyticRuleVersion1": "1.0.1",
- "analyticRulecontentId1": "5a6ce089-e756-40fb-b022-c8e8864a973a",
- "_analyticRulecontentId1": "[variables('analyticRulecontentId1')]",
- "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId1'))]",
- "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId1'))))]",
- "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId1'),'-', variables('analyticRuleVersion1'))))]",
- "analyticRuleVersion2": "1.0.1",
- "analyticRulecontentId2": "64d16e62-1a17-4a35-9ea7-2b9fe6f07118",
- "_analyticRulecontentId2": "[variables('analyticRulecontentId2')]",
- "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]",
- "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId2'))))]",
- "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId2'),'-', variables('analyticRuleVersion2'))))]",
- "analyticRuleVersion3": "1.0.1",
- "analyticRulecontentId3": "3094e036-e5ae-4d6e-8626-b0f86ebc71f2",
- "_analyticRulecontentId3": "[variables('analyticRulecontentId3')]",
- "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId3'))]",
- "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId3'))))]",
- "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId3'),'-', variables('analyticRuleVersion3'))))]",
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
"resources": [
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('dataConnectorTemplateSpecName1')]",
+ "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Salesforce Service Cloud data connector with template version 3.0.0",
+ "description": "Salesforce-BruteForce_AnalyticalRules Analytics Rule with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('dataConnectorVersion1')]",
+ "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
"parameters": {},
"variables": {},
"resources": [
{
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
- "apiVersion": "2021-03-01-preview",
- "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "Scheduled",
"location": "[parameters('workspace-location')]",
- "kind": "GenericUI",
"properties": {
- "connectorUiConfig": {
- "id": "[variables('_uiConfigId1')]",
- "title": "Salesforce Service Cloud (using Azure Functions)",
- "publisher": "Salesforce",
- "descriptionMarkdown": "The Salesforce Service Cloud data connector provides the capability to ingest information about your Salesforce operational events into Microsoft Sentinel through the REST API. The connector provides ability to review events in your org on an accelerated basis, get [event log files](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/event_log_file_hourly_overview.htm) in hourly increments for recent activity.",
- "additionalRequirementBanner": "These queries are dependent on a parser based on a Kusto Function deployed as part of the solution.",
- "graphQueries": [
- {
- "metricName": "Total data received",
- "legend": "SalesforceServiceCloud_CL",
- "baseQuery": "SalesforceServiceCloud_CL"
- }
- ],
- "sampleQueries": [
- {
- "description": "Last Salesforce Service Cloud EventLogFile Events",
- "query": "SalesforceServiceCloud\n | sort by TimeGenerated desc"
- }
- ],
- "dataTypes": [
- {
- "name": "SalesforceServiceCloud_CL",
- "lastDataReceivedQuery": "SalesforceServiceCloud_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
- }
- ],
- "connectivityCriterias": [
- {
- "type": "IsConnectedQuery",
- "value": [
- "SalesforceServiceCloud_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
- ]
- }
- ],
- "availability": {
- "status": 1,
- "isPreview": false
- },
- "permissions": {
- "resourceProvider": [
- {
- "provider": "Microsoft.OperationalInsights/workspaces",
- "permissionsDisplayText": "read and write permissions on the workspace are required.",
- "providerDisplayName": "Workspace",
- "scope": "Workspace",
- "requiredPermissions": {
- "write": true,
- "read": true,
- "delete": true
- }
- },
- {
- "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
- "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
- "providerDisplayName": "Keys",
- "scope": "Workspace",
- "requiredPermissions": {
- "action": true
- }
- }
+ "description": "Identifies evidence of brute force activity against a user based on multiple authentication failures and at least one successful authentication within a given time window. This query limits IPAddresses to 100 and may not potentially cover all IPAddresses.\nThe default failure threshold is 10, success threshold is 1, and the default time window is 20 minutes.",
+ "displayName": "Brute force attack against user credentials",
+ "enabled": false,
+ "query": "let failureCountThreshold = 10;\nlet successCountThreshold = 1;\nlet Failures =\nSalesforceServiceCloud\n| where EventType == \"Login\" and LoginStatus != \"LOGIN_NO_ERROR\"\n| summarize\n FailureStartTime = min(TimeGenerated),\n FailureEndTime = max(TimeGenerated),\n IpAddresses = make_set (ClientIp, 100),\n FailureCount = count() by User, UserId, UserType;\n SalesforceServiceCloud\n | where EventType == \"Login\" and LoginStatus == \"LOGIN_NO_ERROR\"\n | summarize\n SuccessStartTime = min(TimeGenerated),\n SuccessEndTime = max(TimeGenerated),\n IpAddresses = make_set (ClientIp, 100),\n SuccessCount = count() by User, UserId, UserType\n | join kind=leftouter Failures on UserId\n | where FailureCount >= failureCountThreshold and SuccessCount >= successCountThreshold\n | where FailureEndTime < SuccessStartTime\n | project User, EventStartTime = FailureStartTime, EventEndTime = SuccessEndTime, IpAddresses\n",
+ "queryFrequency": "PT1H",
+ "queryPeriod": "PT1H",
+ "severity": "Medium",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "triggerOperator": "GreaterThan",
+ "triggerThreshold": 0,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "SalesforceServiceCloud"
],
- "customs": [
- {
- "name": "Microsoft.Web/sites permissions",
- "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
- },
+ "connectorId": "SalesforceServiceCloud"
+ }
+ ],
+ "tactics": [
+ "CredentialAccess"
+ ],
+ "techniques": [
+ "T1110"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
{
- "name": "REST API Credentials/permissions",
- "description": "**Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** is required for REST API. [See the documentation to learn more about API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm)."
+ "identifier": "FullName",
+ "columnName": "User"
}
- ]
- },
- "instructionSteps": [
- {
- "description": ">**NOTE:** This connector uses Azure Functions to connect to the Salesforce Lightning Platform REST API to pull its logs into Microsoft Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
- },
- {
- "description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
- },
- {
- "description": "**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected which is deployed as part of the solution. To view the function code in Log Analytics, open Log Analytics/Microsoft Sentinel Logs blade, click Functions and search for the alias SalesforceServiceCloud and load the function code or click [here](https://aka.ms/sentinel-SalesforceServiceCloud-parser). The function usually takes 10-15 minutes to activate after solution installation/update."
- },
- {
- "description": "**STEP 1 - Configuration steps for the Salesforce Lightning Platform REST API**\n\n1. See the [link](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm) and follow the instructions for obtaining Salesforce API Authorization credentials. \n2. On the **Set Up Authorization** step choose **Session ID Authorization** method.\n3. You must provide your client id, client secret, username, and password with user security token."
- },
- {
- "description": ">**NOTE:** Ingesting data from on an hourly interval may require additional licensing based on the edition of the Salesforce Service Cloud being used. Please refer to [Salesforce documentation](https://www.salesforce.com/editions-pricing/service-cloud/) and/or support for more details."
- },
- {
- "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Salesforce Service Cloud data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following), as well as the Salesforce API Authorization credentials, readily available.",
- "instructions": [
- {
- "parameters": {
- "fillWith": [
- "WorkspaceId"
- ],
- "label": "Workspace ID"
- },
- "type": "CopyableLabel"
- },
- {
- "parameters": {
- "fillWith": [
- "PrimaryKey"
- ],
- "label": "Primary Key"
- },
- "type": "CopyableLabel"
- }
- ]
- },
- {
- "instructions": [
- {
- "parameters": {
- "instructionSteps": [
- {
- "title": "Option 1 - Azure Resource Manager (ARM) Template",
- "description": "Use this method for automated deployment of the Salesforce Service Cloud data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-SalesforceServiceCloud-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID**, **Workspace Key**, **Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** and deploy. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
- },
- {
- "title": "Option 2 - Manual Deployment of Azure Functions",
- "description": "Use the following step-by-step instructions to deploy the Salesforce Service Cloud data connector manually with Azure Functions (Deployment via Visual Studio Code).",
- "instructions": [
- {
- "parameters": {
- "instructionSteps": [
- {
- "title": "Step 1 - Deploy a Function App",
- "description": "**NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-SalesforceServiceCloud-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it."
- },
- {
- "title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tSalesforceUser\n\t\tSalesforcePass\n\t\tSalesforceSecurityToken\n\t\tSalesforceConsumerKey\n\t\tSalesforceConsumerSecret\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`\n5. Once all application settings have been entered, click **Save**."
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- }
- ]
+ ],
+ "entityType": "Account"
+ }
+ ],
+ "customDetails": {
+ "EventStartTime": "FailureStartTime",
+ "IPAddresses": "IpAddresses",
+ "EventEndTime": "SuccessEndTime"
}
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2023-04-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]",
"properties": {
- "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "kind": "DataConnector",
- "version": "[variables('dataConnectorVersion1')]",
+ "description": "Salesforce Service Cloud Analytics Rule 1",
+ "parentId": "[variables('analyticRuleObject1').analyticRuleId1]",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]",
"source": {
"kind": "Solution",
"name": "Salesforce Service Cloud",
@@ -296,234 +192,179 @@
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "contentKind": "DataConnector",
- "displayName": "Salesforce Service Cloud (using Azure Functions)",
- "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
- "id": "[variables('_dataConnectorcontentProductId1')]",
- "version": "[variables('dataConnectorVersion1')]"
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Brute force attack against user credentials",
+ "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
}
},
{
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
+ "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]",
+ "location": "[parameters('workspace-location')]",
"dependsOn": [
- "[variables('_dataConnectorId1')]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
- "location": "[parameters('workspace-location')]",
- "properties": {
- "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "kind": "DataConnector",
- "version": "[variables('dataConnectorVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Salesforce Service Cloud",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Microsoft",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Microsoft Corporation",
- "email": "support@microsoft.com",
- "tier": "Microsoft",
- "link": "https://support.microsoft.com/"
- }
- }
- },
- {
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
- "apiVersion": "2021-03-01-preview",
- "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
- "location": "[parameters('workspace-location')]",
- "kind": "GenericUI",
"properties": {
- "connectorUiConfig": {
- "title": "Salesforce Service Cloud (using Azure Functions)",
- "publisher": "Salesforce",
- "descriptionMarkdown": "The Salesforce Service Cloud data connector provides the capability to ingest information about your Salesforce operational events into Microsoft Sentinel through the REST API. The connector provides ability to review events in your org on an accelerated basis, get [event log files](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/event_log_file_hourly_overview.htm) in hourly increments for recent activity.",
- "graphQueries": [
- {
- "metricName": "Total data received",
- "legend": "SalesforceServiceCloud_CL",
- "baseQuery": "SalesforceServiceCloud_CL"
- }
- ],
- "dataTypes": [
- {
- "name": "SalesforceServiceCloud_CL",
- "lastDataReceivedQuery": "SalesforceServiceCloud_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
- }
- ],
- "connectivityCriterias": [
- {
- "type": "IsConnectedQuery",
- "value": [
- "SalesforceServiceCloud_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
- ]
- }
- ],
- "sampleQueries": [
- {
- "description": "Last Salesforce Service Cloud EventLogFile Events",
- "query": "SalesforceServiceCloud\n | sort by TimeGenerated desc"
- }
- ],
- "availability": {
- "status": 1,
- "isPreview": false
- },
- "permissions": {
- "resourceProvider": [
- {
- "provider": "Microsoft.OperationalInsights/workspaces",
- "permissionsDisplayText": "read and write permissions on the workspace are required.",
- "providerDisplayName": "Workspace",
- "scope": "Workspace",
- "requiredPermissions": {
- "write": true,
- "read": true,
- "delete": true
- }
- },
- {
- "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
- "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
- "providerDisplayName": "Keys",
- "scope": "Workspace",
- "requiredPermissions": {
- "action": true
- }
- }
- ],
- "customs": [
- {
- "name": "Microsoft.Web/sites permissions",
- "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
- },
- {
- "name": "REST API Credentials/permissions",
- "description": "**Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** is required for REST API. [See the documentation to learn more about API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm)."
- }
- ]
- },
- "instructionSteps": [
- {
- "description": ">**NOTE:** This connector uses Azure Functions to connect to the Salesforce Lightning Platform REST API to pull its logs into Microsoft Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
- },
- {
- "description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
- },
- {
- "description": "**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected which is deployed as part of the solution. To view the function code in Log Analytics, open Log Analytics/Microsoft Sentinel Logs blade, click Functions and search for the alias SalesforceServiceCloud and load the function code or click [here](https://aka.ms/sentinel-SalesforceServiceCloud-parser). The function usually takes 10-15 minutes to activate after solution installation/update."
- },
- {
- "description": "**STEP 1 - Configuration steps for the Salesforce Lightning Platform REST API**\n\n1. See the [link](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm) and follow the instructions for obtaining Salesforce API Authorization credentials. \n2. On the **Set Up Authorization** step choose **Session ID Authorization** method.\n3. You must provide your client id, client secret, username, and password with user security token."
- },
- {
- "description": ">**NOTE:** Ingesting data from on an hourly interval may require additional licensing based on the edition of the Salesforce Service Cloud being used. Please refer to [Salesforce documentation](https://www.salesforce.com/editions-pricing/service-cloud/) and/or support for more details."
- },
+ "description": "Salesforce-PasswordSpray_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
{
- "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Salesforce Service Cloud data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following), as well as the Salesforce API Authorization credentials, readily available.",
- "instructions": [
- {
- "parameters": {
- "fillWith": [
- "WorkspaceId"
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "Scheduled",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "description": "This query searches for failed attempts to log in from more than 15 various users within a 5 minutes timeframe from the same source. This is a potential indication of a password spray attack.",
+ "displayName": "Potential Password Spray Attack",
+ "enabled": false,
+ "query": "let FailureThreshold = 15; \nSalesforceServiceCloud\n| where EventType =~ 'Login' and LoginStatus != 'LOGIN_NO_ERROR'\n| where LoginStatus in~ ('LOGIN_ERROR_INVALID_PASSWORD', 'LOGIN_ERROR_SSO_PWD_INVALID')\n| summarize UserCount=dcount(UserId), Users = make_set(UserId,100) by ClientIp, bin(TimeGenerated, 5m)\n| where UserCount > FailureThreshold\n",
+ "queryFrequency": "PT1H",
+ "queryPeriod": "PT1H",
+ "severity": "Medium",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "triggerOperator": "GreaterThan",
+ "triggerThreshold": 0,
+ "status": "Available",
+ "requiredDataConnectors": [
+ {
+ "dataTypes": [
+ "SalesforceServiceCloud"
],
- "label": "Workspace ID"
- },
- "type": "CopyableLabel"
- },
- {
- "parameters": {
- "fillWith": [
- "PrimaryKey"
+ "connectorId": "SalesforceServiceCloud"
+ }
+ ],
+ "tactics": [
+ "CredentialAccess"
+ ],
+ "techniques": [
+ "T1110"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "identifier": "Address",
+ "columnName": "ClientIp"
+ }
],
- "label": "Primary Key"
- },
- "type": "CopyableLabel"
+ "entityType": "IP"
+ }
+ ],
+ "customDetails": {
+ "Users": "Users"
}
- ]
+ }
},
{
- "instructions": [
- {
- "parameters": {
- "instructionSteps": [
- {
- "title": "Option 1 - Azure Resource Manager (ARM) Template",
- "description": "Use this method for automated deployment of the Salesforce Service Cloud data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-SalesforceServiceCloud-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID**, **Workspace Key**, **Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** and deploy. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
- },
- {
- "title": "Option 2 - Manual Deployment of Azure Functions",
- "description": "Use the following step-by-step instructions to deploy the Salesforce Service Cloud data connector manually with Azure Functions (Deployment via Visual Studio Code).",
- "instructions": [
- {
- "parameters": {
- "instructionSteps": [
- {
- "title": "Step 1 - Deploy a Function App",
- "description": "**NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-SalesforceServiceCloud-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it."
- },
- {
- "title": "Step 2 - Configure the Function App",
- "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tSalesforceUser\n\t\tSalesforcePass\n\t\tSalesforceSecurityToken\n\t\tSalesforceConsumerKey\n\t\tSalesforceConsumerSecret\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`\n5. Once all application settings have been entered, click **Save**."
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- }
- ]
- },
- "type": "InstructionStepsGroup"
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]",
+ "properties": {
+ "description": "Salesforce Service Cloud Analytics Rule 2",
+ "parentId": "[variables('analyticRuleObject2').analyticRuleId2]",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]",
+ "source": {
+ "kind": "Solution",
+ "name": "Salesforce Service Cloud",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Microsoft Corporation",
+ "email": "support@microsoft.com",
+ "tier": "Microsoft",
+ "link": "https://support.microsoft.com/"
}
- ]
+ }
}
- ],
- "id": "[variables('_uiConfigId1')]",
- "additionalRequirementBanner": "These queries are dependent on a parser based on a Kusto Function deployed as part of the solution."
- }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Potential Password Spray Attack",
+ "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('parserTemplateSpecName1')]",
+ "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SalesforceServiceCloud Data Parser with template version 3.0.0",
+ "description": "Salesforce-SigninsMultipleCountries_AnalyticalRules Analytics Rule with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('parserVersion1')]",
+ "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
"parameters": {},
"variables": {},
"resources": [
{
- "name": "[variables('_parserName1')]",
- "apiVersion": "2022-10-01",
- "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
+ "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "apiVersion": "2023-02-01-preview",
+ "kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
- "eTag": "*",
- "displayName": "SalesforceServiceCloud",
- "category": "Microsoft Sentinel Parser",
- "functionAlias": "SalesforceServiceCloud",
- "query": "SalesforceServiceCloud_CL \n| extend \n\t\tRequestSize=column_ifexists('request_size_s',''),\n\t\tExecTime=column_ifexists('exec_time_s',''),\n\t\tAction=column_ifexists('action_s',''),\n\t\tPlatformType=column_ifexists('platform_type_s',''),\n\t\tOsName=column_ifexists('os_name_s',''),\n\t\tOsVersion=column_ifexists('os_version_s',''),\n\t\tTimestamp=column_ifexists('timestamp_s',''),\n\t\tStatusCode=column_ifexists('status_code_s',''),\n\t\tEventType=column_ifexists('event_type_s',''),\n\t\tReferrerUri=column_ifexists('referrer_uri_s',''),\n\t\tUserAgent=column_ifexists('user_agent_s',''),\n\t\tBrowserType=column_ifexists('browser_type_s',''),\n\t\tTime=column_ifexists('time_s',''),\n\t\tResponseSize=column_ifexists('response_size_s',''),\n\t\tDeviceId=column_ifexists('device_id_s',''),\n\t\tDeviceModel=column_ifexists('device_model_s',''),\n\t\tSourceIp=column_ifexists('source_ip_s',''),\n\t\tClientIp=column_ifexists('client_ip_s',''),\n\t\tSuccess=column_ifexists('success_s',''),\n\t\tUri=column_ifexists('uri_s',''),\n\t\tUrl=column_ifexists('url_s',''),\n\t\tClientName=column_ifexists('client_name_s',''),\n\t\tUserType=column_ifexists('user_type_s',''),\n\t\tUserInitiatedLogout=column_ifexists('user_initiated_logout_s',''),\n\t\tUserIdDerived=column_ifexists('user_id_derived_s',''),\n\t\tUserId=column_ifexists('user_id_s',''),\n\t\tUserEmail=column_ifexists('user_email_s',''),\n\t\tUser=column_ifexists('user_name_s',''),\n\t\tUriIdDerived=column_ifexists('uri_id_derived_s',''),\n\t\tUiEventType=column_ifexists('ui_event_type_s',''),\n\t\tUiEventTimestamp=column_ifexists('ui_event_timestamp_s',''),\n\t\tUiEventSource=column_ifexists('ui_event_source_s',''),\n\t\tUiEventSequenceNum=column_ifexists('ui_event_sequence_num_s',''),\n\t\tUiEventId=column_ifexists('ui_event_id_s',''),\n\t\tTlsProtocol=column_ifexists('tls_protocol_s',''),\n\t\tTimestampDerived=column_ifexists('timestamp_derived_t',''),\n\t\tTargetUiElement=column_ifexists('target_ui_element_s',''),\n\t\tSort=column_ifexists('sort_s',''),\n\t\tSessionType=column_ifexists('session_type_s',''),\n\t\tSessionLevel=column_ifexists('session_level_s',''),\n\t\tSessionKey=column_ifexists('session_key_s',''),\n\t\tSearchQuery=column_ifexists('search_query_s',''),\n\t\tSdkVersion=column_ifexists('sdk_version_s',''),\n\t\tSdkAppVersion=column_ifexists('sdk_app_version_s',''),\n\t\tSdkAppType=column_ifexists('sdk_app_type_s',''),\n\t\tRunTime=column_ifexists('run_time_s',''),\n\t\tRowsProcessed=column_ifexists('rows_processed_s',''),\n\t\tRowCount=column_ifexists('row_count_s',''),\n\t\tResolutionType=column_ifexists('resolution_type_s',''),\n\t\tRequestStatus=column_ifexists('request_status_s',''),\n\t\tRequestId=column_ifexists('request_id_s',''),\n\t\tReportIdDerived=column_ifexists('report_id_derived_s',''),\n\t\tReportId=column_ifexists('report_id_s',''),\n\t\tRenderingType=column_ifexists('rendering_type_s',''),\n\t\tRelatedList=column_ifexists('related_list_s',''),\n\t\tRecordType=column_ifexists('record_type_s',''),\n\t\tRecordId=column_ifexists('record_id_s',''),\n\t\tQuiddity=column_ifexists('quiddity_s',''),\n\t\tQueryId=column_ifexists('query_id_s',''),\n\t\tPrevpageUrl=column_ifexists('prevpage_url_s',''),\n\t\tPrevpageEntityType=column_ifexists('prevpage_entity_type_s',''),\n\t\tPrevpageEntityId=column_ifexists('prevpage_entity_id_s',''),\n\t\tPrevpageContext=column_ifexists('prevpage_context_s',''),\n\t\tPrevpageAppName=column_ifexists('prevpage_app_name_s',''),\n\t\tPrefixesSearched=column_ifexists('prefixes_searched_s',''),\n\t\tParentUiElement=column_ifexists('parent_ui_element_s',''),\n\t\tPageUrl=column_ifexists('page_url_s',''),\n\t\tPageStartTime=column_ifexists('page_start_time_s',''),\n\t\tPageEntityType=column_ifexists('page_entity_type_s',''),\n\t\tPageEntityId=column_ifexists('page_entity_id_s',''),\n\t\tPageContext=column_ifexists('page_context_s',''),\n\t\tPageAppName=column_ifexists('page_app_name_s',''),\n\t\tOrigin=column_ifexists('origin_s',''),\n\t\tOrganizationId=column_ifexists('organization_id_s',''),\n\t\tNumResults=column_ifexists('num_results_s',''),\n\t\tNumberSoqlQueries=column_ifexists('number_soql_queries_s',''),\n\t\tNumberFields=column_ifexists('number_fields_s',''),\n\t\tNumberExceptionFilters=column_ifexists('number_exception_filters_s',''),\n\t\tNumberColumns=column_ifexists('number_columns_s',''),\n\t\tNumberBuckets=column_ifexists('number_buckets_s',''),\n\t\tMethodName=column_ifexists('method_name_s',''),\n\t\tMethod=column_ifexists('method_s',''),\n\t\tMediaType=column_ifexists('media_type_s',''),\n\t\tLoginStatus=column_ifexists('login_status_s',''),\n\t\tLoginKey=column_ifexists('login_key_s',''),\n\t\tHttpMethod=column_ifexists('http_method_s',''),\n\t\tGrandparentUiElement=column_ifexists('grandparent_ui_element_s',''),\n\t\tEntryPoint=column_ifexists('entry_point_s',''),\n\t\tEntityName=column_ifexists('entity_name_s',''),\n\t\tEntity=column_ifexists('entity_s',''),\n\t\tEffectivePageTime=column_ifexists('effective_page_time_s',''),\n\t\tDuration=column_ifexists('duration_s',''),\n\t\tDisplayType=column_ifexists('display_type_s',''),\n\t\tDeviceSessionId=column_ifexists('device_session_id_s',''),\n\t\tDevicePlatform=column_ifexists('device_platform_s',''),\n\t\tDbTotalTime=column_ifexists('db_total_time_s',''),\n\t\tDbCpuTime=column_ifexists('db_cpu_time_s',''),\n\t\tDbBlocks=column_ifexists('db_blocks_s',''),\n\t\tCpuTime=column_ifexists('cpu_time_s',''),\n\t\tConnectionType=column_ifexists('connection_type_s',''),\n\t\tComponentName=column_ifexists('component_name_s',''),\n\t\tClientVersion=column_ifexists('client_version_s',''),\n\t\tClientId=column_ifexists('client_id_s',''),\n\t\tCipherSuite=column_ifexists('cipher_suite_s',''),\n\t\tCalloutTime=column_ifexists('callout_time_s',''),\n\t\tBrowserVersion=column_ifexists('browser_version_s',''),\n\t\tBrowserName=column_ifexists('browser_name_s',''),\n\t\tAverageRowSize=column_ifexists('average_row_size_s',''),\n\t\tAppType=column_ifexists('app_type_s',''),\n\t\tAppName=column_ifexists('app_name_s',''),\n\t\tApiVersion=column_ifexists('api_version_s',''),\n\t\tApiType=column_ifexists('api_type_s',''),\n ArticleVersionId=column_ifexists('article_version_id_s',''),\n\t\tArticleVersion=column_ifexists('article_version_s',''),\n\t\tArticleStatus=column_ifexists('article_status_s',''),\n\t\tArticleId=column_ifexists('article_id_s',''),\n AnalyticsMode=column_ifexists('analytics_mode_s',''),\n BatchId=column_ifexists('batch_id_s',''),\n ClickedRecordId=column_ifexists('clicked_record_id_s',''),\n\t\tClassName=column_ifexists('class_name_s',''),\n ComponentIdDerived=column_ifexists('component_id_derived_s',''),\n\t\tComponentId=column_ifexists('component_id_s',''),\n ControllerType=column_ifexists('controller_type_s',''),\n\t\tContext=column_ifexists('context_s',''),\n\t\tConsoleIdDerived=column_ifexists('console_id_derived_s',''),\n\t\tConsoleId=column_ifexists('console_id_s',''), \n ClientInfo=column_ifexists('client_info_s',''),\n DstBytes=column_ifexists('request_size_s',''),\n\t\tDstUser=column_ifexists('delegated_user_name_s',''),\n DstUserSid=column_ifexists('delegated_user_id_s',''),\n\t\tDstUserSidDerived=column_ifexists('delegated_user_id_derived_s',''),\n Data=column_ifexists('data_s',''),\n\t\tDashboardType=column_ifexists('dashboard_type_s',''),\n\t\tDashboardIdDerived=column_ifexists('dashboard_id_derived_s',''),\n\t\tDashboardId=column_ifexists('dashboard_id_s',''),\n\t\tDashboardComponentId=column_ifexists('dashboard_component_id_s',''),\n\t\tDvcAction=column_ifexists('action_s',''),\n\t\tDvcOS=column_ifexists('platform_type_s',''),\n\t\tDvcOSName=column_ifexists('os_name_s',''),\n\t\tDvcOSVersion=column_ifexists('os_version_s',''),\n DeliveryLocation=column_ifexists('delivery_location_s',''),\n\t\tDeliveryId=column_ifexists('delivery_id_s',''),\n DocumentIdDerived=column_ifexists('document_id_derived_s',''),\n\t\tDocumentId=column_ifexists('document_id_s',''),\n EntityType=column_ifexists('entity_type_s',''),\n EntityId=column_ifexists('entity_id_s',''),\n FileType=column_ifexists('file_type_s',''),\n\t\tFilePreviewType=column_ifexists('file_preview_type_s',''),\n\t\tExceptionType=column_ifexists('exception_type_s',''),\n\t\tExceptionMessage=column_ifexists('exception_message_s',''),\n\t\tEpt=column_ifexists('ept_s',''),\n EventCount=column_ifexists('number_of_records_s',''),\n\t\tEventEndTime=column_ifexists('timestamp_s',''),\n\t\tEventResult=column_ifexists('status_code_s',''),\n\t\tFileSize=column_ifexists('size_bytes_s',''),\n HttpReferrerOriginal=column_ifexists('referrer_uri_s',''),\n\t\tHttpUserAgentOriginal=column_ifexists('user_agent_s',''),\n\t\tHttpUserAgent=column_ifexists('browser_type_s',''),\n LogGroupId=column_ifexists('log_group_id_s',''),\n\t\tLimitUsagePercent=column_ifexists('limit_usage_percent_s',''),\n\t\tLicenseContext=column_ifexists('license_context_s',''),\n\t\tLastVersion=column_ifexists('last_version_s',''),\n\t\tLanguage=column_ifexists('language_s',''),\n\t\tJobId=column_ifexists('job_id_s',''),\n\t\tIsSuccess=column_ifexists('is_success_s',''),\n\t\tIsSecure=column_ifexists('is_secure_s',''),\n\t\tIsScheduled=column_ifexists('is_scheduled_s',''),\n\t\tIsNew=column_ifexists('is_new_s',''),\n\t\tIsMobile=column_ifexists('is_mobile_s',''),\n\t\tIsLongRunningRequest=column_ifexists('is_long_running_request_s',''),\n\t\tIsGuest=column_ifexists('is_guest_s',''),\n\t\tIsFirstRequest=column_ifexists('is_first_request_s',''),\n\t\tIsError=column_ifexists('is_error_s',''),\n\t\tIsApi=column_ifexists('is_api_s',''),\n\t\tIsAjaxRequest=column_ifexists('is_ajax_request_s',''),\n ManagedPackageNamespace=column_ifexists('managed_package_namespace_s',''),\n HttpHeaders=column_ifexists('http_headers_s',''),\n\t\tNetworkDuration=column_ifexists('time_s',''),\n Name=column_ifexists('name_s',''),\n NumberFailures=column_ifexists('number_failures_s',''),\n NumClicks=column_ifexists('num_clicks_s',''),\n OperationType=column_ifexists('operation_type_s',''),\n\t\tNumSessions=column_ifexists('num_sessions_s',''),\n PageName=column_ifexists('page_name_s',''),\n Query=column_ifexists('query_s',''),\n RequestType=column_ifexists('request_type_s',''),\n ReportDescription=column_ifexists('report_description_s',''),\n\t\tReopenCount=column_ifexists('reopen_count_s',''),\n RelatedEntityId=column_ifexists('related_entity_id_s',''),\n RecordIdDerived=column_ifexists('record_id_derived_s',''),\n ReadTime=column_ifexists('read_time_s',''),\n\t\tRank=column_ifexists('rank_s',''),\n\t\tSrcBytes=column_ifexists('response_size_s',''),\n\t\tSrcDvcId=column_ifexists('device_id_s',''),\n\t\tSrcDvcModelName=column_ifexists('device_model_s',''),\n\t\tSrcIpAddr=column_ifexists('source_ip_s',''),\n\t\tSrcNatIpAddr=column_ifexists('client_ip_s',''),\n SessionId=column_ifexists('session_id_s',''),\n SiteId=column_ifexists('site_id_s',''),\n\t\tSharingPermission=column_ifexists('sharing_permission_s',''),\n\t\tSharingOperation=column_ifexists('sharing_operation_s',''),\n\t\tSharedWithEntityId=column_ifexists('shared_with_entity_id_s',''),\n\t\tUrlOriginal=column_ifexists('url_s',''),\n\t\tWaveTimestamp=column_ifexists('wave_timestamp_s',''),\n\t\tWaveSessionId=column_ifexists('wave_session_id_g',''),\n\t\tViewStateSize=column_ifexists('view_state_size_s',''),\n\t\tVersionIdDerived=column_ifexists('version_id_derived_s',''),\n\t\tVersionId=column_ifexists('version_id_s',''),\n TriggerType=column_ifexists('trigger_type_s',''),\n\t\tTriggerName=column_ifexists('trigger_name_s',''),\n\t\tTriggerId=column_ifexists('trigger_id_s',''),\n\t\tTransactionType=column_ifexists('transaction_type_s',''),\n\t\tTotalTime=column_ifexists('total_time_s',''),\n TabId=column_ifexists('tab_id_s',''),\n\t\tStackTrace=column_ifexists('stack_trace_s','')\n| project-away *_s\n",
- "functionParameters": "",
- "version": 2,
- "tags": [
+ "description": "This query searches for successful user logins from different countries within 30 mins.",
+ "displayName": "User Sign in from different countries",
+ "enabled": false,
+ "query": "let threshold = 2;\nlet Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)\n[@\"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv\"];\nlet UsersLocation = SalesforceServiceCloud\n| where EventType =~ 'Login' and LoginStatus=~'LOGIN_NO_ERROR'\n| project TimeGenerated, ClientIp, UserId, User, UserType ;\nUsersLocation\n| extend Dummy=1\n| summarize count() by Hour=bin(TimeGenerated,30m), ClientIp,User, Dummy\n| partition by Hour(\n lookup (Countrydb|extend Dummy=1) on Dummy\n | where ipv4_is_match(ClientIp, Network)\n )\n| summarize NumOfCountries = dcount(country_name) by User, Hour\n| where NumOfCountries >= threshold\n",
+ "queryFrequency": "PT1H",
+ "queryPeriod": "PT1H",
+ "severity": "Medium",
+ "suppressionDuration": "PT1H",
+ "suppressionEnabled": false,
+ "triggerOperator": "GreaterThan",
+ "triggerThreshold": 0,
+ "status": "Available",
+ "requiredDataConnectors": [
{
- "name": "description",
- "value": ""
+ "dataTypes": [
+ "SalesforceServiceCloud"
+ ],
+ "connectorId": "SalesforceServiceCloud"
+ }
+ ],
+ "tactics": [
+ "InitialAccess"
+ ],
+ "techniques": [
+ "T1078"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "identifier": "AadUserId",
+ "columnName": "User"
+ }
+ ],
+ "entityType": "Account"
}
]
}
@@ -531,18 +372,16 @@
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId1'),'/'))))]",
- "dependsOn": [
- "[variables('_parserName1')]"
- ],
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]",
"properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
- "contentId": "[variables('_parserContentId1')]",
- "kind": "Parser",
- "version": "[variables('parserVersion1')]",
+ "description": "Salesforce Service Cloud Analytics Rule 3",
+ "parentId": "[variables('analyticRuleObject3').analyticRuleId3]",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "kind": "AnalyticsRule",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]",
"source": {
- "name": "Salesforce Service Cloud",
"kind": "Solution",
+ "name": "Salesforce Service Cloud",
"sourceId": "[variables('_solutionId')]"
},
"author": {
@@ -564,108 +403,196 @@
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_parserContentId1')]",
- "contentKind": "Parser",
- "displayName": "SalesforceServiceCloud",
- "contentProductId": "[variables('_parsercontentProductId1')]",
- "id": "[variables('_parsercontentProductId1')]",
- "version": "[variables('parserVersion1')]"
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
- "apiVersion": "2022-10-01",
- "name": "[variables('_parserName1')]",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "eTag": "*",
- "displayName": "SalesforceServiceCloud",
- "category": "Microsoft Sentinel Parser",
- "functionAlias": "SalesforceServiceCloud",
- "query": "SalesforceServiceCloud_CL \n| extend \n\t\tRequestSize=column_ifexists('request_size_s',''),\n\t\tExecTime=column_ifexists('exec_time_s',''),\n\t\tAction=column_ifexists('action_s',''),\n\t\tPlatformType=column_ifexists('platform_type_s',''),\n\t\tOsName=column_ifexists('os_name_s',''),\n\t\tOsVersion=column_ifexists('os_version_s',''),\n\t\tTimestamp=column_ifexists('timestamp_s',''),\n\t\tStatusCode=column_ifexists('status_code_s',''),\n\t\tEventType=column_ifexists('event_type_s',''),\n\t\tReferrerUri=column_ifexists('referrer_uri_s',''),\n\t\tUserAgent=column_ifexists('user_agent_s',''),\n\t\tBrowserType=column_ifexists('browser_type_s',''),\n\t\tTime=column_ifexists('time_s',''),\n\t\tResponseSize=column_ifexists('response_size_s',''),\n\t\tDeviceId=column_ifexists('device_id_s',''),\n\t\tDeviceModel=column_ifexists('device_model_s',''),\n\t\tSourceIp=column_ifexists('source_ip_s',''),\n\t\tClientIp=column_ifexists('client_ip_s',''),\n\t\tSuccess=column_ifexists('success_s',''),\n\t\tUri=column_ifexists('uri_s',''),\n\t\tUrl=column_ifexists('url_s',''),\n\t\tClientName=column_ifexists('client_name_s',''),\n\t\tUserType=column_ifexists('user_type_s',''),\n\t\tUserInitiatedLogout=column_ifexists('user_initiated_logout_s',''),\n\t\tUserIdDerived=column_ifexists('user_id_derived_s',''),\n\t\tUserId=column_ifexists('user_id_s',''),\n\t\tUserEmail=column_ifexists('user_email_s',''),\n\t\tUser=column_ifexists('user_name_s',''),\n\t\tUriIdDerived=column_ifexists('uri_id_derived_s',''),\n\t\tUiEventType=column_ifexists('ui_event_type_s',''),\n\t\tUiEventTimestamp=column_ifexists('ui_event_timestamp_s',''),\n\t\tUiEventSource=column_ifexists('ui_event_source_s',''),\n\t\tUiEventSequenceNum=column_ifexists('ui_event_sequence_num_s',''),\n\t\tUiEventId=column_ifexists('ui_event_id_s',''),\n\t\tTlsProtocol=column_ifexists('tls_protocol_s',''),\n\t\tTimestampDerived=column_ifexists('timestamp_derived_t',''),\n\t\tTargetUiElement=column_ifexists('target_ui_element_s',''),\n\t\tSort=column_ifexists('sort_s',''),\n\t\tSessionType=column_ifexists('session_type_s',''),\n\t\tSessionLevel=column_ifexists('session_level_s',''),\n\t\tSessionKey=column_ifexists('session_key_s',''),\n\t\tSearchQuery=column_ifexists('search_query_s',''),\n\t\tSdkVersion=column_ifexists('sdk_version_s',''),\n\t\tSdkAppVersion=column_ifexists('sdk_app_version_s',''),\n\t\tSdkAppType=column_ifexists('sdk_app_type_s',''),\n\t\tRunTime=column_ifexists('run_time_s',''),\n\t\tRowsProcessed=column_ifexists('rows_processed_s',''),\n\t\tRowCount=column_ifexists('row_count_s',''),\n\t\tResolutionType=column_ifexists('resolution_type_s',''),\n\t\tRequestStatus=column_ifexists('request_status_s',''),\n\t\tRequestId=column_ifexists('request_id_s',''),\n\t\tReportIdDerived=column_ifexists('report_id_derived_s',''),\n\t\tReportId=column_ifexists('report_id_s',''),\n\t\tRenderingType=column_ifexists('rendering_type_s',''),\n\t\tRelatedList=column_ifexists('related_list_s',''),\n\t\tRecordType=column_ifexists('record_type_s',''),\n\t\tRecordId=column_ifexists('record_id_s',''),\n\t\tQuiddity=column_ifexists('quiddity_s',''),\n\t\tQueryId=column_ifexists('query_id_s',''),\n\t\tPrevpageUrl=column_ifexists('prevpage_url_s',''),\n\t\tPrevpageEntityType=column_ifexists('prevpage_entity_type_s',''),\n\t\tPrevpageEntityId=column_ifexists('prevpage_entity_id_s',''),\n\t\tPrevpageContext=column_ifexists('prevpage_context_s',''),\n\t\tPrevpageAppName=column_ifexists('prevpage_app_name_s',''),\n\t\tPrefixesSearched=column_ifexists('prefixes_searched_s',''),\n\t\tParentUiElement=column_ifexists('parent_ui_element_s',''),\n\t\tPageUrl=column_ifexists('page_url_s',''),\n\t\tPageStartTime=column_ifexists('page_start_time_s',''),\n\t\tPageEntityType=column_ifexists('page_entity_type_s',''),\n\t\tPageEntityId=column_ifexists('page_entity_id_s',''),\n\t\tPageContext=column_ifexists('page_context_s',''),\n\t\tPageAppName=column_ifexists('page_app_name_s',''),\n\t\tOrigin=column_ifexists('origin_s',''),\n\t\tOrganizationId=column_ifexists('organization_id_s',''),\n\t\tNumResults=column_ifexists('num_results_s',''),\n\t\tNumberSoqlQueries=column_ifexists('number_soql_queries_s',''),\n\t\tNumberFields=column_ifexists('number_fields_s',''),\n\t\tNumberExceptionFilters=column_ifexists('number_exception_filters_s',''),\n\t\tNumberColumns=column_ifexists('number_columns_s',''),\n\t\tNumberBuckets=column_ifexists('number_buckets_s',''),\n\t\tMethodName=column_ifexists('method_name_s',''),\n\t\tMethod=column_ifexists('method_s',''),\n\t\tMediaType=column_ifexists('media_type_s',''),\n\t\tLoginStatus=column_ifexists('login_status_s',''),\n\t\tLoginKey=column_ifexists('login_key_s',''),\n\t\tHttpMethod=column_ifexists('http_method_s',''),\n\t\tGrandparentUiElement=column_ifexists('grandparent_ui_element_s',''),\n\t\tEntryPoint=column_ifexists('entry_point_s',''),\n\t\tEntityName=column_ifexists('entity_name_s',''),\n\t\tEntity=column_ifexists('entity_s',''),\n\t\tEffectivePageTime=column_ifexists('effective_page_time_s',''),\n\t\tDuration=column_ifexists('duration_s',''),\n\t\tDisplayType=column_ifexists('display_type_s',''),\n\t\tDeviceSessionId=column_ifexists('device_session_id_s',''),\n\t\tDevicePlatform=column_ifexists('device_platform_s',''),\n\t\tDbTotalTime=column_ifexists('db_total_time_s',''),\n\t\tDbCpuTime=column_ifexists('db_cpu_time_s',''),\n\t\tDbBlocks=column_ifexists('db_blocks_s',''),\n\t\tCpuTime=column_ifexists('cpu_time_s',''),\n\t\tConnectionType=column_ifexists('connection_type_s',''),\n\t\tComponentName=column_ifexists('component_name_s',''),\n\t\tClientVersion=column_ifexists('client_version_s',''),\n\t\tClientId=column_ifexists('client_id_s',''),\n\t\tCipherSuite=column_ifexists('cipher_suite_s',''),\n\t\tCalloutTime=column_ifexists('callout_time_s',''),\n\t\tBrowserVersion=column_ifexists('browser_version_s',''),\n\t\tBrowserName=column_ifexists('browser_name_s',''),\n\t\tAverageRowSize=column_ifexists('average_row_size_s',''),\n\t\tAppType=column_ifexists('app_type_s',''),\n\t\tAppName=column_ifexists('app_name_s',''),\n\t\tApiVersion=column_ifexists('api_version_s',''),\n\t\tApiType=column_ifexists('api_type_s',''),\n ArticleVersionId=column_ifexists('article_version_id_s',''),\n\t\tArticleVersion=column_ifexists('article_version_s',''),\n\t\tArticleStatus=column_ifexists('article_status_s',''),\n\t\tArticleId=column_ifexists('article_id_s',''),\n AnalyticsMode=column_ifexists('analytics_mode_s',''),\n BatchId=column_ifexists('batch_id_s',''),\n ClickedRecordId=column_ifexists('clicked_record_id_s',''),\n\t\tClassName=column_ifexists('class_name_s',''),\n ComponentIdDerived=column_ifexists('component_id_derived_s',''),\n\t\tComponentId=column_ifexists('component_id_s',''),\n ControllerType=column_ifexists('controller_type_s',''),\n\t\tContext=column_ifexists('context_s',''),\n\t\tConsoleIdDerived=column_ifexists('console_id_derived_s',''),\n\t\tConsoleId=column_ifexists('console_id_s',''), \n ClientInfo=column_ifexists('client_info_s',''),\n DstBytes=column_ifexists('request_size_s',''),\n\t\tDstUser=column_ifexists('delegated_user_name_s',''),\n DstUserSid=column_ifexists('delegated_user_id_s',''),\n\t\tDstUserSidDerived=column_ifexists('delegated_user_id_derived_s',''),\n Data=column_ifexists('data_s',''),\n\t\tDashboardType=column_ifexists('dashboard_type_s',''),\n\t\tDashboardIdDerived=column_ifexists('dashboard_id_derived_s',''),\n\t\tDashboardId=column_ifexists('dashboard_id_s',''),\n\t\tDashboardComponentId=column_ifexists('dashboard_component_id_s',''),\n\t\tDvcAction=column_ifexists('action_s',''),\n\t\tDvcOS=column_ifexists('platform_type_s',''),\n\t\tDvcOSName=column_ifexists('os_name_s',''),\n\t\tDvcOSVersion=column_ifexists('os_version_s',''),\n DeliveryLocation=column_ifexists('delivery_location_s',''),\n\t\tDeliveryId=column_ifexists('delivery_id_s',''),\n DocumentIdDerived=column_ifexists('document_id_derived_s',''),\n\t\tDocumentId=column_ifexists('document_id_s',''),\n EntityType=column_ifexists('entity_type_s',''),\n EntityId=column_ifexists('entity_id_s',''),\n FileType=column_ifexists('file_type_s',''),\n\t\tFilePreviewType=column_ifexists('file_preview_type_s',''),\n\t\tExceptionType=column_ifexists('exception_type_s',''),\n\t\tExceptionMessage=column_ifexists('exception_message_s',''),\n\t\tEpt=column_ifexists('ept_s',''),\n EventCount=column_ifexists('number_of_records_s',''),\n\t\tEventEndTime=column_ifexists('timestamp_s',''),\n\t\tEventResult=column_ifexists('status_code_s',''),\n\t\tFileSize=column_ifexists('size_bytes_s',''),\n HttpReferrerOriginal=column_ifexists('referrer_uri_s',''),\n\t\tHttpUserAgentOriginal=column_ifexists('user_agent_s',''),\n\t\tHttpUserAgent=column_ifexists('browser_type_s',''),\n LogGroupId=column_ifexists('log_group_id_s',''),\n\t\tLimitUsagePercent=column_ifexists('limit_usage_percent_s',''),\n\t\tLicenseContext=column_ifexists('license_context_s',''),\n\t\tLastVersion=column_ifexists('last_version_s',''),\n\t\tLanguage=column_ifexists('language_s',''),\n\t\tJobId=column_ifexists('job_id_s',''),\n\t\tIsSuccess=column_ifexists('is_success_s',''),\n\t\tIsSecure=column_ifexists('is_secure_s',''),\n\t\tIsScheduled=column_ifexists('is_scheduled_s',''),\n\t\tIsNew=column_ifexists('is_new_s',''),\n\t\tIsMobile=column_ifexists('is_mobile_s',''),\n\t\tIsLongRunningRequest=column_ifexists('is_long_running_request_s',''),\n\t\tIsGuest=column_ifexists('is_guest_s',''),\n\t\tIsFirstRequest=column_ifexists('is_first_request_s',''),\n\t\tIsError=column_ifexists('is_error_s',''),\n\t\tIsApi=column_ifexists('is_api_s',''),\n\t\tIsAjaxRequest=column_ifexists('is_ajax_request_s',''),\n ManagedPackageNamespace=column_ifexists('managed_package_namespace_s',''),\n HttpHeaders=column_ifexists('http_headers_s',''),\n\t\tNetworkDuration=column_ifexists('time_s',''),\n Name=column_ifexists('name_s',''),\n NumberFailures=column_ifexists('number_failures_s',''),\n NumClicks=column_ifexists('num_clicks_s',''),\n OperationType=column_ifexists('operation_type_s',''),\n\t\tNumSessions=column_ifexists('num_sessions_s',''),\n PageName=column_ifexists('page_name_s',''),\n Query=column_ifexists('query_s',''),\n RequestType=column_ifexists('request_type_s',''),\n ReportDescription=column_ifexists('report_description_s',''),\n\t\tReopenCount=column_ifexists('reopen_count_s',''),\n RelatedEntityId=column_ifexists('related_entity_id_s',''),\n RecordIdDerived=column_ifexists('record_id_derived_s',''),\n ReadTime=column_ifexists('read_time_s',''),\n\t\tRank=column_ifexists('rank_s',''),\n\t\tSrcBytes=column_ifexists('response_size_s',''),\n\t\tSrcDvcId=column_ifexists('device_id_s',''),\n\t\tSrcDvcModelName=column_ifexists('device_model_s',''),\n\t\tSrcIpAddr=column_ifexists('source_ip_s',''),\n\t\tSrcNatIpAddr=column_ifexists('client_ip_s',''),\n SessionId=column_ifexists('session_id_s',''),\n SiteId=column_ifexists('site_id_s',''),\n\t\tSharingPermission=column_ifexists('sharing_permission_s',''),\n\t\tSharingOperation=column_ifexists('sharing_operation_s',''),\n\t\tSharedWithEntityId=column_ifexists('shared_with_entity_id_s',''),\n\t\tUrlOriginal=column_ifexists('url_s',''),\n\t\tWaveTimestamp=column_ifexists('wave_timestamp_s',''),\n\t\tWaveSessionId=column_ifexists('wave_session_id_g',''),\n\t\tViewStateSize=column_ifexists('view_state_size_s',''),\n\t\tVersionIdDerived=column_ifexists('version_id_derived_s',''),\n\t\tVersionId=column_ifexists('version_id_s',''),\n TriggerType=column_ifexists('trigger_type_s',''),\n\t\tTriggerName=column_ifexists('trigger_name_s',''),\n\t\tTriggerId=column_ifexists('trigger_id_s',''),\n\t\tTransactionType=column_ifexists('transaction_type_s',''),\n\t\tTotalTime=column_ifexists('total_time_s',''),\n TabId=column_ifexists('tab_id_s',''),\n\t\tStackTrace=column_ifexists('stack_trace_s','')\n| project-away *_s\n",
- "functionParameters": "",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": ""
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "location": "[parameters('workspace-location')]",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId1'),'/'))))]",
- "dependsOn": [
- "[variables('_parserId1')]"
- ],
- "properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
- "contentId": "[variables('_parserContentId1')]",
- "kind": "Parser",
- "version": "[variables('parserVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Salesforce Service Cloud",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Microsoft",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Microsoft Corporation",
- "email": "support@microsoft.com",
- "tier": "Microsoft",
- "link": "https://support.microsoft.com/"
- }
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "User Sign in from different countries",
+ "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('workbookTemplateSpecName1')]",
+ "name": "[variables('dataConnectorTemplateSpecName1')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SalesforceServiceCloudWorkbook Workbook with template version 3.0.0",
+ "description": "Salesforce Service Cloud data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('workbookVersion1')]",
+ "contentVersion": "[variables('dataConnectorVersion1')]",
"parameters": {},
"variables": {},
"resources": [
{
- "type": "Microsoft.Insights/workbooks",
- "name": "[variables('workbookContentId1')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
"location": "[parameters('workspace-location')]",
- "kind": "shared",
- "apiVersion": "2021-08-01",
- "metadata": {
- "description": "Sets the time name for analysis."
- },
+ "kind": "GenericUI",
"properties": {
- "displayName": "[parameters('workbook1-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Salesforce Service Cloud Workbook\\n---\\n\\nThis workbook brings together queries and visualizations to assist you in identifying potential threats in your Salesforce Service cloud audit data. Visualizations may not appear if no data is present.\\n\\nTo begin select the desired TimeRange to filter the data to the timeframe you want to focus on. Note if you have a large amount of salesforce service cloud data, queries may timeout with a large time range, if this is the case simply select a smaller time range.: \",\"style\":\"info\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"412a09a0-64ae-4614-aec6-cbfc9273b82b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"value\":{\"durationMs\":1800000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 32\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"ae90d1dc-20da-4948-80da-127b210bf152\",\"cellValue\":\"view_tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"User Logins\",\"subTarget\":\"1\",\"style\":\"link\"},{\"id\":\"af58b4d9-a888-43ed-91a9-6e9f539a61d4\",\"cellValue\":\"view_tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"API Usage\",\"subTarget\":\"2\",\"style\":\"link\"}]},\"name\":\"links - 34\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"User login locations\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)\\n[@\\\"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv\\\"];\\nlet UsersLocation = SalesforceServiceCloud\\n| where EventType == \\\"Login\\\"\\n| project TimeGenerated, SourceIp;\\nUsersLocation\\n| extend Dummy=1\\n| summarize count() by Hour=bin(TimeGenerated,24h), SourceIp,Dummy\\n| partition by Hour(\\n lookup (Countrydb|extend Dummy=1) on Dummy\\n | where ipv4_is_match(SourceIp, Network)\\n )\\n| summarize sum(count_) by country_name\",\"size\":3,\"title\":\"Heat Map- Geographical - {TimeRange:label}\",\"timeContextFromParameter\":\"TimeRange\",\"exportedParameters\":[{\"fieldName\":\"TimeGenerated\",\"parameterName\":\"RetTime\"},{\"parameterType\":1}],\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"map\",\"chartSettings\":{\"showLegend\":true},\"mapSettings\":{\"locInfo\":\"CountryRegion\",\"locInfoColumn\":\"country_name\",\"sizeSettings\":\"sum_count_\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"sum_count_\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"nodeColorField\":\"sum_count_\",\"colorAggregation\":\"Sum\",\"type\":\"heatmap\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"70\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| summarize AvgLogintime = avg(toint(RunTime)), MaxLoginTime = max(toint(RunTime)), TotalLoginRequests = count() by EventType\\r\\n| project-away EventType\",\"size\":1,\"title\":\"Overview - User login requests\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AvgLogintime\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":23,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"MaxLoginTime\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":23,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"TotalLoginRequests\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\"}}}],\"rowLimit\":1},\"tileSettings\":{\"showBorder\":false}},\"customWidth\":\"30\",\"name\":\"query - 8\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| summarize count() by bin(TimeGenerated, 1h),User, ClientIp \\r\\n| top 10 by count_\",\"size\":0,\"title\":\"Top 10 users with maximun logins - {TimeRange:label}\",\"exportFieldName\":\"UserId\",\"exportParameterName\":\"RetUser\",\"exportDefaultValue\":\"all users\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"user_name_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"TimeGenerated\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false},\"chartSettings\":{\"showLegend\":true}},\"customWidth\":\"60\",\"name\":\"query - 2\"},{\"type\":1,\"content\":{\"json\":\"To leverage infomation about Malicious IP, Threat Indicator solution should be configured and ThreatIntelligenceIndicator table should have information of malicious IP.\",\"style\":\"info\"},\"customWidth\":\"10\",\"name\":\"text - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\" let malicious_ips =\\r\\n ThreatIntelligenceIndicator\\r\\n | where isnotempty(NetworkIP)\\r\\n | summarize make_list(NetworkIP); \\r\\n SalesforceServiceCloud\\r\\n | where EventType == 'Login'\\r\\n | distinct User,ClientIp\\r\\n | where ClientIp in (malicious_ips)\\r\\n | project UserName = User, MaliciousIP = ClientIp\\r\\n\",\"size\":1,\"title\":\"Malicious IP- User Login\",\"noDataMessage\":\"No Malicious IP found\",\"timeBrushParameterName\":\"TimeBrush\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"UserName\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"MaliciousIP\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}}]},\"graphSettings\":{\"type\":0},\"chartSettings\":{\"showMetrics\":false}},\"customWidth\":\"30\",\"name\":\"query - 23\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'LoginAS'\\r\\n| project UserID = UserId,DerivedUSerID = UserIdDerived,EventType = EventType, IPAddress = ClientIp, LoginKey = LoginKey, OrgID = OrganizationId, RequestID = RequestId, SessionKey = SessionKey\\r\\n| limit 10\",\"size\":0,\"title\":\"User Activity- LoginAS(Top 10)\",\"noDataMessage\":\"No user impersonation found\",\"exportFieldName\":\"IPAddress\",\"exportParameterName\":\"RetIP\",\"exportDefaultValue\":\"all IP addresses\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"IPAddress\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"TotalRecords\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}},\"showBorder\":false}},\"customWidth\":\"60\",\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'LoginAs'\\r\\n| where isnotempty(User)\\r\\n| summarize count() by User,UserIdDerived,ClientIp\\r\\n| project UserName = User,DerivedUSerID = UserIdDerived,IPAddress = ClientIp, count_\",\"size\":1,\"title\":\"User Impersonation from different IP Addresses\",\"color\":\"blue\",\"noDataMessage\":\"No user impersonation found\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"UserName\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"DerivedUSerID\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"IPAddress\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"count_\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}}],\"labelSettings\":[{\"columnId\":\"UserName\",\"label\":\"User Name\"},{\"columnId\":\"DerivedUSerID\",\"label\":\"Impersonated ID\"},{\"columnId\":\"IPAddress\",\"label\":\"IP Address\"},{\"columnId\":\"count_\",\"label\":\"Total Login\"}]},\"chartSettings\":{\"xAxis\":\"IPAddress\",\"yAxis\":[\"count_\"],\"showLegend\":true}},\"customWidth\":\"40\",\"name\":\"query - 24\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| where isnotempty(User)\\r\\n| project UserName= User,APIType= ApiType, Browser= BrowserType, CipherSuite =CipherSuite, IP =ClientIp, CPUTime=CpuTime, UserType = UserType\\r\\n| take 200\",\"size\":0,\"title\":\"User Successful Login Activity\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"customWidth\":\"60\",\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| where isnotempty(User)\\r\\n| where LoginStatus !has('LOGIN_NO_ERROR')\\r\\n| summarize count() by User, ClientIp\\r\\n| project UserName = User, IP = ClientIp, Count = count_\",\"size\":1,\"title\":\"User Unsuccessful Logins by IP\",\"noDataMessage\":\"No Unsucessful Login found\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"UserName\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"IP\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"Count\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}}],\"labelSettings\":[{\"columnId\":\"UserName\",\"label\":\"User Name\"},{\"columnId\":\"IP\",\"label\":\"IP Address\"},{\"columnId\":\"Count\",\"label\":\"Count\"}]},\"chartSettings\":{\"xAxis\":\"UserName\",\"yAxis\":[\"Count\"],\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true}}}}},\"customWidth\":\"30\",\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"view_tab\",\"comparison\":\"isEqualTo\",\"value\":\"1\"},\"name\":\"Retrieval Events\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"API Usage\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| summarize count() by EventType\",\"size\":0,\"title\":\"Most fired events\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":50,\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == \\\"ApiTotalUsage\\\"\\r\\n| summarize count() by IPAddress = ClientIp,Entity = EntityName\\r\\n| order by Entity\",\"size\":0,\"title\":\"Most accessed entities by IP Address\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"user_id_s\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"entity_name_s\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"client_ip_s\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"count_\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\"}}}],\"labelSettings\":[{\"columnId\":\"count_\",\"label\":\"Count\"}]}},\"customWidth\":\"50\",\"name\":\"query - 5\",\"styleSettings\":{\"maxWidth\":\"30%\",\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == \\\"ApiTotalUsage\\\"\\r\\n| summarize count() by EntityName\",\"size\":0,\"title\":\"Most accessed Entities\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"name\":\"query - 6\"}]},\"conditionalVisibility\":{\"parameterName\":\"view_tab\",\"comparison\":\"isEqualTo\",\"value\":\"2\"},\"name\":\"APIUsage\"}],\"fromTemplateId\":\"sentinel-SalesforceServiceCloudWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n",
- "version": "1.0",
- "sourceId": "[variables('workspaceResourceId')]",
- "category": "sentinel"
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId1')]",
+ "title": "Salesforce Service Cloud (using Azure Functions)",
+ "publisher": "Salesforce",
+ "descriptionMarkdown": "The Salesforce Service Cloud data connector provides the capability to ingest information about your Salesforce operational events into Microsoft Sentinel through the REST API. The connector provides ability to review events in your org on an accelerated basis, get [event log files](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/event_log_file_hourly_overview.htm) in hourly increments for recent activity.",
+ "additionalRequirementBanner": "These queries are dependent on a parser based on a Kusto Function deployed as part of the solution.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "SalesforceServiceCloud_CL",
+ "baseQuery": "SalesforceServiceCloud_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Last Salesforce Service Cloud EventLogFile Events",
+ "query": "SalesforceServiceCloud\n | sort by TimeGenerated desc"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "SalesforceServiceCloud_CL",
+ "lastDataReceivedQuery": "SalesforceServiceCloud_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "SalesforceServiceCloud_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "REST API Credentials/permissions",
+ "description": "**Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** is required for REST API. [See the documentation to learn more about API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This connector uses Azure Functions to connect to the Salesforce Lightning Platform REST API to pull its logs into Microsoft Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
+ },
+ {
+ "description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
+ },
+ {
+ "description": "**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected which is deployed as part of the solution. To view the function code in Log Analytics, open Log Analytics/Microsoft Sentinel Logs blade, click Functions and search for the alias SalesforceServiceCloud and load the function code or click [here](https://aka.ms/sentinel-SalesforceServiceCloud-parser). The function usually takes 10-15 minutes to activate after solution installation/update."
+ },
+ {
+ "description": "**STEP 1 - Configuration steps for the Salesforce Lightning Platform REST API**\n\n1. See the [link](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm) and follow the instructions for obtaining Salesforce API Authorization credentials. \n2. On the **Set Up Authorization** step choose **Session ID Authorization** method.\n3. You must provide your client id, client secret, username, and password with user security token."
+ },
+ {
+ "description": ">**NOTE:** Ingesting data from on an hourly interval may require additional licensing based on the edition of the Salesforce Service Cloud being used. Please refer to [Salesforce documentation](https://www.salesforce.com/editions-pricing/service-cloud/) and/or support for more details."
+ },
+ {
+ "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Salesforce Service Cloud data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following), as well as the Salesforce API Authorization credentials, readily available.",
+ "instructions": [
+ {
+ "parameters": {
+ "fillWith": [
+ "WorkspaceId"
+ ],
+ "label": "Workspace ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "fillWith": [
+ "PrimaryKey"
+ ],
+ "label": "Primary Key"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ },
+ {
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the Salesforce Service Cloud data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-SalesforceServiceCloud-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID**, **Workspace Key**, **Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** and deploy. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the Salesforce Service Cloud data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "**NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-SalesforceServiceCloud-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tSalesforceUser\n\t\tSalesforcePass\n\t\tSalesforceSecurityToken\n\t\tSalesforceConsumerKey\n\t\tSalesforceConsumerSecret\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`\n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ }
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
"properties": {
- "description": "@{workbookKey=SalesforceServiceCloudWorkbook; logoFileName=salesforce_logo.svg; description=Sets the time name for analysis.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Salesforce Service Cloud; templateRelativePath=SalesforceServiceCloud.json; subtitle=; provider=Salesforce}.description",
- "parentId": "[variables('workbookId1')]",
- "contentId": "[variables('_workbookContentId1')]",
- "kind": "Workbook",
- "version": "[variables('workbookVersion1')]",
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
"source": {
"kind": "Solution",
"name": "Salesforce Service Cloud",
@@ -680,19 +607,6 @@
"email": "support@microsoft.com",
"tier": "Microsoft",
"link": "https://support.microsoft.com/"
- },
- "dependencies": {
- "operator": "AND",
- "criteria": [
- {
- "contentId": "SalesforceServiceCloud",
- "kind": "DataType"
- },
- {
- "contentId": "SalesforceServiceCloud_CL",
- "kind": "DataConnector"
- }
- ]
}
}
}
@@ -703,201 +617,253 @@
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_workbookContentId1')]",
- "contentKind": "Workbook",
- "displayName": "[parameters('workbook1-name')]",
- "contentProductId": "[variables('_workbookcontentProductId1')]",
- "id": "[variables('_workbookcontentProductId1')]",
- "version": "[variables('workbookVersion1')]"
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "contentKind": "DataConnector",
+ "displayName": "Salesforce Service Cloud (using Azure Functions)",
+ "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
+ "id": "[variables('_dataConnectorcontentProductId1')]",
+ "version": "[variables('dataConnectorVersion1')]"
}
},
{
- "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
"dependsOn": [
- "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ "[variables('_dataConnectorId1')]"
],
+ "location": "[parameters('workspace-location')]",
"properties": {
- "description": "Salesforce-BruteForce_AnalyticalRules Analytics Rule with template version 3.0.0",
- "mainTemplate": {
- "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion1')]",
- "parameters": {},
- "variables": {},
- "resources": [
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Salesforce Service Cloud",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Microsoft Corporation",
+ "email": "support@microsoft.com",
+ "tier": "Microsoft",
+ "link": "https://support.microsoft.com/"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "Salesforce Service Cloud (using Azure Functions)",
+ "publisher": "Salesforce",
+ "descriptionMarkdown": "The Salesforce Service Cloud data connector provides the capability to ingest information about your Salesforce operational events into Microsoft Sentinel through the REST API. The connector provides ability to review events in your org on an accelerated basis, get [event log files](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/event_log_file_hourly_overview.htm) in hourly increments for recent activity.",
+ "graphQueries": [
{
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRulecontentId1')]",
- "apiVersion": "2022-04-01-preview",
- "kind": "Scheduled",
- "location": "[parameters('workspace-location')]",
- "properties": {
- "description": "Identifies evidence of brute force activity against a user based on multiple authentication failures \nand at least one successful authentication within a given time window. This query limits IPAddresses to 100 and may not potentially cover all IPAddresses\nThe default failure threshold is 10, success threshold is 1, and the default time window is 20 minutes.",
- "displayName": "Brute force attack against user credentials",
- "enabled": false,
- "query": "let failureCountThreshold = 10;\nlet successCountThreshold = 1;\nlet Failures =\nSalesforceServiceCloud\n| where EventType == \"Login\" and LoginStatus != \"LOGIN_NO_ERROR\"\n| summarize\n FailureStartTime = min(TimeGenerated),\n FailureEndTime = max(TimeGenerated),\n IpAddresses = make_set (ClientIp, 100),\n FailureCount = count() by User, UserId, UserType;\n SalesforceServiceCloud\n | where EventType == \"Login\" and LoginStatus == \"LOGIN_NO_ERROR\"\n | summarize\n SuccessStartTime = min(TimeGenerated),\n SuccessEndTime = max(TimeGenerated),\n IpAddresses = make_set (ClientIp, 100),\n SuccessCount = count() by User, UserId, UserType\n | join kind=leftouter Failures on UserId\n | where FailureCount >= failureCountThreshold and SuccessCount >= successCountThreshold\n | where FailureEndTime < SuccessStartTime\n | project User, EventStartTime = FailureStartTime, EventEndTime = SuccessEndTime, IpAddresses\n",
- "queryFrequency": "PT20M",
- "queryPeriod": "PT20M",
- "severity": "Medium",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "triggerOperator": "GreaterThan",
- "triggerThreshold": 0,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "dataTypes": [
- "SalesforceServiceCloud"
+ "metricName": "Total data received",
+ "legend": "SalesforceServiceCloud_CL",
+ "baseQuery": "SalesforceServiceCloud_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "SalesforceServiceCloud_CL",
+ "lastDataReceivedQuery": "SalesforceServiceCloud_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "SalesforceServiceCloud_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Last Salesforce Service Cloud EventLogFile Events",
+ "query": "SalesforceServiceCloud\n | sort by TimeGenerated desc"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions on the workspace are required.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "write": true,
+ "read": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Microsoft.Web/sites permissions",
+ "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
+ },
+ {
+ "name": "REST API Credentials/permissions",
+ "description": "**Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** is required for REST API. [See the documentation to learn more about API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm)."
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This connector uses Azure Functions to connect to the Salesforce Lightning Platform REST API to pull its logs into Microsoft Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
+ },
+ {
+ "description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
+ },
+ {
+ "description": "**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected which is deployed as part of the solution. To view the function code in Log Analytics, open Log Analytics/Microsoft Sentinel Logs blade, click Functions and search for the alias SalesforceServiceCloud and load the function code or click [here](https://aka.ms/sentinel-SalesforceServiceCloud-parser). The function usually takes 10-15 minutes to activate after solution installation/update."
+ },
+ {
+ "description": "**STEP 1 - Configuration steps for the Salesforce Lightning Platform REST API**\n\n1. See the [link](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart.htm) and follow the instructions for obtaining Salesforce API Authorization credentials. \n2. On the **Set Up Authorization** step choose **Session ID Authorization** method.\n3. You must provide your client id, client secret, username, and password with user security token."
+ },
+ {
+ "description": ">**NOTE:** Ingesting data from on an hourly interval may require additional licensing based on the edition of the Salesforce Service Cloud being used. Please refer to [Salesforce documentation](https://www.salesforce.com/editions-pricing/service-cloud/) and/or support for more details."
+ },
+ {
+ "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Salesforce Service Cloud data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following), as well as the Salesforce API Authorization credentials, readily available.",
+ "instructions": [
+ {
+ "parameters": {
+ "fillWith": [
+ "WorkspaceId"
],
- "connectorId": "SalesforceServiceCloud"
- }
- ],
- "tactics": [
- "CredentialAccess"
- ],
- "techniques": [
- "T1110"
- ],
- "entityMappings": [
- {
- "fieldMappings": [
+ "label": "Workspace ID"
+ },
+ "type": "CopyableLabel"
+ },
+ {
+ "parameters": {
+ "fillWith": [
+ "PrimaryKey"
+ ],
+ "label": "Primary Key"
+ },
+ "type": "CopyableLabel"
+ }
+ ]
+ },
+ {
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
{
- "identifier": "FullName",
- "columnName": "User"
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the Salesforce Service Cloud data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-SalesforceServiceCloud-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID**, **Workspace Key**, **Salesforce API Username**, **Salesforce API Password**, **Salesforce Security Token**, **Salesforce Consumer Key**, **Salesforce Consumer Secret** and deploy. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Functions",
+ "description": "Use the following step-by-step instructions to deploy the Salesforce Service Cloud data connector manually with Azure Functions (Deployment via Visual Studio Code).",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Step 1 - Deploy a Function App",
+ "description": "**NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-SalesforceServiceCloud-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it."
+ },
+ {
+ "title": "Step 2 - Configure the Function App",
+ "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **+ New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tSalesforceUser\n\t\tSalesforcePass\n\t\tSalesforceSecurityToken\n\t\tSalesforceConsumerKey\n\t\tSalesforceConsumerSecret\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`\n5. Once all application settings have been entered, click **Save**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
- ],
- "entityType": "Account"
- }
- ],
- "customDetails": {
- "EventStartTime": "FailureStartTime",
- "IPAddresses": "IpAddresses",
- "EventEndTime": "SuccessEndTime"
- }
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId1'),'/'))))]",
- "properties": {
- "description": "Salesforce Service Cloud Analytics Rule 1",
- "parentId": "[variables('analyticRuleId1')]",
- "contentId": "[variables('_analyticRulecontentId1')]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion1')]",
- "source": {
- "kind": "Solution",
- "name": "Salesforce Service Cloud",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Microsoft",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Microsoft Corporation",
- "email": "support@microsoft.com",
- "tier": "Microsoft",
- "link": "https://support.microsoft.com/"
+ ]
+ },
+ "type": "InstructionStepsGroup"
}
- }
+ ]
}
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_analyticRulecontentId1')]",
- "contentKind": "AnalyticsRule",
- "displayName": "Brute force attack against user credentials",
- "contentProductId": "[variables('_analyticRulecontentProductId1')]",
- "id": "[variables('_analyticRulecontentProductId1')]",
- "version": "[variables('analyticRuleVersion1')]"
+ ],
+ "id": "[variables('_uiConfigId1')]",
+ "additionalRequirementBanner": "These queries are dependent on a parser based on a Kusto Function deployed as part of the solution."
+ }
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleTemplateSpecName2')]",
+ "name": "[variables('parserObject1').parserTemplateSpecName1]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Salesforce-PasswordSpray_AnalyticalRules Analytics Rule with template version 3.0.0",
+ "description": "SalesforceServiceCloud Data Parser with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion2')]",
+ "contentVersion": "[variables('parserObject1').parserVersion1]",
"parameters": {},
"variables": {},
"resources": [
{
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRulecontentId2')]",
- "apiVersion": "2022-04-01-preview",
- "kind": "Scheduled",
+ "name": "[variables('parserObject1')._parserName1]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
"location": "[parameters('workspace-location')]",
"properties": {
- "description": "This query searches for failed attempts to log in from more than 15 various users within a 5 minute timeframe from the same source. This is a potential indication of a password spray attack.",
- "displayName": "Potential Password Spray Attack",
- "enabled": false,
- "query": "let FailureThreshold = 15; \nSalesforceServiceCloud\n| where EventType =~ 'Login' and LoginStatus != 'LOGIN_NO_ERROR'\n| where LoginStatus in~ ('LOGIN_ERROR_INVALID_PASSWORD', 'LOGIN_ERROR_SSO_PWD_INVALID')\n| summarize UserCount=dcount(UserId), Users = make_set(UserId,100) by ClientIp, bin(TimeGenerated, 5m)\n| where UserCount > FailureThreshold\n",
- "queryFrequency": "PT5M",
- "queryPeriod": "PT5M",
- "severity": "Medium",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "triggerOperator": "GreaterThan",
- "triggerThreshold": 0,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "dataTypes": [
- "SalesforceServiceCloud"
- ],
- "connectorId": "SalesforceServiceCloud"
- }
- ],
- "tactics": [
- "CredentialAccess"
- ],
- "techniques": [
- "T1110"
- ],
- "entityMappings": [
+ "eTag": "*",
+ "displayName": "SalesforceServiceCloud",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "SalesforceServiceCloud",
+ "query": "SalesforceServiceCloud_CL \n| extend \n\t\tRequestSize=column_ifexists('request_size_s',''),\n\t\tExecTime=column_ifexists('exec_time_s',''),\n\t\tAction=column_ifexists('action_s',''),\n\t\tPlatformType=column_ifexists('platform_type_s',''),\n\t\tOsName=column_ifexists('os_name_s',''),\n\t\tOsVersion=column_ifexists('os_version_s',''),\n\t\tTimestamp=column_ifexists('timestamp_s',''),\n\t\tStatusCode=column_ifexists('status_code_s',''),\n\t\tEventType=column_ifexists('event_type_s',''),\n\t\tReferrerUri=column_ifexists('referrer_uri_s',''),\n\t\tUserAgent=column_ifexists('user_agent_s',''),\n\t\tBrowserType=column_ifexists('browser_type_s',''),\n\t\tTime=column_ifexists('time_s',''),\n\t\tResponseSize=column_ifexists('response_size_s',''),\n\t\tDeviceId=column_ifexists('device_id_s',''),\n\t\tDeviceModel=column_ifexists('device_model_s',''),\n\t\tSourceIp=column_ifexists('source_ip_s',''),\n\t\tClientIp=column_ifexists('client_ip_s',''),\n\t\tSuccess=column_ifexists('success_s',''),\n\t\tUri=column_ifexists('uri_s',''),\n\t\tUrl=column_ifexists('url_s',''),\n\t\tClientName=column_ifexists('client_name_s',''),\n\t\tUserType=column_ifexists('user_type_s',''),\n\t\tUserInitiatedLogout=column_ifexists('user_initiated_logout_s',''),\n\t\tUserIdDerived=column_ifexists('user_id_derived_s',''),\n\t\tUserId=column_ifexists('user_id_s',''),\n\t\tUserEmail=column_ifexists('user_email_s',''),\n\t\tUser=column_ifexists('user_name_s',''),\n\t\tUriIdDerived=column_ifexists('uri_id_derived_s',''),\n\t\tUiEventType=column_ifexists('ui_event_type_s',''),\n\t\tUiEventTimestamp=column_ifexists('ui_event_timestamp_s',''),\n\t\tUiEventSource=column_ifexists('ui_event_source_s',''),\n\t\tUiEventSequenceNum=column_ifexists('ui_event_sequence_num_s',''),\n\t\tUiEventId=column_ifexists('ui_event_id_s',''),\n\t\tTlsProtocol=column_ifexists('tls_protocol_s',''),\n\t\tTimestampDerived=column_ifexists('timestamp_derived_t',''),\n\t\tTargetUiElement=column_ifexists('target_ui_element_s',''),\n\t\tSort=column_ifexists('sort_s',''),\n\t\tSessionType=column_ifexists('session_type_s',''),\n\t\tSessionLevel=column_ifexists('session_level_s',''),\n\t\tSessionKey=column_ifexists('session_key_s',''),\n\t\tSearchQuery=column_ifexists('search_query_s',''),\n\t\tSdkVersion=column_ifexists('sdk_version_s',''),\n\t\tSdkAppVersion=column_ifexists('sdk_app_version_s',''),\n\t\tSdkAppType=column_ifexists('sdk_app_type_s',''),\n\t\tRunTime=column_ifexists('run_time_s',''),\n\t\tRowsProcessed=column_ifexists('rows_processed_s',''),\n\t\tRowCount=column_ifexists('row_count_s',''),\n\t\tResolutionType=column_ifexists('resolution_type_s',''),\n\t\tRequestStatus=column_ifexists('request_status_s',''),\n\t\tRequestId=column_ifexists('request_id_s',''),\n\t\tReportIdDerived=column_ifexists('report_id_derived_s',''),\n\t\tReportId=column_ifexists('report_id_s',''),\n\t\tRenderingType=column_ifexists('rendering_type_s',''),\n\t\tRelatedList=column_ifexists('related_list_s',''),\n\t\tRecordType=column_ifexists('record_type_s',''),\n\t\tRecordId=column_ifexists('record_id_s',''),\n\t\tQuiddity=column_ifexists('quiddity_s',''),\n\t\tQueryId=column_ifexists('query_id_s',''),\n\t\tPrevpageUrl=column_ifexists('prevpage_url_s',''),\n\t\tPrevpageEntityType=column_ifexists('prevpage_entity_type_s',''),\n\t\tPrevpageEntityId=column_ifexists('prevpage_entity_id_s',''),\n\t\tPrevpageContext=column_ifexists('prevpage_context_s',''),\n\t\tPrevpageAppName=column_ifexists('prevpage_app_name_s',''),\n\t\tPrefixesSearched=column_ifexists('prefixes_searched_s',''),\n\t\tParentUiElement=column_ifexists('parent_ui_element_s',''),\n\t\tPageUrl=column_ifexists('page_url_s',''),\n\t\tPageStartTime=column_ifexists('page_start_time_s',''),\n\t\tPageEntityType=column_ifexists('page_entity_type_s',''),\n\t\tPageEntityId=column_ifexists('page_entity_id_s',''),\n\t\tPageContext=column_ifexists('page_context_s',''),\n\t\tPageAppName=column_ifexists('page_app_name_s',''),\n\t\tOrigin=column_ifexists('origin_s',''),\n\t\tOrganizationId=column_ifexists('organization_id_s',''),\n\t\tNumResults=column_ifexists('num_results_s',''),\n\t\tNumberSoqlQueries=column_ifexists('number_soql_queries_s',''),\n\t\tNumberFields=column_ifexists('number_fields_s',''),\n\t\tNumberExceptionFilters=column_ifexists('number_exception_filters_s',''),\n\t\tNumberColumns=column_ifexists('number_columns_s',''),\n\t\tNumberBuckets=column_ifexists('number_buckets_s',''),\n\t\tMethodName=column_ifexists('method_name_s',''),\n\t\tMethod=column_ifexists('method_s',''),\n\t\tMediaType=column_ifexists('media_type_s',''),\n\t\tLoginStatus=column_ifexists('login_status_s',''),\n\t\tLoginKey=column_ifexists('login_key_s',''),\n\t\tHttpMethod=column_ifexists('http_method_s',''),\n\t\tGrandparentUiElement=column_ifexists('grandparent_ui_element_s',''),\n\t\tEntryPoint=column_ifexists('entry_point_s',''),\n\t\tEntityName=column_ifexists('entity_name_s',''),\n\t\tEntity=column_ifexists('entity_s',''),\n\t\tEffectivePageTime=column_ifexists('effective_page_time_s',''),\n\t\tDuration=column_ifexists('duration_s',''),\n\t\tDisplayType=column_ifexists('display_type_s',''),\n\t\tDeviceSessionId=column_ifexists('device_session_id_s',''),\n\t\tDevicePlatform=column_ifexists('device_platform_s',''),\n\t\tDbTotalTime=column_ifexists('db_total_time_s',''),\n\t\tDbCpuTime=column_ifexists('db_cpu_time_s',''),\n\t\tDbBlocks=column_ifexists('db_blocks_s',''),\n\t\tCpuTime=column_ifexists('cpu_time_s',''),\n\t\tConnectionType=column_ifexists('connection_type_s',''),\n\t\tComponentName=column_ifexists('component_name_s',''),\n\t\tClientVersion=column_ifexists('client_version_s',''),\n\t\tClientId=column_ifexists('client_id_s',''),\n\t\tCipherSuite=column_ifexists('cipher_suite_s',''),\n\t\tCalloutTime=column_ifexists('callout_time_s',''),\n\t\tBrowserVersion=column_ifexists('browser_version_s',''),\n\t\tBrowserName=column_ifexists('browser_name_s',''),\n\t\tAverageRowSize=column_ifexists('average_row_size_s',''),\n\t\tAppType=column_ifexists('app_type_s',''),\n\t\tAppName=column_ifexists('app_name_s',''),\n\t\tApiVersion=column_ifexists('api_version_s',''),\n\t\tApiType=column_ifexists('api_type_s',''),\n ArticleVersionId=column_ifexists('article_version_id_s',''),\n\t\tArticleVersion=column_ifexists('article_version_s',''),\n\t\tArticleStatus=column_ifexists('article_status_s',''),\n\t\tArticleId=column_ifexists('article_id_s',''),\n AnalyticsMode=column_ifexists('analytics_mode_s',''),\n BatchId=column_ifexists('batch_id_s',''),\n ClickedRecordId=column_ifexists('clicked_record_id_s',''),\n\t\tClassName=column_ifexists('class_name_s',''),\n ComponentIdDerived=column_ifexists('component_id_derived_s',''),\n\t\tComponentId=column_ifexists('component_id_s',''),\n ControllerType=column_ifexists('controller_type_s',''),\n\t\tContext=column_ifexists('context_s',''),\n\t\tConsoleIdDerived=column_ifexists('console_id_derived_s',''),\n\t\tConsoleId=column_ifexists('console_id_s',''), \n ClientInfo=column_ifexists('client_info_s',''),\n DstBytes=column_ifexists('request_size_s',''),\n\t\tDstUser=column_ifexists('delegated_user_name_s',''),\n DstUserSid=column_ifexists('delegated_user_id_s',''),\n\t\tDstUserSidDerived=column_ifexists('delegated_user_id_derived_s',''),\n Data=column_ifexists('data_s',''),\n\t\tDashboardType=column_ifexists('dashboard_type_s',''),\n\t\tDashboardIdDerived=column_ifexists('dashboard_id_derived_s',''),\n\t\tDashboardId=column_ifexists('dashboard_id_s',''),\n\t\tDashboardComponentId=column_ifexists('dashboard_component_id_s',''),\n\t\tDvcAction=column_ifexists('action_s',''),\n\t\tDvcOS=column_ifexists('platform_type_s',''),\n\t\tDvcOSName=column_ifexists('os_name_s',''),\n\t\tDvcOSVersion=column_ifexists('os_version_s',''),\n DeliveryLocation=column_ifexists('delivery_location_s',''),\n\t\tDeliveryId=column_ifexists('delivery_id_s',''),\n DocumentIdDerived=column_ifexists('document_id_derived_s',''),\n\t\tDocumentId=column_ifexists('document_id_s',''),\n EntityType=column_ifexists('entity_type_s',''),\n EntityId=column_ifexists('entity_id_s',''),\n FileType=column_ifexists('file_type_s',''),\n\t\tFilePreviewType=column_ifexists('file_preview_type_s',''),\n\t\tExceptionType=column_ifexists('exception_type_s',''),\n\t\tExceptionMessage=column_ifexists('exception_message_s',''),\n\t\tEpt=column_ifexists('ept_s',''),\n EventCount=column_ifexists('number_of_records_s',''),\n\t\tEventEndTime=column_ifexists('timestamp_s',''),\n\t\tEventResult=column_ifexists('status_code_s',''),\n\t\tFileSize=column_ifexists('size_bytes_s',''),\n HttpReferrerOriginal=column_ifexists('referrer_uri_s',''),\n\t\tHttpUserAgentOriginal=column_ifexists('user_agent_s',''),\n\t\tHttpUserAgent=column_ifexists('browser_type_s',''),\n LogGroupId=column_ifexists('log_group_id_s',''),\n\t\tLimitUsagePercent=column_ifexists('limit_usage_percent_s',''),\n\t\tLicenseContext=column_ifexists('license_context_s',''),\n\t\tLastVersion=column_ifexists('last_version_s',''),\n\t\tLanguage=column_ifexists('language_s',''),\n\t\tJobId=column_ifexists('job_id_s',''),\n\t\tIsSuccess=column_ifexists('is_success_s',''),\n\t\tIsSecure=column_ifexists('is_secure_s',''),\n\t\tIsScheduled=column_ifexists('is_scheduled_s',''),\n\t\tIsNew=column_ifexists('is_new_s',''),\n\t\tIsMobile=column_ifexists('is_mobile_s',''),\n\t\tIsLongRunningRequest=column_ifexists('is_long_running_request_s',''),\n\t\tIsGuest=column_ifexists('is_guest_s',''),\n\t\tIsFirstRequest=column_ifexists('is_first_request_s',''),\n\t\tIsError=column_ifexists('is_error_s',''),\n\t\tIsApi=column_ifexists('is_api_s',''),\n\t\tIsAjaxRequest=column_ifexists('is_ajax_request_s',''),\n ManagedPackageNamespace=column_ifexists('managed_package_namespace_s',''),\n HttpHeaders=column_ifexists('http_headers_s',''),\n\t\tNetworkDuration=column_ifexists('time_s',''),\n Name=column_ifexists('name_s',''),\n NumberFailures=column_ifexists('number_failures_s',''),\n NumClicks=column_ifexists('num_clicks_s',''),\n OperationType=column_ifexists('operation_type_s',''),\n\t\tNumSessions=column_ifexists('num_sessions_s',''),\n PageName=column_ifexists('page_name_s',''),\n Query=column_ifexists('query_s',''),\n RequestType=column_ifexists('request_type_s',''),\n ReportDescription=column_ifexists('report_description_s',''),\n\t\tReopenCount=column_ifexists('reopen_count_s',''),\n RelatedEntityId=column_ifexists('related_entity_id_s',''),\n RecordIdDerived=column_ifexists('record_id_derived_s',''),\n ReadTime=column_ifexists('read_time_s',''),\n\t\tRank=column_ifexists('rank_s',''),\n\t\tSrcBytes=column_ifexists('response_size_s',''),\n\t\tSrcDvcId=column_ifexists('device_id_s',''),\n\t\tSrcDvcModelName=column_ifexists('device_model_s',''),\n\t\tSrcIpAddr=column_ifexists('source_ip_s',''),\n\t\tSrcNatIpAddr=column_ifexists('client_ip_s',''),\n SessionId=column_ifexists('session_id_s',''),\n SiteId=column_ifexists('site_id_s',''),\n\t\tSharingPermission=column_ifexists('sharing_permission_s',''),\n\t\tSharingOperation=column_ifexists('sharing_operation_s',''),\n\t\tSharedWithEntityId=column_ifexists('shared_with_entity_id_s',''),\n\t\tUrlOriginal=column_ifexists('url_s',''),\n\t\tWaveTimestamp=column_ifexists('wave_timestamp_s',''),\n\t\tWaveSessionId=column_ifexists('wave_session_id_g',''),\n\t\tViewStateSize=column_ifexists('view_state_size_s',''),\n\t\tVersionIdDerived=column_ifexists('version_id_derived_s',''),\n\t\tVersionId=column_ifexists('version_id_s',''),\n TriggerType=column_ifexists('trigger_type_s',''),\n\t\tTriggerName=column_ifexists('trigger_name_s',''),\n\t\tTriggerId=column_ifexists('trigger_id_s',''),\n\t\tTransactionType=column_ifexists('transaction_type_s',''),\n\t\tTotalTime=column_ifexists('total_time_s',''),\n TabId=column_ifexists('tab_id_s',''),\n\t\tStackTrace=column_ifexists('stack_trace_s','')\n| project-away *_s\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
{
- "fieldMappings": [
- {
- "identifier": "Address",
- "columnName": "ClientIp"
- }
- ],
- "entityType": "IP"
+ "name": "description",
+ "value": ""
}
- ],
- "customDetails": {
- "Users": "Users"
- }
+ ]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId2'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
"properties": {
- "description": "Salesforce Service Cloud Analytics Rule 2",
- "parentId": "[variables('analyticRuleId2')]",
- "contentId": "[variables('_analyticRulecontentId2')]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion2')]",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'SalesforceServiceCloud')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
"source": {
- "kind": "Solution",
"name": "Salesforce Service Cloud",
+ "kind": "Solution",
"sourceId": "[variables('_solutionId')]"
},
"author": {
@@ -919,86 +885,108 @@
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_analyticRulecontentId2')]",
- "contentKind": "AnalyticsRule",
- "displayName": "Potential Password Spray Attack",
- "contentProductId": "[variables('_analyticRulecontentProductId2')]",
- "id": "[variables('_analyticRulecontentProductId2')]",
- "version": "[variables('analyticRuleVersion2')]"
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "contentKind": "Parser",
+ "displayName": "SalesforceServiceCloud",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]",
+ "version": "[variables('parserObject1').parserVersion1]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('parserObject1')._parserName1]",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "SalesforceServiceCloud",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "SalesforceServiceCloud",
+ "query": "SalesforceServiceCloud_CL \n| extend \n\t\tRequestSize=column_ifexists('request_size_s',''),\n\t\tExecTime=column_ifexists('exec_time_s',''),\n\t\tAction=column_ifexists('action_s',''),\n\t\tPlatformType=column_ifexists('platform_type_s',''),\n\t\tOsName=column_ifexists('os_name_s',''),\n\t\tOsVersion=column_ifexists('os_version_s',''),\n\t\tTimestamp=column_ifexists('timestamp_s',''),\n\t\tStatusCode=column_ifexists('status_code_s',''),\n\t\tEventType=column_ifexists('event_type_s',''),\n\t\tReferrerUri=column_ifexists('referrer_uri_s',''),\n\t\tUserAgent=column_ifexists('user_agent_s',''),\n\t\tBrowserType=column_ifexists('browser_type_s',''),\n\t\tTime=column_ifexists('time_s',''),\n\t\tResponseSize=column_ifexists('response_size_s',''),\n\t\tDeviceId=column_ifexists('device_id_s',''),\n\t\tDeviceModel=column_ifexists('device_model_s',''),\n\t\tSourceIp=column_ifexists('source_ip_s',''),\n\t\tClientIp=column_ifexists('client_ip_s',''),\n\t\tSuccess=column_ifexists('success_s',''),\n\t\tUri=column_ifexists('uri_s',''),\n\t\tUrl=column_ifexists('url_s',''),\n\t\tClientName=column_ifexists('client_name_s',''),\n\t\tUserType=column_ifexists('user_type_s',''),\n\t\tUserInitiatedLogout=column_ifexists('user_initiated_logout_s',''),\n\t\tUserIdDerived=column_ifexists('user_id_derived_s',''),\n\t\tUserId=column_ifexists('user_id_s',''),\n\t\tUserEmail=column_ifexists('user_email_s',''),\n\t\tUser=column_ifexists('user_name_s',''),\n\t\tUriIdDerived=column_ifexists('uri_id_derived_s',''),\n\t\tUiEventType=column_ifexists('ui_event_type_s',''),\n\t\tUiEventTimestamp=column_ifexists('ui_event_timestamp_s',''),\n\t\tUiEventSource=column_ifexists('ui_event_source_s',''),\n\t\tUiEventSequenceNum=column_ifexists('ui_event_sequence_num_s',''),\n\t\tUiEventId=column_ifexists('ui_event_id_s',''),\n\t\tTlsProtocol=column_ifexists('tls_protocol_s',''),\n\t\tTimestampDerived=column_ifexists('timestamp_derived_t',''),\n\t\tTargetUiElement=column_ifexists('target_ui_element_s',''),\n\t\tSort=column_ifexists('sort_s',''),\n\t\tSessionType=column_ifexists('session_type_s',''),\n\t\tSessionLevel=column_ifexists('session_level_s',''),\n\t\tSessionKey=column_ifexists('session_key_s',''),\n\t\tSearchQuery=column_ifexists('search_query_s',''),\n\t\tSdkVersion=column_ifexists('sdk_version_s',''),\n\t\tSdkAppVersion=column_ifexists('sdk_app_version_s',''),\n\t\tSdkAppType=column_ifexists('sdk_app_type_s',''),\n\t\tRunTime=column_ifexists('run_time_s',''),\n\t\tRowsProcessed=column_ifexists('rows_processed_s',''),\n\t\tRowCount=column_ifexists('row_count_s',''),\n\t\tResolutionType=column_ifexists('resolution_type_s',''),\n\t\tRequestStatus=column_ifexists('request_status_s',''),\n\t\tRequestId=column_ifexists('request_id_s',''),\n\t\tReportIdDerived=column_ifexists('report_id_derived_s',''),\n\t\tReportId=column_ifexists('report_id_s',''),\n\t\tRenderingType=column_ifexists('rendering_type_s',''),\n\t\tRelatedList=column_ifexists('related_list_s',''),\n\t\tRecordType=column_ifexists('record_type_s',''),\n\t\tRecordId=column_ifexists('record_id_s',''),\n\t\tQuiddity=column_ifexists('quiddity_s',''),\n\t\tQueryId=column_ifexists('query_id_s',''),\n\t\tPrevpageUrl=column_ifexists('prevpage_url_s',''),\n\t\tPrevpageEntityType=column_ifexists('prevpage_entity_type_s',''),\n\t\tPrevpageEntityId=column_ifexists('prevpage_entity_id_s',''),\n\t\tPrevpageContext=column_ifexists('prevpage_context_s',''),\n\t\tPrevpageAppName=column_ifexists('prevpage_app_name_s',''),\n\t\tPrefixesSearched=column_ifexists('prefixes_searched_s',''),\n\t\tParentUiElement=column_ifexists('parent_ui_element_s',''),\n\t\tPageUrl=column_ifexists('page_url_s',''),\n\t\tPageStartTime=column_ifexists('page_start_time_s',''),\n\t\tPageEntityType=column_ifexists('page_entity_type_s',''),\n\t\tPageEntityId=column_ifexists('page_entity_id_s',''),\n\t\tPageContext=column_ifexists('page_context_s',''),\n\t\tPageAppName=column_ifexists('page_app_name_s',''),\n\t\tOrigin=column_ifexists('origin_s',''),\n\t\tOrganizationId=column_ifexists('organization_id_s',''),\n\t\tNumResults=column_ifexists('num_results_s',''),\n\t\tNumberSoqlQueries=column_ifexists('number_soql_queries_s',''),\n\t\tNumberFields=column_ifexists('number_fields_s',''),\n\t\tNumberExceptionFilters=column_ifexists('number_exception_filters_s',''),\n\t\tNumberColumns=column_ifexists('number_columns_s',''),\n\t\tNumberBuckets=column_ifexists('number_buckets_s',''),\n\t\tMethodName=column_ifexists('method_name_s',''),\n\t\tMethod=column_ifexists('method_s',''),\n\t\tMediaType=column_ifexists('media_type_s',''),\n\t\tLoginStatus=column_ifexists('login_status_s',''),\n\t\tLoginKey=column_ifexists('login_key_s',''),\n\t\tHttpMethod=column_ifexists('http_method_s',''),\n\t\tGrandparentUiElement=column_ifexists('grandparent_ui_element_s',''),\n\t\tEntryPoint=column_ifexists('entry_point_s',''),\n\t\tEntityName=column_ifexists('entity_name_s',''),\n\t\tEntity=column_ifexists('entity_s',''),\n\t\tEffectivePageTime=column_ifexists('effective_page_time_s',''),\n\t\tDuration=column_ifexists('duration_s',''),\n\t\tDisplayType=column_ifexists('display_type_s',''),\n\t\tDeviceSessionId=column_ifexists('device_session_id_s',''),\n\t\tDevicePlatform=column_ifexists('device_platform_s',''),\n\t\tDbTotalTime=column_ifexists('db_total_time_s',''),\n\t\tDbCpuTime=column_ifexists('db_cpu_time_s',''),\n\t\tDbBlocks=column_ifexists('db_blocks_s',''),\n\t\tCpuTime=column_ifexists('cpu_time_s',''),\n\t\tConnectionType=column_ifexists('connection_type_s',''),\n\t\tComponentName=column_ifexists('component_name_s',''),\n\t\tClientVersion=column_ifexists('client_version_s',''),\n\t\tClientId=column_ifexists('client_id_s',''),\n\t\tCipherSuite=column_ifexists('cipher_suite_s',''),\n\t\tCalloutTime=column_ifexists('callout_time_s',''),\n\t\tBrowserVersion=column_ifexists('browser_version_s',''),\n\t\tBrowserName=column_ifexists('browser_name_s',''),\n\t\tAverageRowSize=column_ifexists('average_row_size_s',''),\n\t\tAppType=column_ifexists('app_type_s',''),\n\t\tAppName=column_ifexists('app_name_s',''),\n\t\tApiVersion=column_ifexists('api_version_s',''),\n\t\tApiType=column_ifexists('api_type_s',''),\n ArticleVersionId=column_ifexists('article_version_id_s',''),\n\t\tArticleVersion=column_ifexists('article_version_s',''),\n\t\tArticleStatus=column_ifexists('article_status_s',''),\n\t\tArticleId=column_ifexists('article_id_s',''),\n AnalyticsMode=column_ifexists('analytics_mode_s',''),\n BatchId=column_ifexists('batch_id_s',''),\n ClickedRecordId=column_ifexists('clicked_record_id_s',''),\n\t\tClassName=column_ifexists('class_name_s',''),\n ComponentIdDerived=column_ifexists('component_id_derived_s',''),\n\t\tComponentId=column_ifexists('component_id_s',''),\n ControllerType=column_ifexists('controller_type_s',''),\n\t\tContext=column_ifexists('context_s',''),\n\t\tConsoleIdDerived=column_ifexists('console_id_derived_s',''),\n\t\tConsoleId=column_ifexists('console_id_s',''), \n ClientInfo=column_ifexists('client_info_s',''),\n DstBytes=column_ifexists('request_size_s',''),\n\t\tDstUser=column_ifexists('delegated_user_name_s',''),\n DstUserSid=column_ifexists('delegated_user_id_s',''),\n\t\tDstUserSidDerived=column_ifexists('delegated_user_id_derived_s',''),\n Data=column_ifexists('data_s',''),\n\t\tDashboardType=column_ifexists('dashboard_type_s',''),\n\t\tDashboardIdDerived=column_ifexists('dashboard_id_derived_s',''),\n\t\tDashboardId=column_ifexists('dashboard_id_s',''),\n\t\tDashboardComponentId=column_ifexists('dashboard_component_id_s',''),\n\t\tDvcAction=column_ifexists('action_s',''),\n\t\tDvcOS=column_ifexists('platform_type_s',''),\n\t\tDvcOSName=column_ifexists('os_name_s',''),\n\t\tDvcOSVersion=column_ifexists('os_version_s',''),\n DeliveryLocation=column_ifexists('delivery_location_s',''),\n\t\tDeliveryId=column_ifexists('delivery_id_s',''),\n DocumentIdDerived=column_ifexists('document_id_derived_s',''),\n\t\tDocumentId=column_ifexists('document_id_s',''),\n EntityType=column_ifexists('entity_type_s',''),\n EntityId=column_ifexists('entity_id_s',''),\n FileType=column_ifexists('file_type_s',''),\n\t\tFilePreviewType=column_ifexists('file_preview_type_s',''),\n\t\tExceptionType=column_ifexists('exception_type_s',''),\n\t\tExceptionMessage=column_ifexists('exception_message_s',''),\n\t\tEpt=column_ifexists('ept_s',''),\n EventCount=column_ifexists('number_of_records_s',''),\n\t\tEventEndTime=column_ifexists('timestamp_s',''),\n\t\tEventResult=column_ifexists('status_code_s',''),\n\t\tFileSize=column_ifexists('size_bytes_s',''),\n HttpReferrerOriginal=column_ifexists('referrer_uri_s',''),\n\t\tHttpUserAgentOriginal=column_ifexists('user_agent_s',''),\n\t\tHttpUserAgent=column_ifexists('browser_type_s',''),\n LogGroupId=column_ifexists('log_group_id_s',''),\n\t\tLimitUsagePercent=column_ifexists('limit_usage_percent_s',''),\n\t\tLicenseContext=column_ifexists('license_context_s',''),\n\t\tLastVersion=column_ifexists('last_version_s',''),\n\t\tLanguage=column_ifexists('language_s',''),\n\t\tJobId=column_ifexists('job_id_s',''),\n\t\tIsSuccess=column_ifexists('is_success_s',''),\n\t\tIsSecure=column_ifexists('is_secure_s',''),\n\t\tIsScheduled=column_ifexists('is_scheduled_s',''),\n\t\tIsNew=column_ifexists('is_new_s',''),\n\t\tIsMobile=column_ifexists('is_mobile_s',''),\n\t\tIsLongRunningRequest=column_ifexists('is_long_running_request_s',''),\n\t\tIsGuest=column_ifexists('is_guest_s',''),\n\t\tIsFirstRequest=column_ifexists('is_first_request_s',''),\n\t\tIsError=column_ifexists('is_error_s',''),\n\t\tIsApi=column_ifexists('is_api_s',''),\n\t\tIsAjaxRequest=column_ifexists('is_ajax_request_s',''),\n ManagedPackageNamespace=column_ifexists('managed_package_namespace_s',''),\n HttpHeaders=column_ifexists('http_headers_s',''),\n\t\tNetworkDuration=column_ifexists('time_s',''),\n Name=column_ifexists('name_s',''),\n NumberFailures=column_ifexists('number_failures_s',''),\n NumClicks=column_ifexists('num_clicks_s',''),\n OperationType=column_ifexists('operation_type_s',''),\n\t\tNumSessions=column_ifexists('num_sessions_s',''),\n PageName=column_ifexists('page_name_s',''),\n Query=column_ifexists('query_s',''),\n RequestType=column_ifexists('request_type_s',''),\n ReportDescription=column_ifexists('report_description_s',''),\n\t\tReopenCount=column_ifexists('reopen_count_s',''),\n RelatedEntityId=column_ifexists('related_entity_id_s',''),\n RecordIdDerived=column_ifexists('record_id_derived_s',''),\n ReadTime=column_ifexists('read_time_s',''),\n\t\tRank=column_ifexists('rank_s',''),\n\t\tSrcBytes=column_ifexists('response_size_s',''),\n\t\tSrcDvcId=column_ifexists('device_id_s',''),\n\t\tSrcDvcModelName=column_ifexists('device_model_s',''),\n\t\tSrcIpAddr=column_ifexists('source_ip_s',''),\n\t\tSrcNatIpAddr=column_ifexists('client_ip_s',''),\n SessionId=column_ifexists('session_id_s',''),\n SiteId=column_ifexists('site_id_s',''),\n\t\tSharingPermission=column_ifexists('sharing_permission_s',''),\n\t\tSharingOperation=column_ifexists('sharing_operation_s',''),\n\t\tSharedWithEntityId=column_ifexists('shared_with_entity_id_s',''),\n\t\tUrlOriginal=column_ifexists('url_s',''),\n\t\tWaveTimestamp=column_ifexists('wave_timestamp_s',''),\n\t\tWaveSessionId=column_ifexists('wave_session_id_g',''),\n\t\tViewStateSize=column_ifexists('view_state_size_s',''),\n\t\tVersionIdDerived=column_ifexists('version_id_derived_s',''),\n\t\tVersionId=column_ifexists('version_id_s',''),\n TriggerType=column_ifexists('trigger_type_s',''),\n\t\tTriggerName=column_ifexists('trigger_name_s',''),\n\t\tTriggerId=column_ifexists('trigger_id_s',''),\n\t\tTransactionType=column_ifexists('transaction_type_s',''),\n\t\tTotalTime=column_ifexists('total_time_s',''),\n TabId=column_ifexists('tab_id_s',''),\n\t\tStackTrace=column_ifexists('stack_trace_s','')\n| project-away *_s\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'SalesforceServiceCloud')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
+ "source": {
+ "kind": "Solution",
+ "name": "Salesforce Service Cloud",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Microsoft Corporation",
+ "email": "support@microsoft.com",
+ "tier": "Microsoft",
+ "link": "https://support.microsoft.com/"
+ }
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('analyticRuleTemplateSpecName3')]",
+ "name": "[variables('workbookTemplateSpecName1')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Salesforce-SigninsMultipleCountries_AnalyticalRules Analytics Rule with template version 3.0.0",
+ "description": "SalesforceServiceCloud Workbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion3')]",
+ "contentVersion": "[variables('workbookVersion1')]",
"parameters": {},
"variables": {},
"resources": [
{
- "type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('analyticRulecontentId3')]",
- "apiVersion": "2022-04-01-preview",
- "kind": "Scheduled",
+ "type": "Microsoft.Insights/workbooks",
+ "name": "[variables('workbookContentId1')]",
"location": "[parameters('workspace-location')]",
+ "kind": "shared",
+ "apiVersion": "2021-08-01",
+ "metadata": {
+ "description": "Sets the time name for analysis."
+ },
"properties": {
- "description": "This query searches for successful user logins from different countries within 30min.",
- "displayName": "User Sign in from different countries",
- "enabled": false,
- "query": "let threshold = 2;\nlet Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)\n[@\"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv\"];\nlet UsersLocation = SalesforceServiceCloud\n| where EventType =~ 'Login' and LoginStatus=~'LOGIN_NO_ERROR'\n| project TimeGenerated, ClientIp, UserId, User, UserType ;\nUsersLocation\n| extend Dummy=1\n| summarize count() by Hour=bin(TimeGenerated,30m), ClientIp,User, Dummy\n| partition by Hour(\n lookup (Countrydb|extend Dummy=1) on Dummy\n | where ipv4_is_match(ClientIp, Network)\n )\n| summarize NumOfCountries = dcount(country_name) by User, Hour\n| where NumOfCountries >= threshold\n",
- "queryFrequency": "PT30M",
- "queryPeriod": "PT30M",
- "severity": "Medium",
- "suppressionDuration": "PT1H",
- "suppressionEnabled": false,
- "triggerOperator": "GreaterThan",
- "triggerThreshold": 0,
- "status": "Available",
- "requiredDataConnectors": [
- {
- "dataTypes": [
- "SalesforceServiceCloud"
- ],
- "connectorId": "SalesforceServiceCloud"
- }
- ],
- "tactics": [
- "InitialAccess"
- ],
- "techniques": [
- "T1078"
- ],
- "entityMappings": [
- {
- "fieldMappings": [
- {
- "identifier": "AadUserId",
- "columnName": "User"
- }
- ],
- "entityType": "Account"
- }
- ]
+ "displayName": "[parameters('workbook1-name')]",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Salesforce Service Cloud Workbook\\n---\\n\\nThis workbook brings together queries and visualizations to assist you in identifying potential threats in your Salesforce Service cloud audit data. Visualizations may not appear if no data is present.\\n\\nTo begin select the desired TimeRange to filter the data to the timeframe you want to focus on. Note if you have a large amount of salesforce service cloud data, queries may timeout with a large time range, if this is the case simply select a smaller time range.: \",\"style\":\"info\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"412a09a0-64ae-4614-aec6-cbfc9273b82b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"value\":{\"durationMs\":1800000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 32\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"ae90d1dc-20da-4948-80da-127b210bf152\",\"cellValue\":\"view_tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"User Logins\",\"subTarget\":\"1\",\"style\":\"link\"},{\"id\":\"af58b4d9-a888-43ed-91a9-6e9f539a61d4\",\"cellValue\":\"view_tab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"API Usage\",\"subTarget\":\"2\",\"style\":\"link\"}]},\"name\":\"links - 34\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"User login locations\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Countrydb = externaldata(Network:string, geoname_id:string, continent_code:string, continent_name:string, country_iso_code:string, country_name:string)\\n[@\\\"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv\\\"];\\nlet UsersLocation = SalesforceServiceCloud\\n| where EventType == \\\"Login\\\"\\n| project TimeGenerated, SourceIp;\\nUsersLocation\\n| extend Dummy=1\\n| summarize count() by Hour=bin(TimeGenerated,24h), SourceIp,Dummy\\n| partition by Hour(\\n lookup (Countrydb|extend Dummy=1) on Dummy\\n | where ipv4_is_match(SourceIp, Network)\\n )\\n| summarize sum(count_) by country_name\",\"size\":3,\"title\":\"Heat Map- Geographical - {TimeRange:label}\",\"timeContextFromParameter\":\"TimeRange\",\"exportedParameters\":[{\"fieldName\":\"TimeGenerated\",\"parameterName\":\"RetTime\"},{\"parameterType\":1}],\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"map\",\"chartSettings\":{\"showLegend\":true},\"mapSettings\":{\"locInfo\":\"CountryRegion\",\"locInfoColumn\":\"country_name\",\"sizeSettings\":\"sum_count_\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"sum_count_\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"nodeColorField\":\"sum_count_\",\"colorAggregation\":\"Sum\",\"type\":\"heatmap\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"70\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| summarize AvgLogintime = avg(toint(RunTime)), MaxLoginTime = max(toint(RunTime)), TotalLoginRequests = count() by EventType\\r\\n| project-away EventType\",\"size\":1,\"title\":\"Overview - User login requests\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AvgLogintime\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":23,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"MaxLoginTime\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":23,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"TotalLoginRequests\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\"}}}],\"rowLimit\":1},\"tileSettings\":{\"showBorder\":false}},\"customWidth\":\"30\",\"name\":\"query - 8\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| summarize count() by bin(TimeGenerated, 1h),User, ClientIp \\r\\n| top 10 by count_\",\"size\":0,\"title\":\"Top 10 users with maximun logins - {TimeRange:label}\",\"exportFieldName\":\"UserId\",\"exportParameterName\":\"RetUser\",\"exportDefaultValue\":\"all users\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"user_name_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"TimeGenerated\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false},\"chartSettings\":{\"showLegend\":true}},\"customWidth\":\"60\",\"name\":\"query - 2\"},{\"type\":1,\"content\":{\"json\":\"To leverage infomation about Malicious IP, Threat Indicator solution should be configured and ThreatIntelligenceIndicator table should have information of malicious IP.\",\"style\":\"info\"},\"customWidth\":\"10\",\"name\":\"text - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\" let malicious_ips =\\r\\n ThreatIntelligenceIndicator\\r\\n | where isnotempty(NetworkIP)\\r\\n | summarize make_list(NetworkIP); \\r\\n SalesforceServiceCloud\\r\\n | where EventType == 'Login'\\r\\n | distinct User,ClientIp\\r\\n | where ClientIp in (malicious_ips)\\r\\n | project UserName = User, MaliciousIP = ClientIp\\r\\n\",\"size\":1,\"title\":\"Malicious IP- User Login\",\"noDataMessage\":\"No Malicious IP found\",\"timeBrushParameterName\":\"TimeBrush\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"UserName\",\"formatter\":8,\"formatOptions\":{\"min\":0,\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"MaliciousIP\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}}]},\"graphSettings\":{\"type\":0},\"chartSettings\":{\"showMetrics\":false}},\"customWidth\":\"30\",\"name\":\"query - 23\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'LoginAS'\\r\\n| project UserID = UserId,DerivedUSerID = UserIdDerived,EventType = EventType, IPAddress = ClientIp, LoginKey = LoginKey, OrgID = OrganizationId, RequestID = RequestId, SessionKey = SessionKey\\r\\n| limit 10\",\"size\":0,\"title\":\"User Activity- LoginAS(Top 10)\",\"noDataMessage\":\"No user impersonation found\",\"exportFieldName\":\"IPAddress\",\"exportParameterName\":\"RetIP\",\"exportDefaultValue\":\"all IP addresses\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"IPAddress\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"TotalRecords\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}},\"showBorder\":false}},\"customWidth\":\"60\",\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'LoginAs'\\r\\n| where isnotempty(User)\\r\\n| summarize count() by User,UserIdDerived,ClientIp\\r\\n| project UserName = User,DerivedUSerID = UserIdDerived,IPAddress = ClientIp, count_\",\"size\":1,\"title\":\"User Impersonation from different IP Addresses\",\"color\":\"blue\",\"noDataMessage\":\"No user impersonation found\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"UserName\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"DerivedUSerID\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"IPAddress\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"count_\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}}],\"labelSettings\":[{\"columnId\":\"UserName\",\"label\":\"User Name\"},{\"columnId\":\"DerivedUSerID\",\"label\":\"Impersonated ID\"},{\"columnId\":\"IPAddress\",\"label\":\"IP Address\"},{\"columnId\":\"count_\",\"label\":\"Total Login\"}]},\"chartSettings\":{\"xAxis\":\"IPAddress\",\"yAxis\":[\"count_\"],\"showLegend\":true}},\"customWidth\":\"40\",\"name\":\"query - 24\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| where isnotempty(User)\\r\\n| project UserName= User,APIType= ApiType, Browser= BrowserType, CipherSuite =CipherSuite, IP =ClientIp, CPUTime=CpuTime, UserType = UserType\\r\\n| take 200\",\"size\":0,\"title\":\"User Successful Login Activity\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"customWidth\":\"60\",\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == 'Login'\\r\\n| where isnotempty(User)\\r\\n| where LoginStatus !has('LOGIN_NO_ERROR')\\r\\n| summarize count() by User, ClientIp\\r\\n| project UserName = User, IP = ClientIp, Count = count_\",\"size\":1,\"title\":\"User Unsuccessful Logins by IP\",\"noDataMessage\":\"No Unsucessful Login found\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"UserName\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"IP\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"Count\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}}],\"labelSettings\":[{\"columnId\":\"UserName\",\"label\":\"User Name\"},{\"columnId\":\"IP\",\"label\":\"IP Address\"},{\"columnId\":\"Count\",\"label\":\"Count\"}]},\"chartSettings\":{\"xAxis\":\"UserName\",\"yAxis\":[\"Count\"],\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":true}}}}},\"customWidth\":\"30\",\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"view_tab\",\"comparison\":\"isEqualTo\",\"value\":\"1\"},\"name\":\"Retrieval Events\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"API Usage\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| summarize count() by EventType\",\"size\":0,\"title\":\"Most fired events\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":50,\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == \\\"ApiTotalUsage\\\"\\r\\n| summarize count() by IPAddress = ClientIp,Entity = EntityName\\r\\n| order by Entity\",\"size\":0,\"title\":\"Most accessed entities by IP Address\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"user_id_s\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\"}}},{\"columnMatch\":\"entity_name_s\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"client_ip_s\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"}},{\"columnMatch\":\"count_\",\"formatter\":8,\"formatOptions\":{\"palette\":\"categorical\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\"}}}],\"labelSettings\":[{\"columnId\":\"count_\",\"label\":\"Count\"}]}},\"customWidth\":\"50\",\"name\":\"query - 5\",\"styleSettings\":{\"maxWidth\":\"30%\",\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SalesforceServiceCloud\\r\\n| where EventType == \\\"ApiTotalUsage\\\"\\r\\n| summarize count() by EntityName\",\"size\":0,\"title\":\"Most accessed Entities\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"name\":\"query - 6\"}]},\"conditionalVisibility\":{\"parameterName\":\"view_tab\",\"comparison\":\"isEqualTo\",\"value\":\"2\"},\"name\":\"APIUsage\"}],\"fromTemplateId\":\"sentinel-SalesforceServiceCloudWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "version": "1.0",
+ "sourceId": "[variables('workspaceResourceId')]",
+ "category": "sentinel"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId3'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
"properties": {
- "description": "Salesforce Service Cloud Analytics Rule 3",
- "parentId": "[variables('analyticRuleId3')]",
- "contentId": "[variables('_analyticRulecontentId3')]",
- "kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion3')]",
+ "description": "@{workbookKey=SalesforceServiceCloudWorkbook; logoFileName=salesforce_logo.svg; description=Sets the time name for analysis.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Salesforce Service Cloud; templateRelativePath=SalesforceServiceCloud.json; subtitle=; provider=Salesforce}.description",
+ "parentId": "[variables('workbookId1')]",
+ "contentId": "[variables('_workbookContentId1')]",
+ "kind": "Workbook",
+ "version": "[variables('workbookVersion1')]",
"source": {
"kind": "Solution",
"name": "Salesforce Service Cloud",
@@ -1013,6 +1001,19 @@
"email": "support@microsoft.com",
"tier": "Microsoft",
"link": "https://support.microsoft.com/"
+ },
+ "dependencies": {
+ "operator": "AND",
+ "criteria": [
+ {
+ "contentId": "SalesforceServiceCloud",
+ "kind": "DataType"
+ },
+ {
+ "contentId": "SalesforceServiceCloud_CL",
+ "kind": "DataConnector"
+ }
+ ]
}
}
}
@@ -1023,12 +1024,12 @@
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
- "contentId": "[variables('_analyticRulecontentId3')]",
- "contentKind": "AnalyticsRule",
- "displayName": "User Sign in from different countries",
- "contentProductId": "[variables('_analyticRulecontentProductId3')]",
- "id": "[variables('_analyticRulecontentProductId3')]",
- "version": "[variables('analyticRuleVersion3')]"
+ "contentId": "[variables('_workbookContentId1')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook1-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId1')]",
+ "id": "[variables('_workbookcontentProductId1')]",
+ "version": "[variables('workbookVersion1')]"
}
},
{
@@ -1036,12 +1037,12 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.0",
+ "version": "3.0.1",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Salesforce Service Cloud",
"publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation",
- "descriptionHtml": "Note: There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Salesforce Service Cloud solution for Microsoft Sentinel enables you to ingest Service Cloud events into Microsoft Sentinel.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\nAzure Monitor HTTP Data Collector API
\n \nAzure Functions.
\n \n
\nData Connectors: 1, Parsers: 1, Workbooks: 1, Analytic Rules: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Salesforce Service Cloud solution for Microsoft Sentinel enables you to ingest Service Cloud events into Microsoft Sentinel.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\nAzure Monitor HTTP Data Collector API
\n \nAzure Functions
\n \n
\nData Connectors: 1, Parsers: 1, Workbooks: 1, Analytic Rules: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
"id": "[variables('_solutioncontentProductId')]",
@@ -1066,6 +1067,21 @@
"dependencies": {
"operator": "AND",
"criteria": [
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
+ },
+ {
+ "kind": "AnalyticsRule",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
+ },
{
"kind": "DataConnector",
"contentId": "[variables('_dataConnectorContentId1')]",
@@ -1073,28 +1089,13 @@
},
{
"kind": "Parser",
- "contentId": "[variables('_parserContentId1')]",
- "version": "[variables('parserVersion1')]"
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "version": "[variables('parserObject1').parserVersion1]"
},
{
"kind": "Workbook",
"contentId": "[variables('_workbookContentId1')]",
"version": "[variables('workbookVersion1')]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId1')]",
- "version": "[variables('analyticRuleVersion1')]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId2')]",
- "version": "[variables('analyticRuleVersion2')]"
- },
- {
- "kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId3')]",
- "version": "[variables('analyticRuleVersion3')]"
}
]
},
diff --git a/Solutions/Salesforce Service Cloud/Package/testParameters.json b/Solutions/Salesforce Service Cloud/Package/testParameters.json
new file mode 100644
index 00000000000..9b39a61620f
--- /dev/null
+++ b/Solutions/Salesforce Service Cloud/Package/testParameters.json
@@ -0,0 +1,32 @@
+{
+ "location": {
+ "type": "string",
+ "minLength": 1,
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
+ }
+ },
+ "workspace-location": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
+ }
+ },
+ "workspace": {
+ "defaultValue": "",
+ "type": "string",
+ "metadata": {
+ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
+ }
+ },
+ "workbook1-name": {
+ "type": "string",
+ "defaultValue": "Salesforce Service Cloud",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ }
+}
diff --git a/Solutions/Salesforce Service Cloud/ReleaseNotes.md b/Solutions/Salesforce Service Cloud/ReleaseNotes.md
index 6c1f40e5e37..302ce60bf5d 100644
--- a/Solutions/Salesforce Service Cloud/ReleaseNotes.md
+++ b/Solutions/Salesforce Service Cloud/ReleaseNotes.md
@@ -1,4 +1,5 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------------------|
+| 3.0.1 | 06-02-2025 | Updated timeframes for Salesforce cloud **Analytic rules** |
| 3.0.0 | 05-09-2023 | Manual deployment instructions updated for **Data Connector** |
diff --git a/Solutions/SecurityBridge App/Analytical Rules/CriticalEventTriggered.yaml b/Solutions/SecurityBridge App/Analytical Rules/CriticalEventTriggered.yaml
index b9ced228a4a..785b4226cb1 100644
--- a/Solutions/SecurityBridge App/Analytical Rules/CriticalEventTriggered.yaml
+++ b/Solutions/SecurityBridge App/Analytical Rules/CriticalEventTriggered.yaml
@@ -31,6 +31,6 @@ entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
- columnName: Computer
+ columnName: dvchost
version: 1.0.4
-kind: Scheduled
\ No newline at end of file
+kind: Scheduled
diff --git a/Solutions/SecurityBridge App/Data Connectors/Connector_SecurityBridge.json b/Solutions/SecurityBridge App/Data Connectors/Connector_SecurityBridge.json
index 8ee9ad29493..f838928fe73 100644
--- a/Solutions/SecurityBridge App/Data Connectors/Connector_SecurityBridge.json
+++ b/Solutions/SecurityBridge App/Data Connectors/Connector_SecurityBridge.json
@@ -165,4 +165,4 @@
"instructions": []
}
]
-}
\ No newline at end of file
+}
diff --git a/Solutions/SecurityBridge App/Data/Solution_SecurityBridgeSAP.json b/Solutions/SecurityBridge App/Data/Solution_SecurityBridgeSAP.json
index 559a97bf9ab..1d1d3521588 100644
--- a/Solutions/SecurityBridge App/Data/Solution_SecurityBridgeSAP.json
+++ b/Solutions/SecurityBridge App/Data/Solution_SecurityBridgeSAP.json
@@ -1,6 +1,6 @@
{
"Name": "SecurityBridge App",
- "Author": "Christoph Nagy - christoph.nagy@securitybridge.com",
+ "Author": "SecurityBridge - support@securitybridge.com",
"Logo": "
",
"Description": "The [SecurityBridge App](https://securitybridge.com/) solution provides the capability to ingest SecurityBridge Threat Detection events from all on-premise and cloud based SAP instances into Microsoft Sentinel.\n\nThis solution is dependent on the Custom logs via AMA connector to collect the logs. The Custom logs solution will be installed as part of this solution installation. \n\n **NOTE**: Microsoft recommends installation of Custom logs via AMA Connector. Legacy connector uses the Log Analytics agent which were deprecated on **Aug 31, 2024.** Using MMA and AMA on same machine can cause log duplication and extra ingestion cost [more details](https://learn.microsoft.com/azure/sentinel/ama-migrate?WT.mc_id=Portal-fx).",
"Workbooks": [
@@ -15,8 +15,8 @@
"dependentDomainSolutionIds": [
"azuresentinel.azure-sentinel-solution-customlogsviaama"
],
- "BasePath": "https://raw.githubusercontent.com/frozenstrawberries/Azure-Sentinel/master/Solutions/SecurityBridge/",
- "Version": "3.0.1",
+ "BasePath": "https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SecurityBridge%20App/",
+ "Version": "3.1.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true
-}
\ No newline at end of file
+}
diff --git a/Solutions/SecurityBridge App/Package/3.1.0.zip b/Solutions/SecurityBridge App/Package/3.1.0.zip
new file mode 100644
index 00000000000..cd73478e319
Binary files /dev/null and b/Solutions/SecurityBridge App/Package/3.1.0.zip differ
diff --git a/Solutions/SecurityBridge App/Package/mainTemplate.json b/Solutions/SecurityBridge App/Package/mainTemplate.json
index 97477f24849..2e0e86b0449 100644
--- a/Solutions/SecurityBridge App/Package/mainTemplate.json
+++ b/Solutions/SecurityBridge App/Package/mainTemplate.json
@@ -2,7 +2,7 @@
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
- "author": "Christoph Nagy - christoph.nagy@securitybridge.com",
+ "author": "SecurityBridge - support@securitybridge.com",
"comments": "Solution template for SecurityBridge App"
},
"parameters": {
@@ -38,10 +38,10 @@
}
},
"variables": {
- "email": "christoph.nagy@securitybridge.com",
+ "email": "support@securitybridge.com",
"_email": "[variables('email')]",
"_solutionName": "SecurityBridge App",
- "_solutionVersion": "3.0.1",
+ "_solutionVersion": "3.1.0",
"solutionId": "securitybridge1647511278080.securitybridge-sentinel-app-1",
"_solutionId": "[variables('solutionId')]",
"workbookVersion1": "1.0.0",
@@ -77,7 +77,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SecurityBridgeThreatDetectionforSAP Workbook with template version 3.0.1",
+ "description": "SecurityBridgeThreatDetectionforSAP Workbook with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -117,13 +117,13 @@
"sourceId": "[variables('_solutionId')]"
},
"author": {
- "name": "Christoph Nagy",
+ "name": "SecurityBridge",
"email": "[variables('_email')]"
},
"support": {
- "name": "Christoph Nagy",
- "email": "christoph.nagy@securitybridge.com",
"tier": "Partner",
+ "name": "SecurityBridge",
+ "email": "support@securitybridge.com",
"link": "https://securitybridge.com/contact/"
},
"dependencies": {
@@ -134,7 +134,7 @@
"kind": "DataType"
},
{
- "contentId": "SecurityBridgeSAP",
+ "contentId": "CustomLogsAma",
"kind": "DataConnector"
}
]
@@ -165,7 +165,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "CriticalEventTriggered_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "CriticalEventTriggered_AnalyticalRules Analytics Rule with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -193,10 +193,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "CustomLogsAma",
"datatypes": [
"SecurityBridgeLogs_CL"
- ],
- "connectorId": "CustomLogsAma"
+ ]
}
],
"tactics": [
@@ -207,31 +207,31 @@
],
"entityMappings": [
{
+ "entityType": "Account",
"fieldMappings": [
{
- "columnName": "maincontact",
- "identifier": "Name"
+ "identifier": "Name",
+ "columnName": "maincontact"
}
- ],
- "entityType": "Account"
+ ]
},
{
+ "entityType": "Host",
"fieldMappings": [
{
- "columnName": "dhost",
- "identifier": "HostName"
+ "identifier": "HostName",
+ "columnName": "dhost"
}
- ],
- "entityType": "Host"
+ ]
},
{
+ "entityType": "Host",
"fieldMappings": [
{
- "columnName": "Computer",
- "identifier": "HostName"
+ "identifier": "HostName",
+ "columnName": "dvchost"
}
- ],
- "entityType": "Host"
+ ]
}
]
}
@@ -252,13 +252,13 @@
"sourceId": "[variables('_solutionId')]"
},
"author": {
- "name": "Christoph Nagy",
+ "name": "SecurityBridge",
"email": "[variables('_email')]"
},
"support": {
- "name": "Christoph Nagy",
- "email": "christoph.nagy@securitybridge.com",
"tier": "Partner",
+ "name": "SecurityBridge",
+ "email": "support@securitybridge.com",
"link": "https://securitybridge.com/contact/"
}
}
@@ -287,7 +287,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SecurityBridgeLogs Data Parser with template version 3.0.1",
+ "description": "SecurityBridgeLogs Data Parser with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -333,13 +333,13 @@
"sourceId": "[variables('_solutionId')]"
},
"author": {
- "name": "Christoph Nagy",
+ "name": "SecurityBridge",
"email": "[variables('_email')]"
},
"support": {
- "name": "Christoph Nagy",
- "email": "christoph.nagy@securitybridge.com",
"tier": "Partner",
+ "name": "SecurityBridge",
+ "email": "support@securitybridge.com",
"link": "https://securitybridge.com/contact/"
}
}
@@ -399,13 +399,13 @@
"sourceId": "[variables('_solutionId')]"
},
"author": {
- "name": "Christoph Nagy",
+ "name": "SecurityBridge",
"email": "[variables('_email')]"
},
"support": {
- "name": "Christoph Nagy",
- "email": "christoph.nagy@securitybridge.com",
"tier": "Partner",
+ "name": "SecurityBridge",
+ "email": "support@securitybridge.com",
"link": "https://securitybridge.com/contact/"
}
}
@@ -415,11 +415,11 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.1",
+ "version": "3.1.0",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "SecurityBridge App",
- "publisherDisplayName": "Christoph Nagy",
+ "publisherDisplayName": "SecurityBridge",
"descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe SecurityBridge App solution provides the capability to ingest SecurityBridge Threat Detection events from all on-premise and cloud based SAP instances into Microsoft Sentinel.
\nThis solution is dependent on the Custom logs via AMA connector to collect the logs. The Custom logs solution will be installed as part of this solution installation.
\nNOTE: Microsoft recommends installation of Custom logs via AMA Connector. Legacy connector uses the Log Analytics agent which were deprecated on Aug 31, 2024. Using MMA and AMA on same machine can cause log duplication and extra ingestion cost more details.
\nParsers: 1, Workbooks: 1, Analytic Rules: 1
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
@@ -433,12 +433,12 @@
"sourceId": "[variables('_solutionId')]"
},
"author": {
- "name": "Christoph Nagy",
+ "name": "SecurityBridge",
"email": "[variables('_email')]"
},
"support": {
- "name": "Christoph Nagy",
- "email": "christoph.nagy@securitybridge.com",
+ "name": "SecurityBridge",
+ "email": "support@securitybridge.com",
"tier": "Partner",
"link": "https://securitybridge.com/contact/"
},
@@ -466,7 +466,6 @@
]
},
"firstPublishDate": "2022-02-17",
- "lastPublishDate": "2022-02-17",
"providers": [
"SecurityBridge"
],
diff --git a/Solutions/SecurityBridge App/Parsers/SecurityBridgeLogs.yaml b/Solutions/SecurityBridge App/Parsers/SecurityBridgeLogs.yaml
index acf687292a9..77c73d5940a 100644
--- a/Solutions/SecurityBridge App/Parsers/SecurityBridgeLogs.yaml
+++ b/Solutions/SecurityBridge App/Parsers/SecurityBridgeLogs.yaml
@@ -30,4 +30,4 @@ FunctionQuery: |
SAPinstallationnumber = tostring(replace_string(tostring(split(split(RawData, "SAPinstallationnumber=")[1], "=")[0]), tostring(split(split(split(RawData, "SAPinstallationnumber=")[1], "=")[0], " ")[-1]), "")),
SAPhost = tostring(replace_string(tostring(split(split(RawData, "SAPhost=")[1], "=")[0]), tostring(split(split(split(RawData, "SAPhost=")[1], "=")[0], " ")[-1]), "")),
Severity = case(toint(Severity) < 3, "Low", toint(Severity) < 7, "Medium", toint(Severity) < 9, "High", toint(Severity) >= 9, "Critical", "None"),
- maincontact = split(split(["Main contact area of responsibility"], ',')[-1], ' ')[2]
\ No newline at end of file
+ maincontact = split(split(["Main contact area of responsibility"], ',')[-1], ' ')[2]
diff --git a/Solutions/SecurityBridge App/ReleaseNotes.md b/Solutions/SecurityBridge App/ReleaseNotes.md
index 1c8f09758e7..304501fde9b 100644
--- a/Solutions/SecurityBridge App/ReleaseNotes.md
+++ b/Solutions/SecurityBridge App/ReleaseNotes.md
@@ -1,4 +1,5 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|-----------------------------------------|
+| 3.1.0 | 12-02-2025 | Adjusted contact and support |
| 3.0.1 | 07-01-2025 | Removed Deprecated **Data connector** |
| 3.0.0 | 08-08-2024 | Deprecating data connectors |
\ No newline at end of file
diff --git a/Solutions/SecurityBridge App/SolutionMetadata.json b/Solutions/SecurityBridge App/SolutionMetadata.json
index 30aa51b8498..1022fbcb8fe 100644
--- a/Solutions/SecurityBridge App/SolutionMetadata.json
+++ b/Solutions/SecurityBridge App/SolutionMetadata.json
@@ -1,17 +1,22 @@
{
- "publisherId": "securitybridge1647511278080",
- "offerId": "securitybridge-sentinel-app-1",
- "firstPublishDate": "2022-02-17",
- "lastPublishDate": "2022-02-17",
- "providers": ["SecurityBridge"],
- "categories": {
- "domains" : ["Security - Network"],
- "verticals": ["Finance"]
- },
- "support": {
- "name": "Christoph Nagy",
- "email": "christoph.nagy@securitybridge.com",
- "tier": "Partner",
- "link": "https://securitybridge.com/contact/"
- }
-}
\ No newline at end of file
+ "publisherId": "securitybridge1647511278080",
+ "offerId": "securitybridge-sentinel-app-1",
+ "firstPublishDate": "2022-02-17",
+ "providers": [
+ "SecurityBridge"
+ ],
+ "categories": {
+ "domains": [
+ "Security - Network"
+ ],
+ "verticals": [
+ "Finance"
+ ]
+ },
+ "support": {
+ "tier": "Partner",
+ "name": "SecurityBridge",
+ "email": "support@securitybridge.com",
+ "link": "https://securitybridge.com/contact/"
+ }
+}
diff --git a/Solutions/SecurityBridge App/Workbooks/SecurityBridgeThreatDetectionforSAP.json b/Solutions/SecurityBridge App/Workbooks/SecurityBridgeThreatDetectionforSAP.json
index cb8cac5a2ef..296c4b8d663 100644
--- a/Solutions/SecurityBridge App/Workbooks/SecurityBridgeThreatDetectionforSAP.json
+++ b/Solutions/SecurityBridge App/Workbooks/SecurityBridgeThreatDetectionforSAP.json
@@ -796,4 +796,4 @@
],
"fromTemplateId": "sentinel-SecurityBridge",
"$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
-}
\ No newline at end of file
+}
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_EvidenceOfMimikatzDCShadowAttack.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_EvidenceOfMimikatzDCShadowAttack.yaml
index a4de3d73c5f..bb5598d1684 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_EvidenceOfMimikatzDCShadowAttack.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_EvidenceOfMimikatzDCShadowAttack.yaml
@@ -20,20 +20,13 @@ 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
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
-version: 1.0.1
+version: 2.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_KerberoskrbtgtAccount.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_KerberoskrbtgtAccount.yaml
index b86dcd5905f..13b06cea2cb 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_KerberoskrbtgtAccount.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_KerberoskrbtgtAccount.yaml
@@ -20,20 +20,13 @@ 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
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
-version: 1.0.2
+version: 2.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_RecentsIDHistoryChangesOnADObjects.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_RecentsIDHistoryChangesOnADObjects.yaml
index 305172e0c1a..4e8039a5eab 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_RecentsIDHistoryChangesOnADObjects.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_RecentsIDHistoryChangesOnADObjects.yaml
@@ -21,20 +21,13 @@ 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
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
-version: 1.0.2
+version: 2.0.6
kind: Scheduled
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_WellKnownPrivilegedSIDsInsIDHistory.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_WellKnownPrivilegedSIDsInsIDHistory.yaml
index 5680a302180..329eb60dd27 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_WellKnownPrivilegedSIDsInsIDHistory.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_WellKnownPrivilegedSIDsInsIDHistory.yaml
@@ -21,20 +21,13 @@ 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
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
-version: 1.0.1
+version: 2.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_ZerologonVulnerability.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_ZerologonVulnerability.yaml
index 35c2e5f2daa..0b240a760e6 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_ZerologonVulnerability.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/SemperisDSP_ZerologonVulnerability.yaml
@@ -20,20 +20,13 @@ 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
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
-version: 1.0.2
+version: 2.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Failed_Logons.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Failed_Logons.yaml
index eb2ce206c0b..5b449c0be2e 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Failed_Logons.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Failed_Logons.yaml
@@ -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:
@@ -43,5 +49,5 @@ eventGroupingSettings:
alertDetailsOverride:
alertDisplayNameFormat: Failed Logon -- Alert from Semperis Directory Services Protector
alertDescriptionFormat: A failed logon was detected to the DSP system.
-version: 1.1.1
+version: 2.0.6
kind: Scheduled
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Operations_Critical_Notifications_.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Operations_Critical_Notifications_.yaml
index 9fbd89a8cdb..36d2e5f25e6 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Operations_Critical_Notifications_.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_Operations_Critical_Notifications_.yaml
@@ -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
@@ -49,5 +50,5 @@ eventGroupingSettings:
alertDetailsOverride:
alertDisplayNameFormat: Critical Notification -- Alert from Semperis Directory Services Protector
alertDescriptionFormat: A critical notification was created in the DSP system.
-version: 1.1.1
+version: 2.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_RBAC_Changes.yaml b/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_RBAC_Changes.yaml
index 11cba88a4c2..c335ae85c38 100644
--- a/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_RBAC_Changes.yaml
+++ b/Solutions/Semperis Directory Services Protector/Analytic Rules/Semperis_DSP_RBAC_Changes.yaml
@@ -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
@@ -56,5 +57,5 @@ eventGroupingSettings:
alertDetailsOverride:
alertDisplayNameFormat: RBAC Change -- Alert from Semperis Directory Services Protector
alertDescriptionFormat: A RBAC change was detected in the DSP system.
-version: 1.1.1
+version: 2.0.6
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Data Connectors/SemperisDSP-connector.json b/Solutions/Semperis Directory Services Protector/Data Connectors/SemperisDSP-connector.json
index e14d92fe95f..1b697318462 100644
--- a/Solutions/Semperis Directory Services Protector/Data Connectors/SemperisDSP-connector.json
+++ b/Solutions/Semperis Directory Services Protector/Data Connectors/SemperisDSP-connector.json
@@ -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": {
diff --git a/Solutions/Semperis Directory Services Protector/Data/Solution_Semperis.json b/Solutions/Semperis Directory Services Protector/Data/Solution_Semperis.json
index 59d15c547e6..0fa7fdea947 100644
--- a/Solutions/Semperis Directory Services Protector/Data/Solution_Semperis.json
+++ b/Solutions/Semperis Directory Services Protector/Data/Solution_Semperis.json
@@ -10,7 +10,7 @@
"Workbooks/SemperisDSPSecurityIndicators.json"
],
"Parsers": [
- "Parsers/dsp_parser.txt"
+ "Parsers/dsp_parser.yaml"
],
"Analytic Rules": [
"Analytic Rules/SemperisDSP_EvidenceOfMimikatzDCShadowAttack.yaml",
@@ -26,7 +26,7 @@
"Data Connectors/SemperisDSP-connector.json"
],
"BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Semperis Directory Services Protector",
- "Version": "2.0.5",
+ "Version": "2.0.6",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1Pconnector": false
diff --git a/Solutions/Semperis Directory Services Protector/Package/3.0.0.zip b/Solutions/Semperis Directory Services Protector/Package/3.0.0.zip
new file mode 100644
index 00000000000..4111e76bc2b
Binary files /dev/null and b/Solutions/Semperis Directory Services Protector/Package/3.0.0.zip differ
diff --git a/Solutions/Semperis Directory Services Protector/Package/createUiDefinition.json b/Solutions/Semperis Directory Services Protector/Package/createUiDefinition.json
index fcd6dc6d7ec..1a4317a9155 100644
--- a/Solutions/Semperis Directory Services Protector/Package/createUiDefinition.json
+++ b/Solutions/Semperis Directory Services Protector/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "
\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [Semperis Directory Services Protector](https://www.semperis.com/ds-protector/) solution provides the capability to ingest Windows event logs (i.e., Indicators of Exposure and Indicators of Compromise) into Microsoft Sentinel.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Agent based logs collection from Windows and Linux machines](https://docs.microsoft.com/azure/azure-monitor/agents/data-sources-custom-logs)\n\n**Data Connectors:** 1, **Parsers:** 1, **Workbooks:** 4, **Analytic Rules:** 8\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Semperis%20Directory%20Services%20Protector/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Semperis Directory Services Protector](https://www.semperis.com/ds-protector/) solution provides the capability to ingest Windows event logs (i.e., Indicators of Exposure and Indicators of Compromise) into Microsoft Sentinel.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Agent based logs collection from Windows and Linux machines](https://docs.microsoft.com/azure/azure-monitor/agents/data-sources-custom-logs)\n\n**Data Connectors:** 1, **Parsers:** 1, **Workbooks:** 4, **Analytic Rules:** 8\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
diff --git a/Solutions/Semperis Directory Services Protector/Package/mainTemplate.json b/Solutions/Semperis Directory Services Protector/Package/mainTemplate.json
index 98595f50373..afa1b901eb7 100644
--- a/Solutions/Semperis Directory Services Protector/Package/mainTemplate.json
+++ b/Solutions/Semperis Directory Services Protector/Package/mainTemplate.json
@@ -62,115 +62,120 @@
}
},
"variables": {
+ "_solutionName": "Semperis Directory Services Protector",
+ "_solutionVersion": "3.0.0",
"solutionId": "semperis.directory-services-protector-solution",
"_solutionId": "[variables('solutionId')]",
"workbookVersion1": "1.0.0",
"workbookContentId1": "SemperisDSPADChangesWorkbook",
"workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
- "workbookTemplateSpecName1": "[concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1')))]",
+ "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]",
"_workbookContentId1": "[variables('workbookContentId1')]",
"workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
+ "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
"workbookVersion2": "1.0.0",
"workbookContentId2": "SemperisDSPNotificationsWorkbook",
"workbookId2": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId2'))]",
- "workbookTemplateSpecName2": "[concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2')))]",
+ "workbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2'))))]",
"_workbookContentId2": "[variables('workbookContentId2')]",
+ "_workbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId2'),'-', variables('workbookVersion2'))))]",
"workbookVersion3": "1.0.0",
"workbookContentId3": "SemperisDSPQuickviewDashboardWorkbook",
"workbookId3": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId3'))]",
- "workbookTemplateSpecName3": "[concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3')))]",
+ "workbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3'))))]",
"_workbookContentId3": "[variables('workbookContentId3')]",
+ "_workbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId3'),'-', variables('workbookVersion3'))))]",
"workbookVersion4": "1.0.0",
"workbookContentId4": "SemperisDSPSecurityIndicatorsWorkbook",
"workbookId4": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId4'))]",
- "workbookTemplateSpecName4": "[concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4')))]",
+ "workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]",
"_workbookContentId4": "[variables('workbookContentId4')]",
- "parserVersion1": "1.0.0",
- "parserContentId1": "dsp_parser-Parser",
- "_parserContentId1": "[variables('parserContentId1')]",
- "parserName1": "dsp_parser",
- "_parserName1": "[concat(parameters('workspace'),'/',variables('parserName1'))]",
- "parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
- "_parserId1": "[variables('parserId1')]",
- "parserTemplateSpecName1": "[concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId1')))]",
- "analyticRuleVersion1": "1.0.0",
- "analyticRulecontentId1": "1a6d0a49-64b3-4ca1-96c3-f154c16c218c",
- "_analyticRulecontentId1": "[variables('analyticRulecontentId1')]",
- "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId1'))]",
- "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId1')))]",
- "analyticRuleVersion2": "1.0.0",
- "analyticRulecontentId2": "9ff3b26b-7636-412e-ac46-072b084b94cb",
- "_analyticRulecontentId2": "[variables('analyticRulecontentId2')]",
- "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]",
- "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId2')))]",
- "analyticRuleVersion3": "1.0.0",
- "analyticRulecontentId3": "64796da3-6383-4de2-9c97-866c83c459ae",
- "_analyticRulecontentId3": "[variables('analyticRulecontentId3')]",
- "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId3'))]",
- "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId3')))]",
- "analyticRuleVersion4": "1.0.0",
- "analyticRulecontentId4": "ddd75d93-5b8b-4349-babe-c4e15343c5a3",
- "_analyticRulecontentId4": "[variables('analyticRulecontentId4')]",
- "analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId4'))]",
- "analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId4')))]",
- "analyticRuleVersion5": "1.0.0",
- "analyticRulecontentId5": "85c1f9e4-6f14-46bf-82d5-dbe495b92aab",
- "_analyticRulecontentId5": "[variables('analyticRulecontentId5')]",
- "analyticRuleId5": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId5'))]",
- "analyticRuleTemplateSpecName5": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId5')))]",
- "analyticRuleVersion6": "1.0.0",
- "analyticRulecontentId6": "0e105444-fe13-4ce6-9239-21880076a3f9",
- "_analyticRulecontentId6": "[variables('analyticRulecontentId6')]",
- "analyticRuleId6": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId6'))]",
- "analyticRuleTemplateSpecName6": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId6')))]",
- "analyticRuleVersion7": "1.0.0",
- "analyticRulecontentId7": "8f471e21-3bb2-466f-9bc2-0a0326a60788",
- "_analyticRulecontentId7": "[variables('analyticRulecontentId7')]",
- "analyticRuleId7": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId7'))]",
- "analyticRuleTemplateSpecName7": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId7')))]",
- "analyticRuleVersion8": "1.0.0",
- "analyticRulecontentId8": "e5edf3f3-de53-45e6-b0d7-1ce1c048df4a",
- "_analyticRulecontentId8": "[variables('analyticRulecontentId8')]",
- "analyticRuleId8": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId8'))]",
- "analyticRuleTemplateSpecName8": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId8')))]",
+ "_workbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId4'),'-', variables('workbookVersion4'))))]",
+ "parserObject1": {
+ "_parserName1": "[concat(parameters('workspace'),'/','dsp_parser')]",
+ "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'dsp_parser')]",
+ "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('dsp_parser-Parser')))]",
+ "parserVersion1": "1.0.0",
+ "parserContentId1": "dsp_parser-Parser"
+ },
+ "analyticRuleObject1": {
+ "analyticRuleVersion1": "2.0.6",
+ "_analyticRulecontentId1": "1a6d0a49-64b3-4ca1-96c3-f154c16c218c",
+ "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '1a6d0a49-64b3-4ca1-96c3-f154c16c218c')]",
+ "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('1a6d0a49-64b3-4ca1-96c3-f154c16c218c')))]",
+ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','1a6d0a49-64b3-4ca1-96c3-f154c16c218c','-', '2.0.6')))]"
+ },
+ "analyticRuleObject2": {
+ "analyticRuleVersion2": "2.0.6",
+ "_analyticRulecontentId2": "9ff3b26b-7636-412e-ac46-072b084b94cb",
+ "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '9ff3b26b-7636-412e-ac46-072b084b94cb')]",
+ "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('9ff3b26b-7636-412e-ac46-072b084b94cb')))]",
+ "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','9ff3b26b-7636-412e-ac46-072b084b94cb','-', '2.0.6')))]"
+ },
+ "analyticRuleObject3": {
+ "analyticRuleVersion3": "2.0.6",
+ "_analyticRulecontentId3": "64796da3-6383-4de2-9c97-866c83c459ae",
+ "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '64796da3-6383-4de2-9c97-866c83c459ae')]",
+ "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('64796da3-6383-4de2-9c97-866c83c459ae')))]",
+ "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','64796da3-6383-4de2-9c97-866c83c459ae','-', '2.0.6')))]"
+ },
+ "analyticRuleObject4": {
+ "analyticRuleVersion4": "2.0.6",
+ "_analyticRulecontentId4": "ddd75d93-5b8b-4349-babe-c4e15343c5a3",
+ "analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'ddd75d93-5b8b-4349-babe-c4e15343c5a3')]",
+ "analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('ddd75d93-5b8b-4349-babe-c4e15343c5a3')))]",
+ "_analyticRulecontentProductId4": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','ddd75d93-5b8b-4349-babe-c4e15343c5a3','-', '2.0.6')))]"
+ },
+ "analyticRuleObject5": {
+ "analyticRuleVersion5": "2.0.6",
+ "_analyticRulecontentId5": "85c1f9e4-6f14-46bf-82d5-dbe495b92aab",
+ "analyticRuleId5": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '85c1f9e4-6f14-46bf-82d5-dbe495b92aab')]",
+ "analyticRuleTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('85c1f9e4-6f14-46bf-82d5-dbe495b92aab')))]",
+ "_analyticRulecontentProductId5": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','85c1f9e4-6f14-46bf-82d5-dbe495b92aab','-', '2.0.6')))]"
+ },
+ "analyticRuleObject6": {
+ "analyticRuleVersion6": "2.0.6",
+ "_analyticRulecontentId6": "0e105444-fe13-4ce6-9239-21880076a3f9",
+ "analyticRuleId6": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '0e105444-fe13-4ce6-9239-21880076a3f9')]",
+ "analyticRuleTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('0e105444-fe13-4ce6-9239-21880076a3f9')))]",
+ "_analyticRulecontentProductId6": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','0e105444-fe13-4ce6-9239-21880076a3f9','-', '2.0.6')))]"
+ },
+ "analyticRuleObject7": {
+ "analyticRuleVersion7": "2.0.6",
+ "_analyticRulecontentId7": "8f471e21-3bb2-466f-9bc2-0a0326a60788",
+ "analyticRuleId7": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '8f471e21-3bb2-466f-9bc2-0a0326a60788')]",
+ "analyticRuleTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('8f471e21-3bb2-466f-9bc2-0a0326a60788')))]",
+ "_analyticRulecontentProductId7": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','8f471e21-3bb2-466f-9bc2-0a0326a60788','-', '2.0.6')))]"
+ },
+ "analyticRuleObject8": {
+ "analyticRuleVersion8": "2.0.6",
+ "_analyticRulecontentId8": "e5edf3f3-de53-45e6-b0d7-1ce1c048df4a",
+ "analyticRuleId8": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'e5edf3f3-de53-45e6-b0d7-1ce1c048df4a')]",
+ "analyticRuleTemplateSpecName8": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('e5edf3f3-de53-45e6-b0d7-1ce1c048df4a')))]",
+ "_analyticRulecontentProductId8": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','e5edf3f3-de53-45e6-b0d7-1ce1c048df4a','-', '2.0.6')))]"
+ },
"uiConfigId1": "SemperisDSP",
"_uiConfigId1": "[variables('uiConfigId1')]",
"dataConnectorContentId1": "SemperisDSP",
"_dataConnectorContentId1": "[variables('dataConnectorContentId1')]",
"dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
"_dataConnectorId1": "[variables('dataConnectorId1')]",
- "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1')))]",
- "dataConnectorVersion1": "1.0.0"
+ "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
+ "dataConnectorVersion1": "1.0.0",
+ "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
+ "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
"resources": [
{
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
"name": "[variables('workbookTemplateSpecName1')]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Workbook with template",
- "displayName": "Semperis Directory Services Protector workbook template"
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('workbookTemplateSpecName1'),'/',variables('workbookVersion1'))]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('workbookTemplateSpecName1'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSPADChangesWorkbook Workbook with template version 2.0.5",
+ "description": "SemperisDSPADChanges Workbook with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -233,37 +238,30 @@
}
}
]
- }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId1')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook1-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId1')]",
+ "id": "[variables('_workbookcontentProductId1')]",
+ "version": "[variables('workbookVersion1')]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
"name": "[variables('workbookTemplateSpecName2')]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Workbook with template",
- "displayName": "Semperis Directory Services Protector workbook template"
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('workbookTemplateSpecName2'),'/',variables('workbookVersion2'))]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('workbookTemplateSpecName2'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSPNotificationsWorkbook Workbook with template version 2.0.5",
+ "description": "SemperisDSPNotifications Workbook with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -281,7 +279,7 @@
},
"properties": {
"displayName": "[parameters('workbook2-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"9ce8b817-f1ac-44c1-9803-9c29fb852094\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Time\",\"type\":4,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"b5012d54-1341-451b-8c19-2464dad7400d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RuleName\",\"label\":\"Rule Name\",\"type\":1,\"timeContext\":{\"durationMs\":86400000},\"value\":\"\"},{\"id\":\"1e9c0aed-d257-4426-abd4-26d1f244705f\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\":\\\"Critical\\\", \\\"label\\\":\\\"Critical\\\" },\\r\\n { \\\"value\\\":\\\"Warning\\\" , \\\"label\\\":\\\"Warning\\\" },\\r\\n { \\\"value\\\":\\\"Informational\\\" , \\\"label\\\":\\\"Informational\\\" }\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\r\\n| where Source == 'Semperis-DSP-Notifications' \\r\\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\r\\n| mv-expand bagexpansion=array p1Xml\\r\\n| evaluate bag_unpack(p1Xml)\\r\\n| extend Key1=tostring(['@Name']), Value=['#text']\\r\\n| evaluate pivot(Key1, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\r\\n| where (isempty('{Time}') or (todatetime(timeCreated) >= todatetime('{Time:startISO}') and todatetime(timeCreated) <= todatetime('{Time:endISO}'))) and ((isempty('{RuleName}') or indexof(ruleName,'{RuleName}') > -1)) and ((isempty('{Severity}') or severity == '{Severity}'))\\r\\n| order by TimeGenerated desc\\r\\n| project ruleName, fullOperation\\r\\n\",\"size\":0,\"title\":\"Notifications\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"ruleName\",\"label\":\"Rule Name\"},{\"columnId\":\"fullOperation\",\"label\":\"Operation\"}]}},\"name\":\"query - 1\"}],\"fromTemplateId\":\"sentinel-SemperisDSPNotifications\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"9ce8b817-f1ac-44c1-9803-9c29fb852094\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Time\",\"type\":4,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"b5012d54-1341-451b-8c19-2464dad7400d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RuleName\",\"label\":\"Rule Name\",\"type\":1,\"timeContext\":{\"durationMs\":86400000},\"value\":\"\"},{\"id\":\"1e9c0aed-d257-4426-abd4-26d1f244705f\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\":\\\"Critical\\\", \\\"label\\\":\\\"Critical\\\" },\\r\\n { \\\"value\\\":\\\"Warning\\\" , \\\"label\\\":\\\"Warning\\\" },\\r\\n { \\\"value\\\":\\\"Informational\\\" , \\\"label\\\":\\\"Informational\\\" }\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\r\\n| where EventSourceName == 'Semperis-DSP-Notifications' \\r\\n| extend p1Xml = parse_xml(EventData).EventData.Data\\r\\n| mv-expand bagexpansion=array p1Xml\\r\\n| evaluate bag_unpack(p1Xml)\\r\\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\\r\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\r\\n| where (isempty('{Time}') or (todatetime(timeCreated) >= todatetime('{Time:startISO}') and todatetime(timeCreated) <= todatetime('{Time:endISO}'))) and ((isempty('{RuleName}') or indexof(ruleName,'{RuleName}') > -1)) and ((isempty('{Severity}') or severity == '{Severity}'))\\r\\n| order by TimeGenerated desc\\r\\n| project ruleName, severity, Computer, objectDN, timeCreated, fullOperation, attributeName, attributeValue, changedBy, originatingServerName\\r\\n\",\"size\":0,\"title\":\"Notifications\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"ruleName\",\"label\":\"Rule Name\"},{\"columnId\":\"fullOperation\",\"label\":\"Operation\"}]}},\"name\":\"query - 1\"}],\"fromTemplateId\":\"sentinel-SemperisDSPNotifications\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -326,37 +324,30 @@
}
}
]
- }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId2')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook2-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId2')]",
+ "id": "[variables('_workbookcontentProductId2')]",
+ "version": "[variables('workbookVersion2')]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
"name": "[variables('workbookTemplateSpecName3')]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Workbook with template",
- "displayName": "Semperis Directory Services Protector workbook template"
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('workbookTemplateSpecName3'),'/',variables('workbookVersion3'))]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('workbookTemplateSpecName3'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSPQuickviewDashboardWorkbook Workbook with template version 2.0.5",
+ "description": "SemperisDSPQuickviewDashboard Workbook with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -374,7 +365,7 @@
},
"properties": {
"displayName": "[parameters('workbook3-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let day_names =dynamic([\\\"Sunday\\\",\\\"Monday\\\",\\\"Tuesday\\\",\\\"Wednesday\\\",\\\"Thursday\\\",\\\"Friday\\\",\\\"Saturday\\\"]);\\nlet averageData = view() { CommonSecurityLog \\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| where TimeGenerated > datetime(2000-01-01)\\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \\\"\\\"\\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\\\"Average Daily Change\\\"\\n| order by Day asc};\\nlet weeklyData = view() { CommonSecurityLog \\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| where TimeGenerated > startofweek(now())\\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \\\"\\\"\\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\\\"Daily Change\\\"\\n| order by Day asc };\\nunion withsource=TableName averageData,weeklyData\\n| order by Day asc, SortData asc\\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\\n| render barchart with (kind=unstacked)\\n\\n\",\"size\":0,\"title\":\"Weekly Active Directory Change Count\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"chartSettings\":{\"xAxis\":\"Days\",\"seriesLabelSettings\":[{\"seriesName\":\"averageData\",\"label\":\"Average Daily Change\",\"color\":\"gray\"},{\"seriesName\":\"weeklyData\",\"label\":\"Daily Change\",\"color\":\"orange\"}]},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Average_Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Average_Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Average_Count\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"100\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-Operation-Log' and EventID == 20000\\n| sort by TimeGenerated desc \\n| parse RenderedDescription with \\\"Operation: \\\" Operation \\\"Access Granted:\\\" AccessGranted \\\"Result: \\\" Result \\\"Details: \\\" * \\\"Trustee Name: \\\" TrusteeName \\\" Correlation ID: \\\" * \\\" Source: \\\" HostIP \\\"WebSite Target\\\" *\\n| extend host = tostring(HostIP)\\n| extend HostIP = trim_end(\\\":\\\",HostIP)\\n| project TimeGenerated, UserName, HostIP\\n| order by TimeGenerated desc\\n| top 10 by TimeGenerated\",\"size\":1,\"title\":\"Successful Logons\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"TimeGenerated\",\"label\":\"Time Generated\"},{\"columnId\":\"UserName\",\"label\":\"Identity\"},{\"columnId\":\"HostIP\",\"label\":\"Host IP\"}]}},\"customWidth\":\"55\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-Operation-Log' and ( EventID == 20000 or EventID == 20002 )\\n| sort by TimeGenerated desc \\n| parse RenderedDescription with \\\"Operation: \\\" Operation \\\"Access Granted:\\\" AccessGranted \\\"Result: \\\" Result \\\"Details: \\\" * \\\"Trustee Name: \\\" TrusteeName \\\" Correlation ID: \\\" * \\\" Source: \\\" HostIP \\\"WebSite Target\\\" *\\n| extend host = tostring(HostIP)\\n| extend HostIP = trim_end(\\\":\\\",HostIP)\\n| where isnotempty(AccessGranted)\\n| summarize Count=count() by AccessGranted\\n\\n\\n\\n\",\"size\":1,\"title\":\"DSP Logins\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showLegend\":true,\"seriesLabelSettings\":[{\"seriesName\":\" TRUE \",\"color\":\"green\"},{\"seriesName\":\" FALSE \",\"color\":\"redBright\"},{\"color\":\"red\"}]}},\"customWidth\":\"45\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\r\\n| where Source == 'Semperis-DSP-Notifications' \\r\\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\r\\n| mv-expand bagexpansion=array p1Xml\\r\\n| evaluate bag_unpack(p1Xml)\\r\\n| extend Key1=tostring(['@Name']), Value=['#text']\\r\\n| evaluate pivot(Key1, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\r\\n| order by TimeGenerated desc\\r\\n| project ruleName, fullOperation\\r\\n\",\"size\":0,\"title\":\"Notifications\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"rowLimit\":10000,\"labelSettings\":[{\"columnId\":\"ruleName\",\"label\":\"Rule Name\"},{\"columnId\":\"fullOperation\",\"label\":\"Operation\"}]}},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-Operation-Log' and EventID == 20012\\n| sort by TimeGenerated desc\\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=tostring(['@Name']), Value=['#text']\\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\n| parse details 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\\n| extend _AccessGranted = iif(operationName contains \\\"CreateRbacIdentity\\\", \\\"Added\\\", \\\"Removed\\\")\\n| extend _Identity = iif(operationName contains \\\"CreateRbacIdentity\\\", trustee, tostring(substring(trustee,1,strlen(trustee))))\\n| extend _Identity = iif(operationName contains \\\"CreateRbacIdentity\\\", _Identity, replace_string(_Identity,\\\"'\\\",\\\"\\\"))\\n| extend add_personas = replace_string(replace_string(replace_string(personas,\\\"{ Name = \\\",\\\"\\\"),\\\" }\\\",\\\"\\\"),\\\";\\\",\\\",\\\")\\n| extend remove_personas = replace_string(personas,\\\";\\\",\\\",\\\")\\n| extend grid_personas = iif(operationName contains \\\"CreateRbacIdentity\\\", add_personas, remove_personas)\\n| extend date_to_sort = format_datetime(TimeGenerated,\\\"yyyy-mm-dd HH:mm:ss\\\")\\n| order by date_to_sort desc\\n| project TrusteeName, _Identity, _AccessGranted, grid_personas, TimeGenerated\\n\\n\\n\",\"size\":1,\"title\":\"Role Based Access Control Changes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"TrusteeName\",\"label\":\"Changed By\"},{\"columnId\":\"_Identity\",\"label\":\"Identity\"},{\"columnId\":\"_AccessGranted\",\"label\":\"Access Granted\"},{\"columnId\":\"grid_personas\",\"label\":\"Persona Details\"},{\"columnId\":\"TimeGenerated\",\"label\":\"Timestamp\"}]}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CommonSecurityLog\\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity)\\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \\\"\\\"\\n| summarize ChangedCount = count() by tostring(OriginatingUsers)\\n| project replace_string(OriginatingUsers,'\\\\\\\\\\\\\\\\','/'), ChangedCount, OriginatingUsers, \\\"Details\\\"\\n| order by ChangedCount desc\\n| top 5 by ChangedCount\",\"size\":1,\"title\":\"Top 5 Identities Making Changes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"OriginatingUsers\",\"formatter\":5},{\"columnMatch\":\"Column2\",\"formatter\":1,\"formatOptions\":{\"linkTarget\":\"WorkbookTemplate\",\"linkIsContextBlade\":true,\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"templateIdSource\":\"static\",\"templateId\":\"/subscriptions/b57a6492-52e3-4a3c-b970-f1d68b275e11/resourceGroups/DSPSentinel/providers/microsoft.insights/workbooks/18e25ec4-ee8d-4c12-aba1-c60b5159c0bc\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\",\"locationSource\":\"workbook\",\"passSpecificParams\":true,\"templateParameters\":[{\"name\":\"OriginatingUsers\",\"source\":\"column\",\"value\":\"Column1\"}]}}},{\"columnMatch\":\"ParentId\",\"formatter\":5},{\"columnMatch\":\"Id\",\"formatter\":5},{\"columnMatch\":\"Originating Identity\",\"formatter\":1},{\"columnMatch\":\"Group\",\"formatter\":1}],\"labelSettings\":[{\"columnId\":\"Column1\",\"label\":\"Originating Identity\"},{\"columnId\":\"ChangedCount\",\"label\":\"Number of Changes\"},{\"columnId\":\"Column2\",\"label\":\" \"}]}},\"customWidth\":\"35\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CommonSecurityLog\\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| parse DistinguishedName with * \\\"CN\\\\\\\\=\\\" cnName \\\",\\\" *\\n| parse DistinguishedName with * \\\"DC\\\\\\\\=\\\" dcName \\\",\\\" *\\n| where ClassName != \\\"dnsNode\\\"\\n| summarize ChangedCount=count() by cnName\\n| project cnName, ChangedCount, \\\"Details\\\"\\n| order by ChangedCount desc\\n| top 5 by ChangedCount\\n\",\"size\":3,\"title\":\"Top 5 Objects Changed\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Column1\",\"formatter\":1,\"formatOptions\":{\"linkTarget\":\"WorkbookTemplate\",\"linkIsContextBlade\":true,\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"templateIdSource\":\"static\",\"templateId\":\"/subscriptions/b57a6492-52e3-4a3c-b970-f1d68b275e11/resourceGroups/DSPSentinel/providers/microsoft.insights/workbooks/18e25ec4-ee8d-4c12-aba1-c60b5159c2f4\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\",\"locationSource\":\"default\",\"passSpecificParams\":true,\"templateParameters\":[{\"name\":\"cName\",\"source\":\"column\",\"value\":\"cnName\"}]}}}],\"labelSettings\":[{\"columnId\":\"cnName\",\"label\":\"Object Changed\"}]}},\"customWidth\":\"35\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-DSP-Notifications' \\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=tostring(['@Name']), Value=['#text']\\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\n| summarize Count=count() by tostring(fullOperation)\\n\\n\",\"size\":1,\"title\":\"AD Change Types\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"sortBy\":[{\"itemKey\":\"fullOperation\",\"sortOrder\":1}],\"labelSettings\":[{\"columnId\":\"fullOperation\",\"label\":\"Activity\"}]},\"sortBy\":[{\"itemKey\":\"fullOperation\",\"sortOrder\":1}]},\"customWidth\":\"30\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CommonSecurityLog\\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| parse DistinguishedName with * \\\"CN\\\\\\\\=\\\" cnName \\\",\\\" *\\n| parse DistinguishedName with * \\\"DC\\\\\\\\=\\\" dcName \\\",\\\" *\\n| where ClassName == 'group'\\n| project AttributeModificationType,cnName,OriginatingTime,replace_string(OriginatingUsers,\\\"\\\\\\\\\\\\\\\\\\\",\\\"\\\\\\\\\\\"),StringValueFrom,StringValueTo\\n\",\"size\":0,\"title\":\"Builtin Group Changes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Column1\",\"formatter\":1,\"formatOptions\":{\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"templateIdSource\":\"static\",\"templateId\":\"/subscriptions/b57a6492-52e3-4a3c-b970-f1d68b275e11/resourceGroups/DSPSentinel/providers/microsoft.insights/workbooks/18e25ec4-ee8d-4c12-aba1-c60b5159c2f4\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\",\"locationSource\":\"default\",\"passSpecificParams\":true,\"templateParameters\":[{\"name\":\"cName\",\"source\":\"column\",\"value\":\"cnName\"}]}}}],\"rowLimit\":10000,\"labelSettings\":[{\"columnId\":\"AttributeModificationType\",\"label\":\"Attribute Modification Type\"},{\"columnId\":\"cnName\",\"label\":\"Object Changed\"},{\"columnId\":\"OriginatingTime\",\"label\":\"Originating Time\"},{\"columnId\":\"StringValueFrom\",\"label\":\"Value From\"},{\"columnId\":\"StringValueTo\",\"label\":\"Value To\"}]}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-DSP-Security' \\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=tostring(['@Name']), Value=['#text']\\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\n| extend isProblem = iif(result == \\\"Failed\\\", true, false)\\n| where isnotnull(numberOfResults) and isProblem == true\\n| order by tostring(securityIndicatorName)\\n| summarize Count=count() by tostring(securityIndicatorName)\\n| top 5 by Count\\n\\n\",\"size\":1,\"title\":\"Top 5 Failed Security Indicators\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"gridSettings\":{\"rowLimit\":10000},\"chartSettings\":{\"yAxis\":[\"Count\"],\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-DSP-Security' \\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=tostring(['@Name']), Value=['#text']\\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\n| extend isProblem = iif(result == \\\"Failed\\\", true, false)\\n| where isnotnull(numberOfResults) and isProblem == true\\n| order by tostring(securityIndicatorName)\\n| summarize Count=count() by tostring(securityIndicatorName)\\n| top 5 by Count\\n\\n\",\"size\":1,\"title\":\"Top 5 Failed Security Indicators\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"gridSettings\":{\"rowLimit\":10000},\"chartSettings\":{\"yAxis\":[\"Count\"],\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"Event\\n| where Source == 'Semperis-DSP-Security' \\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=tostring(['@Name']), Value=['#text']\\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\\n| extend isProblem = iif(result == \\\"Failed\\\", true, false)\\n| where isnotnull(numberOfResults) and isProblem == true\\n| summarize Count=count() by tostring(securityFrameworkTags)\\n\\n\",\"size\":0,\"title\":\"Amount of Generated Events per Category\",\"timeContext\":{\"durationMs\":14400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"gridSettings\":{\"rowLimit\":10000},\"chartSettings\":{\"yAxis\":[\"Count\"],\"showLegend\":true}},\"name\":\"query - 2\"}],\"styleSettings\":{\"paddingStyle\":\"wide\",\"spacingStyle\":\"wide\"},\"fromTemplateId\":\"sentinel-SemperisDSPQuickviewDashboard\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let day_names =dynamic([\\\"Sunday\\\",\\\"Monday\\\",\\\"Tuesday\\\",\\\"Wednesday\\\",\\\"Thursday\\\",\\\"Friday\\\",\\\"Saturday\\\"]);\\nlet averageData = view() { CommonSecurityLog \\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| where TimeGenerated > datetime(2000-01-01)\\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \\\"\\\"\\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\\\"Average Daily Change\\\"\\n| order by Day asc};\\nlet weeklyData = view() { CommonSecurityLog \\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| where TimeGenerated > startofweek(now())\\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \\\"\\\"\\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\\\"Daily Change\\\"\\n| order by Day asc };\\nunion withsource=TableName averageData,weeklyData\\n| order by Day asc, SortData asc\\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\\n| render barchart with (kind=unstacked)\\n\\n\",\"size\":0,\"title\":\"Weekly Active Directory Change Count\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"chartSettings\":{\"xAxis\":\"Days\",\"seriesLabelSettings\":[{\"seriesName\":\"averageData\",\"label\":\"Average Daily Change\",\"color\":\"gray\"},{\"seriesName\":\"weeklyData\",\"label\":\"Daily Change\",\"color\":\"orange\"}]},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Average_Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Average_Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Average_Count\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"100\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20000\\n| sort by TimeGenerated desc \\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| extend details = column_ifexists('details', '')\\n| parse details with * \\\"Trustee Name: \\\" TrusteeName \\\" Correlation ID: \\\" * \\\" Source: \\\" HostIP \\\":\\\" * \\\" Target\\\" *\\n| extend host = tostring(HostIP)\\n| project TimeGenerated, TrusteeName, HostIP\\n| order by TimeGenerated desc\\n| top 10 by TimeGenerated\",\"size\":1,\"title\":\"Successful Logons\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"TimeGenerated\",\"label\":\"Time Generated\"}]}},\"customWidth\":\"55\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-Operation-Log' and ( EventID == 20000 or EventID == 20002 )\\n| sort by TimeGenerated desc \\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| extend details = column_ifexists('details', ''), accessGrated = column_ifexists('accessGrated', '')\\n| parse details with * \\\"Trustee Name: \\\" TrusteeName \\\" Correlation ID: \\\" * \\\" Source: \\\" HostIP \\\":\\\" * \\\" Target\\\" *\\n| extend host = tostring(HostIP)\\n| where isnotempty(accessGrated)\\n| summarize Count=count() by accessGrated\\n\",\"size\":1,\"title\":\"DSP Logins\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showLegend\":true,\"seriesLabelSettings\":[{\"seriesName\":\" TRUE \",\"color\":\"green\"},{\"seriesName\":\" FALSE \",\"color\":\"redBright\"},{\"color\":\"red\"}]}},\"customWidth\":\"45\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\r\\n| where EventSourceName == 'Semperis-DSP-Notifications' \\r\\n| extend p1Xml = parse_xml(EventData).EventData.Data\\r\\n| mv-expand bagexpansion=array p1Xml\\r\\n| evaluate bag_unpack(p1Xml)\\r\\n| extend Name=tostring(['@Name']), Value=['#text']\\r\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\r\\n| order by TimeGenerated desc\\r\\n| project ruleName, severity, fullOperation, attributeName, attributeValue, changedBy, originatingServerName\\r\\n\",\"size\":0,\"title\":\"Notifications\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"rowLimit\":10000,\"labelSettings\":[{\"columnId\":\"ruleName\",\"label\":\"Rule Name\"},{\"columnId\":\"fullOperation\",\"label\":\"Operation\"}]}},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20012\\n| sort by TimeGenerated desc\\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| extend details=column_ifexists(tostring('details'), '')\\n| parse details 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\\n| where isnotempty(operationName)\\n| extend _AccessGranted = iif(operationName contains \\\"CreateRbacIdentity\\\", \\\"Added\\\", \\\"Removed\\\")\\n| extend _Identity = iif(operationName contains \\\"CreateRbacIdentity\\\", trustee, tostring(substring(trustee,1,strlen(trustee))))\\n| extend _Identity = iif(operationName contains \\\"CreateRbacIdentity\\\", _Identity, replace_string(_Identity,\\\"'\\\",\\\"\\\"))\\n| extend add_personas = replace_string(replace_string(replace_string(personas,\\\"{ Name = \\\",\\\"\\\"),\\\" }\\\",\\\"\\\"),\\\";\\\",\\\",\\\")\\n| extend remove_personas = replace_string(personas,\\\";\\\",\\\",\\\")\\n| extend grid_personas = iif(operationName contains \\\"CreateRbacIdentity\\\", add_personas, remove_personas)\\n| extend date_to_sort = format_datetime(TimeGenerated,\\\"yyyy-mm-dd HH:mm:ss\\\")\\n| order by date_to_sort desc\\n| project TrusteeName, _Identity, _AccessGranted, grid_personas, TimeGenerated\\n\\n\\n\",\"size\":1,\"title\":\"Role Based Access Control Changes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"TrusteeName\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"TrusteeName\",\"label\":\"Changed By\"},{\"columnId\":\"_Identity\",\"label\":\"Identity\"},{\"columnId\":\"_AccessGranted\",\"label\":\"Access Granted\"},{\"columnId\":\"TimeGenerated\",\"label\":\"Timestamp\"}]},\"sortBy\":[{\"itemKey\":\"TrusteeName\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CommonSecurityLog\\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity)\\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \\\"\\\"\\n| summarize ChangedCount = count() by tostring(OriginatingUsers)\\n| project replace_string(OriginatingUsers,'\\\\\\\\\\\\\\\\','/'), ChangedCount, OriginatingUsers, \\\"Details\\\"\\n| order by ChangedCount desc\\n| top 5 by ChangedCount\",\"size\":1,\"title\":\"Top 5 Identities Making Changes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"OriginatingUsers\",\"formatter\":5},{\"columnMatch\":\"Column2\",\"formatter\":1,\"formatOptions\":{\"linkTarget\":\"WorkbookTemplate\",\"linkIsContextBlade\":true,\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\",\"locationSource\":\"workbook\",\"passSpecificParams\":true,\"templateParameters\":[{\"name\":\"OriginatingUsers\",\"source\":\"column\",\"value\":\"Column1\"}]}}},{\"columnMatch\":\"ParentId\",\"formatter\":5},{\"columnMatch\":\"Id\",\"formatter\":5},{\"columnMatch\":\"Originating Identity\",\"formatter\":1},{\"columnMatch\":\"Group\",\"formatter\":1}],\"labelSettings\":[{\"columnId\":\"Column1\",\"label\":\"Originating Identity\"},{\"columnId\":\"ChangedCount\",\"label\":\"Number of Changes\"},{\"columnId\":\"Column2\",\"label\":\" \"}]}},\"customWidth\":\"35\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CommonSecurityLog\\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| extend DistinguishedName = column_ifexists('DistinguishedName', '')\\n| where isnotempty(DistinguishedName)\\n| parse DistinguishedName with * \\\"CN=\\\" cnName \\\",\\\" *\\n| parse DistinguishedName with * \\\"DC=\\\" dcName \\\",\\\" *\\n| where ClassName != \\\"dnsNode\\\"\\n| summarize ChangedCount=count() by cnName\\n| project cnName, ChangedCount, \\\"Details\\\"\\n| order by ChangedCount desc\\n| top 5 by ChangedCount\\n\",\"size\":3,\"title\":\"Top 5 Objects Changed\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Column1\",\"formatter\":1,\"formatOptions\":{\"linkTarget\":\"WorkbookTemplate\",\"linkIsContextBlade\":true,\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\",\"locationSource\":\"default\",\"passSpecificParams\":true,\"templateParameters\":[{\"name\":\"cName\",\"source\":\"column\",\"value\":\"cnName\"}]}}}],\"labelSettings\":[{\"columnId\":\"cnName\",\"label\":\"Object Changed\"}]}},\"customWidth\":\"35\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-DSP-Notifications' \\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Key1=tostring(['@Name']), Value=['#text']\\n| evaluate pivot(Key1, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| summarize Count=count() by tostring(fullOperation)\\n\\n\",\"size\":1,\"title\":\"AD Change Types\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"sortBy\":[{\"itemKey\":\"fullOperation\",\"sortOrder\":1}],\"labelSettings\":[{\"columnId\":\"fullOperation\",\"label\":\"Activity\"}]},\"sortBy\":[{\"itemKey\":\"fullOperation\",\"sortOrder\":1}]},\"customWidth\":\"30\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CommonSecurityLog\\n| extend p1Array = split(AdditionalExtensions,\\\";\\\")\\n| mv-expand bagexpansion=array p1Array\\n| evaluate bag_unpack(p1Array)\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\\n| parse DistinguishedName with * \\\"CN\\\\\\\\=\\\" cnName \\\",\\\" *\\n| parse DistinguishedName with * \\\"DC\\\\\\\\=\\\" dcName \\\",\\\" *\\n| where ClassName == 'group'\\n| project AttributeModificationType,cnName,OriginatingTime,replace_string(OriginatingUsers,\\\"\\\\\\\\\\\\\\\\\\\",\\\"\\\\\\\\\\\"),StringValueFrom,StringValueTo\\n\",\"size\":0,\"title\":\"Builtin Group Changes\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Column1\",\"formatter\":1,\"formatOptions\":{\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\",\"locationSource\":\"default\",\"passSpecificParams\":true,\"templateParameters\":[{\"name\":\"cName\",\"source\":\"column\",\"value\":\"cnName\"}]}}}],\"rowLimit\":10000,\"labelSettings\":[{\"columnId\":\"AttributeModificationType\",\"label\":\"Attribute Modification Type\"},{\"columnId\":\"cnName\",\"label\":\"Object Changed\"},{\"columnId\":\"OriginatingTime\",\"label\":\"Originating Time\"},{\"columnId\":\"StringValueFrom\",\"label\":\"Value From\"},{\"columnId\":\"StringValueTo\",\"label\":\"Value To\"}]}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-DSP-Notifications' \\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| extend result=column_ifexists(tostring('result'), ''), numberOfResults=column_ifexists(tostring('numberOfResults'), ''), securityIndicatorName=column_ifexists(tostring('securityIndicatorName'), '')\\n| extend isProblem = iif(result == \\\"Failed\\\", true, false)\\n| where isnotnull(numberOfResults) and isProblem == true\\n| order by tostring(securityIndicatorName)\\n| summarize Count=count() by tostring(securityIndicatorName)\\n| top 5 by Count\\n\\n\",\"size\":1,\"title\":\"Top 5 Failed Security Indicators\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"gridSettings\":{\"rowLimit\":10000},\"chartSettings\":{\"yAxis\":[\"Count\"],\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-DSP-Notifications' \\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| extend result=column_ifexists(tostring('result'), ''), numberOfResults=column_ifexists(tostring('numberOfResults'), ''), securityIndicatorName=column_ifexists(tostring('securityIndicatorName'), '')\\n| extend isProblem = iif(result == \\\"Failed\\\", true, false)\\n| where isnotnull(numberOfResults) and isProblem == true\\n| order by tostring(securityIndicatorName)\\n| summarize Count=count() by tostring(securityIndicatorName)\\n| top 5 by Count\\n\\n\",\"size\":1,\"title\":\"Top 5 Failed Security Indicators\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"gridSettings\":{\"rowLimit\":10000},\"chartSettings\":{\"yAxis\":[\"Count\"],\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityEvent\\n| where EventSourceName == 'Semperis-DSP-Notifications' \\n| extend p1Xml = parse_xml(EventData).EventData.Data\\n| mv-expand bagexpansion=array p1Xml\\n| evaluate bag_unpack(p1Xml)\\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\\n| extend result=column_ifexists(tostring('result'), ''), numberOfResults=column_ifexists(tostring('numberOfResults'), ''), securityFrameworkTags=column_ifexists(tostring('securityFrameworkTags'), '')\\n| extend isProblem = iif(result == \\\"Failed\\\", true, false)\\n| where isnotnull(numberOfResults) and isProblem == true\\n| summarize Count=count() by tostring(securityFrameworkTags)\\n\\n\",\"size\":0,\"title\":\"Amount of Generated Events per Category\",\"timeContext\":{\"durationMs\":14400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"gridSettings\":{\"rowLimit\":10000},\"chartSettings\":{\"yAxis\":[\"Count\"],\"showLegend\":true}},\"name\":\"query - 2\"}],\"styleSettings\":{\"paddingStyle\":\"wide\",\"spacingStyle\":\"wide\"},\"fromTemplateId\":\"sentinel-SemperisDSPQuickviewDashboard\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -419,37 +410,30 @@
}
}
]
- }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId3')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook3-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId3')]",
+ "id": "[variables('_workbookcontentProductId3')]",
+ "version": "[variables('workbookVersion3')]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
"name": "[variables('workbookTemplateSpecName4')]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Workbook with template",
- "displayName": "Semperis Directory Services Protector workbook template"
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('workbookTemplateSpecName4'),'/',variables('workbookVersion4'))]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Workbook"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('workbookTemplateSpecName4'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSPSecurityIndicatorsWorkbook Workbook with template version 2.0.5",
+ "description": "SemperisDSPSecurityIndicators Workbook with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion4')]",
@@ -467,7 +451,7 @@
},
"properties": {
"displayName": "[parameters('workbook4-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Semperis Directory Services Protector\\r\\n\\r\\n**Semperis Directory Services Protector** (DSP) provides valuable insight into your Active Directory security posture. It queries your Active Directory environment and performs a set of tests against many aspects of Active Directory's security posture, including AD Delegation, Account security, AD Infrastructure security, Group Policy security, and Kerberos security.\\r\\n\\r\\nEach security indicator is mapped to MITRE ATT&CK® framework categories, explains what was evaluated, and indicates how likely an exposure will compromise Active Directory. \\r\\n\\r\\nEach IoE found highlights weak Active Directory configurations and provides actionable guidance on how to close gaps before they are exploited by attackers. Using this workbook, you can determine how you are doing from a security perspective, compared to best practice environments.\\r\\n\\r\\nIn case of security regressions, Semperis Directory Services Protector will trigger alerts through Microsoft Sentinel.\"},\"name\":\"text - 2\"},{\"type\":1,\"content\":{\"json\":\"# Security Indicators mapped to MITRE ATT&CK® Framework Categories:\"},\"name\":\"text - 5\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"83787f1b-6573-47c6-8def-36bceb9a8afe\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"label\":\"Time Range\",\"type\":4,\"description\":\" Specify the time range on which to query the data\",\"isRequired\":true,\"value\":{\"durationMs\":604800000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}]},\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"d46aac4d-bcb8-4dbf-a331-3a3538226bc3\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"MitreFramework\",\"label\":\"MITRE ATT&CK Framework\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags)\\r\\n| mv-expand bagexpansion=array parse_csv(SecurityFrameworkTagsCsv) to typeof(string)\\r\\n| summarize Count = count() by SecurityFrameworkTagsCsv\\r\\n| order by Count desc, SecurityFrameworkTagsCsv asc\\r\\n| project Value = SecurityFrameworkTagsCsv, Label = strcat(SecurityFrameworkTagsCsv)\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"cf84c455-c1b9-4785-a592-54834be54097\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Status\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"dsp_parser\\r\\n| where isnotempty(Result)\\r\\n| summarize Count = count() by tostring(Result)\\r\\n| order by Count desc, Result asc\\r\\n| project Value = Result, Label = strcat(Result)\",\"value\":[\"value::all\"],\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| mv-expand bagexpansion=array SecurityFrameworkTagList to typeof(string)\\r\\n| where SecurityFrameworkTagList in ({MitreFramework})\\r\\n| summarize event_count=count() by SecurityFrameworkTagList\\r\\n\",\"size\":0,\"title\":\"Amount of Generated Events per Category\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\",\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"securityFrameworkTags\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"event_count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"event_count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"event_count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"event_count\",\"heatmapPalette\":\"greenRed\"}}},\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Requests = count() by tostring(SecurityIndicatorName)\\r\\n| order by Requests\\r\\n\",\"size\":3,\"title\":\"Breakdown by Indicators of Exposure (IoEs)\",\"noDataMessageStyle\":4,\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"SecurityIndicatorName\",\"formatter\":1},\"subtitleContent\":{\"columnMatch\":\"Requests\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"}},\"showBorder\":false,\"size\":\"auto\"},\"chartSettings\":{\"group\":\"securityIndicatorName\",\"createOtherGroup\":10,\"showMetrics\":false},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Requests\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Requests\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Requests\",\"heatmapPalette\":\"greenRed\"}}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Count = count() by tostring(SecurityFrameworkTags), tostring(SecurityIndicatorName), tostring(SecurityIndicatorDescription), tostring(LikelihoodOfCompromise), tostring(Remediation), tostring(Result), tostring(FirstFound), tostring(Score)\\r\\n| order by Count\\r\\n\",\"size\":0,\"title\":\"Indicators of Exposure (IoEs) Details:\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"SecurityFrameworkTags\",\"sortOrder\":1}],\"labelSettings\":[{\"columnId\":\"SecurityFrameworkTags\",\"label\":\"MITRE ATT&CK Framework\"},{\"columnId\":\"SecurityIndicatorName\",\"label\":\"Indicator of Exposure\"},{\"columnId\":\"SecurityIndicatorDescription\",\"label\":\"Description\"},{\"columnId\":\"LikelihoodOfCompromise\",\"label\":\"Likelihood of Compromise\"},{\"columnId\":\"FirstFound\",\"label\":\"First Time Found\"}]},\"sortBy\":[{\"itemKey\":\"SecurityFrameworkTags\",\"sortOrder\":1}],\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"securityIndicatorName\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"group - 6\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Count = count() by tostring(SecurityIndicatorName)\\r\\n| top 10 by Count desc\",\"size\":3,\"title\":\"Top 10 Indicators of Exposure (IoEs)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"group\":\"SecurityIndicatorName\",\"createOtherGroup\":10,\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":false}}}}},\"customWidth\":\"40\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Count = count() by tostring(SecurityFrameworkTags), tostring(SecurityIndicatorName), tostring(FirstFound), tostring(Remediation)\\r\\n| top 10 by Count desc\\r\\n| project-away Count\",\"size\":0,\"title\":\"Top 10 Indicators of Exposure (IoEs) Details:\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"customWidth\":\"60\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"group - 5\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-SemperisDSPSecurityIndicators\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Semperis Directory Services Protector\\r\\n\\r\\n**Semperis Directory Services Protector** (DSP) provides valuable insight into your Active Directory security posture. It queries your Active Directory environment and performs a set of tests against many aspects of Active Directory's security posture, including AD Delegation, Account security, AD Infrastructure security, Group Policy security, and Kerberos security.\\r\\n\\r\\nEach security indicator is mapped to MITRE ATT&CK® framework categories, explains what was evaluated, and indicates how likely an exposure will compromise Active Directory. \\r\\n\\r\\nEach IoE found highlights weak Active Directory configurations and provides actionable guidance on how to close gaps before they are exploited by attackers. Using this workbook, you can determine how you are doing from a security perspective, compared to best practice environments.\\r\\n\\r\\nIn case of security regressions, Semperis Directory Services Protector will trigger alerts through Microsoft Sentinel.\"},\"name\":\"text - 2\"},{\"type\":1,\"content\":{\"json\":\"# Security Indicators mapped to MITRE ATT&CK® Framework Categories:\"},\"name\":\"text - 5\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"83787f1b-6573-47c6-8def-36bceb9a8afe\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"label\":\"Time Range\",\"type\":4,\"description\":\" Specify the time range on which to query the data\",\"isRequired\":true,\"value\":{\"durationMs\":1209600000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}]},\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"d46aac4d-bcb8-4dbf-a331-3a3538226bc3\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"MitreFramework\",\"label\":\"MITRE ATT&CK Framework\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"dsp_parser\\r\\n| where isnotempty(SecurityFrameworkTags)\\r\\n| mv-expand bagexpansion=array parse_csv(SecurityFrameworkTagsCsv) to typeof(string)\\r\\n| summarize Count = count() by SecurityFrameworkTagsCsv\\r\\n| order by Count desc, SecurityFrameworkTagsCsv asc\\r\\n| project Value = SecurityFrameworkTagsCsv, Label = strcat(SecurityFrameworkTagsCsv)\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"cf84c455-c1b9-4785-a592-54834be54097\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Status\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"dsp_parser\\r\\n| where isnotempty(Result)\\r\\n| summarize Count = count() by tostring(Result)\\r\\n| order by Count desc, Result asc\\r\\n| project Value = Result, Label = strcat(Result)\",\"value\":[\"value::all\"],\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 3\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser_new\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| union (CommonSecurityLog \\r\\n| extend p1Array = split(AdditionalExtensions,\\\"|\\\")\\r\\n| mv-expand bagexpansion=array p1Array\\r\\n| evaluate bag_unpack(p1Array)\\r\\n| extend Name=tostring(split(p1Array,\\\"=\\\")[0]),Value=substring(p1Array,indexof(p1Array,\\\"=\\\")+1)\\r\\n| evaluate pivot(Name, any(Value), Activity, LogSeverity)\\r\\n| extend Activity = column_ifexists('Activity', '')\\r\\n| extend SecurityIndicatorName = Activity\\r\\n| extend LogSeverity = column_ifexists('LogSeverity', '')\\r\\n| extend Severity = LogSeverity\\r\\n| extend Score = \\\"0 F\\\"\\r\\n| extend Result = \\\"\\\"\\r\\n| extend Timestamp = column_ifexists('Timestamp', '')\\r\\n| extend FirstFound = Timestamp\\r\\n| extend SecurityFrameworkTags = column_ifexists('SecurityFrameworkTags', ''))\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| summarize Count = count() by tostring(SecurityIndicatorName), tostring(Severity), tostring(Score), tostring(FirstFound), tostring(Result), tostring(SecurityFrameworkTags)\\r\\n| order by Count\\r\\n\",\"size\":0,\"title\":\"Indicators of Exposure (IoEs) Details:\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Severity\",\"sortOrder\":1}],\"labelSettings\":[{\"columnId\":\"FirstFound\",\"label\":\"Latest alert\"},{\"columnId\":\"SecurityFrameworkTags\",\"label\":\"Security framework tags\"}]},\"sortBy\":[{\"itemKey\":\"Severity\",\"sortOrder\":1}],\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"securityIndicatorName\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser_new\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Requests = count() by tostring(SecurityIndicatorName)\\r\\n| order by Requests\\r\\n\",\"size\":3,\"title\":\"Breakdown by Indicators of Exposure (IoEs)\",\"noDataMessageStyle\":4,\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"SecurityIndicatorName\",\"formatter\":1},\"subtitleContent\":{\"columnMatch\":\"Requests\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"}},\"showBorder\":false,\"size\":\"auto\"},\"chartSettings\":{\"group\":\"securityIndicatorName\",\"createOtherGroup\":10,\"showMetrics\":false},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Requests\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Requests\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Requests\",\"heatmapPalette\":\"greenRed\"}}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"group - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser_new\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| mv-expand bagexpansion=array SecurityFrameworkTagList to typeof(string)\\r\\n| where SecurityFrameworkTagList in ({MitreFramework})\\r\\n| summarize event_count=count() by SecurityFrameworkTagList\\r\\n\",\"size\":0,\"title\":\"Amount of Generated Events per Category\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\",\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"securityFrameworkTags\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"event_count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"event_count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"event_count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"event_count\",\"heatmapPalette\":\"greenRed\"}}},\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser_new\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Count = count() by tostring(SecurityIndicatorName)\\r\\n| top 10 by Count desc\",\"size\":3,\"title\":\"Top 10 Indicators of Exposure (IoEs)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"group\":\"SecurityIndicatorName\",\"createOtherGroup\":10,\"showMetrics\":false,\"showLegend\":true,\"ySettings\":{\"numberFormatSettings\":{\"unit\":0,\"options\":{\"style\":\"decimal\",\"useGrouping\":false}}}}},\"customWidth\":\"40\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"dsp_parser_new\\r\\n| where isnotempty(SecurityFrameworkTags) \\r\\n| where Result in ({Status})\\r\\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\\r\\n| extend MitreFramework = pack_array({MitreFramework})\\r\\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\\r\\n| extend FilterIntersectionCount = array_length(FilterIntersection)\\r\\n| where FilterIntersectionCount > 0\\r\\n| summarize Count = count() by tostring(SecurityFrameworkTags), tostring(SecurityIndicatorName), tostring(Remediation)\\r\\n| top 10 by Count desc\\r\\n| project-away Count\",\"size\":0,\"title\":\"Top 10 Indicators of Exposure (IoEs) Details:\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\"},\"customWidth\":\"60\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"group - 5\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-SemperisDSPSecurityIndicators\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -500,7 +484,7 @@
"operator": "AND",
"criteria": [
{
- "contentId": "Event",
+ "contentId": "dsp_parser",
"kind": "DataType"
},
{
@@ -512,59 +496,53 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('parserTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Parser"
- },
- "properties": {
- "description": "dsp_parser Data Parser with template",
- "displayName": "dsp_parser Data Parser template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_workbookContentId4')]",
+ "contentKind": "Workbook",
+ "displayName": "[parameters('workbook4-name')]",
+ "contentProductId": "[variables('_workbookcontentProductId4')]",
+ "id": "[variables('_workbookcontentProductId4')]",
+ "version": "[variables('workbookVersion4')]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('parserTemplateSpecName1'),'/',variables('parserVersion1'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserObject1').parserTemplateSpecName1]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "Parser"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('parserTemplateSpecName1'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "dsp_parser Data Parser with template version 2.0.5",
+ "description": "dsp_parser Data Parser with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('parserVersion1')]",
+ "contentVersion": "[variables('parserObject1').parserVersion1]",
"parameters": {},
"variables": {},
"resources": [
{
- "name": "[variables('_parserName1')]",
- "apiVersion": "2020-08-01",
+ "name": "[variables('parserObject1')._parserName1]",
+ "apiVersion": "2022-10-01",
"type": "Microsoft.OperationalInsights/workspaces/savedSearches",
"location": "[parameters('workspace-location')]",
"properties": {
"eTag": "*",
- "displayName": "dsp_parser",
- "category": "Samples",
+ "displayName": "Parser for dsp_parser",
+ "category": "Microsoft Sentinel Parser",
"functionAlias": "dsp_parser",
- "query": "\nEvent\r\n| where Source == \"Semperis-DSP-Security\"\r\n| where EventID in (\"9211\",\"9212\",\"9208\")\r\n| parse EventData with \r\n '' DSPData ''\r\n| parse DSPData with \r\n *\r\n '' FirstFound ''\r\n * \r\n| parse DSPData with \r\n '' GenerationTime ''\r\n '' SecurityIndicatorName ''\r\n\t'' Result '' \r\n *\r\n\t'' Score ''\r\n\t'' ForestName ''\r\n\t'' Domains ''\r\n\t'' Severity ''\r\n\t'' Weight ''\r\n\t'' SecurityFrameworkTags ''\r\n\t'' SecurityIndicatorDescription ''\r\n\t'' LikelihoodOfCompromise ''\r\n\t'' ResultMessage ''\r\n\t'' NumberOfResults ''\r\n\t'' Remediation ''\r\n\t'' Schedule ''\r\n * \r\n| extend SecurityFrameworkTagsCsv = replace(@' Mitre:', @'', tostring(SecurityFrameworkTags))\r\n| extend SecurityFrameworkTagsCsv = replace(@'Mitre:', @'', tostring(SecurityFrameworkTagsCsv))\r\n| extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))\r\n",
- "version": 1,
+ "query": "SecurityEvent\n| where EventSourceName == \"Semperis-DSP-Security\"\n| where EventID in (\"9211\", \"9212\", \"9208\")\n| parse EventData with \n '' DSPData ''\n| parse DSPData with \n *\n '' FirstFound ''\n * \n| parse DSPData with \n *\n '' GenerationTime ''\t*\n '' SecurityIndicatorName '' *\n '' Result '' *\n '' Score '' *\n '' ForestName '' *\n '' Domains '' *\n '' Severity '' *\n '' Weight '' *\n '' SecurityFrameworkTags '' *\n '' SecurityIndicatorDescription ''\t*\n '' LikelihoodOfCompromise ''\t*\n '' ResultMessage '' *\n '' NumberOfResults '' *\n '' Remediation '' *\n '' Schedule ''\n *\n| extend SecurityFrameworkTagsCsv = replace(@' Mitre:', @'', tostring(SecurityFrameworkTags))\n| extend SecurityFrameworkTagsCsv = replace(@'Mitre:', @'', tostring(SecurityFrameworkTagsCsv))\n| extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))\n| extend GenerationTimeTags = tostring(DSPData)\n",
+ "functionParameters": "",
+ "version": 2,
"tags": [
{
"name": "description",
- "value": "dsp_parser"
+ "value": ""
}
]
}
@@ -572,15 +550,15 @@
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId1'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
"dependsOn": [
- "[variables('_parserName1')]"
+ "[variables('parserObject1')._parserId1]"
],
"properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
- "contentId": "[variables('_parserContentId1')]",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'dsp_parser')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
"kind": "Parser",
- "version": "[variables('parserVersion1')]",
+ "version": "[variables('parserObject1').parserVersion1]",
"source": {
"name": "Semperis Directory Services Protector",
"kind": "Solution",
@@ -597,36 +575,54 @@
}
}
]
- }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "contentKind": "Parser",
+ "displayName": "Parser for dsp_parser",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]",
+ "version": "[variables('parserObject1').parserVersion1]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/savedSearches",
- "apiVersion": "2021-06-01",
- "name": "[variables('_parserName1')]",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('parserObject1')._parserName1]",
"location": "[parameters('workspace-location')]",
"properties": {
"eTag": "*",
- "displayName": "dsp_parser",
- "category": "Samples",
+ "displayName": "Parser for dsp_parser",
+ "category": "Microsoft Sentinel Parser",
"functionAlias": "dsp_parser",
- "query": "\nEvent\r\n| where Source == \"Semperis-DSP-Security\"\r\n| where EventID in (\"9211\",\"9212\",\"9208\")\r\n| parse EventData with \r\n '' DSPData ''\r\n| parse DSPData with \r\n *\r\n '' FirstFound ''\r\n * \r\n| parse DSPData with \r\n '' GenerationTime ''\r\n '' SecurityIndicatorName ''\r\n\t'' Result '' \r\n *\r\n\t'' Score ''\r\n\t'' ForestName ''\r\n\t'' Domains ''\r\n\t'' Severity ''\r\n\t'' Weight ''\r\n\t'' SecurityFrameworkTags ''\r\n\t'' SecurityIndicatorDescription ''\r\n\t'' LikelihoodOfCompromise ''\r\n\t'' ResultMessage ''\r\n\t'' NumberOfResults ''\r\n\t'' Remediation ''\r\n\t'' Schedule ''\r\n * \r\n| extend SecurityFrameworkTagsCsv = replace(@' Mitre:', @'', tostring(SecurityFrameworkTags))\r\n| extend SecurityFrameworkTagsCsv = replace(@'Mitre:', @'', tostring(SecurityFrameworkTagsCsv))\r\n| extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))\r\n",
- "version": 1
+ "query": "SecurityEvent\n| where EventSourceName == \"Semperis-DSP-Security\"\n| where EventID in (\"9211\", \"9212\", \"9208\")\n| parse EventData with \n '' DSPData ''\n| parse DSPData with \n *\n '' FirstFound ''\n * \n| parse DSPData with \n *\n '' GenerationTime ''\t*\n '' SecurityIndicatorName '' *\n '' Result '' *\n '' Score '' *\n '' ForestName '' *\n '' Domains '' *\n '' Severity '' *\n '' Weight '' *\n '' SecurityFrameworkTags '' *\n '' SecurityIndicatorDescription ''\t*\n '' LikelihoodOfCompromise ''\t*\n '' ResultMessage '' *\n '' NumberOfResults '' *\n '' Remediation '' *\n '' Schedule ''\n *\n| extend SecurityFrameworkTagsCsv = replace(@' Mitre:', @'', tostring(SecurityFrameworkTags))\n| extend SecurityFrameworkTagsCsv = replace(@'Mitre:', @'', tostring(SecurityFrameworkTagsCsv))\n| extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))\n| extend GenerationTimeTags = tostring(DSPData)\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
"location": "[parameters('workspace-location')]",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId1'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
"dependsOn": [
- "[variables('_parserId1')]"
+ "[variables('parserObject1')._parserId1]"
],
"properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
- "contentId": "[variables('_parserContentId1')]",
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'dsp_parser')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
"kind": "Parser",
- "version": "[variables('parserVersion1')]",
+ "version": "[variables('parserObject1').parserVersion1]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -643,50 +639,32 @@
}
},
{
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName1')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 1 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName1'),'/',variables('analyticRuleVersion1'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName1'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSP_EvidenceOfMimikatzDCShadowAttack_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "SemperisDSP_EvidenceOfMimikatzDCShadowAttack_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion1')]",
+ "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId1')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "Mimikatz's DCShadow switch allows a user who has compromised an AD domain, to inject arbitrary changes into AD using a \"fake\" domain controller. These changes bypass the security event log and can't be spotted using normal AD tools. This rule looks for evidence that a machine has been used in this capacity.",
"displayName": "Semperis DSP Mimikatz's DCShadow Alert",
"enabled": false,
- "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Evidence of Mimikatz DCShadow attack\"\n",
+ "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Evidence of Mimikatz DCShadow attack\"\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "High",
@@ -697,10 +675,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SemperisDSP",
"dataTypes": [
"dsp_parser"
- ],
- "connectorId": "SemperisDSP"
+ ]
}
],
"tactics": [
@@ -708,19 +686,34 @@
],
"techniques": [
"T1207"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId1'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 1",
- "parentId": "[variables('analyticRuleId1')]",
- "contentId": "[variables('_analyticRulecontentId1')]",
+ "parentId": "[variables('analyticRuleObject1').analyticRuleId1]",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion1')]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -737,54 +730,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName2')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 2 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Mimikatz's DCShadow Alert",
+ "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName2'),'/',variables('analyticRuleVersion2'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName2'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSP_KerberoskrbtgtAccount_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "SemperisDSP_KerberoskrbtgtAccount_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion2')]",
+ "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId2')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "The krbtgt user account is a special (disabled) user account in every Active Directory domain that has a special role in Kerberos function. If this account's password is compromised, Golden Ticket attacks can be performed to get access to any resource in the AD domain. This indicator looks for a krbtgt user account whose password hasn't been changed in the past 180 days. While Microsoft recommends changing the password every year, STIG recommends changing it every 180 days.",
"displayName": "Semperis DSP Kerberos krbtgt account with old password",
"enabled": false,
- "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Kerberos krbtgt account with old password\"\n",
+ "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Kerberos krbtgt account with old password\"\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "Medium",
@@ -795,27 +781,48 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SemperisDSP",
"dataTypes": [
"dsp_parser"
- ],
- "connectorId": "SemperisDSP"
+ ]
}
],
"tactics": [
"CredentialAccess"
+ ],
+ "subTechniques": [
+ "T1558.001"
+ ],
+ "techniques": [
+ "T1558"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId2'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 2",
- "parentId": "[variables('analyticRuleId2')]",
- "contentId": "[variables('_analyticRulecontentId2')]",
+ "parentId": "[variables('analyticRuleObject2').analyticRuleId2]",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion2')]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -832,54 +839,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName3')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 3 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Kerberos krbtgt account with old password",
+ "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName3'),'/',variables('analyticRuleVersion3'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName3'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSP_RecentsIDHistoryChangesOnADObjects_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "SemperisDSP_RecentsIDHistoryChangesOnADObjects_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion3')]",
+ "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId3')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "This indicator detects any recent changes to sIDHistory on AD objects, including changes to non-privileged accounts where privileged SIDs are added.",
"displayName": "Semperis DSP Recent sIDHistory changes on AD objects",
"enabled": false,
- "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Recent sIDHistory changes on objects\"\n",
+ "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Recent sIDHistory changes on objects\"\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "High",
@@ -890,27 +890,46 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SemperisDSP",
"dataTypes": [
"dsp_parser"
- ],
- "connectorId": "SemperisDSP"
+ ]
}
],
"tactics": [
- "PrivilegeEscalation"
+ "PrivilegeEscalation",
+ "Persistence"
+ ],
+ "techniques": [
+ "T1098"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId3'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 3",
- "parentId": "[variables('analyticRuleId3')]",
- "contentId": "[variables('_analyticRulecontentId3')]",
+ "parentId": "[variables('analyticRuleObject3').analyticRuleId3]",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion3')]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -927,54 +946,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName4')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 4 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Recent sIDHistory changes on AD objects",
+ "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName4'),'/',variables('analyticRuleVersion4'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject4').analyticRuleTemplateSpecName4]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName4'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSP_WellKnownPrivilegedSIDsInsIDHistory_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "SemperisDSP_WellKnownPrivilegedSIDsInsIDHistory_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion4')]",
+ "contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId4')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject4')._analyticRulecontentId4]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "This indicator looks for security principals that contain specific SIDs of accounts from built-in privileged groups within their sIDHistory attribute. This would allow those security principals to have the same privileges as those privileged accounts, but in a way that is not obvious to monitor (e.g. through group membership).",
"displayName": "Semperis DSP Well-known privileged SIDs in sIDHistory",
"enabled": false,
- "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Well-known privileged SIDs in sIDHistory\"\n",
+ "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Well-known privileged SIDs in sIDHistory\"\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "Medium",
@@ -985,10 +997,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SemperisDSP",
"dataTypes": [
"dsp_parser"
- ],
- "connectorId": "SemperisDSP"
+ ]
}
],
"tactics": [
@@ -997,19 +1009,34 @@
],
"techniques": [
"T1134"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId4'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject4').analyticRuleId4,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 4",
- "parentId": "[variables('analyticRuleId4')]",
- "contentId": "[variables('_analyticRulecontentId4')]",
+ "parentId": "[variables('analyticRuleObject4').analyticRuleId4]",
+ "contentId": "[variables('analyticRuleObject4')._analyticRulecontentId4]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion4')]",
+ "version": "[variables('analyticRuleObject4').analyticRuleVersion4]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -1026,54 +1053,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName5')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 5 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject4')._analyticRulecontentId4]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Well-known privileged SIDs in sIDHistory",
+ "contentProductId": "[variables('analyticRuleObject4')._analyticRulecontentProductId4]",
+ "id": "[variables('analyticRuleObject4')._analyticRulecontentProductId4]",
+ "version": "[variables('analyticRuleObject4').analyticRuleVersion4]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName5'),'/',variables('analyticRuleVersion5'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject5').analyticRuleTemplateSpecName5]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName5'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SemperisDSP_ZerologonVulnerability_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "SemperisDSP_ZerologonVulnerability_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion5')]",
+ "contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId5')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject5')._analyticRulecontentId5]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "This indicator looks for security vulnerability to CVE-2020-1472, which was patched by Microsoft in August 2020. Without this patch, an unauthenticated attacker can exploit CVE-2020-1472 to elevate their privileges and get administrative access on the domain.",
"displayName": "Semperis DSP Zerologon vulnerability",
"enabled": false,
- "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Zerologon vulnerability\"\n",
+ "query": "dsp_parser\n| where EventID == 9212\n| where SecurityIndicatorName == \"Zerologon vulnerability\"\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "Medium",
@@ -1084,27 +1104,45 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SemperisDSP",
"dataTypes": [
"dsp_parser"
- ],
- "connectorId": "SemperisDSP"
+ ]
}
],
"tactics": [
"PrivilegeEscalation"
+ ],
+ "techniques": [
+ "T1068"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId5'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject5').analyticRuleId5,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 5",
- "parentId": "[variables('analyticRuleId5')]",
- "contentId": "[variables('_analyticRulecontentId5')]",
+ "parentId": "[variables('analyticRuleObject5').analyticRuleId5]",
+ "contentId": "[variables('analyticRuleObject5')._analyticRulecontentId5]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion5')]",
+ "version": "[variables('analyticRuleObject5').analyticRuleVersion5]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -1121,54 +1159,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName6')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 6 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject5')._analyticRulecontentId5]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Zerologon vulnerability",
+ "contentProductId": "[variables('analyticRuleObject5')._analyticRulecontentProductId5]",
+ "id": "[variables('analyticRuleObject5')._analyticRulecontentProductId5]",
+ "version": "[variables('analyticRuleObject5').analyticRuleVersion5]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName6'),'/',variables('analyticRuleVersion6'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject6').analyticRuleTemplateSpecName6]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName6'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Semperis_DSP_Failed_Logons_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "Semperis_DSP_Failed_Logons_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion6')]",
+ "contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId6')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject6')._analyticRulecontentId6]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "Alerts when there are failed logons in the DSP system.",
"displayName": "Semperis DSP Failed Logons",
"enabled": false,
- "query": "Event\n| where Source == 'Semperis-Operation-Log' and EventID == 20002\n| sort by TimeGenerated desc \n| parse RenderedDescription with \"Operation: \" Operation \"Access Granted:\" AccessGranted \"Result: \" Result \"Details: \" * \"Trustee Name: \" TrusteeName \" Correlation ID: \" * \" Source: \" HostIP \"WebSite Target\" *\n| extend host = tostring(HostIP)\n| extend HostIP = trim_end(\":\", HostIP)\n| project TimeGenerated, UserName, HostIP, _ResourceId\n| order by TimeGenerated desc\n| top 10 by TimeGenerated\n| count\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20002\n| sort by TimeGenerated desc \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend det = column_ifexists('details', '')\n| parse det with * \"Trustee Name: \" TrusteeName \" Correlation ID: \" * \" Source: \" HostIP \"WebSite Target\" *\n| extend host = tostring(HostIP)\n| extend HostIP = trim_end(\":\", HostIP)\n| project TimeGenerated, TrusteeName, HostIP, _ResourceId\n| extend NTDomain = tostring(split(TrusteeName, '\\\\', 0)[0]), Name = tostring(split(TrusteeName, '\\\\', 1)[0]) \n",
"queryFrequency": "PT30M",
"queryPeriod": "PT30M",
"severity": "Medium",
@@ -1177,25 +1208,65 @@
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
+ "requiredDataConnectors": [
+ {
+ "connectorId": "SemperisDSP",
+ "dataTypes": [
+ "dsp_parser"
+ ]
+ }
+ ],
+ "tactics": [
+ "InitialAccess",
+ "CredentialAccess"
+ ],
+ "techniques": [
+ "T1078",
+ "T1110"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostIP",
+ "identifier": "Address"
+ }
+ ],
+ "entityType": "IP"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "Name",
+ "identifier": "Name"
+ },
+ {
+ "columnName": "NTDomain",
+ "identifier": "NTDomain"
+ }
+ ],
+ "entityType": "Account"
+ }
+ ],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "A failed logon was detected to the DSP system.",
- "alertDisplayNameFormat": "Failed Logon -- Alert from Semperis Directory Services Protector"
+ "alertDisplayNameFormat": "Failed Logon -- Alert from Semperis Directory Services Protector",
+ "alertDescriptionFormat": "A failed logon was detected to the DSP system."
}
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId6'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject6').analyticRuleId6,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 6",
- "parentId": "[variables('analyticRuleId6')]",
- "contentId": "[variables('_analyticRulecontentId6')]",
+ "parentId": "[variables('analyticRuleObject6').analyticRuleId6]",
+ "contentId": "[variables('analyticRuleObject6')._analyticRulecontentId6]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion6')]",
+ "version": "[variables('analyticRuleObject6').analyticRuleVersion6]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -1212,54 +1283,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName7')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 7 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject6')._analyticRulecontentId6]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Failed Logons",
+ "contentProductId": "[variables('analyticRuleObject6')._analyticRulecontentProductId6]",
+ "id": "[variables('analyticRuleObject6')._analyticRulecontentProductId6]",
+ "version": "[variables('analyticRuleObject6').analyticRuleVersion6]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName7'),'/',variables('analyticRuleVersion7'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject7').analyticRuleTemplateSpecName7]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName7'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Semperis_DSP_Operations_Critical_Notifications__AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "Semperis_DSP_Operations_Critical_Notifications__AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion7')]",
+ "contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId7')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject7')._analyticRulecontentId7]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "Alerts when there are critical notifications fired in the DSP system.",
"displayName": "Semperis DSP Operations Critical Notifications",
"enabled": false,
- "query": "Event\n| where Source == 'Semperis-DSP-Notifications' and EventID == 30001\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| parse column_ifexists('objectDN', '') with * \"CN=\" cnName \",\" *\n| where \"Critical\" == column_ifexists('severity', \"\")\n| count",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-DSP-Notifications' and EventID == 30001\n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| parse column_ifexists('objectDN', '') with * \"CN=\" cnName \",\" *\n| where \"Critical\" == column_ifexists('severity', \"\")\n| extend NTDomain = tostring(split(changedBy, '\\\\', 0)[0]), LoginUser = tostring(split(changedBy, '\\\\', 1)[0])\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT30M",
"queryPeriod": "PT30M",
"severity": "Medium",
@@ -1268,25 +1332,71 @@
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
+ "requiredDataConnectors": [
+ {
+ "connectorId": "SemperisDSP",
+ "dataTypes": [
+ "dsp_parser"
+ ]
+ }
+ ],
+ "tactics": [
+ "InitialAccess",
+ "CredentialAccess",
+ "ResourceDevelopment"
+ ],
+ "techniques": [
+ "T1133",
+ "T1110",
+ "T1584"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "LoginUser",
+ "identifier": "Name"
+ },
+ {
+ "columnName": "NTDomain",
+ "identifier": "NTDomain"
+ }
+ ],
+ "entityType": "Account"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
+ ],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "A critical notification was created in the DSP system.",
- "alertDisplayNameFormat": "Critical Notification -- Alert from Semperis Directory Services Protector"
+ "alertDisplayNameFormat": "Critical Notification -- Alert from Semperis Directory Services Protector",
+ "alertDescriptionFormat": "A critical notification was created in the DSP system."
}
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId7'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject7').analyticRuleId7,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 7",
- "parentId": "[variables('analyticRuleId7')]",
- "contentId": "[variables('_analyticRulecontentId7')]",
+ "parentId": "[variables('analyticRuleObject7').analyticRuleId7]",
+ "contentId": "[variables('analyticRuleObject7')._analyticRulecontentId7]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion7')]",
+ "version": "[variables('analyticRuleObject7').analyticRuleVersion7]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -1303,54 +1413,47 @@
}
}
]
- }
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
- "name": "[variables('analyticRuleTemplateSpecName8')]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
- "properties": {
- "description": "Semperis Directory Services Protector Analytics Rule 8 with template",
- "displayName": "Semperis Directory Services Protector Analytics Rule template"
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject7')._analyticRulecontentId7]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP Operations Critical Notifications",
+ "contentProductId": "[variables('analyticRuleObject7')._analyticRulecontentProductId7]",
+ "id": "[variables('analyticRuleObject7')._analyticRulecontentProductId7]",
+ "version": "[variables('analyticRuleObject7').analyticRuleVersion7]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('analyticRuleTemplateSpecName8'),'/',variables('analyticRuleVersion8'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('analyticRuleObject8').analyticRuleTemplateSpecName8]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "AnalyticsRule"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName8'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Semperis_DSP_RBAC_Changes_AnalyticalRules Analytics Rule with template version 2.0.5",
+ "description": "Semperis_DSP_RBAC_Changes_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('analyticRuleVersion8')]",
+ "contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
- "name": "[variables('AnalyticRulecontentId8')]",
- "apiVersion": "2022-04-01-preview",
+ "name": "[variables('analyticRuleObject8')._analyticRulecontentId8]",
+ "apiVersion": "2023-02-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "Alerts when there are RBAC changes in the DSP system.",
"displayName": "Semperis DSP RBAC Changes",
"enabled": false,
- "query": "Event \n| where Source == 'Semperis-Operation-Log' and EventID == 20012 \n| order by TimeGenerated desc\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| extend det = column_ifexists('details', '')\n| 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\n| extend _AccessGranted = iif(operationName contains \"CreateRbacIdentity\", \"Added\", \"Removed\")\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", trustee, tostring(substring(trustee, 1, strlen(trustee))))\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", _Identity, replace_string(_Identity, \"'\", \"\"))\n| extend add_personas = replace_string(replace_string(replace_string(personas, \"{ Name = \", \"\"), \" }\", \"\"), \";\", \",\")\n| extend remove_personas = replace_string(personas, \";\", \",\")\n| extend grid_personas = iif(operationName contains \"CreateRbacIdentity\", add_personas, remove_personas)\n| extend date_to_sort = format_datetime(TimeGenerated, \"yyyy-mm-dd HH:mm:ss\")\n| order by date_to_sort desc\n| count\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20012 \n| order by TimeGenerated desc\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, Computer, Level, EventLevelName, EventID, Type, _ResourceId)\n| extend det = column_ifexists('details', '')\n| 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\n| extend _AccessGranted = iif(operationName contains \"CreateRbacIdentity\", \"Added\", \"Removed\")\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", trustee, tostring(substring(trustee, 1, strlen(trustee))))\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", _Identity, replace_string(_Identity, \"'\", \"\"))\n| extend add_personas = replace_string(replace_string(replace_string(personas, \"{ Name = \", \"\"), \" }\", \"\"), \";\", \",\")\n| extend remove_personas = replace_string(personas, \";\", \",\")\n| extend grid_personas = iif(operationName contains \"CreateRbacIdentity\", add_personas, remove_personas)\n| extend date_to_sort = format_datetime(TimeGenerated, \"yyyy-mm-dd HH:mm:ss\")\n| order by date_to_sort desc\n| extend NTDomain = tostring(split(TrusteeName, '\\\\', 0)[0]), LoginUser = tostring(split(TrusteeName, '\\\\', 1)[0])\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT30M",
"queryPeriod": "PT30M",
"severity": "Medium",
@@ -1359,25 +1462,69 @@
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
+ "requiredDataConnectors": [
+ {
+ "connectorId": "SemperisDSP",
+ "dataTypes": [
+ "dsp_parser"
+ ]
+ }
+ ],
+ "tactics": [
+ "PrivilegeEscalation",
+ "Persistence"
+ ],
+ "techniques": [
+ "T1548",
+ "T1098"
+ ],
+ "entityMappings": [
+ {
+ "fieldMappings": [
+ {
+ "columnName": "LoginUser",
+ "identifier": "Name"
+ },
+ {
+ "columnName": "NTDomain",
+ "identifier": "NTDomain"
+ }
+ ],
+ "entityType": "Account"
+ },
+ {
+ "fieldMappings": [
+ {
+ "columnName": "HostName",
+ "identifier": "HostName"
+ },
+ {
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
+ }
+ ],
+ "entityType": "Host"
+ }
+ ],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"alertDetailsOverride": {
- "alertDescriptionFormat": "A RBAC change was detected in the DSP system.",
- "alertDisplayNameFormat": "RBAC Change -- Alert from Semperis Directory Services Protector"
+ "alertDisplayNameFormat": "RBAC Change -- Alert from Semperis Directory Services Protector",
+ "alertDescriptionFormat": "A RBAC change was detected in the DSP system."
}
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId8'),'/'))))]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject8').analyticRuleId8,'/'))))]",
"properties": {
"description": "Semperis Directory Services Protector Analytics Rule 8",
- "parentId": "[variables('analyticRuleId8')]",
- "contentId": "[variables('_analyticRulecontentId8')]",
+ "parentId": "[variables('analyticRuleObject8').analyticRuleId8]",
+ "contentId": "[variables('analyticRuleObject8')._analyticRulecontentId8]",
"kind": "AnalyticsRule",
- "version": "[variables('analyticRuleVersion8')]",
+ "version": "[variables('analyticRuleObject8').analyticRuleVersion8]",
"source": {
"kind": "Solution",
"name": "Semperis Directory Services Protector",
@@ -1394,37 +1541,30 @@
}
}
]
- }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('analyticRuleObject8')._analyticRulecontentId8]",
+ "contentKind": "AnalyticsRule",
+ "displayName": "Semperis DSP RBAC Changes",
+ "contentProductId": "[variables('analyticRuleObject8')._analyticRulecontentProductId8]",
+ "id": "[variables('analyticRuleObject8')._analyticRulecontentProductId8]",
+ "version": "[variables('analyticRuleObject8').analyticRuleVersion8]"
}
},
{
- "type": "Microsoft.Resources/templateSpecs",
- "apiVersion": "2021-05-01",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
"name": "[variables('dataConnectorTemplateSpecName1')]",
"location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "DataConnector"
- },
- "properties": {
- "description": "Semperis Directory Services Protector data connector with template",
- "displayName": "Semperis Directory Services Protector template"
- }
- },
- {
- "type": "Microsoft.Resources/templateSpecs/versions",
- "apiVersion": "2021-05-01",
- "name": "[concat(variables('dataConnectorTemplateSpecName1'),'/',variables('dataConnectorVersion1'))]",
- "location": "[parameters('workspace-location')]",
- "tags": {
- "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]",
- "hidden-sentinelContentType": "DataConnector"
- },
"dependsOn": [
- "[resourceId('Microsoft.Resources/templateSpecs', variables('dataConnectorTemplateSpecName1'))]"
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Semperis Directory Services Protector data connector with template version 2.0.5",
+ "description": "Semperis Directory Services Protector data connector with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -1524,11 +1664,15 @@
"description": "**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected [**dsp_parser**](https://aka.ms/sentinel-SemperisDSP-parser) which is deployed with the Microsoft Sentinel Solution."
},
{
- "description": "On your **Semperis DSP Management Server** install the Microsoft agent for Windows.",
- "title": "1. Configure Semperis DSP Management Server to send Windows event logs to your Microsoft Sentinel Workspace"
+ "description": "Collect Windows security events logs from your **Semperis DSP Management Server** .",
+ "title": "**Configure Windows Security Events via AMA connector**"
},
{
- "description": "You can skip this step if you have already installed the Microsoft agent for Windows",
+ "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": "1. Install the Azure Monitor Agent (AMA)"
+ },
+ {
+ "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": {
@@ -1551,22 +1695,48 @@
"type": "InstructionStepsGroup"
}
],
- "title": "2. Install and onboard the Microsoft agent for Windows"
+ "title": "2. Create a Data Collection Rule (DCR)"
+ },
+ {
+ "description": "Collect syslog messages send from your **Semperis DSP Management Server** .",
+ "title": "**Configure Common Event Format via AMA connector**"
+ },
+ {
+ "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": "1. Install the Azure Monitor Agent (AMA)"
},
{
- "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**",
+ "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 the Semperis DSP Windows event logs to be collected by the agent"
+ "title": "2. Create a Data Collection Rule (DCR)"
},
{
- "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": "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": "3. Configure sending CEF logs on your Semperis DSP Management Server"
+ },
+ {
+ "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": {
@@ -1590,7 +1760,7 @@
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
+ "apiVersion": "2023-04-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
"properties": {
"parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
@@ -1613,12 +1783,23 @@
}
}
]
- }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId1')]",
+ "contentKind": "DataConnector",
+ "displayName": "Semperis Directory Services Protector",
+ "contentProductId": "[variables('_dataConnectorcontentProductId1')]",
+ "id": "[variables('_dataConnectorcontentProductId1')]",
+ "version": "[variables('dataConnectorVersion1')]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
+ "apiVersion": "2023-04-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]",
"dependsOn": [
"[variables('_dataConnectorId1')]"
@@ -1735,11 +1916,15 @@
"description": "**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected [**dsp_parser**](https://aka.ms/sentinel-SemperisDSP-parser) which is deployed with the Microsoft Sentinel Solution."
},
{
- "description": "On your **Semperis DSP Management Server** install the Microsoft agent for Windows.",
- "title": "1. Configure Semperis DSP Management Server to send Windows event logs to your Microsoft Sentinel Workspace"
+ "description": "Collect Windows security events logs from your **Semperis DSP Management Server** .",
+ "title": "**Configure Windows Security Events via AMA connector**"
+ },
+ {
+ "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": "1. Install the Azure Monitor Agent (AMA)"
},
{
- "description": "You can skip this step if you have already installed the Microsoft agent for Windows",
+ "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": {
@@ -1762,22 +1947,48 @@
"type": "InstructionStepsGroup"
}
],
- "title": "2. Install and onboard the Microsoft agent for Windows"
+ "title": "2. Create a Data Collection Rule (DCR)"
+ },
+ {
+ "description": "Collect syslog messages send from your **Semperis DSP Management Server** .",
+ "title": "**Configure Common Event Format via AMA connector**"
+ },
+ {
+ "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": "1. Install the Azure Monitor Agent (AMA)"
},
{
- "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**",
+ "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 the Semperis DSP Windows event logs to be collected by the agent"
+ "title": "2. Create a Data Collection Rule (DCR)"
+ },
+ {
+ "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": "3. Configure sending CEF logs on your Semperis DSP Management Server"
},
{
- "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."
}
],
"id": "[variables('_uiConfigId1')]",
@@ -1786,13 +1997,20 @@
}
},
{
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
+ "apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "2.0.5",
+ "version": "3.0.0",
"kind": "Solution",
- "contentSchemaVersion": "2.0.0",
+ "contentSchemaVersion": "3.0.0",
+ "displayName": "Semperis Directory Services Protector",
+ "publisherDisplayName": "Semperis",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Semperis Directory Services Protector solution provides the capability to ingest Windows event logs (i.e., Indicators of Exposure and Indicators of Compromise) into Microsoft Sentinel.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\n- Agent based logs collection from Windows and Linux machines
\n
\nData Connectors: 1, Parsers: 1, Workbooks: 4, Analytic Rules: 8
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "contentKind": "Solution",
+ "contentProductId": "[variables('_solutioncontentProductId')]",
+ "id": "[variables('_solutioncontentProductId')]",
+ "icon": "
",
"contentId": "[variables('_solutionId')]",
"parentId": "[variables('_solutionId')]",
"source": {
@@ -1833,48 +2051,48 @@
},
{
"kind": "Parser",
- "contentId": "[variables('_parserContentId1')]",
- "version": "[variables('parserVersion1')]"
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "version": "[variables('parserObject1').parserVersion1]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId1')]",
- "version": "[variables('analyticRuleVersion1')]"
+ "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
+ "version": "[variables('analyticRuleObject1').analyticRuleVersion1]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId2')]",
- "version": "[variables('analyticRuleVersion2')]"
+ "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
+ "version": "[variables('analyticRuleObject2').analyticRuleVersion2]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId3')]",
- "version": "[variables('analyticRuleVersion3')]"
+ "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
+ "version": "[variables('analyticRuleObject3').analyticRuleVersion3]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId4')]",
- "version": "[variables('analyticRuleVersion4')]"
+ "contentId": "[variables('analyticRuleObject4')._analyticRulecontentId4]",
+ "version": "[variables('analyticRuleObject4').analyticRuleVersion4]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId5')]",
- "version": "[variables('analyticRuleVersion5')]"
+ "contentId": "[variables('analyticRuleObject5')._analyticRulecontentId5]",
+ "version": "[variables('analyticRuleObject5').analyticRuleVersion5]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId6')]",
- "version": "[variables('analyticRuleVersion6')]"
+ "contentId": "[variables('analyticRuleObject6')._analyticRulecontentId6]",
+ "version": "[variables('analyticRuleObject6').analyticRuleVersion6]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId7')]",
- "version": "[variables('analyticRuleVersion7')]"
+ "contentId": "[variables('analyticRuleObject7')._analyticRulecontentId7]",
+ "version": "[variables('analyticRuleObject7').analyticRuleVersion7]"
},
{
"kind": "AnalyticsRule",
- "contentId": "[variables('analyticRulecontentId8')]",
- "version": "[variables('analyticRuleVersion8')]"
+ "contentId": "[variables('analyticRuleObject8')._analyticRulecontentId8]",
+ "version": "[variables('analyticRuleObject8').analyticRuleVersion8]"
},
{
"kind": "DataConnector",
diff --git a/Solutions/Semperis Directory Services Protector/Package/testParameters.json b/Solutions/Semperis Directory Services Protector/Package/testParameters.json
new file mode 100644
index 00000000000..7275f20ea9a
--- /dev/null
+++ b/Solutions/Semperis Directory Services Protector/Package/testParameters.json
@@ -0,0 +1,56 @@
+{
+ "location": {
+ "type": "string",
+ "minLength": 1,
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
+ }
+ },
+ "workspace-location": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
+ }
+ },
+ "workspace": {
+ "defaultValue": "",
+ "type": "string",
+ "metadata": {
+ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
+ }
+ },
+ "workbook1-name": {
+ "type": "string",
+ "defaultValue": "Semperis DSP AD Changes",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook2-name": {
+ "type": "string",
+ "defaultValue": "Semperis DSP Notifications",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook3-name": {
+ "type": "string",
+ "defaultValue": "Semperis DSP Quickview Dashboard",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ },
+ "workbook4-name": {
+ "type": "string",
+ "defaultValue": "Semperis DSP Security Indicators",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name for the workbook"
+ }
+ }
+}
diff --git a/Solutions/Semperis Directory Services Protector/Parsers/dsp_parser.yaml b/Solutions/Semperis Directory Services Protector/Parsers/dsp_parser.yaml
index dafb73e4ee3..040fbceddee 100644
--- a/Solutions/Semperis Directory Services Protector/Parsers/dsp_parser.yaml
+++ b/Solutions/Semperis Directory Services Protector/Parsers/dsp_parser.yaml
@@ -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
- '' DSPData ''
+ '' DSPData ''
| parse DSPData with
*
'' FirstFound ''
*
| parse DSPData with
- '' GenerationTime ''
- '' SecurityIndicatorName ''
- '' Result ''
*
- '' Score ''
- '' ForestName ''
- '' Domains ''
- '' Severity ''
- '' Weight ''
- '' SecurityFrameworkTags ''
- '' SecurityIndicatorDescription ''
- '' LikelihoodOfCompromise ''
- '' ResultMessage ''
- '' NumberOfResults ''
- '' Remediation ''
- '' Schedule ''
- *
+ '' GenerationTime '' *
+ '' SecurityIndicatorName '' *
+ '' Result '' *
+ '' Score '' *
+ '' ForestName '' *
+ '' Domains '' *
+ '' Severity '' *
+ '' Weight '' *
+ '' SecurityFrameworkTags '' *
+ '' SecurityIndicatorDescription '' *
+ '' LikelihoodOfCompromise '' *
+ '' ResultMessage '' *
+ '' NumberOfResults '' *
+ '' Remediation '' *
+ '' Schedule ''
+ *
| extend SecurityFrameworkTagsCsv = replace(@' Mitre:', @'', tostring(SecurityFrameworkTags))
| extend SecurityFrameworkTagsCsv = replace(@'Mitre:', @'', tostring(SecurityFrameworkTagsCsv))
- | extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))
\ No newline at end of file
+ | extend SecurityFrameworkTags = replace(@'Mitre:', @'', tostring(SecurityFrameworkTags))
+ | extend GenerationTimeTags = tostring(DSPData)
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPNotifications.json b/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPNotifications.json
index e0cc38344b2..8016d31611d 100644
--- a/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPNotifications.json
+++ b/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPNotifications.json
@@ -82,7 +82,6 @@
"name": "Severity",
"type": 2,
"typeSettings": {
- "additionalResourceOptions": [],
"showDefault": false
},
"jsonData": "[\r\n { \"value\":\"Critical\", \"label\":\"Critical\" },\r\n { \"value\":\"Warning\" , \"label\":\"Warning\" },\r\n { \"value\":\"Informational\" , \"label\":\"Informational\" }\r\n]",
@@ -102,7 +101,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\r\n| where Source == 'Semperis-DSP-Notifications' \r\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\r\n| mv-expand bagexpansion=array p1Xml\r\n| evaluate bag_unpack(p1Xml)\r\n| extend Key1=tostring(['@Name']), Value=['#text']\r\n| evaluate pivot(Key1, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\r\n| where (isempty('{Time}') or (todatetime(timeCreated) >= todatetime('{Time:startISO}') and todatetime(timeCreated) <= todatetime('{Time:endISO}'))) and ((isempty('{RuleName}') or indexof(ruleName,'{RuleName}') > -1)) and ((isempty('{Severity}') or severity == '{Severity}'))\r\n| order by TimeGenerated desc\r\n| project ruleName, fullOperation\r\n",
+ "query": "SecurityEvent\r\n| where EventSourceName == 'Semperis-DSP-Notifications' \r\n| extend p1Xml = parse_xml(EventData).EventData.Data\r\n| mv-expand bagexpansion=array p1Xml\r\n| evaluate bag_unpack(p1Xml)\r\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\r\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\r\n| where (isempty('{Time}') or (todatetime(timeCreated) >= todatetime('{Time:startISO}') and todatetime(timeCreated) <= todatetime('{Time:endISO}'))) and ((isempty('{RuleName}') or indexof(ruleName,'{RuleName}') > -1)) and ((isempty('{Severity}') or severity == '{Severity}'))\r\n| order by TimeGenerated desc\r\n| project ruleName, severity, Computer, objectDN, timeCreated, fullOperation, attributeName, attributeValue, changedBy, originatingServerName\r\n",
"size": 0,
"title": "Notifications",
"queryType": 0,
diff --git a/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPQuickviewDashboard.json b/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPQuickviewDashboard.json
index 505049e3f9c..0ec753cd6d8 100644
--- a/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPQuickviewDashboard.json
+++ b/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPQuickviewDashboard.json
@@ -5,7 +5,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "let day_names =dynamic([\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);\nlet averageData = view() { CommonSecurityLog \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > datetime(2000-01-01)\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Average Daily Change\"\n| order by Day asc};\nlet weeklyData = view() { CommonSecurityLog \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > startofweek(now())\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Daily Change\"\n| order by Day asc };\nunion withsource=TableName averageData,weeklyData\n| order by Day asc, SortData asc\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\n| render barchart with (kind=unstacked)\n\n",
+ "query": "let day_names =dynamic([\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);\nlet averageData = view() { CommonSecurityLog \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > datetime(2000-01-01)\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Average Daily Change\"\n| order by Day asc};\nlet weeklyData = view() { CommonSecurityLog \n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| where TimeGenerated > startofweek(now())\n| where isnotnull(OriginatingUsers) and OriginatingUsers != \"\"\n| summarize Count=count() by Year=getyear(TimeGenerated), Month=monthofyear(TimeGenerated), Day=dayofmonth(TimeGenerated)\n| summarize Average_Count=toint(avg(Count)) by Day=dayofweek(make_datetime(Year,Month,Day)), SortData=\"Daily Change\"\n| order by Day asc };\nunion withsource=TableName averageData,weeklyData\n| order by Day asc, SortData asc\n| project Average_Count,Day,TableName,SortData,Days=tostring(day_names[indexof('00010203040506', format_timespan(Day,'dd'))/2])\n| render barchart with (kind=unstacked)\n\n",
"size": 0,
"title": "Weekly Active Directory Change Count",
"queryType": 0,
@@ -49,7 +49,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-Operation-Log' and EventID == 20000\n| sort by TimeGenerated desc \n| parse RenderedDescription with \"Operation: \" Operation \"Access Granted:\" AccessGranted \"Result: \" Result \"Details: \" * \"Trustee Name: \" TrusteeName \" Correlation ID: \" * \" Source: \" HostIP \"WebSite Target\" *\n| extend host = tostring(HostIP)\n| extend HostIP = trim_end(\":\",HostIP)\n| project TimeGenerated, UserName, HostIP\n| order by TimeGenerated desc\n| top 10 by TimeGenerated",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20000\n| sort by TimeGenerated desc \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend details = column_ifexists('details', '')\n| parse details with * \"Trustee Name: \" TrusteeName \" Correlation ID: \" * \" Source: \" HostIP \":\" * \" Target\" *\n| extend host = tostring(HostIP)\n| project TimeGenerated, TrusteeName, HostIP\n| order by TimeGenerated desc\n| top 10 by TimeGenerated",
"size": 1,
"title": "Successful Logons",
"queryType": 0,
@@ -59,14 +59,6 @@
{
"columnId": "TimeGenerated",
"label": "Time Generated"
- },
- {
- "columnId": "UserName",
- "label": "Identity"
- },
- {
- "columnId": "HostIP",
- "label": "Host IP"
}
]
}
@@ -81,7 +73,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-Operation-Log' and ( EventID == 20000 or EventID == 20002 )\n| sort by TimeGenerated desc \n| parse RenderedDescription with \"Operation: \" Operation \"Access Granted:\" AccessGranted \"Result: \" Result \"Details: \" * \"Trustee Name: \" TrusteeName \" Correlation ID: \" * \" Source: \" HostIP \"WebSite Target\" *\n| extend host = tostring(HostIP)\n| extend HostIP = trim_end(\":\",HostIP)\n| where isnotempty(AccessGranted)\n| summarize Count=count() by AccessGranted\n\n\n\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-Operation-Log' and ( EventID == 20000 or EventID == 20002 )\n| sort by TimeGenerated desc \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend details = column_ifexists('details', ''), accessGrated = column_ifexists('accessGrated', '')\n| parse details with * \"Trustee Name: \" TrusteeName \" Correlation ID: \" * \" Source: \" HostIP \":\" * \" Target\" *\n| extend host = tostring(HostIP)\n| where isnotempty(accessGrated)\n| summarize Count=count() by accessGrated\n",
"size": 1,
"title": "DSP Logins",
"queryType": 0,
@@ -114,7 +106,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\r\n| where Source == 'Semperis-DSP-Notifications' \r\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\r\n| mv-expand bagexpansion=array p1Xml\r\n| evaluate bag_unpack(p1Xml)\r\n| extend Key1=tostring(['@Name']), Value=['#text']\r\n| evaluate pivot(Key1, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\r\n| order by TimeGenerated desc\r\n| project ruleName, fullOperation\r\n",
+ "query": "SecurityEvent\r\n| where EventSourceName == 'Semperis-DSP-Notifications' \r\n| extend p1Xml = parse_xml(EventData).EventData.Data\r\n| mv-expand bagexpansion=array p1Xml\r\n| evaluate bag_unpack(p1Xml)\r\n| extend Name=tostring(['@Name']), Value=['#text']\r\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\r\n| order by TimeGenerated desc\r\n| project ruleName, severity, fullOperation, attributeName, attributeValue, changedBy, originatingServerName\r\n",
"size": 0,
"title": "Notifications",
"queryType": 0,
@@ -144,13 +136,19 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-Operation-Log' and EventID == 20012\n| sort by TimeGenerated desc\n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=tostring(['@Name']), Value=['#text']\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| parse details 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\n| extend _AccessGranted = iif(operationName contains \"CreateRbacIdentity\", \"Added\", \"Removed\")\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", trustee, tostring(substring(trustee,1,strlen(trustee))))\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", _Identity, replace_string(_Identity,\"'\",\"\"))\n| extend add_personas = replace_string(replace_string(replace_string(personas,\"{ Name = \",\"\"),\" }\",\"\"),\";\",\",\")\n| extend remove_personas = replace_string(personas,\";\",\",\")\n| extend grid_personas = iif(operationName contains \"CreateRbacIdentity\", add_personas, remove_personas)\n| extend date_to_sort = format_datetime(TimeGenerated,\"yyyy-mm-dd HH:mm:ss\")\n| order by date_to_sort desc\n| project TrusteeName, _Identity, _AccessGranted, grid_personas, TimeGenerated\n\n\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20012\n| sort by TimeGenerated desc\n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend details=column_ifexists(tostring('details'), '')\n| parse details 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\n| where isnotempty(operationName)\n| extend _AccessGranted = iif(operationName contains \"CreateRbacIdentity\", \"Added\", \"Removed\")\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", trustee, tostring(substring(trustee,1,strlen(trustee))))\n| extend _Identity = iif(operationName contains \"CreateRbacIdentity\", _Identity, replace_string(_Identity,\"'\",\"\"))\n| extend add_personas = replace_string(replace_string(replace_string(personas,\"{ Name = \",\"\"),\" }\",\"\"),\";\",\",\")\n| extend remove_personas = replace_string(personas,\";\",\",\")\n| extend grid_personas = iif(operationName contains \"CreateRbacIdentity\", add_personas, remove_personas)\n| extend date_to_sort = format_datetime(TimeGenerated,\"yyyy-mm-dd HH:mm:ss\")\n| order by date_to_sort desc\n| project TrusteeName, _Identity, _AccessGranted, grid_personas, TimeGenerated\n\n\n",
"size": 1,
"title": "Role Based Access Control Changes",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces",
"visualization": "table",
"gridSettings": {
+ "sortBy": [
+ {
+ "itemKey": "TrusteeName",
+ "sortOrder": 2
+ }
+ ],
"labelSettings": [
{
"columnId": "TrusteeName",
@@ -164,17 +162,18 @@
"columnId": "_AccessGranted",
"label": "Access Granted"
},
- {
- "columnId": "grid_personas",
- "label": "Persona Details"
- },
{
"columnId": "TimeGenerated",
"label": "Timestamp"
}
]
},
- "sortBy": []
+ "sortBy": [
+ {
+ "itemKey": "TrusteeName",
+ "sortOrder": 2
+ }
+ ]
},
"customWidth": "50",
"name": "query - 2",
@@ -264,7 +263,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "CommonSecurityLog\n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| parse DistinguishedName with * \"CN\\\\=\" cnName \",\" *\n| parse DistinguishedName with * \"DC\\\\=\" dcName \",\" *\n| where ClassName != \"dnsNode\"\n| summarize ChangedCount=count() by cnName\n| project cnName, ChangedCount, \"Details\"\n| order by ChangedCount desc\n| top 5 by ChangedCount\n",
+ "query": "CommonSecurityLog\n| extend p1Array = split(AdditionalExtensions,\";\")\n| mv-expand bagexpansion=array p1Array\n| evaluate bag_unpack(p1Array)\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\n| evaluate pivot(Name, any(Value), TimeGenerated, TenantId, DeviceVendor, DeviceProduct, DeviceVersion, DeviceEventClassID, Activity, LogSeverity, OriginalLogSeverity, DeviceAction)\n| extend DistinguishedName = column_ifexists('DistinguishedName', '')\n| where isnotempty(DistinguishedName)\n| parse DistinguishedName with * \"CN=\" cnName \",\" *\n| parse DistinguishedName with * \"DC=\" dcName \",\" *\n| where ClassName != \"dnsNode\"\n| summarize ChangedCount=count() by cnName\n| project cnName, ChangedCount, \"Details\"\n| order by ChangedCount desc\n| top 5 by ChangedCount\n",
"size": 3,
"title": "Top 5 Objects Changed",
"queryType": 0,
@@ -313,7 +312,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-DSP-Notifications' \n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=tostring(['@Name']), Value=['#text']\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| summarize Count=count() by tostring(fullOperation)\n\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-DSP-Notifications' \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Key1=tostring(['@Name']), Value=['#text']\n| evaluate pivot(Key1, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| summarize Count=count() by tostring(fullOperation)\n\n",
"size": 1,
"title": "AD Change Types",
"queryType": 0,
@@ -413,7 +412,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-DSP-Security' \n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=tostring(['@Name']), Value=['#text']\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| extend isProblem = iif(result == \"Failed\", true, false)\n| where isnotnull(numberOfResults) and isProblem == true\n| order by tostring(securityIndicatorName)\n| summarize Count=count() by tostring(securityIndicatorName)\n| top 5 by Count\n\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-DSP-Notifications' \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend result=column_ifexists(tostring('result'), ''), numberOfResults=column_ifexists(tostring('numberOfResults'), ''), securityIndicatorName=column_ifexists(tostring('securityIndicatorName'), '')\n| extend isProblem = iif(result == \"Failed\", true, false)\n| where isnotnull(numberOfResults) and isProblem == true\n| order by tostring(securityIndicatorName)\n| summarize Count=count() by tostring(securityIndicatorName)\n| top 5 by Count\n\n",
"size": 1,
"title": "Top 5 Failed Security Indicators",
"queryType": 0,
@@ -439,7 +438,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-DSP-Security' \n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=tostring(['@Name']), Value=['#text']\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| extend isProblem = iif(result == \"Failed\", true, false)\n| where isnotnull(numberOfResults) and isProblem == true\n| order by tostring(securityIndicatorName)\n| summarize Count=count() by tostring(securityIndicatorName)\n| top 5 by Count\n\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-DSP-Notifications' \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend result=column_ifexists(tostring('result'), ''), numberOfResults=column_ifexists(tostring('numberOfResults'), ''), securityIndicatorName=column_ifexists(tostring('securityIndicatorName'), '')\n| extend isProblem = iif(result == \"Failed\", true, false)\n| where isnotnull(numberOfResults) and isProblem == true\n| order by tostring(securityIndicatorName)\n| summarize Count=count() by tostring(securityIndicatorName)\n| top 5 by Count\n\n",
"size": 1,
"title": "Top 5 Failed Security Indicators",
"queryType": 0,
@@ -465,7 +464,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "Event\n| where Source == 'Semperis-DSP-Security' \n| extend p1Xml = parse_xml(EventData).DataItem.EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=tostring(['@Name']), Value=['#text']\n| evaluate pivot(Name, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, EventCategory, UserName, Type, _ResourceId)\n| extend isProblem = iif(result == \"Failed\", true, false)\n| where isnotnull(numberOfResults) and isProblem == true\n| summarize Count=count() by tostring(securityFrameworkTags)\n\n",
+ "query": "SecurityEvent\n| where EventSourceName == 'Semperis-DSP-Notifications' \n| extend p1Xml = parse_xml(EventData).EventData.Data\n| mv-expand bagexpansion=array p1Xml\n| evaluate bag_unpack(p1Xml)\n| extend Name=column_ifexists(tostring('@Name'), ''), Value=column_ifexists('#text', '')\n| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)\n| extend result=column_ifexists(tostring('result'), ''), numberOfResults=column_ifexists(tostring('numberOfResults'), ''), securityFrameworkTags=column_ifexists(tostring('securityFrameworkTags'), '')\n| extend isProblem = iif(result == \"Failed\", true, false)\n| where isnotnull(numberOfResults) and isProblem == true\n| summarize Count=count() by tostring(securityFrameworkTags)\n\n",
"size": 0,
"title": "Amount of Generated Events per Category",
"timeContext": {
@@ -487,11 +486,10 @@
"name": "query - 2"
}
],
- "fallbackResourceIds": [],
"styleSettings": {
"paddingStyle": "wide",
"spacingStyle": "wide"
},
"fromTemplateId": "sentinel-SemperisDSPQuickviewDashboard",
"$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
-}
+}
\ No newline at end of file
diff --git a/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPSecurityIndicators.json b/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPSecurityIndicators.json
index 89aef527d5f..6a9eefe2005 100644
--- a/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPSecurityIndicators.json
+++ b/Solutions/Semperis Directory Services Protector/Workbooks/SemperisDSPSecurityIndicators.json
@@ -29,7 +29,7 @@
"description": " Specify the time range on which to query the data",
"isRequired": true,
"value": {
- "durationMs": 604800000
+ "durationMs": 1209600000
},
"typeSettings": {
"selectableValues": [
@@ -108,7 +108,10 @@
"timeContextFromParameter": "TimeRange",
"defaultValue": "value::all",
"queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces"
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "value": [
+ "value::all"
+ ]
},
{
"id": "cf84c455-c1b9-4785-a592-54834be54097",
@@ -143,57 +146,6 @@
},
"name": "parameters - 3"
},
- {
- "type": 3,
- "content": {
- "version": "KqlItem/1.0",
- "query": "dsp_parser\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| mv-expand bagexpansion=array SecurityFrameworkTagList to typeof(string)\r\n| where SecurityFrameworkTagList in ({MitreFramework})\r\n| summarize event_count=count() by SecurityFrameworkTagList\r\n",
- "size": 0,
- "title": "Amount of Generated Events per Category",
- "timeContextFromParameter": "TimeRange",
- "queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "visualization": "barchart",
- "graphSettings": {
- "type": 0,
- "topContent": {
- "columnMatch": "securityFrameworkTags",
- "formatter": 1
- },
- "centerContent": {
- "columnMatch": "event_count",
- "formatter": 1,
- "numberFormat": {
- "unit": 17,
- "options": {
- "maximumSignificantDigits": 3,
- "maximumFractionDigits": 2
- }
- }
- }
- },
- "chartSettings": {
- "createOtherGroup": null
- },
- "mapSettings": {
- "locInfo": "LatLong",
- "sizeSettings": "event_count",
- "sizeAggregation": "Sum",
- "legendMetric": "event_count",
- "legendAggregation": "Sum",
- "itemColorSettings": {
- "type": "heatmap",
- "colorAggregation": "Sum",
- "nodeColorField": "event_count",
- "heatmapPalette": "greenRed"
- }
- }
- },
- "name": "query - 5",
- "styleSettings": {
- "showBorder": true
- }
- },
{
"type": 12,
"content": {
@@ -204,58 +156,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "dsp_parser\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Requests = count() by tostring(SecurityIndicatorName)\r\n| order by Requests\r\n",
- "size": 3,
- "title": "Breakdown by Indicators of Exposure (IoEs)",
- "noDataMessageStyle": 4,
- "timeContextFromParameter": "TimeRange",
- "queryType": 0,
- "resourceType": "microsoft.operationalinsights/workspaces",
- "visualization": "tiles",
- "tileSettings": {
- "titleContent": {
- "columnMatch": "SecurityIndicatorName",
- "formatter": 1
- },
- "subtitleContent": {
- "columnMatch": "Requests",
- "formatter": 12,
- "formatOptions": {
- "palette": "auto"
- }
- },
- "showBorder": false,
- "size": "auto"
- },
- "chartSettings": {
- "group": "securityIndicatorName",
- "createOtherGroup": 10,
- "showMetrics": false
- },
- "mapSettings": {
- "locInfo": "LatLong",
- "sizeSettings": "Requests",
- "sizeAggregation": "Sum",
- "legendMetric": "Requests",
- "legendAggregation": "Sum",
- "itemColorSettings": {
- "type": "heatmap",
- "colorAggregation": "Sum",
- "nodeColorField": "Requests",
- "heatmapPalette": "greenRed"
- }
- }
- },
- "name": "query - 2",
- "styleSettings": {
- "showBorder": true
- }
- },
- {
- "type": 3,
- "content": {
- "version": "KqlItem/1.0",
- "query": "dsp_parser\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Count = count() by tostring(SecurityFrameworkTags), tostring(SecurityIndicatorName), tostring(SecurityIndicatorDescription), tostring(LikelihoodOfCompromise), tostring(Remediation), tostring(Result), tostring(FirstFound), tostring(Score)\r\n| order by Count\r\n",
+ "query": "dsp_parser_new\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| union (CommonSecurityLog \r\n| extend p1Array = split(AdditionalExtensions,\"|\")\r\n| mv-expand bagexpansion=array p1Array\r\n| evaluate bag_unpack(p1Array)\r\n| extend Name=tostring(split(p1Array,\"=\")[0]),Value=substring(p1Array,indexof(p1Array,\"=\")+1)\r\n| evaluate pivot(Name, any(Value), Activity, LogSeverity)\r\n| extend Activity = column_ifexists('Activity', '')\r\n| extend SecurityIndicatorName = Activity\r\n| extend LogSeverity = column_ifexists('LogSeverity', '')\r\n| extend Severity = LogSeverity\r\n| extend Score = \"0 F\"\r\n| extend Result = \"\"\r\n| extend Timestamp = column_ifexists('Timestamp', '')\r\n| extend FirstFound = Timestamp\r\n| extend SecurityFrameworkTags = column_ifexists('SecurityFrameworkTags', ''))\r\n| where isnotempty(SecurityFrameworkTags) \r\n| summarize Count = count() by tostring(SecurityIndicatorName), tostring(Severity), tostring(Score), tostring(FirstFound), tostring(Result), tostring(SecurityFrameworkTags)\r\n| order by Count\r\n",
"size": 0,
"title": "Indicators of Exposure (IoEs) Details:",
"timeContextFromParameter": "TimeRange",
@@ -266,36 +167,24 @@
"gridSettings": {
"sortBy": [
{
- "itemKey": "SecurityFrameworkTags",
+ "itemKey": "Severity",
"sortOrder": 1
}
],
"labelSettings": [
{
- "columnId": "SecurityFrameworkTags",
- "label": "MITRE ATT&CK Framework"
- },
- {
- "columnId": "SecurityIndicatorName",
- "label": "Indicator of Exposure"
- },
- {
- "columnId": "SecurityIndicatorDescription",
- "label": "Description"
- },
- {
- "columnId": "LikelihoodOfCompromise",
- "label": "Likelihood of Compromise"
+ "columnId": "FirstFound",
+ "label": "Latest alert"
},
{
- "columnId": "FirstFound",
- "label": "First Time Found"
+ "columnId": "SecurityFrameworkTags",
+ "label": "Security framework tags"
}
]
},
"sortBy": [
{
- "itemKey": "SecurityFrameworkTags",
+ "itemKey": "Severity",
"sortOrder": 1
}
],
@@ -325,11 +214,110 @@
"styleSettings": {
"showBorder": true
}
+ },
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "dsp_parser_new\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Requests = count() by tostring(SecurityIndicatorName)\r\n| order by Requests\r\n",
+ "size": 3,
+ "title": "Breakdown by Indicators of Exposure (IoEs)",
+ "noDataMessageStyle": 4,
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "tiles",
+ "tileSettings": {
+ "titleContent": {
+ "columnMatch": "SecurityIndicatorName",
+ "formatter": 1
+ },
+ "subtitleContent": {
+ "columnMatch": "Requests",
+ "formatter": 12,
+ "formatOptions": {
+ "palette": "auto"
+ }
+ },
+ "showBorder": false,
+ "size": "auto"
+ },
+ "chartSettings": {
+ "group": "securityIndicatorName",
+ "createOtherGroup": 10,
+ "showMetrics": false
+ },
+ "mapSettings": {
+ "locInfo": "LatLong",
+ "sizeSettings": "Requests",
+ "sizeAggregation": "Sum",
+ "legendMetric": "Requests",
+ "legendAggregation": "Sum",
+ "itemColorSettings": {
+ "type": "heatmap",
+ "colorAggregation": "Sum",
+ "nodeColorField": "Requests",
+ "heatmapPalette": "greenRed"
+ }
+ }
+ },
+ "name": "query - 2",
+ "styleSettings": {
+ "showBorder": true
+ }
}
]
},
"name": "group - 6"
},
+ {
+ "type": 3,
+ "content": {
+ "version": "KqlItem/1.0",
+ "query": "dsp_parser_new\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| mv-expand bagexpansion=array SecurityFrameworkTagList to typeof(string)\r\n| where SecurityFrameworkTagList in ({MitreFramework})\r\n| summarize event_count=count() by SecurityFrameworkTagList\r\n",
+ "size": 0,
+ "title": "Amount of Generated Events per Category",
+ "timeContextFromParameter": "TimeRange",
+ "queryType": 0,
+ "resourceType": "microsoft.operationalinsights/workspaces",
+ "visualization": "barchart",
+ "graphSettings": {
+ "type": 0,
+ "topContent": {
+ "columnMatch": "securityFrameworkTags",
+ "formatter": 1
+ },
+ "centerContent": {
+ "columnMatch": "event_count",
+ "formatter": 1,
+ "numberFormat": {
+ "unit": 17,
+ "options": {
+ "maximumSignificantDigits": 3,
+ "maximumFractionDigits": 2
+ }
+ }
+ }
+ },
+ "mapSettings": {
+ "locInfo": "LatLong",
+ "sizeSettings": "event_count",
+ "sizeAggregation": "Sum",
+ "legendMetric": "event_count",
+ "legendAggregation": "Sum",
+ "itemColorSettings": {
+ "type": "heatmap",
+ "colorAggregation": "Sum",
+ "nodeColorField": "event_count",
+ "heatmapPalette": "greenRed"
+ }
+ }
+ },
+ "name": "query - 5",
+ "styleSettings": {
+ "showBorder": true
+ }
+ },
{
"type": 12,
"content": {
@@ -340,14 +328,13 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "dsp_parser\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Count = count() by tostring(SecurityIndicatorName)\r\n| top 10 by Count desc",
+ "query": "dsp_parser_new\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Count = count() by tostring(SecurityIndicatorName)\r\n| top 10 by Count desc",
"size": 3,
"title": "Top 10 Indicators of Exposure (IoEs)",
"timeContextFromParameter": "TimeRange",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces",
"visualization": "piechart",
- "sortBy": [],
"chartSettings": {
"group": "SecurityIndicatorName",
"createOtherGroup": 10,
@@ -374,7 +361,7 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
- "query": "dsp_parser\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Count = count() by tostring(SecurityFrameworkTags), tostring(SecurityIndicatorName), tostring(FirstFound), tostring(Remediation)\r\n| top 10 by Count desc\r\n| project-away Count",
+ "query": "dsp_parser_new\r\n| where isnotempty(SecurityFrameworkTags) \r\n| where Result in ({Status})\r\n| extend SecurityFrameworkTagList = parse_csv(SecurityFrameworkTagsCsv)\r\n| extend MitreFramework = pack_array({MitreFramework})\r\n| extend FilterIntersection = set_intersect(SecurityFrameworkTagList, MitreFramework)\r\n| extend FilterIntersectionCount = array_length(FilterIntersection)\r\n| where FilterIntersectionCount > 0\r\n| summarize Count = count() by tostring(SecurityFrameworkTags), tostring(SecurityIndicatorName), tostring(Remediation)\r\n| top 10 by Count desc\r\n| project-away Count",
"size": 0,
"title": "Top 10 Indicators of Exposure (IoEs) Details:",
"timeContextFromParameter": "TimeRange",
diff --git a/Solutions/Semperis Directory Services Protector/Workbooks/workbooksMetadata.json b/Solutions/Semperis Directory Services Protector/Workbooks/workbooksMetadata.json
index 7c5b8863c6b..032c0817a7d 100644
--- a/Solutions/Semperis Directory Services Protector/Workbooks/workbooksMetadata.json
+++ b/Solutions/Semperis Directory Services Protector/Workbooks/workbooksMetadata.json
@@ -16,9 +16,16 @@
"workbookKey": "SemperisDSPNotificationsWorkbook",
"logoFileName": "Semperis.svg",
"description": "View notification data related to the Semperis DSP system.",
- "dataTypesDependencies": [ "Event" ],
- "dataConnectorsDependencies": [ "SemperisDSP-connector" ],
- "previewImagesFileNames": [ "notifications-black.png", "notifications-white.png" ],
+ "dataTypesDependencies": [
+ "Event"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "notifications-black.png",
+ "notifications-white.png"
+ ],
"version": "1.0.0",
"title": "Semperis DSP Notifications",
"templateRelativePath": "SemperisDSPNotifications.json",
@@ -29,9 +36,16 @@
"workbookKey": "SemperisDSPQuickviewDashboardWorkbook",
"logoFileName": "Semperis.svg",
"description": "View data related to the Semperis DSP system.",
- "dataTypesDependencies": [ "Event" ],
- "dataConnectorsDependencies": [ "SemperisDSP-connector" ],
- "previewImagesFileNames": [ "quickview-black.png", "quickview-white.png" ],
+ "dataTypesDependencies": [
+ "Event"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "quickview-black.png",
+ "quickview-white.png"
+ ],
"version": "1.0.0",
"title": "Semperis DSP Quickview Dashboard",
"templateRelativePath": "SemperisDSPQuickviewDashboard.json",
@@ -42,9 +56,16 @@
"workbookKey": "SemperisDSPSecurityIndicatorsWorkbook",
"logoFileName": "Semperis.svg",
"description": "View security indicator data related to the Semperis DSP system.",
- "dataTypesDependencies": [ "dsp_parser" ],
- "dataConnectorsDependencies": [ "SemperisDSP-connector" ],
- "previewImagesFileNames": [ "indicators-black.png", "indicators-white.png" ],
+ "dataTypesDependencies": [
+ "dsp_parser"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "indicators-black.png",
+ "indicators-white.png"
+ ],
"version": "1.0.0",
"title": "Semperis DSP Security Indicators",
"templateRelativePath": "SemperisDSPSecurityIndicators.json",
diff --git a/Solutions/SentinelOne/Data Connectors/SentinelOne_ccp/connectorDefinition.json b/Solutions/SentinelOne/Data Connectors/SentinelOne_ccp/connectorDefinition.json
index d8008a62274..f07f9667945 100644
--- a/Solutions/SentinelOne/Data Connectors/SentinelOne_ccp/connectorDefinition.json
+++ b/Solutions/SentinelOne/Data Connectors/SentinelOne_ccp/connectorDefinition.json
@@ -6,7 +6,7 @@
"properties": {
"connectorUiConfig": {
"id": "SentinelOneCCP",
- "title": "SentinelOne (Preview)",
+ "title": "SentinelOne",
"publisher": "Microsoft",
"descriptionMarkdown": "The [SentinelOne](https://usea1-nessat.sentinelone.net/api-doc/overview) data connector allows ingesting logs from the SentinelOne API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the SentinelOne API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
diff --git a/Solutions/SentinelOne/Package/3.0.6.zip b/Solutions/SentinelOne/Package/3.0.6.zip
new file mode 100644
index 00000000000..0a9034cbbc5
Binary files /dev/null and b/Solutions/SentinelOne/Package/3.0.6.zip differ
diff --git a/Solutions/SentinelOne/Package/mainTemplate.json b/Solutions/SentinelOne/Package/mainTemplate.json
index 0b20e2e2637..df45fa48f89 100644
--- a/Solutions/SentinelOne/Package/mainTemplate.json
+++ b/Solutions/SentinelOne/Package/mainTemplate.json
@@ -55,7 +55,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "SentinelOne",
- "_solutionVersion": "3.0.5",
+ "_solutionVersion": "3.0.6",
"solutionId": "azuresentinel.azure-sentinel-solution-sentinelone",
"_solutionId": "[variables('solutionId')]",
"workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
@@ -227,7 +227,7 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnectorDefinition1')]",
- "displayName": "SentinelOne (Preview)",
+ "displayName": "SentinelOne",
"contentKind": "DataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -244,7 +244,7 @@
"properties": {
"connectorUiConfig": {
"id": "SentinelOneCCP",
- "title": "SentinelOne (Preview)",
+ "title": "SentinelOne",
"publisher": "Microsoft",
"descriptionMarkdown": "The [SentinelOne](https://usea1-nessat.sentinelone.net/api-doc/overview) data connector allows ingesting logs from the SentinelOne API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the SentinelOne API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
@@ -320,7 +320,8 @@
],
"connectivityCriteria": [
{
- "type": "HasDataConnectors"
+ "type": "HasDataConnectors",
+ "value": null
}
],
"availability": {
@@ -2033,7 +2034,7 @@
"properties": {
"connectorUiConfig": {
"id": "SentinelOneCCP",
- "title": "SentinelOne (Preview)",
+ "title": "SentinelOne",
"publisher": "Microsoft",
"descriptionMarkdown": "The [SentinelOne](https://usea1-nessat.sentinelone.net/api-doc/overview) data connector allows ingesting logs from the SentinelOne API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the SentinelOne API to fetch logs and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
"graphQueries": [
@@ -2230,14 +2231,14 @@
],
"properties": {
"contentId": "[variables('_dataConnectorContentIdConnections1')]",
- "displayName": "SentinelOne (Preview)",
+ "displayName": "SentinelOne",
"contentKind": "ResourcesDataConnector",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorCCPVersion')]",
"parameters": {
"connectorDefinitionName": {
- "defaultValue": "SentinelOne (Preview)",
+ "defaultValue": "SentinelOne",
"type": "string",
"minLength": 1
},
@@ -2670,7 +2671,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOne data connector with template version 3.0.5",
+ "description": "SentinelOne data connector with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion2')]",
@@ -3027,7 +3028,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOne Workbook with template version 3.0.5",
+ "description": "SentinelOne Workbook with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -3115,7 +3116,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOne Data Parser with template version 3.0.5",
+ "description": "SentinelOne Data Parser with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -3247,7 +3248,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneAdminLoginNewIP_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneAdminLoginNewIP_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -3275,10 +3276,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3361,7 +3362,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneAgentUninstalled_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneAgentUninstalled_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -3389,10 +3390,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3465,7 +3466,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneAlertFromCustomRule_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneAlertFromCustomRule_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -3493,10 +3494,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3569,7 +3570,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneBlacklistHashDeleted_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneBlacklistHashDeleted_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -3597,10 +3598,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3686,7 +3687,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneExclusionAdded_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneExclusionAdded_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -3714,10 +3715,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3790,7 +3791,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneMultipleAlertsOnHost_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneMultipleAlertsOnHost_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -3818,10 +3819,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3894,7 +3895,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneNewAdmin_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneNewAdmin_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]",
@@ -3922,10 +3923,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -3998,7 +3999,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneRuleDeleted_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneRuleDeleted_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]",
@@ -4026,10 +4027,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -4102,7 +4103,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneRuleDisabled_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneRuleDisabled_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]",
@@ -4130,10 +4131,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -4206,7 +4207,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneSameCustomRuleHitOnDiffHosts_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneSameCustomRuleHitOnDiffHosts_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]",
@@ -4234,10 +4235,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -4312,7 +4313,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneViewAgentPassphrase_AnalyticalRules Analytics Rule with template version 3.0.5",
+ "description": "SentinelOneViewAgentPassphrase_AnalyticalRules Analytics Rule with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject11').analyticRuleVersion11]",
@@ -4340,10 +4341,10 @@
"status": "Available",
"requiredDataConnectors": [
{
+ "connectorId": "SentinelOne",
"dataTypes": [
"SentinelOne"
- ],
- "connectorId": "SentinelOne"
+ ]
}
],
"tactics": [
@@ -4425,7 +4426,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneAgentNotUpdated_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneAgentNotUpdated_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
@@ -4510,7 +4511,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneAgentStatus_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneAgentStatus_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
@@ -4595,7 +4596,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneAlertTriggers_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneAlertTriggers_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
@@ -4680,7 +4681,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneHostNotScanned_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneHostNotScanned_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
@@ -4765,7 +4766,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneNewRules_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneNewRules_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]",
@@ -4850,7 +4851,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneRulesDeleted_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneRulesDeleted_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]",
@@ -4935,7 +4936,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneScannedHosts_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneScannedHosts_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]",
@@ -5020,7 +5021,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneSourcesByAlertCount_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneSourcesByAlertCount_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]",
@@ -5105,7 +5106,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneUninstalledAgents_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneUninstalledAgents_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]",
@@ -5190,7 +5191,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "SentinelOneUsersByAlertCount_HuntingQueries Hunting Query with template version 3.0.5",
+ "description": "SentinelOneUsersByAlertCount_HuntingQueries Hunting Query with template version 3.0.6",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]",
@@ -5271,7 +5272,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.5",
+ "version": "3.0.6",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "SentinelOne",
diff --git a/Solutions/SentinelOne/ReleaseNotes.md b/Solutions/SentinelOne/ReleaseNotes.md
index 7db9a1bd0e7..753b668f5ab 100644
--- a/Solutions/SentinelOne/ReleaseNotes.md
+++ b/Solutions/SentinelOne/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
+| 3.0.6 | 10-02-2025 | Advancing CCP **Data Connector** from Public preview to Global Availability.|
| 3.0.5 | 20-01-2025 | Updated "Sentinel One - Agent uninstalled from multiple hosts" **Analytic Rule** with ActivityType |
| 3.0.4 | 15-01-2025 | Added older Function app **Data Connector** again to SOlution until final deprecation of Function app happens |
| 3.0.3 | 12-12-2024 | Added new CCP **Data Connector** and Updated **Parser** |
diff --git a/Solutions/SlashNext/ReleaseNotes.md b/Solutions/SlashNext/ReleaseNotes.md
new file mode 100644
index 00000000000..87630807b4d
--- /dev/null
+++ b/Solutions/SlashNext/ReleaseNotes.md
@@ -0,0 +1,3 @@
+| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
+|---------------|----------------------------------|-----------------------------------------------------------------------------------------------------|
+| 3.0.0 | 17-12-2024 | Modified the Phishing Investigation application in **Data Connector** Function App.
Added new **Playbook** Phishing Incident Investigation. |
\ No newline at end of file
diff --git a/Solutions/Snowflake/Data Connectors/SnowflakeConn.zip b/Solutions/Snowflake/Data Connectors/SnowflakeConn.zip
index ebc0d991d21..ffec76d7aec 100644
Binary files a/Solutions/Snowflake/Data Connectors/SnowflakeConn.zip and b/Solutions/Snowflake/Data Connectors/SnowflakeConn.zip differ
diff --git a/Solutions/Snowflake/Data Connectors/requirements.txt b/Solutions/Snowflake/Data Connectors/requirements.txt
index 9e3083e81a0..117b343ec3d 100644
--- a/Solutions/Snowflake/Data Connectors/requirements.txt
+++ b/Solutions/Snowflake/Data Connectors/requirements.txt
@@ -2,5 +2,5 @@ azure-functions
requests==2.31.0
python-dateutil==2.8.2
azure-storage-file-share==12.5.0
-snowflake-connector-python==3.12.3
+snowflake-connector-python==3.13.1
cffi==1.14.6
\ No newline at end of file
diff --git a/Solutions/VaronisSaaS/Package/3.0.1.zip b/Solutions/VaronisSaaS/Package/3.0.1.zip
new file mode 100644
index 00000000000..183db820896
Binary files /dev/null and b/Solutions/VaronisSaaS/Package/3.0.1.zip differ
diff --git a/Solutions/VaronisSaaS/Package/createUiDefinition.json b/Solutions/VaronisSaaS/Package/createUiDefinition.json
index 3d9a32087d2..121ff7582f2 100644
--- a/Solutions/VaronisSaaS/Package/createUiDefinition.json
+++ b/Solutions/VaronisSaaS/Package/createUiDefinition.json
@@ -64,7 +64,7 @@
}
},
{
- "name": "dataconnectors-link2",
+ "name": "dataconnectors-link1",
"type": "Microsoft.Common.TextBlock",
"options": {
"link": {
diff --git a/Solutions/VaronisSaaS/Package/mainTemplate.json b/Solutions/VaronisSaaS/Package/mainTemplate.json
index 895ac4b2039..f795447f8f5 100644
--- a/Solutions/VaronisSaaS/Package/mainTemplate.json
+++ b/Solutions/VaronisSaaS/Package/mainTemplate.json
@@ -39,7 +39,7 @@
},
"variables": {
"_solutionName": "VaronisSaaS",
- "_solutionVersion": "3.0.0",
+ "_solutionVersion": "3.0.1",
"solutionId": "varonis.microsoft-sentinel-solution-varonissaas",
"_solutionId": "[variables('solutionId')]",
"workbookVersion1": "1.0.0",
@@ -70,7 +70,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VaronisSaaS Workbook with template version 3.0.0",
+ "description": "VaronisSaaS Workbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -157,7 +157,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VaronisSaaS data connector with template version 3.0.0",
+ "description": "VaronisSaaS data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -484,7 +484,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.0",
+ "version": "3.0.1",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "VaronisSaaS",
diff --git a/Solutions/Vectra XDR/Data Connectors/VectraDataConnector/VectraXDR_API_FunctionApp.json b/Solutions/Vectra XDR/Data Connectors/VectraDataConnector/VectraXDR_API_FunctionApp.json
index 9d6343a8290..9612e66b781 100644
--- a/Solutions/Vectra XDR/Data Connectors/VectraDataConnector/VectraXDR_API_FunctionApp.json
+++ b/Solutions/Vectra XDR/Data Connectors/VectraDataConnector/VectraXDR_API_FunctionApp.json
@@ -231,7 +231,7 @@
},
{
"title": "",
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-VectraXDR-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. VECTRAXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8 or above.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-VectraXDR320-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. VECTRAXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8 or above.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"title": "",
diff --git a/Solutions/Vectra XDR/Data/Solution_VectraXDR.json b/Solutions/Vectra XDR/Data/Solution_VectraXDR.json
index 72a0d0373f5..90f4f52e2b4 100644
--- a/Solutions/Vectra XDR/Data/Solution_VectraXDR.json
+++ b/Solutions/Vectra XDR/Data/Solution_VectraXDR.json
@@ -44,7 +44,7 @@
"Playbooks/VectraUpdateIncidentBasedOnTagAndNotify/azuredeploy.json"
],
"BasePath": "C:\\Azure-Sentinel\\Solutions\\Vectra XDR",
- "Version": "3.2.0",
+ "Version": "3.2.1",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1PConnector": false
diff --git a/Solutions/Vectra XDR/Package/3.2.1.zip b/Solutions/Vectra XDR/Package/3.2.1.zip
new file mode 100644
index 00000000000..282f8f2e7c0
Binary files /dev/null and b/Solutions/Vectra XDR/Package/3.2.1.zip differ
diff --git a/Solutions/Vectra XDR/Package/mainTemplate.json b/Solutions/Vectra XDR/Package/mainTemplate.json
index d804c39642d..15276469e01 100644
--- a/Solutions/Vectra XDR/Package/mainTemplate.json
+++ b/Solutions/Vectra XDR/Package/mainTemplate.json
@@ -41,7 +41,7 @@
"email": "tme@vetcra.ai",
"_email": "[variables('email')]",
"_solutionName": "Vectra XDR",
- "_solutionVersion": "3.2.0",
+ "_solutionVersion": "3.2.1",
"solutionId": "vectraaiinc.vectra-xdr-for-microsoft-sentinel",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "VectraXDR",
@@ -291,7 +291,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Vectra XDR data connector with template version 3.2.0",
+ "description": "Vectra XDR data connector with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -531,7 +531,7 @@
"title": "Option 2 - Manual Deployment of Azure Functions"
},
{
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-VectraXDR-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. VECTRAXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8 or above.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-VectraXDR320-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. VECTRAXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8 or above.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tVectra Base URL (https://) \n\t\tVectra Client Id - Health \n\t\tVectra Client Secret Key - Health \n\t\tVectra Client Id - Entity Scoring \n\t\tVectra Client Secret - Entity Scoring \n\t\tVectra Client Id - Detections \n\t\tVectra Client Secret - Detections \n\t\tVectra Client Id - Audits \n\t\tVectra Client Secret - Audits \n\t\tVectra Client Id - Lockdown \n\t\tVectra Client Secret - Lockdown \n\t\tVectra Client Id - Host-Entity \n\t\tVectra Client Secret - Host-Entity \n\t\tVectra Client Id - Account-Entity \n\t\tVectra Client Secret - Account-Entity \n\t\tKey Vault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tStartTime (in MM/DD/YYYY HH:MM:SS Format) \n\t\tInclude Score Decrease \n\t\tAudits Table Name \n\t\tDetections Table Name \n\t\tEntity Scoring Table Name \n\t\tLockdown Table Name \n\t\tHealth Table Name \n\t\tEntities Table Name \n\t\tLog Level (Default: INFO) \n\t\tLockdown Schedule \n\t\tHealth Schedule \n\t\tDetections Schedule \n\t\tAudits Schedule \n\t\tEntity Scoring Schedule \n\t\tEntities Schedule \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**."
@@ -842,7 +842,7 @@
"title": "Option 2 - Manual Deployment of Azure Functions"
},
{
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-VectraXDR-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. VECTRAXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8 or above.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-VectraXDR320-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. VECTRAXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8 or above.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tVectra Base URL (https://) \n\t\tVectra Client Id - Health \n\t\tVectra Client Secret Key - Health \n\t\tVectra Client Id - Entity Scoring \n\t\tVectra Client Secret - Entity Scoring \n\t\tVectra Client Id - Detections \n\t\tVectra Client Secret - Detections \n\t\tVectra Client Id - Audits \n\t\tVectra Client Secret - Audits \n\t\tVectra Client Id - Lockdown \n\t\tVectra Client Secret - Lockdown \n\t\tVectra Client Id - Host-Entity \n\t\tVectra Client Secret - Host-Entity \n\t\tVectra Client Id - Account-Entity \n\t\tVectra Client Secret - Account-Entity \n\t\tKey Vault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tStartTime (in MM/DD/YYYY HH:MM:SS Format) \n\t\tInclude Score Decrease \n\t\tAudits Table Name \n\t\tDetections Table Name \n\t\tEntity Scoring Table Name \n\t\tLockdown Table Name \n\t\tHealth Table Name \n\t\tEntities Table Name \n\t\tLog Level (Default: INFO) \n\t\tLockdown Schedule \n\t\tHealth Schedule \n\t\tDetections Schedule \n\t\tAudits Schedule \n\t\tEntity Scoring Schedule \n\t\tEntities Schedule \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**."
@@ -862,7 +862,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraDetections Data Parser with template version 3.2.0",
+ "description": "VectraDetections Data Parser with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -994,7 +994,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAudits Data Parser with template version 3.2.0",
+ "description": "VectraAudits Data Parser with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject2').parserVersion2]",
@@ -1126,7 +1126,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraEntityScoring Data Parser with template version 3.2.0",
+ "description": "VectraEntityScoring Data Parser with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject3').parserVersion3]",
@@ -1258,7 +1258,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraHealth Data Parser with template version 3.2.0",
+ "description": "VectraHealth Data Parser with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject4').parserVersion4]",
@@ -1390,7 +1390,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraLockdown Data Parser with template version 3.2.0",
+ "description": "VectraLockdown Data Parser with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject5').parserVersion5]",
@@ -1522,7 +1522,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Create_Incident_Based_On_Tag_For_Account_Entity_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "description": "Create_Incident_Based_On_Tag_For_Account_Entity_AnalyticalRules Analytics Rule with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -1656,7 +1656,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Create_Incident_Based_On_Tag_For_Host_Entity_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "description": "Create_Incident_Based_On_Tag_For_Host_Entity_AnalyticalRules Analytics Rule with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -1796,7 +1796,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Priority_Host_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "description": "Priority_Host_AnalyticalRules Analytics Rule with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -1930,7 +1930,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Priority_Account_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "description": "Priority_Account_AnalyticalRules Analytics Rule with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]",
@@ -2064,7 +2064,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Detection_Host_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "description": "Detection_Host_AnalyticalRules Analytics Rule with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]",
@@ -2197,7 +2197,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Detection_Account_AnalyticalRules Analytics Rule with template version 3.2.0",
+ "description": "Detection_Account_AnalyticalRules Analytics Rule with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]",
@@ -2330,7 +2330,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraXDR Workbook with template version 3.2.0",
+ "description": "VectraXDR Workbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -2434,7 +2434,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAddNoteToEntity Playbook with template version 3.2.0",
+ "description": "VectraAddNoteToEntity Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion1')]",
@@ -3926,7 +3926,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAddTagToEntityAllDetections Playbook with template version 3.2.0",
+ "description": "VectraAddTagToEntityAllDetections Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion2')]",
@@ -6055,7 +6055,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAddTagToEntity Playbook with template version 3.2.0",
+ "description": "VectraAddTagToEntity Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion3')]",
@@ -7457,7 +7457,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAddTagToEntitySelectedDetections Playbook with template version 3.2.0",
+ "description": "VectraAddTagToEntitySelectedDetections Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion4')]",
@@ -9469,7 +9469,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraDynamicAssignMemberToGroup Playbook with template version 3.2.0",
+ "description": "VectraDynamicAssignMemberToGroup Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion5')]",
@@ -10831,7 +10831,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAssignDynamicUserToEntity Playbook with template version 3.2.0",
+ "description": "VectraAssignDynamicUserToEntity Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion6')]",
@@ -13700,7 +13700,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraStaticAssignMemberToGroup Playbook with template version 3.2.0",
+ "description": "VectraStaticAssignMemberToGroup Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion7')]",
@@ -14360,7 +14360,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraAssignStaticUserToEntity Playbook with template version 3.2.0",
+ "description": "VectraAssignStaticUserToEntity Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion8')]",
@@ -16543,7 +16543,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraDecorateIncidentBasedOnTag Playbook with template version 3.2.0",
+ "description": "VectraDecorateIncidentBasedOnTag Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion9')]",
@@ -17402,7 +17402,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraDecorateIncidentBasedOnTagAndNotify Playbook with template version 3.2.0",
+ "description": "VectraDecorateIncidentBasedOnTagAndNotify Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion10')]",
@@ -18339,7 +18339,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraDynamicResolveAssignment Playbook with template version 3.2.0",
+ "description": "VectraDynamicResolveAssignment Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion11')]",
@@ -22007,7 +22007,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraGenerateAccessToken Playbook with template version 3.2.0",
+ "description": "VectraGenerateAccessToken Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion12')]",
@@ -23008,7 +23008,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraIncidentTimelineUpdate Playbook with template version 3.2.0",
+ "description": "VectraIncidentTimelineUpdate Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion13')]",
@@ -23560,7 +23560,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraMarkDetectionsAsFixed Playbook with template version 3.2.0",
+ "description": "VectraMarkDetectionsAsFixed Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion14')]",
@@ -25601,7 +25601,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraOperateOnEntitySourceIP Playbook with template version 3.2.0",
+ "description": "VectraOperateOnEntitySourceIP Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion15')]",
@@ -26588,7 +26588,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraStaticResolveAssignment Playbook with template version 3.2.0",
+ "description": "VectraStaticResolveAssignment Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion16')]",
@@ -29458,7 +29458,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "VectraUpdateIncidentBasedOnTagAndNotify Playbook with template version 3.2.0",
+ "description": "VectraUpdateIncidentBasedOnTagAndNotify Playbook with template version 3.2.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion17')]",
@@ -31269,7 +31269,7 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.2.0",
+ "version": "3.2.1",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Vectra XDR",
diff --git a/Solutions/ZeroNetworks/Data Connectors/SegmentFunctionConnector/DataConnector_API_AzureFunctionApp_ZeroNetworks_Segment_Audit.json b/Solutions/ZeroNetworks/Data Connectors/SegmentFunctionConnector/DataConnector_API_AzureFunctionApp_ZeroNetworks_Segment_Audit.json
index 4c44db5b0db..9ca8492c542 100644
--- a/Solutions/ZeroNetworks/Data Connectors/SegmentFunctionConnector/DataConnector_API_AzureFunctionApp_ZeroNetworks_Segment_Audit.json
+++ b/Solutions/ZeroNetworks/Data Connectors/SegmentFunctionConnector/DataConnector_API_AzureFunctionApp_ZeroNetworks_Segment_Audit.json
@@ -1,8 +1,8 @@
{
"id": "ZeroNetworksSegmentAuditFunction",
- "title": "Zero Networks Segment Audit (Function)",
+ "title": "Zero Networks Segment Audit",
"publisher": "Zero Networks",
- "descriptionMarkdown": "The [Zero Networks Segment](https://zeronetworks.com/product/) Audit data connector provides the capability to ingest Audit events into Microsoft Sentinel through the REST API. Refer to API guide for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
+ "descriptionMarkdown": "The [Zero Networks Segment](https://zeronetworks.com/product) Audit data connector provides the capability to ingest Audit events into Microsoft Sentinel through the REST API. Refer to API guide for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
"graphQueries": [
{
"metricName": "Total data received",
@@ -114,7 +114,7 @@
},
{
"title": "",
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-powershell#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/ZeroNetworks/SegmentFunctionConnector/AzureFunction_ZeroNetworks_Segment_Audit.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ZNSegmentAuditXXXXX).\n\n\te. **Select a runtime:** Choose PowerShell.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-powershell#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://github.com/Azure/Azure-Sentinel/raw/refs/heads/master/Solutions/ZeroNetworks/Data%20Connectors/SegmentFunctionConnector/AzureFunction_ZeroNetworks_Segment_Audit.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ZNSegmentAuditXXXXX).\n\n\te. **Select a runtime:** Choose PowerShell.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"title": "",
diff --git a/Solutions/ZeroNetworks/Data/Solution_ZeroNetworks.json b/Solutions/ZeroNetworks/Data/Solution_ZeroNetworks.json
index a45a79383ea..54712a357f4 100644
--- a/Solutions/ZeroNetworks/Data/Solution_ZeroNetworks.json
+++ b/Solutions/ZeroNetworks/Data/Solution_ZeroNetworks.json
@@ -2,7 +2,7 @@
"Name": "ZeroNetworks",
"Author": "Nicholas DiCola - nicholas@zeronetworks.com",
"Logo": "
",
- "Description": "The [Zero Networks Segment](https://zeronetworks.com/product/) solution for Microsoft Sentinel allows monitoring Zero Networks Segment Audit activity. Audit log data is ingested in Microsoft Sentinel using REST API.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs\n\n a. [Azure Monitor HTTP Data Collector API ](https://learn.microsoft.com/azure/azure-monitor/logs/data-collector-api)\n\n b. [Azure Functions](https://azure.microsoft.com/products/functions/#overview)",
+ "Description": "The [Zero Networks Segment](https://zeronetworks.com/product) solution for Microsoft Sentinel allows monitoring Zero Networks Segment Audit activity. Audit log data is ingested in Microsoft Sentinel using REST API.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs\n\n a. [Azure Monitor HTTP Data Collector API ](https://learn.microsoft.com/azure/azure-monitor/logs/data-collector-api)\n\n b. [Azure Functions](https://azure.microsoft.com/products/functions/#overview)",
"Workbooks": [
"Workbooks/ZNSegmentAudit.json"
],
diff --git a/Solutions/ZeroNetworks/Package/3.0.1.zip b/Solutions/ZeroNetworks/Package/3.0.1.zip
new file mode 100644
index 00000000000..8137e1bcfea
Binary files /dev/null and b/Solutions/ZeroNetworks/Package/3.0.1.zip differ
diff --git a/Solutions/ZeroNetworks/Package/createUiDefinition.json b/Solutions/ZeroNetworks/Package/createUiDefinition.json
index cb5be28d7ce..267ab930608 100644
--- a/Solutions/ZeroNetworks/Package/createUiDefinition.json
+++ b/Solutions/ZeroNetworks/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/ZeroNetworks/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Zero Networks Segment](https://zeronetworks.com/product/) solution for Microsoft Sentinel allows monitoring Zero Networks Segment Audit activity. Audit log data is ingested in Microsoft Sentinel using REST API.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs\n\n a. [Azure Monitor HTTP Data Collector API ](https://learn.microsoft.com/azure/azure-monitor/logs/data-collector-api)\n\n b. [Azure Functions](https://azure.microsoft.com/products/functions/#overview)\n\n**Data Connectors:** 2, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3, **Hunting Queries:** 4, **Custom Azure Logic Apps Connectors:** 1, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/ZeroNetworks/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Zero Networks Segment](https://zeronetworks.com/product) solution for Microsoft Sentinel allows monitoring Zero Networks Segment Audit activity. Audit log data is ingested in Microsoft Sentinel using REST API.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs\n\n a. [Azure Monitor HTTP Data Collector API ](https://learn.microsoft.com/azure/azure-monitor/logs/data-collector-api)\n\n b. [Azure Functions](https://azure.microsoft.com/products/functions/#overview)\n\n**Data Connectors:** 2, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3, **Hunting Queries:** 4, **Custom Azure Logic Apps Connectors:** 1, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
diff --git a/Solutions/ZeroNetworks/Package/mainTemplate.json b/Solutions/ZeroNetworks/Package/mainTemplate.json
index da278568d67..913827b8fd3 100644
--- a/Solutions/ZeroNetworks/Package/mainTemplate.json
+++ b/Solutions/ZeroNetworks/Package/mainTemplate.json
@@ -35,13 +35,17 @@
"metadata": {
"description": "Name for the workbook"
}
+ },
+ "uri": {
+ "type": "string",
+ "defaultValue": "https://portal.zeronetworks.com/api/v1/audit"
}
},
"variables": {
"email": "nicholas@zeronetworks.com",
"_email": "[variables('email')]",
"_solutionName": "ZeroNetworks",
- "_solutionVersion": "3.0.0",
+ "_solutionVersion": "3.0.1",
"solutionId": "zeronetworksltd1629013803351.azure-sentinel-solution-znsegmentaudit",
"_solutionId": "[variables('solutionId')]",
"workbookVersion1": "1.0.0",
@@ -162,7 +166,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentAudit Workbook with template version 3.0.0",
+ "description": "ZNSegmentAudit Workbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -240,7 +244,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_workbookContentId1')]",
"contentKind": "Workbook",
"displayName": "[parameters('workbook1-name')]",
@@ -258,7 +262,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentMachineRemovedfromProtection_AnalyticalRules Analytics Rule with template version 3.0.0",
+ "description": "ZNSegmentMachineRemovedfromProtection_AnalyticalRules Analytics Rule with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -359,7 +363,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]",
"contentKind": "AnalyticsRule",
"displayName": "Zero Networks Segement - Machine Removed from protection",
@@ -377,7 +381,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentNewAPIToken_AnalyticalRules Analytics Rule with template version 3.0.0",
+ "description": "ZNSegmentNewAPIToken_AnalyticalRules Analytics Rule with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -469,7 +473,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]",
"contentKind": "AnalyticsRule",
"displayName": "Zero Networks Segment - New API Token created",
@@ -487,7 +491,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentRareJITRuleCreation_AnalyticalRules Analytics Rule with template version 3.0.0",
+ "description": "ZNSegmentRareJITRuleCreation_AnalyticalRules Analytics Rule with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]",
@@ -588,7 +592,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]",
"contentKind": "AnalyticsRule",
"displayName": "Zero Networks Segment - Rare JIT Rule Creation",
@@ -606,7 +610,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentAudit Data Parser with template version 3.0.0",
+ "description": "ZNSegmentAudit Data Parser with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject1').parserVersion1]",
@@ -669,7 +673,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('parserObject1').parserContentId1]",
"contentKind": "Parser",
"displayName": "ZNSegmentAudit",
@@ -738,7 +742,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentExcessiveAccessbyUser_HuntingQueries Hunting Query with template version 3.0.0",
+ "description": "ZNSegmentExcessiveAccessbyUser_HuntingQueries Hunting Query with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]",
@@ -805,7 +809,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('huntingQueryObject1')._huntingQuerycontentId1]",
"contentKind": "HuntingQuery",
"displayName": "Zero Networks Segment - Excessive access by user",
@@ -823,7 +827,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentExcessiveAccesstoBuiltinGroupbyUser_HuntingQueries Hunting Query with template version 3.0.0",
+ "description": "ZNSegmentExcessiveAccesstoBuiltinGroupbyUser_HuntingQueries Hunting Query with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]",
@@ -890,7 +894,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('huntingQueryObject2')._huntingQuerycontentId2]",
"contentKind": "HuntingQuery",
"displayName": "Zero Networks Segment - Excessive access to a built-in group by user",
@@ -908,7 +912,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentInboundBlockRulesDeleted_HuntingQueries Hunting Query with template version 3.0.0",
+ "description": "ZNSegmentInboundBlockRulesDeleted_HuntingQueries Hunting Query with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]",
@@ -975,7 +979,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('huntingQueryObject3')._huntingQuerycontentId3]",
"contentKind": "HuntingQuery",
"displayName": "Zero Networks Segment - Inbound Block Rules Deleted",
@@ -993,7 +997,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegmentOutboundBlockRulesDeleted_HuntingQueries Hunting Query with template version 3.0.0",
+ "description": "ZNSegmentOutboundBlockRulesDeleted_HuntingQueries Hunting Query with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]",
@@ -1060,7 +1064,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('huntingQueryObject4')._huntingQuerycontentId4]",
"contentKind": "HuntingQuery",
"displayName": "Zero Networks Segment - Outbound Block Rules Deleted",
@@ -1078,7 +1082,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZeroNetworks data connector with template version 3.0.0",
+ "description": "ZeroNetworks data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -1235,7 +1239,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_dataConnectorContentId1')]",
"contentKind": "DataConnector",
"displayName": "Zero Networks Segment Audit",
@@ -1401,7 +1405,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZeroNetworks data connector with template version 3.0.0",
+ "description": "ZeroNetworks data connector with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion2')]",
@@ -1419,7 +1423,7 @@
"id": "[variables('_uiConfigId2')]",
"title": "Zero Networks Segment Audit (Function) (using Azure Functions)",
"publisher": "Zero Networks",
- "descriptionMarkdown": "The [Zero Networks Segment](https://zeronetworks.com/product/) Audit data connector provides the capability to ingest Audit events into Microsoft Sentinel through the REST API. Refer to API guide for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
+ "descriptionMarkdown": "The [Zero Networks Segment](https://zeronetworks.com/product) Audit data connector provides the capability to ingest Audit events into Microsoft Sentinel through the REST API. Refer to API guide for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
"graphQueries": [
{
"metricName": "Total data received",
@@ -1527,7 +1531,7 @@
"title": "Option 2 - Manual Deployment of Azure Functions"
},
{
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-powershell#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/ZeroNetworks/SegmentFunctionConnector/AzureFunction_ZeroNetworks_Segment_Audit.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ZNSegmentAuditXXXXX).\n\n\te. **Select a runtime:** Choose PowerShell.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-powershell#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://github.com/Azure/Azure-Sentinel/raw/refs/heads/master/Solutions/ZeroNetworks/Data%20Connectors/SegmentFunctionConnector/AzureFunction_ZeroNetworks_Segment_Audit.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ZNSegmentAuditXXXXX).\n\n\te. **Select a runtime:** Choose PowerShell.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select ** New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tAPIToken\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n\t\turi\n\t\ttableName\n> - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n3. Once all application settings have been entered, click **Save**."
@@ -1585,7 +1589,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_dataConnectorContentId2')]",
"contentKind": "DataConnector",
"displayName": "Zero Networks Segment Audit (Function) (using Azure Functions)",
@@ -1634,7 +1638,7 @@
"connectorUiConfig": {
"title": "Zero Networks Segment Audit (Function) (using Azure Functions)",
"publisher": "Zero Networks",
- "descriptionMarkdown": "The [Zero Networks Segment](https://zeronetworks.com/product/) Audit data connector provides the capability to ingest Audit events into Microsoft Sentinel through the REST API. Refer to API guide for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
+ "descriptionMarkdown": "The [Zero Networks Segment](https://zeronetworks.com/product) Audit data connector provides the capability to ingest Audit events into Microsoft Sentinel through the REST API. Refer to API guide for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
"graphQueries": [
{
"metricName": "Total data received",
@@ -1742,7 +1746,7 @@
"title": "Option 2 - Manual Deployment of Azure Functions"
},
{
- "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-powershell#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/DataConnectors/ZeroNetworks/SegmentFunctionConnector/AzureFunction_ZeroNetworks_Segment_Audit.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ZNSegmentAuditXXXXX).\n\n\te. **Select a runtime:** Choose PowerShell.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
+ "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-powershell#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://github.com/Azure/Azure-Sentinel/raw/refs/heads/master/Solutions/ZeroNetworks/Data%20Connectors/SegmentFunctionConnector/AzureFunction_ZeroNetworks_Segment_Audit.zip) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ZNSegmentAuditXXXXX).\n\n\te. **Select a runtime:** Choose PowerShell.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select ** New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tAPIToken\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n\t\turi\n\t\ttableName\n> - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n3. Once all application settings have been entered, click **Save**."
@@ -1761,7 +1765,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZeroNetworksConnector Playbook with template version 3.0.0",
+ "description": "ZeroNetworksConnector Playbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion1')]",
@@ -2423,7 +2427,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_playbookContentId1')]",
"contentKind": "LogicAppsCustomConnector",
"displayName": "ZeroNetworksConnector",
@@ -2441,7 +2445,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegment-AddAssettoProtection Playbook with template version 3.0.0",
+ "description": "ZNSegment-AddAssettoProtection Playbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion2')]",
@@ -2776,7 +2780,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_playbookContentId2')]",
"contentKind": "Playbook",
"displayName": "ZNSegment-AddAssettoProtection",
@@ -2794,7 +2798,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZNSegment-AddBlockOutboundRule Playbook with template version 3.0.0",
+ "description": "ZNSegment-AddBlockOutboundRule Playbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion3')]",
@@ -3114,7 +3118,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_playbookContentId3')]",
"contentKind": "Playbook",
"displayName": "ZNSegment-AddBlockOutboundRule",
@@ -3132,7 +3136,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ZeroNetworksSegment-EnrichIncident Playbook with template version 3.0.0",
+ "description": "ZeroNetworksSegment-EnrichIncident Playbook with template version 3.0.1",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('playbookVersion4')]",
@@ -3444,7 +3448,7 @@
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"contentId": "[variables('_playbookContentId4')]",
"contentKind": "Playbook",
"displayName": "ZeroNetworksSegment-EnrichIncident",
@@ -3458,12 +3462,12 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.0",
+ "version": "3.0.1",
"kind": "Solution",
- "contentSchemaVersion": "3.0.0",
+ "contentSchemaVersion": "3.0.1",
"displayName": "ZeroNetworks",
"publisherDisplayName": "Zero Networks",
- "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Zero Networks Segment solution for Microsoft Sentinel allows monitoring Zero Networks Segment Audit activity. Audit log data is ingested in Microsoft Sentinel using REST API.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs
\n\nAzure Monitor HTTP Data Collector API
\n \nAzure Functions
\n \n
\nData Connectors: 2, Parsers: 1, Workbooks: 1, Analytic Rules: 3, Hunting Queries: 4, Custom Azure Logic Apps Connectors: 1, Playbooks: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Zero Networks Segment solution for Microsoft Sentinel allows monitoring Zero Networks Segment Audit activity. Audit log data is ingested in Microsoft Sentinel using REST API.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs
\n\nAzure Monitor HTTP Data Collector API
\n \nAzure Functions
\n \n
\nData Connectors: 2, Parsers: 1, Workbooks: 1, Analytic Rules: 3, Hunting Queries: 4, Custom Azure Logic Apps Connectors: 1, Playbooks: 3
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
"id": "[variables('_solutioncontentProductId')]",
diff --git a/Solutions/ZeroNetworks/ReleaseNotes.md b/Solutions/ZeroNetworks/ReleaseNotes.md
index b41b155d639..33cf87c6f95 100644
--- a/Solutions/ZeroNetworks/ReleaseNotes.md
+++ b/Solutions/ZeroNetworks/ReleaseNotes.md
@@ -1,3 +1,4 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|--------------------------------------------------------|
+| 3.0.1 | 06-02-2025 | Added missing parameter **URI** to Solution. |
| 3.0.0 | 11-12-2024 | Updated solution to 3.0.0 |
\ No newline at end of file
diff --git a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1
index ff5a9cce98f..38772d3f447 100644
--- a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1
+++ b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1
@@ -2195,7 +2195,7 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe
}
}
$connectDataSourcesLink = [PSCustomObject] @{
- name = "dataconnectors-link2";
+ name = "dataconnectors-link$($global:connectorCounter)";
type = "Microsoft.Common.TextBlock";
options = [PSCustomObject] @{
link = [PSCustomObject] @{
@@ -2718,6 +2718,10 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe
{
$alertRule.entityMappings = @($alertRule.entityMappings);
}
+ elseif($yamlField -eq "sentinelEntitiesMappings" -and $yaml.$yamlField.length -lt 2)
+ {
+ $alertRule.sentinelEntitiesMappings = @($alertRule.sentinelEntitiesMappings);
+ }
}
}
# Create Alert Rule Resource Object
diff --git a/Tools/Create-Azure-Sentinel-Solution/common/createCCPConnector.ps1 b/Tools/Create-Azure-Sentinel-Solution/common/createCCPConnector.ps1
index b0d74ad9a57..0a38d9cc17d 100644
--- a/Tools/Create-Azure-Sentinel-Solution/common/createCCPConnector.ps1
+++ b/Tools/Create-Azure-Sentinel-Solution/common/createCCPConnector.ps1
@@ -89,7 +89,7 @@ function New-ParametersForConnectorInstuctions($instructions) {
}
else {
$instructionType = $instruction.type;
- Write-Host "Specified Instruction type '$instructionType' is not from the instruction type list like Textbox, OAuthForm and ContextPane!"
+ Write-Host "Info: Specified Instruction type '$instructionType' is not from the instruction type list like Textbox, OAuthForm and ContextPane!"
}
}
}
@@ -245,6 +245,18 @@ function addWorkspaceParameter($templateResourceObj, $parameterName) {
return $templateResourceObj;
}
+function addGuidValueParameter($templateResourceObj) {
+ $hasParameter = [bool]($templateResourceObj.parameters.PSobject.Properties.name -match "guidValue")
+ if (!$hasParameter) {
+ $templateResourceObj.parameters | Add-Member -NotePropertyName "guidValue" -NotePropertyValue ([PSCustomObject] @{
+ defaultValue = "[[newGuid()]";
+ type = "string";
+ })
+ }
+
+ return $templateResourceObj;
+}
+
function Add-NewObjectParameter {
param (
[Parameter(Mandatory = $true)] [PSCustomObject] $TemplateResourceObj,
@@ -378,17 +390,18 @@ function createCCPConnectorResources($contentResourceDetails, $dataFileMetadata,
$splitNamesBySlash = $dataConnectorName -split '/'
$concatenateParts = @()
$outputString = ''
+ $guidValue = "parameters('guidValue')"
foreach ($currentName in $splitNamesBySlash) {
if ($currentName.Contains('{{')) {
$placeHolderFieldName = $currentName -replace '{{', '' -replace '}}', ''
$placeHolderMatched = [regex]::Matches($currentName, $placeHolderPatternMatches)
if ($placeHolderMatched.Length -eq $currentName.Length) {
- $concatenateParts += "parameters('$($placeHolderFieldName)')"
-
- if ($placeHolderFieldName -like '*workspace*') {
+ if ($placeHolderFieldName -eq 'workspace') {
+ $concatenateParts += "parameters('innerWorkspace')"
$templateContentConnections.properties.mainTemplate = addWorkspaceParameter -templateResourceObj $templateContentConnections.properties.mainTemplate -parameterName $($placeHolderFieldName)
} else {
+ $concatenateParts += "parameters('$($placeHolderFieldName)')"
$templateContentConnections.properties.mainTemplate = addNewParameter -templateResourceObj $templateContentConnections.properties.mainTemplate -parameterName $($placeHolderFieldName) -isSecret $false
}
} else {
@@ -396,12 +409,12 @@ function createCCPConnectorResources($contentResourceDetails, $dataFileMetadata,
$concatenateParts += "'/$($text)'"
$parameterNameValue = $placeHolderMatched.Value -replace '{{', '' -replace '}}', ''
$concatenateParts += "parameters('$($parameterNameValue)')"
-
+
$templateContentConnections.properties.mainTemplate = addNewParameter -templateResourceObj $templateContentConnections.properties.mainTemplate -parameterName $($parameterNameValue) -isSecret $false
}
} else {
if ($currentName.Count -eq 1 -and $currentName -like '{{') {
- $concatenateParts = "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', '$($currentName)')]"
+ $concatenateParts = "[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', '$($currentName)', $guidValue)]"
} else {
if ($concatenateParts.Count -ge 1) {
# if we have multiple parts in name {{innerWorkspace}}/Microsoft.SecurityInsights/OktaDCV1_{{domainname}}
@@ -413,19 +426,15 @@ function createCCPConnectorResources($contentResourceDetails, $dataFileMetadata,
}
}
}
-
+
if ($concatenateParts.Count -gt 1 -and $concatenateParts -notmatch 'concat') {
- $outputString = "[[concat($($concatenateParts -join ', '))]"
+ $outputString = "[[concat($($concatenateParts -join ', '), $guidValue)]"
} elseif ($concatenateParts.Count -eq 1 -and $concatenateParts[0] -match 'parameters') {
# if we just have parameters('abcwork')
- $outputString = "[[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', $($concatenateParts[0]))]"
+ $outputString = "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', $($concatenateParts[0]), $guidValue)]"
} else {
# if we just have 'abcwork'
- $outputString = "[[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', '$($concatenateParts[0])')]"
- }
-
- if ($outputString -like "*parameters('workspace')*") {
- $outputString = $outputString.Replace("[[", "[")
+ $outputString = "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', '$($concatenateParts[0])', $guidValue)]"
}
return $outputString
@@ -433,7 +442,12 @@ function createCCPConnectorResources($contentResourceDetails, $dataFileMetadata,
function CCPDataConnectorsResource($fileContent) {
if ($fileContent.type -eq "Microsoft.SecurityInsights/dataConnectors") {
-
+ # add parameter of guidValue if not present
+ $templateContentConnections.properties.mainTemplate = addGuidValueParameter -templateResourceObj $templateContentConnections.properties.mainTemplate
+
+ # add parameter of innerWorkspace if not present
+ $templateContentConnections.properties.mainTemplate = addWorkspaceParameter -templateResourceObj $templateContentConnections.properties.mainTemplate -parameterName 'innerWorkspace' -isSecret $false
+
Write-Host "Processing for CCP Poller file path: $ccpPollerFilePath"
$resourceName = GetDataConnectorPollerResourceName -dataConnectorName $fileContent.name
@@ -523,6 +537,10 @@ function createCCPConnectorResources($contentResourceDetails, $dataFileMetadata,
$armResource.properties.auth | Add-Member -MemberType NoteProperty -Name "servicePrincipalId" -Value "[[parameters('auth').servicePrincipalId]"
}
}
+ elseif ($armResource.kind.ToLower() -eq 'amazonwebservicess3')
+ {
+ CreateAwsResourceProperties -armResource $armResource -templateContentConnections $templateContentConnections -fileType $fileType
+ }
else
{
Write-Host "Error: Data Connector Poller file should have 'kind' attribute with value either 'RestApiPoller', 'GCP', 'AmazonWebServicesS3' or 'Push'." -BackgroundColor Red
@@ -739,7 +757,7 @@ function createCCPConnectorResources($contentResourceDetails, $dataFileMetadata,
$currentStepNum = $global:baseCreateUiDefinition.parameters.steps.Count - 1
$global:baseCreateUiDefinition.parameters.steps[$currentStepNum].elements += $baseDataConnectorTextElement
$connectDataSourcesLink = [PSCustomObject] @{
- name = "dataconnectors-link2";
+ name = "dataconnectors-link$($global:connectorCounter)";
type = "Microsoft.Common.TextBlock";
options = [PSCustomObject] @{
link = [PSCustomObject] @{
@@ -961,4 +979,32 @@ function CreateGCPResourceProperties($armResource, $templateContentConnections,
# Request section subscriptionNames property
ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $false -propertyObject $armResource.properties.request -propertyName 'subscriptionNames' -isInnerObject $true -innerObjectName 'request' -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $true
+}
+
+$awsSolutions = @('VMware Carbon Black Cloud')
+
+function CreateAwsResourceProperties($armResource, $templateContentConnections, $fileType) {
+ $kindType = 'AmazonWebServicesS3'
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $true -propertyObject $armResource.properties -propertyName 'dataTypes' -isInnerObject $false -innerObjectName $null -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $true -propertyObject $armResource.properties.dataTypes -propertyName 'logs' -isInnerObject $true -innerObjectName 'dataTypes' -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $false -propertyObject $armResource.properties.dataTypes.logs -propertyName 'state' -isInnerObject $true -innerObjectName 'logs' -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $true -propertyObject $armResource.properties -propertyName 'dcrConfig' -isInnerObject $false -innerObjectName $null -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+
+ if ($awsSolutions.Contains($solutionName)) {
+ # Handle properties destinationTable and streamName in dc poller file for this solutions as a special case
+ $armResource.properties.dcrConfig.streamName = "[[parameters('streamName')[0]]"
+ $armResource.properties.destinationTable = "[[concat(parameters('streamName')[0],'_CL')]"
+ $templateContentConnections.properties.mainTemplate.parameters | Add-Member -NotePropertyName "streamName" -NotePropertyValue ([PSCustomObject] @{ type = "array" })
+ } else {
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $false -propertyObject $armResource.properties.dcrConfig -propertyName 'streamName' -isInnerObject $true -innerObjectName 'dcrConfig' -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $false -propertyObject $armResource.properties -propertyName 'destinationTable' -isInnerObject $false -innerObjectName $null -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+ }
+
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $false -propertyObject $armResource.properties -propertyName 'roleArn' -isInnerObject $false -innerObjectName $null -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $false
+
+ ProcessPropertyPlaceholders -armResource $armResource -templateContentConnections $templateContentConnections -isOnlyObjectCheck $false -propertyObject $armResource.properties -propertyName 'sqsUrls' -isInnerObject $false -innerObjectName $null -kindType $kindType -isSecret $false -isRequired $true -fileType $fileType -minLength 3 -isCreateArray $true
}
\ No newline at end of file
diff --git a/Workbooks/Images/Preview/IllumioOnPremHealthBlack.png b/Workbooks/Images/Preview/IllumioOnPremHealthBlack.png
new file mode 100644
index 00000000000..7fc6ae08f00
Binary files /dev/null and b/Workbooks/Images/Preview/IllumioOnPremHealthBlack.png differ
diff --git a/Workbooks/Images/Preview/IllumioOnPremHealthWhite.png b/Workbooks/Images/Preview/IllumioOnPremHealthWhite.png
new file mode 100644
index 00000000000..5a3d533efdf
Binary files /dev/null and b/Workbooks/Images/Preview/IllumioOnPremHealthWhite.png differ
diff --git a/Workbooks/Images/Preview/adchanges-black.png b/Workbooks/Images/Preview/adchanges-black.png
new file mode 100644
index 00000000000..193bb51ff0e
Binary files /dev/null and b/Workbooks/Images/Preview/adchanges-black.png differ
diff --git a/Workbooks/Images/Preview/adchanges-white.png b/Workbooks/Images/Preview/adchanges-white.png
new file mode 100644
index 00000000000..210d6ddb0cf
Binary files /dev/null and b/Workbooks/Images/Preview/adchanges-white.png differ
diff --git a/Workbooks/Images/Preview/indicators-black.png b/Workbooks/Images/Preview/indicators-black.png
new file mode 100644
index 00000000000..572eb26e924
Binary files /dev/null and b/Workbooks/Images/Preview/indicators-black.png differ
diff --git a/Workbooks/Images/Preview/indicators-white.png b/Workbooks/Images/Preview/indicators-white.png
new file mode 100644
index 00000000000..c4dbd9321e1
Binary files /dev/null and b/Workbooks/Images/Preview/indicators-white.png differ
diff --git a/Workbooks/Images/Preview/notifications-black.png b/Workbooks/Images/Preview/notifications-black.png
new file mode 100644
index 00000000000..d4ea4f0f239
Binary files /dev/null and b/Workbooks/Images/Preview/notifications-black.png differ
diff --git a/Workbooks/Images/Preview/notifications-white.png b/Workbooks/Images/Preview/notifications-white.png
new file mode 100644
index 00000000000..8c25ad65dc8
Binary files /dev/null and b/Workbooks/Images/Preview/notifications-white.png differ
diff --git a/Workbooks/Images/Preview/quickview-black.png b/Workbooks/Images/Preview/quickview-black.png
new file mode 100644
index 00000000000..2927cee24a0
Binary files /dev/null and b/Workbooks/Images/Preview/quickview-black.png differ
diff --git a/Workbooks/Images/Preview/quickview-white.png b/Workbooks/Images/Preview/quickview-white.png
new file mode 100644
index 00000000000..270a2557265
Binary files /dev/null and b/Workbooks/Images/Preview/quickview-white.png differ
diff --git a/Workbooks/WorkbooksMetadata.json b/Workbooks/WorkbooksMetadata.json
index d0d539073f8..84cb7fe66bd 100644
--- a/Workbooks/WorkbooksMetadata.json
+++ b/Workbooks/WorkbooksMetadata.json
@@ -8023,6 +8023,26 @@
"subtitle": "",
"provider": "Illumio"
},
+ {
+ "workbookKey": "IllumioOnPremHealthWorkbook",
+ "logoFileName": "IllumioLogo.svg",
+ "description": "This workbook leverages events ingested by 'Syslog via AMA devices' and presents insights",
+ "dataTypesDependencies": [
+ "Syslog"
+ ],
+ "dataConnectorsDependencies": [
+ "SyslogAMA"
+ ],
+ "previewImagesFileNames": [
+ "IllumioOnPremHealthWhite.png",
+ "IllumioOnPremHealthBlack.png"
+ ],
+ "version": "1.2.0",
+ "title": "Illumio OnPrem Health Workbook",
+ "templateRelativePath": "IllumioOnPremHealth.json",
+ "subtitle": "",
+ "provider": "Illumio"
+ },
{
"workbookKey": "CEFOverview",
"logoFileName": "Azure_Sentinel.svg",
@@ -8525,5 +8545,86 @@
"templateRelativePath": "SamsungKnoxAssetIntelligence.json",
"subtitle": "",
"provider": "Samsung"
- }
+ },
+ {
+ "workbookKey": "SemperisDSPADChangesWorkbook",
+ "logoFileName": "Semperis.svg",
+ "description": "View change data related to the Semperis DSP system.",
+ "dataTypesDependencies": [
+ "CommonSecurityLog"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "adchanges-black.png",
+ "adchanges-white.png"
+ ],
+ "version": "1.0.0",
+ "title": "Semperis DSP AD Changes",
+ "templateRelativePath": "SemperisDSPADChanges.json",
+ "subtitle": "",
+ "provider": "Semperis"
+ },
+
+ {
+ "workbookKey": "SemperisDSPNotificationsWorkbook",
+ "logoFileName": "Semperis.svg",
+ "description": "View notification data related to the Semperis DSP system.",
+ "dataTypesDependencies": [
+ "Event"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "notifications-black.png",
+ "notifications-white.png"
+ ],
+ "version": "1.0.0",
+ "title": "Semperis DSP Notifications",
+ "templateRelativePath": "SemperisDSPNotifications.json",
+ "subtitle": "",
+ "provider": "Semperis"
+ },
+ {
+ "workbookKey": "SemperisDSPQuickviewDashboardWorkbook",
+ "logoFileName": "Semperis.svg",
+ "description": "View data related to the Semperis DSP system.",
+ "dataTypesDependencies": [
+ "Event"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "quickview-black.png",
+ "quickview-white.png"
+ ],
+ "version": "1.0.0",
+ "title": "Semperis DSP Quickview Dashboard",
+ "templateRelativePath": "SemperisDSPQuickviewDashboard.json",
+ "subtitle": "",
+ "provider": "Semperis"
+ },
+ {
+ "workbookKey": "SemperisDSPSecurityIndicatorsWorkbook",
+ "logoFileName": "Semperis.svg",
+ "description": "View security indicator data related to the Semperis DSP system.",
+ "dataTypesDependencies": [
+ "dsp_parser"
+ ],
+ "dataConnectorsDependencies": [
+ "SemperisDSP-connector"
+ ],
+ "previewImagesFileNames": [
+ "indicators-black.png",
+ "indicators-white.png"
+ ],
+ "version": "1.0.0",
+ "title": "Semperis DSP Security Indicators",
+ "templateRelativePath": "SemperisDSPSecurityIndicators.json",
+ "subtitle": "",
+ "provider": "Semperis"
+ }
]