diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 498bd01..7c1388c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,6 +5,7 @@ # Request review from original author plugins/DigiCert/* @shaswot77 +plugins/Huntress/* @Deenk plugins/FantasyPremierLeague/* @TimWheeler-SQUP plugins/GoogleSheets/* @kieranlangton plugins/MetOffice/* @blackgrouse diff --git a/plugins/Huntress/v1/configValidation.json b/plugins/Huntress/v1/configValidation.json new file mode 100644 index 0000000..bbd4b50 --- /dev/null +++ b/plugins/Huntress/v1/configValidation.json @@ -0,0 +1,11 @@ +{ + "steps": [ + { + "displayName": "API access", + "dataStream": { "name": "organizations" }, + "success": "Successfully connected to Huntress", + "error": "Cannot connect to Huntress. Check your public and private API keys.", + "required": true + } + ] +} diff --git a/plugins/Huntress/v1/cspell.json b/plugins/Huntress/v1/cspell.json new file mode 100644 index 0000000..7ae5c66 --- /dev/null +++ b/plugins/Huntress/v1/cspell.json @@ -0,0 +1,12 @@ +{ + "words": [ + "huntress", + "edr", + "itdr", + "substatus", + "subdomain", + "ipv4", + "footholds", + "ransomware" + ] +} diff --git a/plugins/Huntress/v1/custom_types.json b/plugins/Huntress/v1/custom_types.json new file mode 100644 index 0000000..2378783 --- /dev/null +++ b/plugins/Huntress/v1/custom_types.json @@ -0,0 +1,16 @@ +[ + { + "name": "Huntress Agent", + "sourceType": "Huntress Agent", + "icon": "laptop", + "singular": "Agent", + "plural": "Agents" + }, + { + "name": "Huntress Organization", + "sourceType": "Huntress Organization", + "icon": "building", + "singular": "Organization", + "plural": "Organizations" + } +] diff --git a/plugins/Huntress/v1/dataStreams/agents.json b/plugins/Huntress/v1/dataStreams/agents.json new file mode 100644 index 0000000..b51e75c --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/agents.json @@ -0,0 +1,160 @@ +{ + "name": "agents", + "displayName": "Agents", + "description": "All agents registered with your Huntress account", + "tags": ["Security", "Agents"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "/v1/agents", + "pathToData": "agents", + "expandInnerObjects": true, + "getArgs": [], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Agent ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "hostname", + "displayName": "Hostname", + "shape": "string", + "role": "label" + }, + { + "name": "organization_id", + "displayName": "Organization ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "account_id", + "displayName": "Account ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "domain_name", + "displayName": "Domain Name", + "shape": "string" + }, + { + "name": "os", + "displayName": "Operating System", + "shape": "string" + }, + { + "name": "platform", + "displayName": "Platform", + "shape": "string" + }, + { + "name": "arch", + "displayName": "Architecture", + "shape": "string" + }, + { + "name": "ipv4_address", + "displayName": "IPv4 Address", + "shape": "string" + }, + { + "name": "external_ip", + "displayName": "External IP", + "shape": "string" + }, + { + "name": "mac_addresses", + "displayName": "MAC Addresses", + "shape": "json" + }, + { + "name": "tags", + "displayName": "Tags", + "shape": "json" + }, + { + "name": "version", + "displayName": "Agent Version", + "shape": "string" + }, + { + "name": "edr_version", + "displayName": "EDR Version", + "shape": "string" + }, + { + "name": "defender_status", + "displayName": "Defender Status", + "shape": "string" + }, + { + "name": "defender_substatus", + "displayName": "Defender Substatus", + "shape": "string" + }, + { + "name": "defender_policy_status", + "displayName": "Defender Policy Status", + "shape": "string" + }, + { + "name": "firewall_status", + "displayName": "Firewall Status", + "shape": ["state", { "map": { "success": ["Enabled"], "error": ["Disabled"], "warning": ["Pending Isolation", "Isolated", "Pending Release"] } }] + }, + { + "name": "os_build_version", + "displayName": "OS Build Version", + "shape": "string" + }, + { + "name": "serial_number", + "displayName": "Serial Number", + "shape": "string" + }, + { + "name": "last_callback_at", + "displayName": "Last Callback At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "last_survey_at", + "displayName": "Last Survey At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "created_at", + "displayName": "Created At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/dataStreams/agentsByOrganization.json b/plugins/Huntress/v1/dataStreams/agentsByOrganization.json new file mode 100644 index 0000000..872512b --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/agentsByOrganization.json @@ -0,0 +1,169 @@ +{ + "name": "agentsByOrganization", + "displayName": "Agents by Organization", + "description": "Agents filtered by a scoped Huntress Organization", + "tags": ["Security", "Agents"], + "baseDataSourceName": "httpRequestScoped", + "objectLimit": 1, + "matches": { + "sourceType": { + "type": "equals", + "value": "Huntress Organization" + } + }, + "config": { + "httpMethod": "get", + "endpointPath": "/v1/agents", + "pathToData": "agents", + "expandInnerObjects": true, + "getArgs": [ + { "key": "organization_id", "value": "{{objects[0].organization_id}}" } + ], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Agent ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "hostname", + "displayName": "Hostname", + "shape": "string", + "role": "label" + }, + { + "name": "organization_id", + "displayName": "Organization ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "account_id", + "displayName": "Account ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "domain_name", + "displayName": "Domain Name", + "shape": "string" + }, + { + "name": "os", + "displayName": "Operating System", + "shape": "string" + }, + { + "name": "platform", + "displayName": "Platform", + "shape": "string" + }, + { + "name": "arch", + "displayName": "Architecture", + "shape": "string" + }, + { + "name": "ipv4_address", + "displayName": "IPv4 Address", + "shape": "string" + }, + { + "name": "external_ip", + "displayName": "External IP", + "shape": "string" + }, + { + "name": "mac_addresses", + "displayName": "MAC Addresses", + "shape": "json" + }, + { + "name": "tags", + "displayName": "Tags", + "shape": "json" + }, + { + "name": "version", + "displayName": "Agent Version", + "shape": "string" + }, + { + "name": "edr_version", + "displayName": "EDR Version", + "shape": "string" + }, + { + "name": "defender_status", + "displayName": "Defender Status", + "shape": "string" + }, + { + "name": "defender_substatus", + "displayName": "Defender Substatus", + "shape": "string" + }, + { + "name": "defender_policy_status", + "displayName": "Defender Policy Status", + "shape": "string" + }, + { + "name": "firewall_status", + "displayName": "Firewall Status", + "shape": ["state", { "map": { "success": ["Enabled"], "error": ["Disabled"], "warning": ["Pending Isolation", "Isolated", "Pending Release"] } }] + }, + { + "name": "os_build_version", + "displayName": "OS Build Version", + "shape": "string" + }, + { + "name": "serial_number", + "displayName": "Serial Number", + "shape": "string" + }, + { + "name": "last_callback_at", + "displayName": "Last Callback At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "last_survey_at", + "displayName": "Last Survey At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "created_at", + "displayName": "Created At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/dataStreams/escalations.json b/plugins/Huntress/v1/dataStreams/escalations.json new file mode 100644 index 0000000..b0e7a8e --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/escalations.json @@ -0,0 +1,95 @@ +{ + "name": "escalations", + "displayName": "Escalations", + "description": "Escalated security issues requiring attention across organizations", + "tags": ["Security", "Incidents"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "/v1/escalations", + "pathToData": "escalations", + "expandInnerObjects": true, + "getArgs": [], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Escalation ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "subject", + "displayName": "Subject", + "shape": "string", + "role": "label" + }, + { + "name": "type", + "displayName": "Type", + "shape": "string" + }, + { + "name": "severity", + "displayName": "Severity", + "shape": ["state", { "map": { "error": ["critical"], "warning": ["high"], "success": ["low"] } }] + }, + { + "name": "status", + "displayName": "Status", + "shape": ["state", { "map": { "success": ["resolved"], "warning": ["open", "sent"] } }] + }, + { + "name": "subtype", + "displayName": "Subtype", + "shape": "string" + }, + { + "name": "account.name", + "displayName": "Account", + "shape": "string" + }, + { + "name": "organizations", + "displayName": "Organizations", + "shape": "json" + }, + { + "name": "resolved_at", + "displayName": "Resolved At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "created_at", + "displayName": "Created At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/dataStreams/incident_reports.json b/plugins/Huntress/v1/dataStreams/incident_reports.json new file mode 100644 index 0000000..45cbd6b --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/incident_reports.json @@ -0,0 +1,105 @@ +{ + "name": "incident_reports", + "displayName": "Incident Reports", + "description": "Incident reports raised by the Huntress SOC against your agents", + "tags": ["Security", "Incidents"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "/v1/incident_reports", + "pathToData": "incident_reports", + "expandInnerObjects": true, + "getArgs": [], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Incident ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "subject", + "displayName": "Subject", + "shape": "string", + "role": "label" + }, + { + "name": "severity", + "displayName": "Severity", + "shape": ["state", { "map": { "error": ["critical"], "warning": ["high"], "success": ["low"] } }] + }, + { + "name": "status", + "displayName": "Status", + "shape": ["state", { "map": { "success": ["closed", "dismissed", "partner_dismissed"], "warning": ["sent", "auto_remediating", "deleting"] } }] + }, + { + "name": "platform", + "displayName": "Platform", + "shape": "string" + }, + { + "name": "organization_id", + "displayName": "Organization ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "agent_id", + "displayName": "Agent ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "indicator_types", + "displayName": "Indicator Types", + "shape": "json" + }, + { + "name": "summary", + "displayName": "Summary", + "shape": "string" + }, + { + "name": "sent_at", + "displayName": "Sent At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "closed_at", + "displayName": "Closed At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "status_updated_at", + "displayName": "Status Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/dataStreams/organizations.json b/plugins/Huntress/v1/dataStreams/organizations.json new file mode 100644 index 0000000..4f529dc --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/organizations.json @@ -0,0 +1,85 @@ +{ + "name": "organizations", + "displayName": "Organizations", + "description": "All organizations in your Huntress account", + "tags": ["Security", "Organizations"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "/v1/organizations", + "pathToData": "organizations", + "expandInnerObjects": true, + "getArgs": [], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Organization ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "name", + "displayName": "Organization Name", + "shape": "string", + "role": "label" + }, + { + "name": "agents_count", + "displayName": "Agents", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "incident_reports_count", + "displayName": "Incident Reports", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "logs_sources_count", + "displayName": "SIEM Sources", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "billable_identity_count", + "displayName": "Billable Identities", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "key", + "displayName": "Subdomain Key", + "shape": "string" + }, + { + "name": "created_at", + "displayName": "Created At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/dataStreams/platform_actions.json b/plugins/Huntress/v1/dataStreams/platform_actions.json new file mode 100644 index 0000000..a929eb3 --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/platform_actions.json @@ -0,0 +1,95 @@ +{ + "name": "platform_actions", + "displayName": "Platform Actions", + "description": "Operational issues requiring attention, such as Defender being disabled or integration failures", + "tags": ["Security", "Incidents"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "/v1/platform_actions", + "pathToData": "platform_actions", + "expandInnerObjects": true, + "getArgs": [], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Platform Action ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "subject", + "displayName": "Subject", + "shape": "string", + "role": "label" + }, + { + "name": "type", + "displayName": "Type", + "shape": "string" + }, + { + "name": "severity", + "displayName": "Severity", + "shape": ["state", { "map": { "error": ["critical"], "warning": ["high"], "success": ["low"] } }] + }, + { + "name": "status", + "displayName": "Status", + "shape": ["state", { "map": { "success": ["resolved"], "warning": ["open", "sent"] } }] + }, + { + "name": "subtype", + "displayName": "Subtype", + "shape": "string" + }, + { + "name": "account.name", + "displayName": "Account", + "shape": "string" + }, + { + "name": "organizations", + "displayName": "Organizations", + "shape": "json" + }, + { + "name": "resolved_at", + "displayName": "Resolved At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "created_at", + "displayName": "Created At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/dataStreams/signals.json b/plugins/Huntress/v1/dataStreams/signals.json new file mode 100644 index 0000000..afd890b --- /dev/null +++ b/plugins/Huntress/v1/dataStreams/signals.json @@ -0,0 +1,105 @@ +{ + "name": "signals", + "displayName": "Signals", + "description": "Threat detection signals investigated by the Huntress SOC", + "tags": ["Security", "Signals"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "/v1/signals", + "pathToData": "signals", + "expandInnerObjects": true, + "getArgs": [], + "headers": [], + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "in": { + "realm": "payload", + "path": "pagination.next_page_token" + }, + "out": { + "realm": "queryArg", + "path": "page_token" + } + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Signal ID", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "id", + "visible": false + }, + { + "name": "name", + "displayName": "Signal Name", + "shape": "string", + "role": "label" + }, + { + "name": "status", + "displayName": "Status", + "shape": ["state", { "map": { "success": ["closed"], "warning": ["reported"] } }] + }, + { + "name": "type", + "displayName": "Type", + "shape": "string" + }, + { + "name": "investigation_context", + "displayName": "Investigation Context", + "shape": "string" + }, + { + "name": "entity.id", + "displayName": "Entity ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "entity.name", + "displayName": "Entity", + "shape": "string" + }, + { + "name": "entity.type", + "displayName": "Entity Type", + "shape": "string" + }, + { + "name": "organization.id", + "displayName": "Organization ID", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "organization.name", + "displayName": "Organization", + "shape": "string" + }, + { + "name": "investigated_at", + "displayName": "Investigated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "created_at", + "displayName": "Created At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "name": "updated_at", + "displayName": "Updated At", + "shape": ["date", { "timeZone": "Etc/UTC" }] + }, + { + "pattern": ".*" + } + ], + "timeframes": false +} diff --git a/plugins/Huntress/v1/defaultContent/agents.dash.json b/plugins/Huntress/v1/defaultContent/agents.dash.json new file mode 100644 index 0000000..8bcd2f4 --- /dev/null +++ b/plugins/Huntress/v1/defaultContent/agents.dash.json @@ -0,0 +1,564 @@ +{ + "name": "Huntress Agents", + "path": "agents", + "folderPath": [], + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "version": 1, + "columns": 12, + "contents": [ + { + "x": 0, + "y": 0, + "w": 3, + "h": 2, + "i": "45df2e68-3ef8-4010-a653-b3e1cb99ad25", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Total Agents", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 3, + "y": 0, + "w": 3, + "h": 2, + "i": "48829397-e6e8-48a4-a697-9ef07a54476d", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "firewall_status", + "operation": "notequals", + "value": "Enabled" + } + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "monitorOld": { + "tileRollsUp": true, + "monitorType": "threshold", + "condition": { + "columns": [], + "logic": { + "if": [ + { + ">": [ + { + "var": "count" + }, + 0 + ] + }, + "error" + ] + } + }, + "_type": "simple", + "aggregation": "count", + "groupBy": "__group_by_none__", + "frequency": 15 + }, + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Firewall Not Enabled", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 6, + "y": 0, + "w": 3, + "h": 2, + "i": "276a70a7-3627-42e2-9bdf-5c4be66428b6", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "defender_status", + "operation": "equals", + "value": "Unhealthy" + } + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "monitorOld": { + "tileRollsUp": true, + "monitorType": "threshold", + "condition": { + "columns": [], + "logic": { + "if": [ + { + ">": [ + { + "var": "count" + }, + 0 + ] + }, + "error" + ] + } + }, + "_type": "simple", + "aggregation": "count", + "groupBy": "__group_by_none__", + "frequency": 15 + }, + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Defender Unhealthy", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 9, + "y": 0, + "w": 3, + "h": 2, + "i": "4e45724f-dd56-45bc-afe2-38be0979ff44", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "defender_policy_status", + "operation": "equals", + "value": "Non Compliant" + } + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "monitorOld": { + "tileRollsUp": true, + "monitorType": "threshold", + "condition": { + "columns": [], + "logic": { + "if": [ + { + ">": [ + { + "var": "count" + }, + 0 + ] + }, + "warning" + ] + } + }, + "_type": "simple", + "aggregation": "count", + "groupBy": "__group_by_none__", + "frequency": 15 + }, + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Policy Non-Compliant", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 0, + "y": 2, + "w": 4, + "h": 4, + "i": "76d6e45e-00a1-46ef-8594-151f4a491eb5", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "group": { + "by": [ + "platform", + "uniqueValues" + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Agents by Platform", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "labelColumn": "platform_uniqueValues", + "valueColumn": "platform", + "legendMode": "table", + "legendPosition": "right", + "showValuesAsPercentage": false, + "hideCenterValue": false + } + } + } + } + }, + { + "x": 4, + "y": 2, + "w": 4, + "h": 4, + "i": "ba5cdda0-6799-4e1f-a004-bc5ce9910743", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "group": { + "by": [ + "defender_status", + "uniqueValues" + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Agents by Defender Status", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "labelColumn": "defender_status_uniqueValues", + "valueColumn": "defender_status", + "legendMode": "table", + "legendPosition": "right", + "showValuesAsPercentage": false, + "hideCenterValue": false + } + } + } + } + }, + { + "x": 8, + "y": 2, + "w": 4, + "h": 4, + "i": "7259b481-a0ca-4369-83d4-bf77b399caf0", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "group": { + "by": [ + "firewall_status", + "uniqueValues" + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Agents by Firewall Status", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "labelColumn": "firewall_status_uniqueValues", + "valueColumn": "firewall_status", + "legendMode": "table", + "legendPosition": "right", + "showValuesAsPercentage": false, + "hideCenterValue": false + } + } + } + } + }, + { + "x": 0, + "y": 6, + "w": 6, + "h": 5, + "i": "34041486-98cf-477b-9d41-ff791e41af64", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "firewall_status", + "operation": "notequals", + "value": "Enabled" + } + ] + }, + "sort": { + "by": [ + [ + "last_callback_at", + "desc" + ] + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "⚠️ Firewall Not Enabled", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "hostname", + "os", + "ipv4_address", + "last_callback_at" + ] + } + } + } + } + }, + { + "x": 6, + "y": 6, + "w": 6, + "h": 5, + "i": "60594b28-c13b-4b9f-bd37-61105afa86bc", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "defender_status", + "operation": "equals", + "value": "Unhealthy" + } + ] + }, + "sort": { + "by": [ + [ + "last_survey_at", + "desc" + ] + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "🛡️ Defender Needs Attention", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "hostname", + "defender_status", + "defender_substatus", + "defender_policy_status", + "last_survey_at" + ] + } + } + } + } + }, + { + "x": 0, + "y": 11, + "w": 12, + "h": 8, + "i": "0e509127-fd5c-46f2-bc89-aaf65ceaeeb2", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agents", + "sort": { + "by": [ + [ + "hostname", + "asc" + ] + ] + }, + "id": "{{dataStreams.agents}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "All Agents", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "hostname", + "os", + "platform", + "ipv4_address", + "firewall_status", + "defender_status", + "defender_policy_status", + "version", + "last_callback_at" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/Huntress/v1/defaultContent/agentsByOrganization.dash.json b/plugins/Huntress/v1/defaultContent/agentsByOrganization.dash.json new file mode 100644 index 0000000..8ed8855 --- /dev/null +++ b/plugins/Huntress/v1/defaultContent/agentsByOrganization.dash.json @@ -0,0 +1,607 @@ +{ + "name": "Huntress Agents by Organization", + "path": "agentsByOrganization", + "folderPath": [], + "schemaVersion": "1.4", + "variables": [ + "{{variables.[Organization]}}" + ], + "dashboard": { + "_type": "layout/grid", + "version": 1, + "columns": 12, + "contents": [ + { + "x": 0, + "y": 0, + "w": 3, + "h": 2, + "i": "6bd74ce9-4a48-43b0-9ea3-12ea4055eb0e", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "Total Agents", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 3, + "y": 0, + "w": 3, + "h": 2, + "i": "0339d4e6-1afe-45c6-8be4-c7d3aaf5f125", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "firewall_status", + "operation": "notequals", + "value": "Enabled" + } + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "monitorOld": { + "tileRollsUp": true, + "monitorType": "threshold", + "condition": { + "columns": [], + "logic": { + "if": [ + { + ">": [ + { + "var": "count" + }, + 0 + ] + }, + "error" + ] + } + }, + "_type": "simple", + "aggregation": "count", + "groupBy": "__group_by_none__", + "frequency": 15 + }, + "title": "Firewall Not Enabled", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 6, + "y": 0, + "w": 3, + "h": 2, + "i": "f8850a23-c91c-444c-9b39-fa79ae4fb691", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "defender_status", + "operation": "equals", + "value": "Unhealthy" + } + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "monitorOld": { + "tileRollsUp": true, + "monitorType": "threshold", + "condition": { + "columns": [], + "logic": { + "if": [ + { + ">": [ + { + "var": "count" + }, + 0 + ] + }, + "error" + ] + } + }, + "_type": "simple", + "aggregation": "count", + "groupBy": "__group_by_none__", + "frequency": 15 + }, + "title": "Defender Unhealthy", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 9, + "y": 0, + "w": 3, + "h": 2, + "i": "d728f248-d0d0-4e39-b863-0da0f43d291e", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "defender_policy_status", + "operation": "equals", + "value": "Non Compliant" + } + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "monitorOld": { + "tileRollsUp": true, + "monitorType": "threshold", + "condition": { + "columns": [], + "logic": { + "if": [ + { + ">": [ + { + "var": "count" + }, + 0 + ] + }, + "warning" + ] + } + }, + "_type": "simple", + "aggregation": "count", + "groupBy": "__group_by_none__", + "frequency": 15 + }, + "title": "Policy Non-Compliant", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "agents", + "value": { + "type": "count" + } + } + } + } + } + }, + { + "x": 0, + "y": 2, + "w": 4, + "h": 4, + "i": "85a1e49f-6023-4995-b1b5-182433b59b08", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "group": { + "by": [ + "platform", + "uniqueValues" + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "Agents by Platform", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "labelColumn": "platform_uniqueValues", + "valueColumn": "platform", + "legendMode": "table", + "legendPosition": "right", + "showValuesAsPercentage": false, + "hideCenterValue": false + } + } + } + } + }, + { + "x": 4, + "y": 2, + "w": 4, + "h": 4, + "i": "7cc64d63-80b7-42b4-abb0-422d28b7d332", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "group": { + "by": [ + "defender_status", + "uniqueValues" + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "Agents by Defender Status", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "labelColumn": "defender_status_uniqueValues", + "valueColumn": "defender_status", + "legendMode": "table", + "legendPosition": "right", + "showValuesAsPercentage": false, + "hideCenterValue": false + } + } + } + } + }, + { + "x": 8, + "y": 2, + "w": 4, + "h": 4, + "i": "5cbb5561-33e9-42e5-855a-de0239b08354", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "group": { + "by": [ + "firewall_status", + "uniqueValues" + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "Agents by Firewall Status", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "labelColumn": "firewall_status_uniqueValues", + "valueColumn": "firewall_status", + "legendMode": "table", + "legendPosition": "right", + "showValuesAsPercentage": false, + "hideCenterValue": false + } + } + } + } + }, + { + "x": 0, + "y": 6, + "w": 6, + "h": 5, + "i": "dc5e2e5a-f024-4027-97c9-43345f12272a", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "firewall_status", + "operation": "notequals", + "value": "Enabled" + } + ] + }, + "sort": { + "by": [ + [ + "last_callback_at", + "desc" + ] + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "⚠️ Firewall Not Enabled", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "hostname", + "os", + "ipv4_address", + "last_callback_at" + ] + } + } + } + } + }, + { + "x": 6, + "y": 6, + "w": 6, + "h": 5, + "i": "76d01314-30b7-4e9a-9835-7c2d2f1f7786", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "defender_status", + "operation": "equals", + "value": "Unhealthy" + } + ] + }, + "sort": { + "by": [ + [ + "last_survey_at", + "desc" + ] + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "🛡️ Defender Needs Attention", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "hostname", + "defender_status", + "defender_substatus", + "defender_policy_status", + "last_survey_at" + ] + } + } + } + } + }, + { + "x": 0, + "y": 11, + "w": 12, + "h": 8, + "i": "a8844f57-2304-4119-8222-732e3f70c104", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "agentsByOrganization", + "sort": { + "by": [ + [ + "hostname", + "asc" + ] + ] + }, + "id": "{{dataStreams.agentsByOrganization}}" + }, + "scope": { + "scope": "{{scopes.[Huntress Organizations]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Organization]}}" + }, + "variables": [ + "{{variables.[Organization]}}" + ], + "_type": "tile/data-stream", + "description": "", + "title": "All Agents", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "hostname", + "os", + "platform", + "ipv4_address", + "firewall_status", + "defender_status", + "defender_policy_status", + "version", + "last_callback_at" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/Huntress/v1/defaultContent/incidents.dash.json b/plugins/Huntress/v1/defaultContent/incidents.dash.json new file mode 100644 index 0000000..6debe09 --- /dev/null +++ b/plugins/Huntress/v1/defaultContent/incidents.dash.json @@ -0,0 +1,59 @@ +{ + "name": "Huntress Incident Reports", + "path": "incidents", + "folderPath": [], + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "version": 1, + "columns": 12, + "contents": [ + { + "x": 0, + "y": 0, + "w": 12, + "h": 8, + "i": "b2c3d4e5-f6a7-8901-bcde-f12345678901", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "incident_reports", + "id": "{{dataStreams.incident_reports}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "All Incident Reports", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "subject", + "severity", + "status", + "organization_id", + "agent_id", + "sent_at" + ], + "hiddenColumns": [ + "id", + "body", + "account_id", + "indicator_counts", + "remediations" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/Huntress/v1/defaultContent/manifest.json b/plugins/Huntress/v1/defaultContent/manifest.json new file mode 100644 index 0000000..8683f20 --- /dev/null +++ b/plugins/Huntress/v1/defaultContent/manifest.json @@ -0,0 +1,20 @@ +{ + "items": [ + { + "name": "agents", + "type": "dashboard" + }, + { + "name": "agentsByOrganization", + "type": "dashboard" + }, + { + "name": "incidents", + "type": "dashboard" + }, + { + "name": "platform_actions", + "type": "dashboard" + } + ] +} diff --git a/plugins/Huntress/v1/defaultContent/platform_actions.dash.json b/plugins/Huntress/v1/defaultContent/platform_actions.dash.json new file mode 100644 index 0000000..c5f0475 --- /dev/null +++ b/plugins/Huntress/v1/defaultContent/platform_actions.dash.json @@ -0,0 +1,52 @@ +{ + "name": "Huntress Platform Actions", + "path": "platform_actions", + "folderPath": [], + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "version": 1, + "columns": 12, + "contents": [ + { + "x": 0, + "y": 0, + "w": 12, + "h": 8, + "i": "c3d4e5f6-a7b8-9012-cdef-123456789012", + "static": false, + "moved": false, + "z": 0, + "config": { + "timeframe": "none", + "dataStream": { + "name": "platform_actions", + "id": "{{dataStreams.platform_actions}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "All Platform Actions", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "subject", + "severity", + "status", + "type", + "subtype", + "created_at" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/Huntress/v1/defaultContent/scopes.json b/plugins/Huntress/v1/defaultContent/scopes.json new file mode 100644 index 0000000..3dff890 --- /dev/null +++ b/plugins/Huntress/v1/defaultContent/scopes.json @@ -0,0 +1,32 @@ +[ + { + "matches": { + "sourceType": { + "type": "equals", + "value": "Huntress Agent" + } + }, + "name": "Huntress Agents", + "variable": { + "allowMultipleSelection": false, + "default": "none", + "name": "Agent", + "type": "object" + } + }, + { + "matches": { + "sourceType": { + "type": "equals", + "value": "Huntress Organization" + } + }, + "name": "Huntress Organizations", + "variable": { + "allowMultipleSelection": false, + "default": "none", + "name": "Organization", + "type": "object" + } + } +] diff --git a/plugins/Huntress/v1/docs/README.md b/plugins/Huntress/v1/docs/README.md new file mode 100644 index 0000000..43a1198 --- /dev/null +++ b/plugins/Huntress/v1/docs/README.md @@ -0,0 +1,25 @@ +# Before you start + +To connect SquaredUp to Huntress, you will need to generate API credentials. + +## Generate API credentials + +1. Log in to your Huntress account at `https://.huntress.io`. +2. Open the dropdown menu at the top-right corner of the site header and select **API Credentials**. +3. Click on the **Setup** (or **Create API Credential**) button. +4. Click the **Generate** button to create a public and private key pair for Huntress API access. + +You will receive a **Public Key** and a **Private Key**. These will act as your `publicKey` and `privateKey` in SquaredUp. +**Important:** Make sure to copy the private key immediately, as it may only be displayed once! + +The default account-level credential is read-only, which is all this plugin needs. + +## Configure the plugin + +1. Add the **Huntress** plugin in SquaredUp. +2. Enter the **Public Key** and **Private Key** generated from Huntress. +3. Save the configuration to begin querying your agents, organizations, and incident reports. + +## Rate limits + +The Huntress API is limited to 60 requests per minute on a sliding window. Initial syncs of large environments (thousands of agents or many incident reports) may take longer to complete as the plugin paginates within this limit. \ No newline at end of file diff --git a/plugins/Huntress/v1/icon.png b/plugins/Huntress/v1/icon.png new file mode 100644 index 0000000..ff302a9 Binary files /dev/null and b/plugins/Huntress/v1/icon.png differ diff --git a/plugins/Huntress/v1/indexDefinitions/default.json b/plugins/Huntress/v1/indexDefinitions/default.json new file mode 100644 index 0000000..f532d6d --- /dev/null +++ b/plugins/Huntress/v1/indexDefinitions/default.json @@ -0,0 +1,45 @@ +{ + "steps": [ + { + "name": "agents", + "dataStream": { + "name": "agents" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "hostname", + "type": { "value": "Huntress Agent" }, + "properties": [ + "domain_name", + "os", + "platform", + "ipv4_address", + "external_ip", + "firewall_status", + "defender_status", + "version", + "organization_id" + ] + } + }, + { + "name": "organizations", + "dataStream": { + "name": "organizations" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { "value": "Huntress Organization" }, + "properties": [ + "agents_count", + "incident_reports_count", + "key", + { "organization_id": "id" } + ] + } + } + ] +} diff --git a/plugins/Huntress/v1/metadata.json b/plugins/Huntress/v1/metadata.json new file mode 100644 index 0000000..3585c8d --- /dev/null +++ b/plugins/Huntress/v1/metadata.json @@ -0,0 +1,39 @@ +{ + "name": "huntress", + "displayName": "Huntress", + "version": "1.0.0", + "author": { + "name": "Dan Watts", + "type": "community" + }, + "description": "Monitor agents, incidents, and organizations across your Huntress Managed Security Platform.", + "category": "Security", + "type": "cloud", + "restrictedToPlatforms": [], + "importNotSupported": false, + "schemaVersion": "2.0", + "base": { + "plugin": "WebAPI", + "majorVersion": "1", + "config": { + "authMode": "basic", + "queryArgs": [], + "headers": [], + "baseUrl": "https://api.huntress.io", + "basicAuthUsername": "{{publicKey}}", + "basicAuthPassword": "{{privateKey}}" + } + }, + "links": [ + { + "category": "documentation", + "url": "https://github.com/squaredup/plugins/blob/main/plugins/Huntress/v1/docs/README.md", + "label": "Help adding this plugin" + }, + { + "category": "source", + "url": "https://github.com/squaredup/plugins/tree/main/plugins/Huntress/v1", + "label": "Repository" + } + ] +} \ No newline at end of file diff --git a/plugins/Huntress/v1/ui.json b/plugins/Huntress/v1/ui.json new file mode 100644 index 0000000..afc6669 --- /dev/null +++ b/plugins/Huntress/v1/ui.json @@ -0,0 +1,22 @@ +[ + { + "type": "text", + "name": "publicKey", + "label": "API public key", + "help": "Generate API credentials at your Huntress account under Account > API Credentials", + "validation": { + "required": true + }, + "placeholder": "e.g. pub_XXXXXXXXXXXXXXXXXXXXXXXX" + }, + { + "type": "password", + "name": "privateKey", + "label": "API private key", + "help": "The private key is only shown once when generated — store it securely before saving", + "validation": { + "required": true + }, + "placeholder": "e.g. priv_XXXXXXXXXXXXXXXXXXXXXXX" + } +] \ No newline at end of file