psengine 2.10.0__tar.gz → 2.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {psengine-2.10.0 → psengine-2.11.0}/PKG-INFO +2 -2
- {psengine-2.10.0 → psengine-2.11.0}/psengine/common_models.py +1 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/endpoints.py +5 -0
- psengine-2.11.0/psengine/risk_rules/__init__.py +17 -0
- psengine-2.11.0/psengine/risk_rules/errors.py +22 -0
- psengine-2.11.0/psengine/risk_rules/models.py +33 -0
- psengine-2.11.0/psengine/risk_rules/risk_rule.py +78 -0
- psengine-2.11.0/psengine/risk_rules/risk_rule_mgr.py +63 -0
- {psengine-2.10.0 → psengine-2.11.0}/pyproject.toml +4 -4
- {psengine-2.10.0 → psengine-2.11.0}/pyproject.toml.orig +4 -4
- {psengine-2.10.0 → psengine-2.11.0}/README.md +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/_sdk_id.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/markdown.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/note.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/analyst_notes/note_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/asi.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/asi_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/client.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/asi/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/base_http_client.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/classic_alert.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/classic_alert_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/markdown/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/markdown/markdown.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/classic_alerts/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/collective_insights.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/insight.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/collective_insights/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/config/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/config/config.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/config/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/detection_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/detection_rule.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/detection/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/lookup.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/lookup_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/base_enriched_entity.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/lookup.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/models/soar.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/soar.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/enrich/soar_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/entity_list.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/entity_list_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_lists/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/entity_match.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/entity_match_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/entity_match/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/fusion_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/fusion/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/helpers/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/helpers/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/identity.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/identity_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/common_models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/detections.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/incident_report.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/identity/models/lookup.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/links/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/links/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/links/links.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/links/links_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/links/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/logger/rf_logger.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/auto_sigma_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/auto_yara_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/malware_intel.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/malware_intel_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/malware_intel/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/markdown.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/markdown_strings.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/markdown/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/mappings.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_code_repo.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_compromised_bank_checks.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_cyber_vulnerability.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_domain_abuse.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_geopolitics_facility.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_identity_exposure.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_malicious_sites.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_malware_report.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_third_party_risk.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/common_models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/code_repo.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/common.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/domain_abuse.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/generic.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/geopolitics.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/malicious_sites.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/panel_log_v2.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/tpr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/vulnerability.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_status.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_code_repo_leak.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_compromised_bank_checks.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_cyber_vulnerability.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_domain_abuse.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_geopolitics_facility.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_identity_exposures.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_malicious_sites.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_malware_report.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_third_party_risk.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/search_endpoint.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/pa_category.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/playbook_alert_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/playbook_alerts.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/rf_client.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risk_history/risk_history_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/risklists/risklist_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/client.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/analysis.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/behavioral_report.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/overview_report.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/models/static_report.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/sandbox.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/sandbox/sandbox_mgr.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/base_stix_entity.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/complex_entity.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/constants.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/enriched_indicator.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/helpers.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/rf_bundle.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/simple_entity.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/stix2/util.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/__init__.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/errors.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/models.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/threat_map.py +0 -0
- {psengine-2.10.0 → psengine-2.11.0}/psengine/threat_maps/threat_map_mgr.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: psengine
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.11.0
|
|
4
4
|
Summary: psengine is a simple, yet elegant, library for rapid development of integrations with Recorded Future.
|
|
5
5
|
Keywords: API,Recorded Future,Cyber Security Engineering,Threat Intelligence
|
|
6
6
|
Author: Moise Medici, Patrick Kinsella, Ernest Bartosevic
|
|
@@ -25,7 +25,7 @@ Requires-Dist: stix2~=3.0.2
|
|
|
25
25
|
Requires-Dist: python-dateutil>=2.7.0
|
|
26
26
|
Requires-Dist: more-itertools>=9.0.0,<=11.1.0
|
|
27
27
|
Requires-Dist: pydantic>=2.7,<3.0.0
|
|
28
|
-
Requires-Dist: pydantic-settings[toml]>=2.14.2,<2.
|
|
28
|
+
Requires-Dist: pydantic-settings[toml]>=2.14.2,<2.16.0
|
|
29
29
|
Requires-Python: >=3.10, <3.15
|
|
30
30
|
Project-URL: Homepage, https://recordedfuture-professionalservices.github.io/psengine/latest/
|
|
31
31
|
Project-URL: Changelog, https://recordedfuture-professionalservices.github.io/psengine/latest/CHANGELOG/
|
|
@@ -141,6 +141,11 @@ EP_AUTO_SIGMA_JOB_ID_RETRY = EP_AUTO_SIGMA_JOB_ID + '/retry'
|
|
|
141
141
|
EP_RISK_HISTORY_BASE = BASE_URL + '/risk'
|
|
142
142
|
EP_RISK_HISTORY = EP_RISK_HISTORY_BASE + '/history'
|
|
143
143
|
|
|
144
|
+
###############################################################################
|
|
145
|
+
# Risk Rules API Endpoints
|
|
146
|
+
###############################################################################
|
|
147
|
+
EP_RISK_RULES = CONNECT_API_BASE_URL + '/{}/riskrules'
|
|
148
|
+
|
|
144
149
|
###############################################################################
|
|
145
150
|
# Links API Endpoints
|
|
146
151
|
###############################################################################
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
##################################### TERMS OF USE ###########################################
|
|
2
|
+
# The following code is provided for demonstration purpose only, and should not be used #
|
|
3
|
+
# without independent verification. Recorded Future makes no representations or warranties, #
|
|
4
|
+
# express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
|
|
5
|
+
# information it may retrieve, and provides it both strictly “as-is” and without assuming #
|
|
6
|
+
# responsibility for any information it may retrieve. Recorded Future shall not be liable #
|
|
7
|
+
# for, and you assume all risk of using, the foregoing. By using this code, Customer #
|
|
8
|
+
# represents that it is solely responsible for having all necessary licenses, permissions, #
|
|
9
|
+
# rights, and/or consents to connect to third party APIs, and that it is solely responsible #
|
|
10
|
+
# for having all necessary licenses, permissions, rights, and/or consents to any data #
|
|
11
|
+
# accessed from any third party API. #
|
|
12
|
+
##############################################################################################
|
|
13
|
+
|
|
14
|
+
from .errors import RiskRuleError, RiskRuleFetchError
|
|
15
|
+
from .models import RiskRuleCategory, RiskRuleEntityType
|
|
16
|
+
from .risk_rule import RiskRule
|
|
17
|
+
from .risk_rule_mgr import RiskRuleMgr
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
##################################### TERMS OF USE ###########################################
|
|
2
|
+
# The following code is provided for demonstration purpose only, and should not be used #
|
|
3
|
+
# without independent verification. Recorded Future makes no representations or warranties, #
|
|
4
|
+
# express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
|
|
5
|
+
# information it may retrieve, and provides it both strictly “as-is” and without assuming #
|
|
6
|
+
# responsibility for any information it may retrieve. Recorded Future shall not be liable #
|
|
7
|
+
# for, and you assume all risk of using, the foregoing. By using this code, Customer #
|
|
8
|
+
# represents that it is solely responsible for having all necessary licenses, permissions, #
|
|
9
|
+
# rights, and/or consents to connect to third party APIs, and that it is solely responsible #
|
|
10
|
+
# for having all necessary licenses, permissions, rights, and/or consents to any data #
|
|
11
|
+
# accessed from any third party API. #
|
|
12
|
+
##############################################################################################
|
|
13
|
+
|
|
14
|
+
from ..errors import RecordedFutureError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RiskRuleError(RecordedFutureError):
|
|
18
|
+
"""Base error for the risk_rules module."""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RiskRuleFetchError(RecordedFutureError):
|
|
22
|
+
"""Raised when the risk rules for an entity type cannot be fetched."""
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
##################################### TERMS OF USE ###########################################
|
|
2
|
+
# The following code is provided for demonstration purpose only, and should not be used #
|
|
3
|
+
# without independent verification. Recorded Future makes no representations or warranties, #
|
|
4
|
+
# express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
|
|
5
|
+
# information it may retrieve, and provides it both strictly “as-is” and without assuming #
|
|
6
|
+
# responsibility for any information it may retrieve. Recorded Future shall not be liable #
|
|
7
|
+
# for, and you assume all risk of using, the foregoing. By using this code, Customer #
|
|
8
|
+
# represents that it is solely responsible for having all necessary licenses, permissions, #
|
|
9
|
+
# rights, and/or consents to connect to third party APIs, and that it is solely responsible #
|
|
10
|
+
# for having all necessary licenses, permissions, rights, and/or consents to any data #
|
|
11
|
+
# accessed from any third party API. #
|
|
12
|
+
##############################################################################################
|
|
13
|
+
|
|
14
|
+
from enum import Enum
|
|
15
|
+
|
|
16
|
+
from ..common_models import RFBaseModel
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class RiskRuleEntityType(str, Enum):
|
|
20
|
+
"""Enum of IOC entity types supported by the `/v2/{entity_type}/riskrules` endpoint."""
|
|
21
|
+
|
|
22
|
+
IP = 'ip'
|
|
23
|
+
DOMAIN = 'domain'
|
|
24
|
+
HASH = 'hash'
|
|
25
|
+
VULNERABILITY = 'vulnerability'
|
|
26
|
+
URL = 'url'
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class RiskRuleCategory(RFBaseModel):
|
|
30
|
+
"""A framework category attached to a risk rule (e.g. MITRE tactic or technique)."""
|
|
31
|
+
|
|
32
|
+
name: str
|
|
33
|
+
framework: str
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
##################################### TERMS OF USE ###########################################
|
|
2
|
+
# The following code is provided for demonstration purpose only, and should not be used #
|
|
3
|
+
# without independent verification. Recorded Future makes no representations or warranties, #
|
|
4
|
+
# express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
|
|
5
|
+
# information it may retrieve, and provides it both strictly “as-is” and without assuming #
|
|
6
|
+
# responsibility for any information it may retrieve. Recorded Future shall not be liable #
|
|
7
|
+
# for, and you assume all risk of using, the foregoing. By using this code, Customer #
|
|
8
|
+
# represents that it is solely responsible for having all necessary licenses, permissions, #
|
|
9
|
+
# rights, and/or consents to connect to third party APIs, and that it is solely responsible #
|
|
10
|
+
# for having all necessary licenses, permissions, rights, and/or consents to any data #
|
|
11
|
+
# accessed from any third party API. #
|
|
12
|
+
##############################################################################################
|
|
13
|
+
|
|
14
|
+
from functools import total_ordering
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from pydantic import Field
|
|
18
|
+
|
|
19
|
+
from ..common_models import RFBaseModel
|
|
20
|
+
from .models import RiskRuleCategory
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@total_ordering
|
|
24
|
+
class RiskRule(RFBaseModel):
|
|
25
|
+
"""Validate data received from the `/v2/{entity_type}/riskrules` endpoint.
|
|
26
|
+
|
|
27
|
+
A Recorded Future risk rule is a scoring rule that contributes to the overall risk score of an
|
|
28
|
+
entity of a given IOC type (ip, domain, hash, url, vulnerability). Each rule has a criticality
|
|
29
|
+
level (1-3), a human readable label, a description of what it detects, and a count of entities
|
|
30
|
+
currently matching the rule.
|
|
31
|
+
|
|
32
|
+
This class supports hashing, equality comparison, string representation, and total ordering
|
|
33
|
+
of `RiskRule` instances.
|
|
34
|
+
|
|
35
|
+
Hashing:
|
|
36
|
+
Returns a hash value based on the tuple `(name, criticality)`.
|
|
37
|
+
|
|
38
|
+
Equality:
|
|
39
|
+
Two `RiskRule` instances are equal if they share the same `name` and `criticality`.
|
|
40
|
+
|
|
41
|
+
Greater-than Comparison:
|
|
42
|
+
A rule is "greater" than another if its `criticality` is higher. When two rules share the
|
|
43
|
+
same criticality, the one whose `name` sorts later alphabetically is considered greater.
|
|
44
|
+
Combined with `@total_ordering`, this yields most-critical-first when using `sorted()` in
|
|
45
|
+
reverse (or `sorted(rules, reverse=True)`).
|
|
46
|
+
|
|
47
|
+
String Representation:
|
|
48
|
+
Returns a compact one-line summary of the rule.
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
>>> print(risk_rule)
|
|
52
|
+
Risk Rule: bogusBgp, Criticality: 1 (Unusual), Count: 24590
|
|
53
|
+
```
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
name: str
|
|
57
|
+
description: str
|
|
58
|
+
criticality: int
|
|
59
|
+
criticality_label: str = Field(alias='criticalityLabel')
|
|
60
|
+
count: int
|
|
61
|
+
categories: list[RiskRuleCategory] = []
|
|
62
|
+
related_entities: list[Any] = Field(alias='relatedEntities', default=[])
|
|
63
|
+
|
|
64
|
+
def __hash__(self):
|
|
65
|
+
return hash((self.name, self.criticality))
|
|
66
|
+
|
|
67
|
+
def __eq__(self, other: 'RiskRule'):
|
|
68
|
+
return (self.name, self.criticality) == (other.name, other.criticality)
|
|
69
|
+
|
|
70
|
+
def __gt__(self, other: 'RiskRule'):
|
|
71
|
+
return (self.criticality, self.name) > (other.criticality, other.name)
|
|
72
|
+
|
|
73
|
+
def __str__(self):
|
|
74
|
+
return (
|
|
75
|
+
f'Risk Rule: {self.name}, '
|
|
76
|
+
f'Criticality: {self.criticality} ({self.criticality_label}), '
|
|
77
|
+
f'Count: {self.count}'
|
|
78
|
+
)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
##################################### TERMS OF USE ###########################################
|
|
2
|
+
# The following code is provided for demonstration purpose only, and should not be used #
|
|
3
|
+
# without independent verification. Recorded Future makes no representations or warranties, #
|
|
4
|
+
# express, implied, statutory, or otherwise, regarding any aspect of this code or of the #
|
|
5
|
+
# information it may retrieve, and provides it both strictly “as-is” and without assuming #
|
|
6
|
+
# responsibility for any information it may retrieve. Recorded Future shall not be liable #
|
|
7
|
+
# for, and you assume all risk of using, the foregoing. By using this code, Customer #
|
|
8
|
+
# represents that it is solely responsible for having all necessary licenses, permissions, #
|
|
9
|
+
# rights, and/or consents to connect to third party APIs, and that it is solely responsible #
|
|
10
|
+
# for having all necessary licenses, permissions, rights, and/or consents to any data #
|
|
11
|
+
# accessed from any third party API. #
|
|
12
|
+
##############################################################################################
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from typing import Annotated
|
|
16
|
+
|
|
17
|
+
from pydantic import validate_call
|
|
18
|
+
from typing_extensions import Doc
|
|
19
|
+
|
|
20
|
+
from ..endpoints import EP_RISK_RULES
|
|
21
|
+
from ..helpers import debug_call
|
|
22
|
+
from ..helpers.helpers import connection_exceptions
|
|
23
|
+
from ..rf_client import RFClient
|
|
24
|
+
from .errors import RiskRuleFetchError
|
|
25
|
+
from .models import RiskRuleEntityType
|
|
26
|
+
from .risk_rule import RiskRule
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class RiskRuleMgr:
|
|
30
|
+
"""Manages requests for Recorded Future risk rules."""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
rf_token: Annotated[str | None, Doc('Recorded Future API token.')] = None,
|
|
35
|
+
):
|
|
36
|
+
"""Initializes the `RiskRuleMgr` object."""
|
|
37
|
+
self.log = logging.getLogger(__name__)
|
|
38
|
+
self.rf_client = RFClient(api_token=rf_token) if rf_token else RFClient()
|
|
39
|
+
|
|
40
|
+
@debug_call
|
|
41
|
+
@validate_call
|
|
42
|
+
@connection_exceptions(ignore_status_code=[], exception_to_raise=RiskRuleFetchError)
|
|
43
|
+
def fetch(
|
|
44
|
+
self,
|
|
45
|
+
entity_type: Annotated[
|
|
46
|
+
RiskRuleEntityType,
|
|
47
|
+
Doc('The IOC type to fetch risk rules for: ip, domain, hash, vulnerability, or url.'),
|
|
48
|
+
],
|
|
49
|
+
) -> Annotated[list[RiskRule], Doc('The list of risk rules for the given IOC type.')]:
|
|
50
|
+
"""Fetch every risk rule defined for the given IOC type.
|
|
51
|
+
|
|
52
|
+
Endpoint:
|
|
53
|
+
`/v2/{entity_type}/riskrules`
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValidationError: If `entity_type` is not one of the supported IOC types.
|
|
57
|
+
RiskRuleFetchError: If an API error occurs while fetching risk rules.
|
|
58
|
+
"""
|
|
59
|
+
url = EP_RISK_RULES.format(entity_type.value)
|
|
60
|
+
self.log.info(f'Fetching risk rules for entity type: {entity_type.value}')
|
|
61
|
+
response = self.rf_client.request('get', url).json()
|
|
62
|
+
results = response['data']['results']
|
|
63
|
+
return [RiskRule.model_validate(r) for r in results]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "psengine"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.11.0"
|
|
4
4
|
readme = "README.md"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
requires-python = ">=3.10, <3.15"
|
|
@@ -33,7 +33,7 @@ dependencies = [
|
|
|
33
33
|
"python-dateutil>=2.7.0",
|
|
34
34
|
"more-itertools>=9.0.0, <=11.1.0",
|
|
35
35
|
"pydantic>=2.7, <3.0.0",
|
|
36
|
-
"pydantic-settings[toml]>=2.14.2,<2.
|
|
36
|
+
"pydantic-settings[toml]>=2.14.2,<2.16.0",
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
[[project.authors]]
|
|
@@ -59,8 +59,8 @@ dev = [
|
|
|
59
59
|
"pytest-mock==3.15.1",
|
|
60
60
|
"pytest-md==0.2.0",
|
|
61
61
|
"pytest-random-order==1.2.0",
|
|
62
|
-
"pytest-httpdbg==0.10.
|
|
63
|
-
"ruff
|
|
62
|
+
"pytest-httpdbg==0.10.3",
|
|
63
|
+
"ruff>=0.16.1,<0.17.0",
|
|
64
64
|
"mimesis>=19.1.0",
|
|
65
65
|
"freezegun>=1.5.5",
|
|
66
66
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "psengine"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.11.0"
|
|
4
4
|
readme = "README.md"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
requires-python = ">=3.10, <3.15"
|
|
@@ -36,7 +36,7 @@ dependencies = [
|
|
|
36
36
|
"python-dateutil>=2.7.0",
|
|
37
37
|
"more-itertools>=9.0.0, <=11.1.0",
|
|
38
38
|
"pydantic>=2.7, <3.0.0",
|
|
39
|
-
"pydantic-settings[toml]>=2.14.2,<2.
|
|
39
|
+
"pydantic-settings[toml]>=2.14.2,<2.16.0",
|
|
40
40
|
]
|
|
41
41
|
|
|
42
42
|
|
|
@@ -52,8 +52,8 @@ dev = [
|
|
|
52
52
|
"pytest-mock==3.15.1",
|
|
53
53
|
"pytest-md==0.2.0",
|
|
54
54
|
"pytest-random-order==1.2.0",
|
|
55
|
-
"pytest-httpdbg==0.10.
|
|
56
|
-
"ruff
|
|
55
|
+
"pytest-httpdbg==0.10.3",
|
|
56
|
+
"ruff>=0.16.1,<0.17.0",
|
|
57
57
|
"mimesis>=19.1.0",
|
|
58
58
|
"freezegun>=1.5.5",
|
|
59
59
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_domain_abuse.py
RENAMED
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_identity_exposure.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_malicious_sites.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_malware_report.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/markdown/markdown_third_party_risk.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/domain_abuse.py
RENAMED
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/geopolitics.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/malicious_sites.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/panel_log_v2.py
RENAMED
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/panel_log/vulnerability.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_compromised_bank_checks.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_cyber_vulnerability.py
RENAMED
|
File without changes
|
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_geopolitics_facility.py
RENAMED
|
File without changes
|
{psengine-2.10.0 → psengine-2.11.0}/psengine/playbook_alerts/models/pba_identity_exposures.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|