Overview
This lab provides a reviewed Codeless Connector Framework (CCF) Push artifact set plus an owner-bound Sentinel sandbox. The PowerShell script does not misrepresent a raw connector-definition deployment as a complete solution:
- Infrastructure script: Log Analytics workspace with Microsoft Sentinel enabled
- CCF Push artifacts: Table, DCR, UI definition, and push configuration for Microsoft’s official solution-packaging flow
- Data Source: abuse.ch Feodotracker botnet C2 indicators (real threat intelligence)
- Detection: 5 disabled-by-default analytics-rule examples for botnet C2 patterns and network TI correlation
- Visualization: Threat Intelligence Dashboard workbook
After the sandbox is deployed, package the four artifacts with the current official Azure-Sentinel tooling, inspect and deploy the generated solution, and only then use its portal button to provision the DCE, DCR, table, Entra app, secret, and role assignment.
Prerequisites
- Azure permission to create the resource group plus Contributor and Microsoft Sentinel Contributor on the target scope
- Owner or User Access Administrator, or equivalent exact role-assignment permission, for the generated DCR
- Entra permission to create an application and client secret (typically Application Developer or higher)
- Access to the official Azure-Sentinel repository and its current solution-packaging tooling
- PowerShell 7.3+ with Azure CLI installed and authenticated
- Python 3.10+ with
pip(for the sender script)
Quick Start
# Preview with no Azure or local-state writes
./labs/sentinel-ccf-push/scripts/Deploy-Lab.ps1 -Location "eastus" -WhatIf
# Deploy the owned sandbox + disabled rules + workbook. This validates the
# connector artifacts but does not package or install the connector solution.
./labs/sentinel-ccf-push/scripts/Deploy-Lab.ps1 -Location "eastus"
# Follow Microsoft's CCF Push guide to package connector/*.json with the
# official Azure-Sentinel tooling and deploy the generated package here.
# Then click the packaged connector's portal button and set its credentials:
# Set environment variables from the connector credentials
export CCF_TENANT_ID="<tenant-id>"
export CCF_CLIENT_ID="<client-id>"
export CCF_CLIENT_SECRET="<client-secret>"
export CCF_DCE_URI="<dce-uri>"
export CCF_DCR_ID="<dcr-immutable-id>"
# Run initial data ingestion
python3 -m pip install --require-hashes -r ./labs/sentinel-ccf-push/scripts/requirements.lock
python3 -m unittest discover -s ./labs/sentinel-ccf-push/tests -v
python3 ./labs/sentinel-ccf-push/scripts/Send-ThreatIntel.py
# Validate end-to-end
./labs/sentinel-ccf-push/scripts/Test-CCFPush.ps1 -ProjectName "ccf-push-lab"
The deployment records an ignored, project-specific ownership manifest before
its first Azure write and refuses to adopt an existing resource group or
same-name Sentinel content without exact provenance. The five analytics rules
remain disabled unless you rerun with -EnableSentinelRules after reviewing
and tuning their KQL. The sender honors Retry-After for HTTP 429 responses and retries a bounded
number of times. If the final attempt is still rate-limited, it raises an error
and the process/workflow fails; a terminal 429 is never reported as successful
ingestion. The scheduled GitHub Actions workflow runs the same unit tests before
it pushes any indicators.
What Gets Deployed
| Resource | Type | Purpose |
|---|---|---|
| Log Analytics workspace | Infrastructure | Data storage |
| Sentinel onboarding | Infrastructure | Enable Sentinel blade |
| Four CCF Push JSON artifacts | Local/packaging input | Must be packaged with Microsoft’s current official tooling |
| Packaged connector definition | Data Connector | Gallery entry with deploy button, created only after separate package deployment |
FeodoTracker_CL custom table | Custom Table | Provisioned by the packaged connector workflow |
| LAB - New Feed Malware Label Observed | Disabled rule example (High) | New-to-workspace label for review |
| LAB - Feed Indicator Count Increase | Disabled rule example (Medium) | >50% change between adjacent 24-hour windows |
| LAB - Recent Feed Indicators on 443 or 8443 | Disabled rule example (High) | Port-based feed triage, not proof of encryption |
| LAB - Feed Country Concentration | Disabled rule example (Medium) | Geographic aggregation, not attribution |
| LAB - Network Traffic Match to Feed Indicator | Disabled rule example (High) | IP-match triage lead, not proof of compromise |
| Threat Intelligence Dashboard | Workbook | 5-panel C2 monitoring |
Cost Estimate
- Log Analytics and Sentinel charges depend on region, tier, retention, and current meters
- Feodotracker data: ~500 indicators per batch โ negligible
- No Azure Function/Logic App runtime for the connector path
- Total: typically low for lab workloads; confirm current regional ingestion pricing before budgeting
Cleanup
./labs/sentinel-ccf-push/scripts/Deploy-Lab.ps1 -Destroy -WhatIf
./labs/sentinel-ccf-push/scripts/Deploy-Lab.ps1 -Destroy
-Destroy -WhatIf is a preview and deletes nothing. The live command requires
the exact local ownership manifest and matching subscription, tenant, group,
and owner tag; it waits for deletion and verifies completion before removing
the manifest. Portal-created tenant objects and GitHub secrets remain explicit
manual cleanup items because the script cannot safely infer that they are
unused elsewhere.
Links
- Blog post: Build a Custom Sentinel Connector in 5 Minutes with CCF Push
- GitHub: j-dahl7/sentinel-ccf-push-connector
- Microsoft Learn: Create and package a CCF Push connector
- abuse.ch Feodotracker: feodotracker.abuse.ch
