@@ -407,19 +407,30 @@ def read(self, **kwargs):
407
407
"""
408
408
409
409
def create (self , ** kwargs ):
410
- observable_data = kwargs .get ("observableData" , None )
410
+ observable_data = kwargs .get ("observableData" , {})
411
+ simple_observable_key = kwargs .get ("simple_observable_key" , None )
412
+ simple_observable_value = kwargs .get ("simple_observable_value" , None )
411
413
created_by = kwargs .get ("createdBy" , None )
412
414
object_marking = kwargs .get ("objectMarking" , None )
413
415
object_label = kwargs .get ("objectLabel" , None )
414
416
external_references = kwargs .get ("externalReferences" , None )
415
417
update = kwargs .get ("update" , False )
416
418
419
+ no_global_attributes = ["File.MD5" , "File.SHA-1" , "File-SHA256" , "File.SHA-512" ]
417
420
create_indicator = (
418
421
observable_data ["x_opencti_create_indicator" ]
419
422
if "x_opencti_create_indicator" in observable_data
420
423
else kwargs .get ("createIndicator" , False )
421
424
)
422
- type = observable_data ["type" ].title ()
425
+ attribute = None
426
+ if simple_observable_key is not None :
427
+ key_split = simple_observable_key .split ("." )
428
+ type = key_split [0 ]
429
+ attribute = key_split [1 ]
430
+ else :
431
+ type = (
432
+ observable_data ["type" ].title () if "type" in observable_data else None
433
+ )
423
434
if type .lower () == "file" :
424
435
type = "StixFile"
425
436
elif type .lower () == "ipv4-addr" :
@@ -530,6 +541,10 @@ def create(self, **kwargs):
530
541
else None ,
531
542
"rir" : observable_data ["rir" ] if "rir" in observable_data else None ,
532
543
}
544
+ if simple_observable_value is not None :
545
+ input_variables ["AutonomousSystem" ][
546
+ attribute
547
+ ] = simple_observable_value
533
548
elif type == "Directory" :
534
549
input_variables ["Directory" ] = {
535
550
"path" : observable_data ["path" ],
@@ -546,15 +561,21 @@ def create(self, **kwargs):
546
561
if "atime" in observable_data
547
562
else None ,
548
563
}
564
+ if attribute is not None :
565
+ input_variables ["Directory" ][attribute ] = simple_observable_value
549
566
elif type == "Domain-Name" :
550
567
input_variables ["DomainName" ] = {"value" : observable_data ["value" ]}
568
+ if attribute is not None :
569
+ input_variables ["DomainName" ][attribute ] = simple_observable_value
551
570
elif type == "Email-Addr" :
552
571
input_variables ["EmailAddr" ] = {
553
572
"value" : observable_data ["value" ],
554
573
"display_name" : observable_data ["display_name" ]
555
574
if "display_name" in observable_data
556
575
else None ,
557
576
}
577
+ if simple_observable_value is not None :
578
+ input_variables ["EmailAddr" ][attribute ] = simple_observable_value
558
579
elif type == "Email-Message" :
559
580
input_variables ["EmailMessage" ] = {
560
581
"is_multipart" : observable_data ["is_multipart" ]
@@ -579,6 +600,8 @@ def create(self, **kwargs):
579
600
if "body" in observable_data
580
601
else None ,
581
602
}
603
+ if attribute is not None :
604
+ input_variables ["EmailMessage" ][attribute ] = simple_observable_value
582
605
elif type == "Email-Mime-Part-Type" :
583
606
input_variables ["EmailMimePartType" ] = {
584
607
"body" : observable_data ["body" ]
@@ -591,6 +614,10 @@ def create(self, **kwargs):
591
614
if "content_disposition" in observable_data
592
615
else None ,
593
616
}
617
+ if attribute is not None :
618
+ input_variables ["EmailMimePartType" ][
619
+ attribute
620
+ ] = simple_observable_value
594
621
elif type == "Artifact" :
595
622
hashes = []
596
623
for key , value in observable_data ["hashes" ].items ():
@@ -611,10 +638,23 @@ def create(self, **kwargs):
611
638
if "decryption_key" in observable_data
612
639
else None ,
613
640
}
641
+ if attribute is not None :
642
+ input_variables ["Artifact" ][attribute ] = simple_observable_value
614
643
elif type == "StixFile" :
615
644
hashes = []
616
- for key , value in observable_data ["hashes" ].items ():
617
- hashes .append ({"algorithm" : key , "hash" : value })
645
+ if simple_observable_key == "File.MD5" :
646
+ hashes .append ({"algorithm" : "MD5" , "hash" : simple_observable_value })
647
+ if simple_observable_key == "File.SHA-1" :
648
+ hashes .append (
649
+ {"algorithm" : "SHA-1" , "hash" : simple_observable_value }
650
+ )
651
+ if simple_observable_key == "File.SHA-256" :
652
+ hashes .append (
653
+ {"algorithm" : "SHA-256" , "hash" : simple_observable_value }
654
+ )
655
+ if "hashes" in observable_data :
656
+ for key , value in observable_data ["hashes" ].items ():
657
+ hashes .append ({"algorithm" : key , "hash" : value })
618
658
input_variables ["StixFile" ] = {
619
659
"hashes" : hashes if len (hashes ) > 0 else None ,
620
660
"extensions" : observable_data ["extensions" ]
@@ -691,30 +731,42 @@ def create(self, **kwargs):
691
731
if "subject_public_key_exponent" in observable_data
692
732
else None ,
693
733
}
734
+ if attribute is not None :
735
+ input_variables ["X509Certificate" ][
736
+ attribute
737
+ ] = simple_observable_value
694
738
elif type == "IPv4-Addr" :
695
739
input_variables ["IPv4Addr" ] = {
696
740
"value" : observable_data ["value" ]
697
741
if "value" in observable_data
698
742
else None ,
699
743
}
744
+ if attribute is not None :
745
+ input_variables ["IPv4Addr" ][attribute ] = simple_observable_value
700
746
elif type == "IPv6-Addr" :
701
747
input_variables ["IPv6Addr" ] = {
702
748
"value" : observable_data ["value" ]
703
749
if "value" in observable_data
704
750
else None ,
705
751
}
752
+ if attribute is not None :
753
+ input_variables ["IPv6Addr" ][attribute ] = simple_observable_value
706
754
elif type == "Mac-Addr" :
707
755
input_variables ["MacAddr" ] = {
708
756
"value" : observable_data ["value" ]
709
757
if "value" in observable_data
710
758
else None ,
711
759
}
760
+ if attribute is not None :
761
+ input_variables ["MacAddr" ][attribute ] = simple_observable_value
712
762
elif type == "Mutex" :
713
763
input_variables ["Mutex" ] = {
714
764
"name" : observable_data ["name" ]
715
765
if "name" in observable_data
716
766
else None ,
717
767
}
768
+ if attribute is not None :
769
+ input_variables ["Mutex" ][attribute ] = simple_observable_value
718
770
elif type == "Network-Traffic" :
719
771
input_variables ["NetworkTraffic" ] = {
720
772
"extensions" : observable_data ["extensions" ]
@@ -749,6 +801,10 @@ def create(self, **kwargs):
749
801
if "dst_packets" in observable_data
750
802
else None ,
751
803
}
804
+ if attribute is not None :
805
+ input_variables ["NetworkTraffic" ][
806
+ attribute
807
+ ] = simple_observable_value
752
808
elif type == "Process" :
753
809
input_variables ["Process" ] = {
754
810
"extensions" : observable_data ["extensions" ]
@@ -769,6 +825,8 @@ def create(self, **kwargs):
769
825
if "environment_variables" in observable_data
770
826
else None ,
771
827
}
828
+ if attribute is not None :
829
+ input_variables ["Process" ][attribute ] = simple_observable_value
772
830
elif type == "Software" :
773
831
input_variables ["Software" ] = {
774
832
"name" : observable_data ["name" ]
@@ -788,12 +846,16 @@ def create(self, **kwargs):
788
846
if "version" in observable_data
789
847
else None ,
790
848
}
849
+ if attribute is not None :
850
+ input_variables ["Software" ][attribute ] = simple_observable_value
791
851
elif type == "Url" :
792
852
input_variables ["Url" ] = {
793
853
"value" : observable_data ["value" ]
794
854
if "value" in observable_data
795
855
else None ,
796
856
}
857
+ if attribute is not None :
858
+ input_variables ["Url" ][attribute ] = simple_observable_value
797
859
elif type == "User-Account" :
798
860
input_variables ["UserAccount" ] = {
799
861
"extensions" : observable_data ["extensions" ]
@@ -844,6 +906,8 @@ def create(self, **kwargs):
844
906
if "account_last_login" in observable_data
845
907
else None ,
846
908
}
909
+ if attribute is not None :
910
+ input_variables ["UserAccount" ][attribute ] = simple_observable_value
847
911
elif type == "Windows-Registry-Key" :
848
912
input_variables ["WindowsRegistryKey " ] = {
849
913
"attribute_key" : observable_data ["attribute_key" ]
@@ -856,8 +920,12 @@ def create(self, **kwargs):
856
920
if "number_of_subkeys" in observable_data
857
921
else None ,
858
922
}
923
+ if attribute is not None :
924
+ input_variables ["WindowsRegistryKey" ][
925
+ attribute
926
+ ] = simple_observable_value
859
927
elif type == "Windows-Registry-Value-Type" :
860
- input_variables ["WindowsRegistryKey " ] = {
928
+ input_variables ["WindowsRegistryKeyValueType " ] = {
861
929
"name" : observable_data ["name" ]
862
930
if "name" in observable_data
863
931
else None ,
@@ -868,6 +936,10 @@ def create(self, **kwargs):
868
936
if "data_type" in observable_data
869
937
else None ,
870
938
}
939
+ if attribute is not None :
940
+ input_variables ["WindowsRegistryKeyValueType" ][
941
+ attribute
942
+ ] = simple_observable_value
871
943
elif type == "X509-V3-Extensions-Type" :
872
944
input_variables ["X509V3ExtensionsType " ] = {
873
945
"basic_constraints" : observable_data ["basic_constraints" ]
@@ -933,36 +1005,60 @@ def create(self, **kwargs):
933
1005
if "policy_mappings" in observable_data
934
1006
else None ,
935
1007
}
1008
+ if attribute is not None :
1009
+ input_variables ["X509V3ExtensionsType" ][
1010
+ attribute
1011
+ ] = simple_observable_value
936
1012
elif type == "X-OpenCTI-Cryptographic-Key" :
937
1013
input_variables ["XOpenCTICryptographicKey" ] = {
938
1014
"value" : observable_data ["value" ]
939
1015
if "value" in observable_data
940
1016
else None ,
941
1017
}
1018
+ if attribute is not None :
1019
+ input_variables ["XOpenCTICryptographicKey" ][
1020
+ attribute
1021
+ ] = simple_observable_value
942
1022
elif type == "X-OpenCTI-Cryptocurrency-Wallet" :
943
1023
input_variables ["XOpenCTICryptocurrencyWallet" ] = {
944
1024
"value" : observable_data ["value" ]
945
1025
if "value" in observable_data
946
1026
else None ,
947
1027
}
1028
+ if attribute is not None :
1029
+ input_variables ["XOpenCTICryptocurrencyWallet" ][
1030
+ attribute
1031
+ ] = simple_observable_value
948
1032
elif type == "X-OpenCTI-Hostname" :
949
1033
input_variables ["XOpenCTIHostname" ] = {
950
1034
"value" : observable_data ["value" ]
951
1035
if "value" in observable_data
952
1036
else None ,
953
1037
}
1038
+ if attribute is not None :
1039
+ input_variables ["XOpenCTIHostname" ][
1040
+ attribute
1041
+ ] = simple_observable_value
954
1042
elif type == "X-OpenCTI-Text" :
955
1043
input_variables ["XOpenCTIText" ] = {
956
1044
"value" : observable_data ["value" ]
957
1045
if "value" in observable_data
958
1046
else None ,
959
1047
}
1048
+ if attribute is not None :
1049
+ input_variables ["XOpenCTIUserAgent" ][
1050
+ attribute
1051
+ ] = simple_observable_value
960
1052
elif type == "X-OpenCTI-User-Agent" :
961
1053
input_variables ["XOpenCTIUserAgent" ] = {
962
1054
"value" : observable_data ["value" ]
963
1055
if "value" in observable_data
964
1056
else None ,
965
1057
}
1058
+ if attribute is not None :
1059
+ input_variables ["XOpenCTIUserAgent" ][
1060
+ attribute
1061
+ ] = simple_observable_value
966
1062
result = self .opencti .query (query , input_variables )
967
1063
return self .opencti .process_multiple_fields (
968
1064
result ["data" ]["stixCyberObservableAdd" ]
0 commit comments