Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Packs/soc-framework-pov-test/.pack-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[file_ignore_list]
.git
.git/*
images
images/*
documentation
documentation/*
1 change: 1 addition & 0 deletions Packs/soc-framework-pov-test/.secrets-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# secrets-ignore
28 changes: 28 additions & 0 deletions Packs/soc-framework-pov-test/Integrations/SOCFWPoVSender/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SOCFWPoVSender

Sends PoV attack scenario event data from XSIAM lists to an XSIAM HTTP Collector endpoint.

Configure one instance per data source. Run `!socfw-pov-send-data` from any case war room or the playground.

## Commands

### socfw-pov-send-data

Reads scenario events from an XSIAM list, rebases timestamps to now, normalizes source-specific fields, rotates suppression IDs, and POSTs to the configured HTTP Collector.

**Arguments:**

| Argument | Required | Description |
|---|---|---|
| `list_name` | Yes | XSIAM list containing scenario event data (JSON array) |
| `global_min` | No | ISO timestamp of earliest event across all sources in this scenario |
| `global_max` | No | ISO timestamp of latest event across all sources in this scenario |
| `compress_window` | No | Override compress window (e.g. `2h`, `30m`). Default: instance setting |

**Example:**

```
!socfw-pov-send-data list_name=SOCFWPoVData_CrowdStrike_TurlaCarbon_V1
global_min=2025-12-02T13:00:00Z global_max=2025-12-04T12:01:07Z
using=socfw_pov_crowdstrike_sender
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import demistomock as demisto # type: ignore
from CommonServerPython import * # type: ignore

import json
import urllib.request
import urllib.error


def _get_api_key(params: dict) -> str:
"""Type 4 credential params return either a plain string or {'password': '...'}."""
val = params.get("api_key", "")
if isinstance(val, dict):
return val.get("password", "")
return str(val or "").strip()


def test_module_command(params: dict) -> str:
url = (params.get("url") or "").strip()
api_key = _get_api_key(params)
source = (params.get("source_name") or "").strip()
if not url:
return "Configuration error: HTTP Collector URL is required."
if not api_key:
return "Configuration error: API Key is required."
if not source:
return "Configuration error: Source Name is required (e.g. crowdstrike or proofpoint)."
return "ok"


def send_data_command(params: dict, args: dict) -> CommandResults:
"""
Receives pre-processed events as a JSON string from SOCFWPoVSend script
and POSTs to the configured HTTP Collector endpoint as NDJSON.
All normalization and timestamp rebasing is done in the script layer.
"""
url = (params.get("url") or "").rstrip("/")
api_key = _get_api_key(params)

json_arg = args.get("JSON", "")
if not json_arg:
raise ValueError("JSON argument is required.")

events = json.loads(json_arg)
if not isinstance(events, list):
events = [events]

if not events:
return CommandResults(readable_output="No events to send.")

# XSIAM HTTP Collector expects newline-delimited JSON (NDJSON)
body = "\n".join(json.dumps(ev) for ev in events).encode("utf-8")

headers = {
"Content-Type": "application/json",
"Authorization": api_key,
}

req = urllib.request.Request(url, data=body, headers=headers, method="POST")
try:
with urllib.request.urlopen(req, timeout=30) as resp:
status = resp.getcode()
if status not in (200, 204):
raise ValueError(f"HTTP {status} from collector")
except urllib.error.HTTPError as e:
raise ValueError(f"HTTP {e.code} from collector: {e.reason}")
except urllib.error.URLError as e:
raise ValueError(f"URL error: {e.reason}")

return CommandResults(
readable_output=f"SOCFWPoVSender: {len(events)} events sent to {url}"
)


def main() -> None:
params = demisto.params()
command = demisto.command()
args = demisto.args()

demisto.debug(f"SOCFWPoVSender: command={command}")

try:
if command == "test-module":
return_results(test_module_command(params))
elif command == "socfw-pov-send-data":
return_results(send_data_command(params, args))
else:
raise NotImplementedError(f"Command '{command}' is not implemented.")
except Exception as e:
return_error(f"SOCFWPoVSender error [{command}]: {str(e)}")


if __name__ in ("__main__", "__builtin__", "builtins"):
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
commonfields:
id: SOCFWPoVSender
version: -1
name: SOCFWPoVSender
display: SOC Framework PoV Sender
category: Utilities
description: |-
Thin HTTP POST wrapper for the SOC Framework PoV Test pack.
Receives pre-processed events from the SOCFWPoVSend script and
posts them as NDJSON to the configured HTTP Collector endpoint.
All list reading, normalization, and timestamp rebasing is handled
by the SOCFWPoVSend script — this integration only stores credentials
and performs the HTTP POST.
configuration:
- name: url
display: HTTP Collector URL
required: true
type: 0
section: Connect
additionalinfo: |-
Full URL of the XSIAM HTTP Collector endpoint for this data source.
Found in Settings → Data Sources → [your collector] → Connection Details.

- name: api_key
display: API Key
required: true
type: 4
section: Connect
additionalinfo: HTTP Collector API key for this data source.

- name: source_name
display: Source Name
required: true
type: 0
defaultvalue: crowdstrike
section: Connect
additionalinfo: |-
Source type label for logging. e.g. crowdstrike, proofpoint.

- name: insecure
display: Trust any certificate (not secure)
required: false
type: 8
section: Connect
advanced: true

- name: proxy
display: Use system proxy settings
required: false
type: 8
section: Connect
advanced: true

script:
script: ''
type: python
subtype: python3
dockerimage: demisto/python3:3.10.14.100715
commands:
- name: socfw-pov-send-data
description: |-
Accepts pre-processed events as a JSON string and posts them as
NDJSON to the configured HTTP Collector. Called by the SOCFWPoVSend
script — do not call directly.
arguments:
- name: JSON
required: true
description: JSON array of events to send (pre-processed by SOCFWPoVSend script).
outputs: []
fromversion: 8.0.0
tests:
- No tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"allRead": true,
"allReadWrite": false,
"dbotCreated": false,
"description": "Turla Carbon scenario — CrowdStrike Falcon endpoint detection events from BYOS MITRE lab execution (December 2025). 138 events covering Execution, Command and Control, Lateral Movement, and Ingress Tool Transfer tactics across hosts hobgoblin and bannik. Used by SOCFWPoVSender to replay the EDR leg of the Turla Carbon attack chain.",
"fromVersion": "6.5.0",
"id": "SOCFWPoVData_CrowdStrike_TurlaCarbon_V1",
"itemVersion": "",
"locked": false,
"name": "SOCFWPoVData_CrowdStrike_TurlaCarbon_V1",
"display_name": "SOCFWPoVData_CrowdStrike_TurlaCarbon_V1",
"packID": "soc-framework-pov-test",
"propagationLabels": ["all"],
"system": false,
"tags": [],
"toVersion": "",
"truncated": false,
"type": "json",
"version": -1
}
Loading
Loading