diff --git a/docs/pycti/pycti.rst b/docs/pycti/pycti.rst index b5829609..4d7ef636 100644 --- a/docs/pycti/pycti.rst +++ b/docs/pycti/pycti.rst @@ -191,6 +191,15 @@ Classes - :py:class:`CustomObservableUserAgent`: User-Agent observable. +- :py:class:`CustomObservableFinancialAccount`: + Financial Account observable. + +- :py:class:`CustomObservableFinancialAsset`: + Financial Asset observable. + +- :py:class:`CustomObservableFinancialTransaction`: + Financial Transaction observable. + - :py:class:`CustomObservableCryptocurrencyWallet`: Cryptocurrency wallet observable. @@ -590,6 +599,27 @@ Classes .. inheritance-diagram:: CustomObservableUserAgent :parts: 1 +.. autoclass:: CustomObservableFinancialAccount + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: CustomObservableFinancialAccount + :parts: 1 + +.. autoclass:: CustomObservableFinancialAsset + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: CustomObservableFinancialAsset + :parts: 1 + +.. autoclass:: CustomObservableFinancialTransaction + :members: + + .. rubric:: Inheritance + .. inheritance-diagram:: CustomObservableFinancialTransaction + :parts: 1 + .. autoclass:: CustomObservableCryptocurrencyWallet :members: diff --git a/examples/create_observable_financial_account.py b/examples/create_observable_financial_account.py new file mode 100644 index 00000000..f44f3006 --- /dev/null +++ b/examples/create_observable_financial_account.py @@ -0,0 +1,25 @@ +# coding: utf-8 + +from pycti import OpenCTIApiClient + +# Variables +api_url = "http://localhost:4000" +api_token = "6C2C9EAE-6FF5-4421-B118-74A3CA5AAC20" + +# OpenCTI initialization +opencti_api_client = OpenCTIApiClient(api_url, api_token) + +process = opencti_api_client.stix_cyber_observable.create( + observableData={ + "type": "Financial-Account", + "account_number": "123-45-9988", + "account_status": "active", + "account_type": "credit_credit_card", + "x_opencti_score": 90, + "iban": "55667", + "bic": "009998877", + "currency_code": "bahraini_dinar_(bhd)", + } +) + +print(process) diff --git a/examples/create_observable_financial_asset.py b/examples/create_observable_financial_asset.py new file mode 100644 index 00000000..0b82118d --- /dev/null +++ b/examples/create_observable_financial_asset.py @@ -0,0 +1,22 @@ +# coding: utf-8 + +from pycti import OpenCTIApiClient + +# Variables +api_url = "http://localhost:4000" +api_token = "6C2C9EAE-6FF5-4421-B118-74A3CA5AAC20" + +# OpenCTI initialization +opencti_api_client = OpenCTIApiClient(api_url, api_token) + +process = opencti_api_client.stix_cyber_observable.create( + observableData={ + "type": "Financial-Asset", + "asset_name": "Joe's Big Boat", + "asset_type": "boat", + "asset_value": 12000000, + "currency_code": "belarusian_ruble_(byr)", + } +) + +print(process) diff --git a/examples/create_observable_financial_transaction.py b/examples/create_observable_financial_transaction.py new file mode 100644 index 00000000..ad3997ba --- /dev/null +++ b/examples/create_observable_financial_transaction.py @@ -0,0 +1,25 @@ +# coding: utf-8 +from dateutil.parser import parse + +from pycti import OpenCTIApiClient + +# Variables +api_url = "http://localhost:4000" +api_token = "6C2C9EAE-6FF5-4421-B118-74A3CA5AAC20" + +# OpenCTI initialization +opencti_api_client = OpenCTIApiClient(api_url, api_token) + +# Define the date +date = parse("2019-02-06").strftime("%Y-%m-%dT%H:%M:%SZ") + +process = opencti_api_client.stix_cyber_observable.create( + observableData={ + "type": "Financial-Transaction", + "transaction_date": date, + "transaction_value": 62000000, + "currency_code": "belarusian_ruble_(byr)", + } +) + +print(process) diff --git a/pycti/__init__.py b/pycti/__init__.py index 1f5d2d45..3d0a4ee4 100644 --- a/pycti/__init__.py +++ b/pycti/__init__.py @@ -55,9 +55,11 @@ CustomObjectCaseIncident, CustomObjectChannel, CustomObjectTask, - CustomObservableBankAccount, CustomObservableCredential, CustomObservableCryptocurrencyWallet, + CustomObservableFinancialAccount, + CustomObservableFinancialAsset, + CustomObservableFinancialTransaction, CustomObservableHostname, CustomObservableMediaContent, CustomObservablePaymentCard, @@ -137,17 +139,18 @@ "CustomObjectCaseIncident", "CustomObjectTask", "CustomObjectChannel", - "StixCyberObservableTypes", "CustomObservableCredential", - "CustomObservableHostname", - "CustomObservableUserAgent", - "CustomObservableBankAccount", + "CustomObservableFinancialAccount", + "CustomObservableFinancialAsset", + "CustomObservableFinancialTransaction", "CustomObservableCryptocurrencyWallet", + "CustomObservableHostname", "CustomObservablePaymentCard", "CustomObservablePhoneNumber", "CustomObservableTrackingNumber", "CustomObservableText", "CustomObservableMediaContent", + "CustomObservableUserAgent", "STIX_EXT_MITRE", "STIX_EXT_OCTI_SCO", "STIX_EXT_OCTI", diff --git a/pycti/entities/opencti_stix_core_object.py b/pycti/entities/opencti_stix_core_object.py index 4013cb38..036ffb5c 100644 --- a/pycti/entities/opencti_stix_core_object.py +++ b/pycti/entities/opencti_stix_core_object.py @@ -616,11 +616,6 @@ def __init__(self, opencti, file): ... on UserAgent { value } - ... on BankAccount { - iban - bic - account_number - } ... on PhoneNumber { value } @@ -643,6 +638,25 @@ def __init__(self, opencti, file): url publication_date } + ... on FinancialAccount { + account_number + account_status + account_type + iban + bic + currency_code + } + ... on FinancialAsset { + asset_name + asset_type + asset_value + currency_code + } + ... on FinancialTransaction { + transaction_date + transaction_value + currency_code + } """ self.properties_with_files = """ id @@ -1280,11 +1294,6 @@ def __init__(self, opencti, file): ... on UserAgent { value } - ... on BankAccount { - iban - bic - account_number - } ... on PhoneNumber { value } @@ -1301,6 +1310,25 @@ def __init__(self, opencti, file): url publication_date } + ... on FinancialAccount { + account_number + account_status + account_type + iban + bic + currency_code + } + ... on FinancialAsset { + asset_name + asset_type + asset_value + currency_code + } + ... on FinancialTransaction { + transaction_date + transaction_value + currency_code + } """ """ diff --git a/pycti/entities/opencti_stix_cyber_observable.py b/pycti/entities/opencti_stix_cyber_observable.py index 3497258d..13abe56b 100644 --- a/pycti/entities/opencti_stix_cyber_observable.py +++ b/pycti/entities/opencti_stix_cyber_observable.py @@ -236,6 +236,7 @@ def add_file(self, **kwargs): """ def create(self, **kwargs): + observable_data = kwargs.get("observableData", {}) simple_observable_id = kwargs.get("simple_observable_id", None) simple_observable_key = kwargs.get("simple_observable_key", None) @@ -269,37 +270,33 @@ def create(self, **kwargs): ) if type is None: return - if type.lower() == "file": - type = "StixFile" - elif type.lower() == "ipv4-addr": - type = "IPv4-Addr" - elif type.lower() == "ipv6-addr": - type = "IPv6-Addr" - elif type.lower() == "hostname" or type.lower() == "x-opencti-hostname": - type = "Hostname" - elif type.lower() == "payment-card" or type.lower() == "x-opencti-payment-card": - type = "Payment-Card" - elif type.lower() == "credential" or type.lower() == "x-opencti-credential": - type = "Credential" - elif ( - type.lower() == "tracking-number" - or type.lower() == "x-opencti-tracking-number" - ): - type = "Tracking-Number" - elif ( - type.lower() == "cryptocurrency-wallet" - or type.lower() == "x-opencti-cryptocurrency-wallet" - ): - type = "Cryptocurrency-Wallet" - elif type.lower() == "user-agent" or type.lower() == "x-opencti-user-agent": - type = "User-Agent" - elif ( - type.lower() == "cryptographic-key" - or type.lower() == "x-opencti-cryptographic-key" - ): - type = "Cryptographic-Key" - elif type.lower() == "text" or type.lower() == "x-opencti-text": - type = "Text" + + type_mappings = { + "credential": "Credential", + "cryptographic-key": "Cryptographic-Key", + "file": "StixFile", + "financial-account": "Financial-Account", + "financial-asset": "Financial-Asset", + "financial-transaction": "Financial-Transaction", + "hostname": "Hostname", + "ipv4-addr": "IPv4-Addr", + "ipv6-addr": "IPv6-Addr", + "payment-card": "Payment-Card", + "text": "Text", + "tracking-number": "Tracking-Number", + "user-agent": "User-Agent", + "x-opencti-credential": "Credential", + "x-opencti-cryptographic-key": "Cryptographic-Key", + "x-opencti-financial-account": "Financial-Account", + "x-opencti-financial-asset": "Financial-Asset", + "x-opencti-financial-transaction": "Financial-Transaction", + "x-opencti-hostname": "Hostname", + "x-opencti-payment-card": "Payment-Card", + "x-opencti-text": "Text", + "x-opencti-tracking-number": "Tracking-Number", + "x-opencti-user-agent": "User-Agent", + } + type = type_mappings.get(type.lower(), type) if "x_opencti_description" in observable_data: x_opencti_description = observable_data["x_opencti_description"] @@ -401,12 +398,14 @@ def create(self, **kwargs): $Hostname: HostnameAddInput $Text: TextAddInput, $UserAgent: UserAgentAddInput - $BankAccount: BankAccountAddInput $PhoneNumber: PhoneNumberAddInput $Credential: CredentialAddInput $TrackingNumber: TrackingNumberAddInput $PaymentCard: PaymentCardAddInput $MediaContent: MediaContentAddInput + $FinancialAccount: FinancialAccountAddInput + $FinancialAsset: FinancialAssetAddInput + $FinancialTransaction: FinancialTransactionAddInput ) { stixCyberObservableAdd( type: $type, @@ -445,12 +444,14 @@ def create(self, **kwargs): Hostname: $Hostname, Text: $Text, UserAgent: $UserAgent - BankAccount: $BankAccount PhoneNumber: $PhoneNumber Credential: $Credential TrackingNumber: $TrackingNumber PaymentCard: $PaymentCard MediaContent: $MediaContent + FinancialAccount: $FinancialAccount + FinancialAsset: $FinancialAsset + FinancialTransaction: $FinancialTransaction ) { id standard_id @@ -953,18 +954,6 @@ def create(self, **kwargs): observable_data["value"] if "value" in observable_data else None ), } - elif type == "Bank-Account": - input_variables["BankAccount"] = { - "iban": ( - observable_data["iban"] if "iban" in observable_data else None - ), - "bic": observable_data["bic"] if "bic" in observable_data else None, - "account_number": ( - observable_data["account_number"] - if "account_number" in observable_data - else None - ), - } elif type == "Phone-Number": input_variables["PhoneNumber"] = { "value": ( @@ -1012,25 +1001,6 @@ def create(self, **kwargs): else None ), } - elif type == "Payment-Card" or type.lower() == "x-opencti-payment-card": - input_variables["PaymentCard"] = { - "card_number": ( - observable_data["card_number"] - if "card_number" in observable_data - else None - ), - "expiration_date": ( - observable_data["expiration_date"] - if "expiration_date" in observable_data - else None - ), - "cvv": observable_data["cvv"] if "cvv" in observable_data else None, - "holder_name": ( - observable_data["holder_name"] - if "holder_name" in observable_data - else None - ), - } elif ( type == "Cryptocurrency-Wallet" or type.lower() == "x-opencti-cryptocurrency-wallet" @@ -1054,6 +1024,37 @@ def create(self, **kwargs): observable_data["value"] if "value" in observable_data else None ), } + elif ( + type == "Financial-Account" + or type.lower() == "x-opencti-financial-account" + ): + input_variables["FinancialAccount"] = { + "iban": observable_data.get("iban"), + "bic": observable_data.get("bic"), + "account_number": observable_data.get("account_number"), + "account_status": observable_data.get("account_status"), + "account_type": observable_data.get("account_type"), + "currency_code": observable_data.get("currency_code"), + } + elif ( + type == "Financial-Asset" or type.lower() == "x-opencti-financial-asset" + ): + input_variables["FinancialAsset"] = { + "asset_name": observable_data.get("asset_name"), + "asset_type": observable_data.get("asset_type"), + "asset_value": observable_data.get("asset_value"), + "currency_code": observable_data.get("currency_code"), + } + elif ( + type == "Financial-Transaction" + or type.lower() == "x-opencti-transaction" + ): + input_variables["FinancialTransaction"] = { + "transaction_date": observable_data.get("transaction_date"), + "transaction_value": observable_data.get("transaction_value"), + "currency_code": observable_data.get("currency_code"), + } + result = self.opencti.query(query, input_variables) if "payload_bin" in observable_data and "mime_type" in observable_data: self.add_file( 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 bc3dd494..2d96ec59 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 @@ -261,11 +261,6 @@ ... on UserAgent { value } - ... on BankAccount { - iban - bic - account_number - } ... on PhoneNumber { value } @@ -288,6 +283,25 @@ url publication_date } + ... on FinancialAccount { + account_number + account_status + account_type + iban + bic + currency_code + } + ... on FinancialAsset { + asset_name + asset_type + asset_value + currency_code + } + ... on FinancialTransaction { + transaction_date + transaction_value + currency_code + } """ SCO_PROPERTIES_WITH_FILES = """ id @@ -561,11 +575,6 @@ ... on UserAgent { value } - ... on BankAccount { - iban - bic - account_number - } ... on PhoneNumber { value } @@ -601,4 +610,23 @@ } } } + ... on FinancialAccount { + account_number + account_status + account_type + iban + bic + currency_code + } + ... on FinancialAsset { + asset_name + asset_type + asset_value + currency_code + } + ... on FinancialTransaction { + transaction_date + transaction_value + currency_code + } """ diff --git a/pycti/utils/constants.py b/pycti/utils/constants.py index d194a203..d6123650 100644 --- a/pycti/utils/constants.py +++ b/pycti/utils/constants.py @@ -38,9 +38,12 @@ class StixCyberObservableTypes(Enum): HOSTNAME = "Hostname" CRYPTOGRAPHIC_KEY = "Cryptographic-Key" CRYPTOCURRENCY_WALLET = "Cryptocurrency-Wallet" + FINANCIAL_ACCOUNT = "Financial-Account" + FINANCIAL_ASSET = "Financial-Asset" + FINANCIAL_TRANSACTION = "Financial-Transaction" TEXT = "Text" USER_AGENT = "User-Agent" - BANK_ACCOUNT = "Bank-Account" + # BANK_ACCOUNT = "Bank-Account" PHONE_NUMBER = "Phone-Number" CREDENTIAL = "Credential" TRACKING_NUMBER = "Tracking-Number" @@ -308,27 +311,27 @@ class CustomObservablePaymentCard: pass -@CustomObservable( - "bank-account", - [ - ("value", StringProperty(required=True)), - ("iban", StringProperty(required=True)), - ("bic", StringProperty(required=False)), - ("account_number", StringProperty(required=False)), - ("spec_version", StringProperty(fixed="2.1")), - ( - "object_marking_refs", - ListProperty( - ReferenceProperty(valid_types="marking-definition", spec_version="2.1") - ), - ), - ], - ["iban"], -) -class CustomObservableBankAccount: - """Bank Account observable.""" - - pass +# @CustomObservable( +# "bank-account", +# [ +# ("value", StringProperty(required=True)), +# ("iban", StringProperty(required=True)), +# ("bic", StringProperty(required=False)), +# ("account_number", StringProperty(required=False)), +# ("spec_version", StringProperty(fixed="2.1")), +# ( +# "object_marking_refs", +# ListProperty( +# ReferenceProperty(valid_types="marking-definition", spec_version="2.1") +# ), +# ), +# ], +# ["iban"], +# ) +# class CustomObservableBankAccount: +# """Bank Account observable.""" + +# pass @CustomObservable( @@ -368,8 +371,6 @@ class CustomObservableCredential: class CustomObservableCryptocurrencyWallet: """Cryptocurrency wallet observable.""" - pass - @CustomObservable( "phone-number", @@ -454,3 +455,70 @@ class CustomObservableMediaContent: """Media-Content observable.""" pass + + +@CustomObservable( + "financial-account", + [ + ("account_number", StringProperty()), + ("account_status", StringProperty()), + ("account_type", StringProperty()), + ("iban", StringProperty()), + ("bic", StringProperty()), + ("currency_code", StringProperty()), + ("spec_version", StringProperty(fixed="2.1")), + ( + "object_marking_refs", + ListProperty( + ReferenceProperty(valid_types="marking-definition", spec_version="2.1") + ), + ), + ], +) +class CustomObservableFinancialAccount: + """Financial account observable.""" + + pass + + +@CustomObservable( + "financial-asset", + [ + ("asset_name", StringProperty()), + ("asset_type", StringProperty()), + ("asset_value", StringProperty()), + ("currency_code", StringProperty()), + ("spec_version", StringProperty(fixed="2.1")), + ( + "object_marking_refs", + ListProperty( + ReferenceProperty(valid_types="marking-definition", spec_version="2.1") + ), + ), + ], +) +class CustomObservableFinancialAsset: + """Financial asset observable.""" + + pass + + +@CustomObservable( + "financial-transaction", + [ + ("transaction_date", StringProperty()), + ("transaction_value", StringProperty()), + ("currency_code", StringProperty()), + ("spec_version", StringProperty(fixed="2.1")), + ( + "object_marking_refs", + ListProperty( + ReferenceProperty(valid_types="marking-definition", spec_version="2.1") + ), + ), + ], +) +class CustomObservableFinancialTransaction: + """Financial transaction observable.""" + + pass diff --git a/pycti/utils/opencti_stix2_utils.py b/pycti/utils/opencti_stix2_utils.py index 321c7418..63e9f961 100644 --- a/pycti/utils/opencti_stix2_utils.py +++ b/pycti/utils/opencti_stix2_utils.py @@ -28,12 +28,15 @@ "cryptocurrency-wallet": "Cryptocurrency-Wallet", "text": "Text", "user-agent": "User-Agent", - "bank-account": "Bank-Account", + # "bank-account": "Bank-Account", "phone-number": "Phone-Number", "credential": "Credential", "tracking-number": "Tracking-Number", "payment-card": "Payment-Card", "media-content": "Media-Content", + "financial-account": "Financial-Account", + "financial-asset": "Financial-Asset", + "financial-transaction": "Financial-Transaction", } PATTERN_MAPPING = { @@ -60,12 +63,15 @@ "Windows-Registry-Key": ["key"], "Windows-Registry-Value-Type": ["name"], "Hostname": ["value"], - "Bank-Account": ["iban"], + # "Bank-Account": ["iban"], "Phone-Number": ["value"], "Payment-Card": ["card_number"], "Tracking-Number": ["value"], "Credential": ["value"], "Media-Content": ["url"], + "Financial-Account": ["account_number"], + "Financial-Asset": ["asset_value"], + "Financial-Transaction": ["transaction_value"], } OBSERVABLES_VALUE_INT = [