From 67dfbf89edb6552154c9c59aef86a61f0daf4c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20S=C3=A8be?= <87119259+CelineSebe@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:15:31 +0200 Subject: [PATCH 1/5] [client] Add new SCO - SSH-key (#10905) --- .../entities/opencti_stix_cyber_observable.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/pycti/entities/opencti_stix_cyber_observable.py b/pycti/entities/opencti_stix_cyber_observable.py index f23ced87b..3c2f47c06 100644 --- a/pycti/entities/opencti_stix_cyber_observable.py +++ b/pycti/entities/opencti_stix_cyber_observable.py @@ -287,6 +287,8 @@ def create(self, **kwargs): type = "IPv6-Addr" elif type.lower() == "persona": type = "Persona" + elif type.lower() == "ssh-key": + type = "SSH-Key" elif type.lower() == "hostname" or type.lower() == "x-opencti-hostname": type = "Hostname" elif type.lower() == "payment-card" or type.lower() == "x-opencti-payment-card": @@ -420,6 +422,7 @@ def create(self, **kwargs): $PaymentCard: PaymentCardAddInput $Persona: PersonaAddInput $MediaContent: MediaContentAddInput + $SSHKey: SSHKeyAddInput ) { stixCyberObservableAdd( type: $type, @@ -465,6 +468,7 @@ def create(self, **kwargs): PaymentCard: $PaymentCard Persona: $Persona MediaContent: $MediaContent + SSHKey: $SSHKey ) { id standard_id @@ -713,6 +717,49 @@ def create(self, **kwargs): else None ), } + elif type == "SSH-Key" or type.lower() == "ssh-key": + input_variables["SSHKey"] = { + "key_type": ( + observable_data["key_type"] + if "key_type" in observable_data + else None + ), + "public_key": ( + observable_data["public_key"] + if "public_key" in observable_data + else None + ), + "fingerprint_sha256": ( + observable_data["fingerprint_sha256"] + if "fingerprint_sha256" in observable_data + else False + ), + "fingerprint_md5": ( + observable_data["fingerprint_md5"] + if "fingerprint_md5" in observable_data + else None + ), + "key_length": ( + observable_data["key_length"] + if "key_length" in observable_data + else None + ), + "comment": ( + observable_data["comment"] + if "comment" in observable_data + else None + ), + "created": ( + observable_data["created"] + if "created" in observable_data + else None + ), + "expiration_date": ( + observable_data["expiration_date"] + if "expiration_date" in observable_data + else None + ), + } elif type == "IPv4-Addr": input_variables["IPv4Addr"] = { "value": ( From 821611c64946c6e34382b3dca3d2e4a3a293fbcc Mon Sep 17 00:00:00 2001 From: ValentinBouzinFiligran <162980256+ValentinBouzinFiligran@users.noreply.github.com> Date: Thu, 16 Oct 2025 11:37:33 +0200 Subject: [PATCH 2/5] [client] SSH Key examples (#10905) --- examples/create_observable_sshkey.py | 17 ++++++++++++++++ examples/delete_observable_sshkey.py | 25 ++++++++++++++++++++++++ examples/update_observable_attributes.py | 9 +++++++++ 3 files changed, 51 insertions(+) create mode 100644 examples/create_observable_sshkey.py create mode 100644 examples/delete_observable_sshkey.py diff --git a/examples/create_observable_sshkey.py b/examples/create_observable_sshkey.py new file mode 100644 index 000000000..bcd9dddf9 --- /dev/null +++ b/examples/create_observable_sshkey.py @@ -0,0 +1,17 @@ +# coding: utf-8 +import os + +from pycti import OpenCTIApiClient + +# Variables +api_url = os.getenv("OPENCTI_API_URL", "http://opencti:4000") +api_token = os.getenv("OPENCTI_API_TOKEN", "bfa014e0-e02e-4aa6-a42b-603b19dcf159") + +# OpenCTI initialization +opencti_api_client = OpenCTIApiClient(api_url, api_token) + +observable_sshkey = opencti_api_client.stix_cyber_observable.create( + observableData={"type": "SSH-Key", "fingerprint_sha256": "sha256_test"} +) + +print(observable_sshkey) diff --git a/examples/delete_observable_sshkey.py b/examples/delete_observable_sshkey.py new file mode 100644 index 000000000..e1cf1a337 --- /dev/null +++ b/examples/delete_observable_sshkey.py @@ -0,0 +1,25 @@ +# coding: utf-8 +import os + +from pycti import OpenCTIApiClient + +# Variables +api_url = os.getenv("OPENCTI_API_URL", "http://opencti:4000") +api_token = os.getenv("OPENCTI_API_TOKEN", "bfa014e0-e02e-4aa6-a42b-603b19dcf159") + +# OpenCTI initialization +opencti_api_client = OpenCTIApiClient(api_url, api_token) + +opencti_api_client.stix_cyber_observable.create( + observableData={"type": "SSH-Key", "fingerprint_sha256": "sha256_test"} +) + +observable_sshkey = opencti_api_client.stix_cyber_observable.read( + filters={ + "mode": "and", + "filters": [{"key": "fingerprint_sha256", "values": ["sha256_test"]}], + "filterGroups": [], + } +) + +opencti_api_client.stix_cyber_observable.delete(id=observable_sshkey.get("id")) diff --git a/examples/update_observable_attributes.py b/examples/update_observable_attributes.py index 26f4b8e47..8988b0762 100644 --- a/examples/update_observable_attributes.py +++ b/examples/update_observable_attributes.py @@ -52,3 +52,12 @@ opencti_api_client.stix_cyber_observable.update_created_by( id=observable["id"], identity_id=author["id"] ) + +observable_sshkey = opencti_api_client.stix_cyber_observable.create( + observableData={"type": "SSH-Key", "fingerprint_sha256": "sha256_test"} +) + +opencti_api_client.stix_cyber_observable.update_field( + id=observable_sshkey.get("id"), + input={"key": "fingerprint_sha256", "value": "sha256_test_edit_name"}, +) From 3946ac59807d3f7b8c8cff1929d5813743210f9d Mon Sep 17 00:00:00 2001 From: CelineSebe Date: Thu, 23 Oct 2025 17:20:09 +0200 Subject: [PATCH 3/5] [client] fix ingestion (#10905) --- pycti/utils/constants.py | 1 + pycti/utils/opencti_stix2_utils.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pycti/utils/constants.py b/pycti/utils/constants.py index 6bd117e71..e1f577af2 100644 --- a/pycti/utils/constants.py +++ b/pycti/utils/constants.py @@ -46,6 +46,7 @@ class StixCyberObservableTypes(Enum): MEDIA_CONTENT = "Media-Content" SIMPLE_OBSERVABLE = "Simple-Observable" PERSONA = "Persona" + SSH_KEY = "SSH-Key" @classmethod def has_value(cls, value: str) -> bool: diff --git a/pycti/utils/opencti_stix2_utils.py b/pycti/utils/opencti_stix2_utils.py index 8b8d8100e..89b239cc6 100644 --- a/pycti/utils/opencti_stix2_utils.py +++ b/pycti/utils/opencti_stix2_utils.py @@ -102,6 +102,7 @@ "media-content": "Media-Content", "simple-observable": "Simple-Observable", "persona": "Persona", + "ssh-key": "SSH-Key" } STIX_OBJECTS = ( From 0905c42889f4ecd9c8d43667f961b3a8a397f608 Mon Sep 17 00:00:00 2001 From: CelineSebe Date: Thu, 23 Oct 2025 17:39:15 +0200 Subject: [PATCH 4/5] [client] fix formatting (#10905) --- pycti/utils/opencti_stix2_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycti/utils/opencti_stix2_utils.py b/pycti/utils/opencti_stix2_utils.py index 89b239cc6..20bc3d0bd 100644 --- a/pycti/utils/opencti_stix2_utils.py +++ b/pycti/utils/opencti_stix2_utils.py @@ -102,7 +102,7 @@ "media-content": "Media-Content", "simple-observable": "Simple-Observable", "persona": "Persona", - "ssh-key": "SSH-Key" + "ssh-key": "SSH-Key", } STIX_OBJECTS = ( From cce8b58a594b6feb6f75ea773db96d4ef43a6095 Mon Sep 17 00:00:00 2001 From: Valentin Bouzin Date: Mon, 27 Oct 2025 10:09:03 +0100 Subject: [PATCH 5/5] [client] add sshkey properties for stix export --- ...pencti_stix_cyber_observable_properties.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py b/pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py index 176de35f7..371f0f6f1 100644 --- a/pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py +++ b/pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py @@ -173,6 +173,16 @@ algorithm hash } + } + ... on SSHKey { + key_type + public_key + fingerprint_sha256 + fingerprint_md5 + key_length + expiration_date + comment + created } ... on IPv4Addr { value @@ -479,6 +489,16 @@ hash } } + ... on SSHKey { + key_type + public_key + fingerprint_sha256 + fingerprint_md5 + key_length + expiration_date + comment + created + } ... on IPv4Addr { value }