Commit Graph

228 Commits

Author SHA1 Message Date
f3nris 1d475a6cf5 fix(sentinelone): count-agents can be asked about the whole fleet again
Declared as a boolean, isActive rendered as a checkbox in the toolbox,
and a checkbox has no empty state: the count was forced to one half of
the fleet or the other, with no way to ask for both. As text, an empty
field means the filter is not sent.

true/yes/1 and false/no/0 are read in any case, a real JSON boolean from
a playbook still works, and anything else is refused rather than folded
into false — that would answer a different question than the one asked.
2026-08-14 23:48:40 +02:00
f3nris 93309ac74d feat(sentinelone): count-agents can be scoped to an account
A multi-tenant console answered one number for the whole estate.
accountIds narrows the count to the accounts asked for, the way
get_threats and get_alerts already do at fetch time.
2026-08-14 23:40:13 +02:00
f3nris a5095d3f0f feat(sentinelone): count-agents can tell the active fleet from the dormant one
isActive splits a count that until now lumped both together. It is sent
only when the caller sets it: an unset boolean must not reach the console
as isActive=false and quietly count the dormant agents instead of all of
them.
2026-08-14 23:30:47 +02:00
f3nris cebb3af796 feat(sentinelone): count-agents can ask about versions, state and hardware
The count only knew where an agent was, not what it was running or what
it runs on. Four filters carry the console's own vocabulary through:
agentVersion__gt to count the fleet still below a target build,
networkStatuses to keep only the endpoints in a given connection state,
operationalStatesNin to leave states out of the tally, and machineTypes
to count servers apart from laptops.

The list filters are split and re-joined so a hand-typed
"connected, disconnected" does not reach the API with the space inside
the value.
2026-08-14 22:39:29 +02:00
f3nris ba6bcd19f4 fix(cortex-xdr): say what went wrong when the API answers something other than JSON (v1.2.1)
A tenant URL that is not the API host answers 200 with the console's HTML
shell, and the client turned that into "Expecting value: line 1 column 1
(char 0)" — a JSON parse error that names neither the URL nor the response.

The shared client now reports the status, content type and first bytes of any
non-JSON reply, and points at the API host the operator was meant to copy.
Around it, the URL is reduced to scheme + host so a pasted /public_api/v1 or
console path cannot double the API root, a missing key or key ID is refused
before the request, and 401/403 recalls the three usual causes (auth mode,
revoked key, clock skew).

Nonce and timestamp now ride along in standard mode too, matching the
reference client, and test_connection probes get_incidents — the read that
ingestion actually depends on — instead of the distribution versions.
2026-08-13 14:35:54 +02:00
f3nris aabe1a6837 feat(riposte-sextant): list the clients, and the identifier to deposit under (v1.1.0)
The refusal you get on the first run is "no Sextant client is paired with this
SOAR client", and it names the identifier it did not recognise — but nothing
told you which ones it would have recognised. This does.

Clients with no pairing appear with an empty identifier, and are surfaced again
under `unpaired`: they are the whole reason somebody runs this command twice,
and spotting them in a list is exactly what nobody does.

Verified against a running Sextant: the paired client comes back with its
identifier, and the route refuses a caller with no ingestion token.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:04:30 +02:00
f3nris 50358ef8a1 feat(riposte-sextant): push agent readings into the SOC steering file
Sextant counts nothing itself: it receives. Until now the opposite was true —
it reached into this SOAR to run a command, which meant SOAR had to host a
whitelist table, a screen to fill it, a dedicated permission and a catalogue
route. Configuration belonging to another product, living here.

As an integration, none of that is needed: an operator creates an instance with
a URL and a token like for any other tool, and a scheduled playbook counts on
the vendor console, maps, then calls push_agent_stats.

The mapping lives in that playbook, which is where it belongs — next to the
connector that produced the numbers, and per client rather than per product.

WHAT THE SCRIPT REFUSES TO DO, and why it matters more than what it does: a
counter left empty is OMITTED, never sent as zero. "We did not measure how many
agents are in error" and "no agent is in error" are opposite pieces of news, and
the second reassures wrongly — the whole steering file exists not to say it. A
counter that is present but not a number is refused instead, naming the field:
that is a broken mapping in the calling playbook, and dropping it silently would
look exactly like "not measured".

Verified against a running Sextant rather than assumed: the deposit files under
the paired client with the empty counter absent, a broken mapping is refused by
name, and an unpaired client comes back saying which identifier was not
recognised.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 08:46:10 +02:00
f3nris 82f22fdbb3 feat(harfanglab): split image_name into the process path and the threat name (v1.4.1)
image_name was left unmapped because HarfangLab prefixes it with the
matched threat name — "[PUADlManager:Win32/OfferCore] C:\Windows\
explorer.exe" — and the clean path was available from the event data.
That reasoning only held for event-log alerts. On the yara, binary and
ioc subtypes there is neither a `process` object nor an `eventlog`
block, so those alerts reached the incident with no process at all.

Both halves are now pulled out, each guarded on the bracket actually
being there: $substringBefore and $substringAfter return the whole
string when the pattern is absent, so without the guard an unprefixed
path would land verbatim in malware.name.

The three entries lead the process block so the more specific sources
below — the matched process object, then the event log's own fields —
still overwrite them when present. malware.name consequently surfaces on
every subtype instead of only where Defender is the source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 18:15:44 +02:00
f3nris f7c5e99cc5 feat(harfanglab): map the fields the alert and threat payloads actually carry (v1.4.0)
Replayed a real get_alerts and a real get_threats response through the
bundled mappers to see what came out.

get_alerts: a sigma alert matching a Windows event log carries the whole
record under `eventlog`, and none of it was mapped. On a Defender 1116
detection that left the malware, the file, the acting user and the
detecting product invisible — the incident indexed a hostname and
nothing else. The event data uses the provider's own field names, spaces
included, so the new entries quote them with JSONata backticks, and
Defender's "file:_" path prefix is stripped. Also added the agent IP
(placed before details_connection.SourceIp so a network alert's own
source still wins), the DNS domain, device type, agent version and
groups, the tenant, the alert subtype and threat type, the string
severity and the event time.

get_threats: `level` had no entry at all, so a threat's severity never
reached the OCSF document even though field_mappings derived the
incident's 1-5 from it. Added it, the event time, and the top agent's
reachability — whether the endpoint is online decides what response is
possible, and it was excluded without a reason.

Both trailers now record why each remaining field is left out, and the
event log's own SYSTEM writer and FQDN spelling are called out: indexing
them would create a junk user entity and a second spelling of one host.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 17:30:01 +02:00
f3nris 6343a0c952 feat(ipinfo): support the Lite API for free/Lite plan tokens (v1.1.0)
The integration only exposed the Core API (/lookup/*), which returns 403
for accounts on the free/Lite plan — including the instance Test button.

Add the Lite endpoints: lite_lookup_ip (GET /lite/{ip}), lite_lookup_me
(GET /lite/me) and lite_batch (POST /batch/lite, code-first because the
endpoint takes a raw JSON array; chunked at the documented 1000-IP cap).

Point test_connection at /lite/me: every plan can reach it, so the token
check now succeeds on Lite-only accounts while still validating Core ones.
Core commands keep their paths and state the plan requirement up front.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 21:01:43 +02:00
Guillaume BOURGEOIS 7efc873867 feat(sentinelone): scope threat and alert fetches to given accounts (v1.4.0)
A multi-tenant console returns every account's threats and alerts at once.
get_threats and get_alerts now take an optional account_ids input, passed
through as the accountIds query parameter, so an ingestion can be pinned to
the accounts the SOC actually watches.

The input is optional, so existing instances and running ingestions keep
their current behaviour.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 15:56:47 +02:00
f3nris 144089a099 fix(harfanglab): flag get_alerts as ingestion-ready (v1.3.1)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 23:19:58 +02:00
f3nris a4b5b44157 fix(harfanglab): null guards and stable attacks array in get_threats mapper
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:52:11 +02:00
f3nris 4ea3af6c1d fix(harfanglab): rework get_threats OCSF mapper from live threat sample
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:49:31 +02:00
f3nris 952dc7efda feat(harfanglab): v1.3.0 — response & triage expansion (27 commands + alert mappers)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:33:59 +02:00
f3nris cba746a9f9 feat(harfanglab): exhaustive alert OCSF mappers (get_alerts + upgraded get_security_events)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:26:19 +02:00
f3nris 5d6f823189 feat(harfanglab): threat triage commands (status, level, comment, note, history)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:20:54 +02:00
f3nris 098b90d6f3 feat(harfanglab): alert triage commands (tag, comment, details, history)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:18:01 +02:00
f3nris db902c35bc feat(harfanglab): alert search and single-threat read commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:14:25 +02:00
f3nris 59e9211c0d feat(harfanglab): threat-level isolation and job lifecycle commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:09:56 +02:00
f3nris fcbd2ff135 feat(harfanglab): quarantine management commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:04:47 +02:00
f3nris ef60cec0fa feat(harfanglab): file/service/scheduled-task deletion commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:01:22 +02:00
f3nris 6d993f584f feat(harfanglab): on-demand AV and YARA scan commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 21:57:37 +02:00
f3nris 6d311740f9 feat(harfanglab): kill/dump process response commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 21:52:39 +02:00
f3nris f6b8c84285 feat(edr): OCSF mappers + ingestion for 6 EDR integrations
Every EDR (category: endpoint) integration is now audited for an OCSF mapper.
Six had a fetch command but no mapper — add a bundled OCSF mapper for each,
wire the fetch command as an ingestion source (ingest: results_path/dedup_key
[/incremental_field]) and add the top-level ingestion block. Field mappings
were derived from each vendor's fetch output and cross-referenced against the
demisto/content reference for that vendor.

- carbon-black-cloud: search_alerts (results_path results, dedup id) — 35 fields
- cisco-secure-endpoint: list_events (data, id) — 21 fields
- cybereason: query_malops (malops, guid, incr start_time) — 6 fields
- sophos-central: list_alerts (items, id) — 14 fields
- trend-vision-one: list_alerts (items, id, incr start_datetime) — 19 fields
- withsecure: list_incidents (items, incidentId) — 7 fields

Validated: every manifest passes ParseManifest+ValidateManifest and every mapper
passes ParseMapperFile with all JSONata source_path/field expressions compiling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 22:37:07 +02:00
f3nris 5ee7352652 fix(ransomware-live): keyless — drop optional API key, no auth required
Ransomware.live's v2 API is free and needs no authentication. Remove the
optional api_key config field and the X-API-KEY header logic from all commands
so instance creation requires no credentials. Only an optional base_url override
remains.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 19:18:49 +02:00
f3nris 534748f16a feat(ransomware-live): add Ransomware.live OSINT integration
Ransomware.live API v2 — OSINT tracking of ransomware/extortion groups and
their claimed victims. 9 read-only commands: recent victims, list groups,
group profile, group victims, and search victims by keyword, country, or date,
plus recent cyberattacks and a test-connection check. Useful for third-party /
supply-chain exposure checks (is a partner or domain listed as a victim?).

API key is optional (sent as X-API-KEY when configured; keyless otherwise).
stdlib-only Python (urllib), no extra dependencies. category: threat_intel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:56:50 +02:00
Guillaume BOURGEOIS a2c9f998c3 feat(feed): add Botvrij.eu OSINT feed connector (IOC lists by type) 2026-07-13 12:15:50 +02:00
Guillaume BOURGEOIS ae7c494658 feat(feed): add Microsoft 365 endpoints feed connector (allowlist / known infra) 2026-07-13 12:15:50 +02:00
Guillaume BOURGEOIS 40252dadcb feat(feed): add generic RSS/Atom IOC feed connector (URL/IP/hash extraction, defang-aware) 2026-07-13 12:15:49 +02:00
Guillaume BOURGEOIS ac2203f9a5 feat(feed): add FIRST EPSS feed connector (exploit-prediction scores) 2026-07-13 12:12:35 +02:00
Guillaume BOURGEOIS 8248c60da8 feat(feed): add NVD CVE feed connector (recent CVEs, NVD 2.0 API) 2026-07-13 12:12:34 +02:00
Guillaume BOURGEOIS 4206b44e78 feat(feed): add CISA KEV feed connector (known exploited vulnerabilities) 2026-07-13 12:12:34 +02:00
Guillaume BOURGEOIS 9cffefbb36 feat(feed): add GCP IP ranges feed connector (allowlist / known infra) 2026-07-13 12:08:49 +02:00
Guillaume BOURGEOIS f7791402a3 feat(feed): add Cloudflare IPs feed connector (allowlist / known infra) 2026-07-13 12:08:49 +02:00
Guillaume BOURGEOIS c42a9cef03 feat(feed): add AWS IP ranges feed connector (allowlist / known infra) 2026-07-13 12:08:48 +02:00
Guillaume BOURGEOIS f6ff018f09 feat(feed): add OpenPhish feed connector (community phishing URLs) 2026-07-12 23:02:11 +02:00
Guillaume BOURGEOIS c091800434 feat(feed): add Emerging Threats feed connector (ET Open reputation lists) 2026-07-12 23:02:11 +02:00
Guillaume BOURGEOIS 929b4166d6 feat(feed): add generic JSON feed connector (configurable field mapping) 2026-07-12 23:02:10 +02:00
Guillaume BOURGEOIS 381b42b6c7 feat(feed): add CINS Army feed connector (CI Army bad-guys list) 2026-07-12 22:59:20 +02:00
Guillaume BOURGEOIS 5715f21603 feat(feed): add Blocklist.de feed connector (fail2ban attacker lists) 2026-07-12 22:59:19 +02:00
Guillaume BOURGEOIS 7543a95711 feat(feed): add DShield block list feed connector (SANS ISC) 2026-07-12 22:59:18 +02:00
Guillaume BOURGEOIS 7187e7b607 feat(feed): add SSL Blacklist feed connector (abuse.ch C2 IP/fingerprint lists) 2026-07-12 22:56:36 +02:00
Guillaume BOURGEOIS 5bb465eb18 feat(feed): add ThreatFox feed connector (abuse.ch IOC export) 2026-07-12 22:56:36 +02:00
Guillaume BOURGEOIS a4dcd00cc7 feat(feed): add URLhaus feed connector (abuse.ch malware URL feed) 2026-07-12 22:56:35 +02:00
Guillaume BOURGEOIS cf923301a7 feat(feed): add Spamhaus DROP feed connector (DROP/DROPv6/ASN-DROP) 2026-07-12 22:49:30 +02:00
Guillaume BOURGEOIS f833bfe3a5 feat(feed): add Tor exit nodes feed connector 2026-07-12 22:49:29 +02:00
Guillaume BOURGEOIS d6129f5d79 feat(feed): add Feodo Tracker feed connector (abuse.ch C2 IP blocklist) 2026-07-12 22:49:28 +02:00
Guillaume BOURGEOIS c779c38dab feat(feed-taxii2): new generic TAXII 2.1 / STIX feed connector
Pulls STIX 2.x indicators from any TAXII 2.1 server, parses the STIX patterns
into normalized IOCs {value,type} for TIM import. list-collections + fetch.
Basic/bearer/none auth, stdlib-only. py_compile clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 22:43:17 +02:00
Guillaume BOURGEOIS 4f94b59e17 feat(feed-plaintext): new generic plain-text threat-intel feed connector
Fetches a line-per-indicator blocklist URL and emits normalized IOCs {value,type}
for TIM import. Comment-char/field-index/type config, auto type-detection.
Optional bearer auth, stdlib-only. py_compile clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 22:43:17 +02:00