feat(ransomwarelive): enrich groups with aliases, leak sites and TTPs (#6299)#6300
feat(ransomwarelive): enrich groups with aliases, leak sites and TTPs (#6299)#6300Lyra-Fox wants to merge 7 commits into
Conversation
…tes, external refs, and TTPs
Contributor License Agreement✅ CLA signed 💚 Thank you @Lyra-Fox for signing the Contributor License Agreement! Your pull request can now be reviewed and merged. We appreciate your contribution to Filigran's open source projects! ❤️ This is an automated message from the Filigran CLA Bot. |
…OMAINS and CONNECTOR_CREATE_LEAK_POST_REFS to false
There was a problem hiding this comment.
Pull request overview
This PR enhances the external-import/ransomwarelive connector to ingest additional group- and victim-level enrichment from the ransomware.live /v2/groups API, with new safety toggles for ingesting leak-site related domains/URLs, plus adds unit tests and documentation updates.
Changes:
- Enrich IntrusionSet/ThreatActor with group aliases and external references (group profile + optional leak-site URLs), and enrich Reports with additional external references (including an optional direct leak-post URL).
- Optionally ingest leak-site FQDNs as
DomainNameobservables related to the IntrusionSet, and createusesrelationships from IntrusionSet to existing ATT&CKAttackPatternobjects. - Add per-run group deduplication and a 30s HTTP timeout; introduce a new unit test suite and update connector docs/config schema.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| external-import/ransomwarelive/tests/test-requirements.txt | Adds test dependencies for the connector’s new unit test suite. |
| external-import/ransomwarelive/tests/test_group_enrichment.py | Adds unit tests for group alias/ext-ref extraction, leak site domain creation, TTP relationships, and per-run deduplication. |
| external-import/ransomwarelive/tests/conftest.py | Ensures src/ is importable during tests. |
| external-import/ransomwarelive/src/ransomwarelive/utils.py | Adds get_group_entry helper for group enrichment lookups. |
| external-import/ransomwarelive/src/ransomwarelive/ransom_conn.py | Implements per-run group enrichment dedup + ATT&CK lookup + toggled leak enrichment; includes marking in bundles. |
| external-import/ransomwarelive/src/ransomwarelive/converter_to_stix.py | Adds group alias/ext-ref extraction, leak-site domain processing, and toggled leak-post report refs. |
| external-import/ransomwarelive/src/ransomwarelive/api_client.py | Adds a 30s request timeout and refines typing. |
| external-import/ransomwarelive/src/models/configs/connector_configs.py | Adds create_leak_site_domains and create_leak_post_refs configuration toggles (default false). |
| external-import/ransomwarelive/README.md | Updates entity mapping and documents the new leak-link toggles and their compliance implications. |
| external-import/ransomwarelive/docker-compose.yml | Documents new env vars in the sample compose configuration. |
| external-import/ransomwarelive/metadata/connector_config_schema.json | Adds the new toggle keys to the generated config schema. |
| external-import/ransomwarelive/metadata/CONNECTOR_CONFIG_DOC.md | Adds the new toggle keys to the generated config documentation. |
- ransom_conn.py: only mark a group as processed in `_collect_group_enrichment_objects` after a matching `group_entry` is found, so a partial/inconsistent `/v2/groups` response doesn't permanently skip the group for the rest of the run (resolves Copilot thread). - ransom_conn.py: correct the `process_group_ttps` docstring — it returns only the `uses` Relationship objects; the referenced AttackPatterns are resolved from OpenCTI by id and are not added to the bundle (resolves Copilot thread). - tests/test-requirements.txt: simplify the include path `../src/../requirements.txt` to `../requirements.txt` (resolves Copilot thread). - requirements.txt: bump pycti to the latest released 7.260604.0 (was 7.260423.0) to match the pin in connectors-sdk @ master; the older pin now conflicts at install time.
The connector was substantially refactored on master after this PR was opened (Campaign support, ConverterToStix(marking_value), helper-based RansomwareAPIClient with retry/30s-timeout, and a restructured create_bundle_list). This merge re-applies the group-enrichment feature on top of master's new structure: - converter_to_stix.py: add aliases + external_references to create_intrusionset / create_threat_actor; gate the leak-post URL (post_url) behind create_leak_post_refs in process_external_references; add _extract_group_aliases(_and_refs) and process_group_leak_sites; enrich process_intrusion_set / process_threat_actor with group aliases and external references derived from the /v2/groups entry. - ransom_conn.py: pass create_leak_site_domains into ConverterToStix, track processed_groups, add attack_pattern_fetcher / process_group_ttps / _collect_group_enrichment_objects, and wire leak-site domains + TTP relationships into create_bundle_list (gated on create_intrusion_set) plus the create_leak_post_refs toggle on report external references. - api_client.py: drop the PR's standalone 30s timeout; master already adds it (plus 429 retry/backoff) in the helper-based client. - Regenerated __metadata__/connector_config_schema.json and CONNECTOR_CONFIG_DOC.md; documented the two toggles in README.md and docker-compose.yml. - tests: update fixtures to the new ConverterToStix(marking_value) signature and the post_url field name; full suite passes (40 tests). - requirements: master moved requirements.txt to src/requirements.txt (pycti pinned to 7.260604.0 to match connectors-sdk @ master); test-requirements points at it.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6300 +/- ##
===========================================
- Coverage 11.82% 0.44% -11.39%
===========================================
Files 1911 1885 -26
Lines 120103 119264 -839
===========================================
- Hits 14204 527 -13677
- Misses 105899 118737 +12838
📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
SamuelHassine
left a comment
There was a problem hiding this comment.
Approving. I read the full changed files (not just the diff) and reconciled the group-enrichment feature onto master's refactored connector. All checks are green (Tests Connectors, codecov patch/project, signed commits, PR conventions), the unit suite passes (40 tests), and all three Copilot threads are addressed and resolved.
Review & reconcile summaryThis PR was 215 commits behind
CI is fully green (Tests Connectors, codecov patch/project, signed commits, PR conventions, do-not-merge, CLA). |
- Reset processed_groups at the start of each collection sweep so a group enriched on an earlier scheduled run is no longer permanently skipped. schedule_iso reuses the connector instance across runs, so without this reset newly disclosed leak sites / TTPs for an already-seen group were never picked up until the process restarted. - Correct the process_external_references docstring to state it returns a list of ExternalReference objects (empty list when none of the expected fields are present), not a single object. - Add unit tests covering the per-run reset of both collectors and tidy a duplicate comment header in the test module.
SamuelHassine
left a comment
There was a problem hiding this comment.
Reviewed the full changed files independently (not just the diff) and addressed every outstanding review thread.
- Fixed the per-run
processed_groupsdedup reset - it was suppressing group enrichment across scheduled runs because the connector instance is reused byschedule_iso. - Corrected the
process_external_referencesdocstring return type. - Added unit tests for the per-run reset on both collectors (42 tests pass);
black/isort/flake8clean.
All five previously-open Copilot threads are resolved. CI is fully green and the PR is mergeable. LGTM.
Review & fix pass completeIndependent senior review of the full changed files plus resolution of every open thread:
All five previously-open Copilot threads are resolved. CI is fully green (Tests Connectors, codecov patch/project, PR conventions, do-not-merge, CLA). |
Resolve the two remaining Copilot review threads. The compliance-sensitive enrichment helpers defaulted their method parameters to True while the connector config toggles (CONNECTOR_CREATE_LEAK_SITE_DOMAINS / CONNECTOR_CREATE_LEAK_POST_REFS) default to False. The runtime always passes the configured value explicitly, so this had no effect on the connector, but any ad-hoc or future call site that forgot the flag would silently emit leak-site domains/URLs and direct leak-post URLs - failing open for behaviour that exists specifically to comply with local rules on handling leaked-data links. - converter_to_stix: ConverterToStix(create_leak_site_domains=...) and process_external_references(create_leak_post_refs=...) now default to False (fail closed), mirroring the config defaults; no runtime behaviour change. - tests: the two cases that exercise leak-site slug references now construct a converter with create_leak_site_domains=True explicitly; added regression tests asserting the default converter omits leak-site slugs and the default process_external_references omits the leak-post URL (44 passing; black / isort / flake8 clean).
SamuelHassine
left a comment
There was a problem hiding this comment.
Re-approving after an independent full-file re-review of the connector and resolving the two remaining Copilot threads in signed commit 6ea348d6da.
Both threads were the same class of issue, and both are legitimate: the compliance-sensitive enrichment helpers (ConverterToStix(create_leak_site_domains=...) and process_external_references(create_leak_post_refs=...)) defaulted their parameters to True while the corresponding config toggles default to False. The runtime always passes the configured value explicitly, so the connector's behaviour was correct, but the method-level defaults failed open - any future/ad-hoc call site that forgot the flag would silently emit leak-site domains/URLs and direct leak-post URLs. They now default to False (fail closed), mirroring the config and the connector's stated compliance posture.
Tests updated accordingly: the two cases that exercise leak-site slug references opt in explicitly, plus new regression tests assert the defaults omit leak-site slugs and the leak-post URL (44 passing; black / isort / flake8 clean).
I also confirmed pycti must stay pinned at 7.260604.0 to match the exact pin in connectors-sdk @ master (this connector installs the SDK from master) - bumping it would conflict at install. All GitHub Actions checks - including the Lint & Format and STIX ID Linter workflows - plus Codecov patch/project are green; 0 unresolved review threads; mergeable: MERGEABLE. LGTM.
Review & fix summary (round 3)Independent full-file re-review of the connector plus the two remaining Copilot threads from the latest review, fixed in signed commit
Status
Non-blocking follow-up (future iteration)
|
Proposed changes
altnameasaliaseson IntrusionSet and ThreatActor.Domain-Nameobservables linked to the IntrusionSet viarelated-to, and add leak-site URLs as external references (gated byCONNECTOR_CREATE_LEAK_SITE_DOMAINS).usesrelationships from IntrusionSet to ATT&CKAttackPatternobjects for each group TTP. Correlation resolves against AttackPatterns already present in OpenCTI (e.g. via the MITRE connector); techniques with no match are silently skipped.CONNECTOR_CREATE_LEAK_POST_REFSto toggle inclusion of the direct leak-post URL on victim Reports.Both new toggles default to
falseto preserve backwards compatibility and to make it easier to comply with differing local regulations around handling links to leaked data.Related issues
Closes #6299
Maintainer review & reconcile (@SamuelHassine)
masterafter a large connector refactor that landed since this PR was opened (Campaign support,ConverterToStix(marking_value), a helper-basedRansomwareAPIClientwith 429 retry/backoff and a 30s timeout, and a restructuredcreate_bundle_list). The PR's standalone 30s timeout is now covered by master's client, so that change was dropped in favour of master's version.Domain-Nameobservables and IntrusionSet -> AttackPatternusesrelationships wired intocreate_bundle_list(gated oncreate_intrusion_set), and thecreate_leak_post_refstoggle gating the leak-post URL (post_url) on report external references.__metadata__/connector_config_schema.jsonand__metadata__/CONNECTOR_CONFIG_DOC.mdfrom the config model; documented the two toggles inREADME.mdanddocker-compose.yml.pyctito matchconnectors-sdk @ master(the old pin conflicted at install time). Master movedrequirements.txttosrc/requirements.txt; the test include now points there.ConverterToStix(marking_value),post_url).Review-and-fix pass (de2419c)
processed_groupswas created once in__init__and never reset. Sinceschedule_isoreuses the connector instance across scheduled runs, a group enriched on an earlier run stayed in the set forever and its newly disclosed leak sites / TTPs were skipped until the process restarted. The set is now reset at the start of each collection sweep (collect_intelligence/collect_historic_intelligence).process_external_referencesdocstring to state it returns a list ofExternalReferenceobjects (empty list when none apply), not a single object.attack_pattern_fetcherconsistent with the connector's other 8 error logs (positionalmetadict); pycti'sAppLogger.error(message, meta=None)binds the second positional argument tometaand already passesexc_info=1, so the change is cosmetic and a one-off would only introduce inconsistency. Noted as a possible repo-wide logging-cleanup follow-up.Review-and-fix pass (6ea348d)
ConverterToStix(create_leak_site_domains=...)andprocess_external_references(create_leak_post_refs=...)now default toFalse, matching theCONNECTOR_CREATE_LEAK_SITE_DOMAINS/CONNECTOR_CREATE_LEAK_POST_REFSconfig defaults. The runtime already passes the configured values explicitly, so there is no behaviour change for the connector; the fix prevents an ad-hoc or future call site that forgets the flag from silently emitting leak-site domains/URLs or direct leak-post URLs (behaviour that exists specifically to help comply with local rules on handling leaked-data links).create_leak_site_domains=Trueexplicitly, and added regression tests asserting the default converter omits leak-site slug URLs and the defaultprocess_external_referencesomits the leak-post URL.7.260604.0to match the exact pin inconnectors-sdk @ master(this connector installs the SDK from master); bumping it further would conflict atpip install.black/isort/flake8clean. All GitHub Actions checks (including the Lint & Format and STIX ID Linter workflows) and Codecov patch/project are green; 0 unresolved review threads.Checklist