-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Attribute.php
3942 lines (3794 loc) · 194 KB
/
Attribute.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
App::uses('AppModel', 'Model');
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');
App::uses('FinancialTool', 'Tools');
App::uses('RandomTool', 'Tools');
class Attribute extends AppModel
{
public $combinedKeys = array('event_id', 'category', 'type');
public $name = 'Attribute'; // TODO general
public $actsAs = array(
'SysLogLogable.SysLogLogable' => array( // TODO Audit, logable
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'full'),
'Trim',
'Containable',
'Regexp' => array('fields' => array('value')),
);
public $displayField = 'value';
public $virtualFields = array(
'value' => "CASE WHEN Attribute.value2 = '' THEN Attribute.value1 ELSE CONCAT(Attribute.value1, '|', Attribute.value2) END",
); // TODO hardcoded
// explanations of certain fields to be used in various views
public $fieldDescriptions = array(
'signature' => array('desc' => 'Is this attribute eligible to automatically create an IDS signature (network IDS or host IDS) out of it ?'),
'distribution' => array('desc' => 'Describes who will have access to the event.')
);
public $distributionDescriptions = array(
0 => array('desc' => 'This field determines the current distribution of the event', 'formdesc' => "This setting will only allow members of your organisation on this server to see it."),
1 => array('desc' => 'This field determines the current distribution of the event', 'formdesc' => "Organisations that are part of this MISP community will be able to see the event."),
2 => array('desc' => 'This field determines the current distribution of the event', 'formdesc' => "Organisations that are either part of this MISP community or part of a directly connected MISP community will be able to see the event."),
3 => array('desc' => 'This field determines the current distribution of the event', 'formdesc' => "This will share the event with all MISP communities, allowing the event to be freely propagated from one server to the next."),
4 => array('desc' => 'This field determines the current distribution of the event', 'formdesc' => "This distribution of this event will be handled by the selected sharing group."),
5 => array('desc' => 'This field determines the current distribution of the event', 'formdesc' => "Inherit the event's distribution settings"),
);
public $distributionLevels = array(
0 => 'Your organisation only', 1 => 'This community only', 2 => 'Connected communities', 3 => 'All communities', 4 => 'Sharing group', 5 => 'Inherit event'
);
public $shortDist = array(0 => 'Organisation', 1 => 'Community', 2 => 'Connected', 3 => 'All', 4 => ' Sharing Group', 5 => 'Inherit');
// these are definitions of possible types + their descriptions and maybe later other behaviors
// e.g. if the attribute should be correlated with others or not
// if these then a category may have upload to be zipped
public $zippedDefinitions = array(
'malware-sample'
);
// if these then a category may have upload
public $uploadDefinitions = array(
'attachment'
);
// skip Correlation for the following types
public $nonCorrelatingTypes = array(
'comment',
'http-method',
'aba-rtn',
'gender',
'counter',
'port',
'nationality',
'cortex',
'boolean'
);
public $primaryOnlyCorrelatingTypes = array(
'ip-src|port',
'ip-dst|port'
);
public $captureFields = array(
'event_id',
'category',
'type',
'value',
'value1',
'value2',
'to_ids',
'uuid',
'timestamp',
'distribution',
'comment',
'sharing_group_id',
'deleted',
'disable_correlation',
'object_id',
'object_relation'
);
public $searchResponseTypes = array(
'xml' => array(
'type' => 'xml',
'layout' => 'xml/default',
'header' => 'Content-Disposition: download; filename="misp.search.attribute.results.xml"'
),
'json' => array(
'type' => 'json',
'layout' => 'json/default',
'header' => 'Content-Disposition: download; filename="misp.search.attribute.results.json"'
),
'openioc' => array(
'type' => 'xml',
'layout' => 'xml/default',
'header' => 'Content-Disposition: download; filename="misp.search.attribute.results.openioc.xml"'
),
);
public $validFormats = array(
'json' => array('json', 'JsonExport', 'json'),
'openioc' => array('xml', 'OpeniocExport', 'ioc'),
'xml' => array('xml', 'XmlExport', 'xml'),
'suricata' => array('txt', 'NidsSuricataExport', 'rules'),
'snort' => array('txt', 'NidsSnortExport', 'rules'),
'text' => array('txt', 'TextExport', 'txt'),
'rpz' => array('rpz', 'RPZExport', 'rpz'),
'csv' => array('csv', 'CsvExport', 'csv'),
'cache' => array('txt', 'CacheExport', 'cache')
);
public $typeDefinitions = array(
'md5' => array('desc' => 'A checksum in md5 format', 'formdesc' => "You are encouraged to use filename|md5 instead. A checksum in md5 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha1' => array('desc' => 'A checksum in sha1 format', 'formdesc' => "You are encouraged to use filename|sha1 instead. A checksum in sha1 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha256' => array('desc' => 'A checksum in sha256 format', 'formdesc' => "You are encouraged to use filename|sha256 instead. A checksum in sha256 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename' => array('desc' => 'Filename', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'pdb' => array('desc' => 'Microsoft Program database (PDB) path information', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'filename|md5' => array('desc' => 'A filename and an md5 hash separated by a |', 'formdesc' => "A filename and an md5 hash separated by a | (no spaces)", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha1' => array('desc' => 'A filename and an sha1 hash separated by a |', 'formdesc' => "A filename and an sha1 hash separated by a | (no spaces)", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha256' => array('desc' => 'A filename and an sha256 hash separated by a |', 'formdesc' => "A filename and an sha256 hash separated by a | (no spaces)", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'ip-src' => array('desc' => "A source IP address of the attacker", 'default_category' => 'Network activity', 'to_ids' => 1),
'ip-dst' => array('desc' => 'A destination IP address of the attacker or C&C server', 'formdesc' => "A destination IP address of the attacker or C&C server. Also set the IDS flag on when this IP is hardcoded in malware", 'default_category' => 'Network activity', 'to_ids' => 1),
'hostname' => array('desc' => 'A full host/dnsname of an attacker', 'formdesc' => "A full host/dnsname of an attacker. Also set the IDS flag on when this hostname is hardcoded in malware", 'default_category' => 'Network activity', 'to_ids' => 1),
'domain' => array('desc' => 'A domain name used in the malware', 'formdesc' => "A domain name used in the malware. Use this instead of hostname when the upper domain is important or can be used to create links between events.", 'default_category' => 'Network activity', 'to_ids' => 1),
'domain|ip' => array('desc' => 'A domain name and its IP address (as found in DNS lookup) separated by a |','formdesc' => "A domain name and its IP address (as found in DNS lookup) separated by a | (no spaces)", 'default_category' => 'Network activity', 'to_ids' => 1),
'email-src' => array('desc' => "The email address used to send the malware.", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'email-dst' => array('desc' => "A recipient email address", 'formdesc' => "A recipient email address that is not related to your constituency.", 'default_category' => 'Network activity', 'to_ids' => 1),
'email-subject' => array('desc' => "The subject of the email", 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-attachment' => array('desc' => "File name of the email attachment.", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'email-body' => array('desc' => 'Email body', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'float' => array('desc' => "A floating point value.", 'default_category' => 'Other', 'to_ids' => 0),
'url' => array('desc' => 'url', 'default_category' => 'Network activity', 'to_ids' => 1),
'http-method' => array('desc' => "HTTP method used by the malware (e.g. POST, GET, ...).", 'default_category' => 'Network activity', 'to_ids' => 0),
'user-agent' => array('desc' => "The user-agent used by the malware in the HTTP request.", 'default_category' => 'Network activity', 'to_ids' => 0),
'ja3-fingerprint-md5' => array('desc' => "JA3 is a method for creating SSL/TLS client fingerprints that should be easy to produce on any platform and can be easily shared for threat intelligence.", 'default_category' => 'Network activity', 'to_ids' => 1),
'hassh-md5' => array('desc' => "hassh is a network fingerprinting standard which can be used to identify specific Client SSH implementations. The fingerprints can be easily stored, searched and shared in the form of an MD5 fingerprint.", 'default_category' => 'Network activity', 'to_ids' => 1),
'hasshserver-md5' => array('desc' => "hasshServer is a network fingerprinting standard which can be used to identify specific Server SSH implementations. The fingerprints can be easily stored, searched and shared in the form of an MD5 fingerprint.", 'default_category' => 'Network activity', 'to_ids' => 1),
'regkey' => array('desc' => "Registry key or value", 'default_category' => 'Persistence mechanism', 'to_ids' => 1),
'regkey|value' => array('desc' => "Registry value + data separated by |", 'default_category' => 'Persistence mechanism', 'to_ids' => 1),
'AS' => array('desc' => 'Autonomous system', 'default_category' => 'Network activity', 'to_ids' => 0),
'snort' => array('desc' => 'An IDS rule in Snort rule-format', 'formdesc' => "An IDS rule in Snort rule-format. This rule will be automatically rewritten in the NIDS exports.", 'default_category' => 'Network activity', 'to_ids' => 1),
'bro' => array('desc' => 'An NIDS rule in the Bro rule-format', 'formdesc' => "An NIDS rule in the Bro rule-format.", 'default_category' => 'Network activity', 'to_ids' => 1),
'zeek' => array('desc' => 'An NIDS rule in the Zeek rule-format', 'formdesc' => "An NIDS rule in the Zeek rule-format.", 'default_category' => 'Network activity', 'to_ids' => 1),
'pattern-in-file' => array('desc' => 'Pattern in file that identifies the malware', 'default_category' => 'Payload installation', 'to_ids' => 1),
'pattern-in-traffic' => array('desc' => 'Pattern in network traffic that identifies the malware', 'default_category' => 'Network activity', 'to_ids' => 1),
'pattern-in-memory' => array('desc' => 'Pattern in memory dump that identifies the malware', 'default_category' => 'Payload installation', 'to_ids' => 1),
'yara' => array('desc' => 'Yara signature', 'default_category' => 'Payload installation', 'to_ids' => 1),
'stix2-pattern' => array('desc' => 'STIX 2 pattern', 'default_category' => 'Payload installation', 'to_ids' => 1),
'sigma' => array('desc' => 'Sigma - Generic Signature Format for SIEM Systems', 'default_category' => 'Payload installation', 'to_ids' => 1),
'gene' => array('desc' => 'GENE - Go Evtx sigNature Engine', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'mime-type' => array('desc' => 'A media type (also MIME type and content type) is a two-part identifier for file formats and format contents transmitted on the Internet', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'identity-card-number' => array('desc' => 'Identity card number', 'default_category' => 'Person', 'to_ids' => 0),
'cookie' => array('desc' => 'HTTP cookie as often stored on the user web client. This can include authentication cookie or session cookie.', 'default_category' => 'Network activity', 'to_ids' => 0),
'vulnerability' => array('desc' => 'A reference to the vulnerability used in the exploit', 'default_category' => 'External analysis', 'to_ids' => 0),
'attachment' => array('desc' => 'Attachment with external information', 'formdesc' => "Please upload files using the <em>Upload Attachment</em> button.", 'default_category' => 'External analysis', 'to_ids' => 0),
'malware-sample' => array('desc' => 'Attachment containing encrypted malware sample', 'formdesc' => "Please upload files using the <em>Upload Attachment</em> button.", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'link' => array('desc' => 'Link to an external information', 'default_category' => 'External analysis', 'to_ids' => 0),
'comment' => array('desc' => 'Comment or description in a human language', 'formdesc' => 'Comment or description in a human language. This will not be correlated with other attributes', 'default_category' => 'Other', 'to_ids' => 0),
'text' => array('desc' => 'Name, ID or a reference', 'default_category' => 'Other', 'to_ids' => 0),
'hex' => array('desc' => 'A value in hexadecimal format', 'default_category' => 'Other', 'to_ids' => 0),
'other' => array('desc' => 'Other attribute', 'default_category' => 'Other', 'to_ids' => 0),
'named pipe' => array('desc' => 'Named pipe, use the format \\.\pipe\<PipeName>', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'mutex' => array('desc' => 'Mutex, use the format \BaseNamedObjects\<Mutex>', 'default_category' => 'Artifacts dropped', 'to_ids' => 1),
'target-user' => array('desc' => 'Attack Targets Username(s)', 'default_category' => 'Targeting data', 'to_ids' => 0),
'target-email' => array('desc' => 'Attack Targets Email(s)', 'default_category' => 'Targeting data', 'to_ids' => 0),
'target-machine' => array('desc' => 'Attack Targets Machine Name(s)', 'default_category' => 'Targeting data', 'to_ids' => 0),
'target-org' => array('desc' => 'Attack Targets Department or Organization(s)', 'default_category' => 'Targeting data', 'to_ids' => 0),
'target-location' => array('desc' => 'Attack Targets Physical Location(s)', 'default_category' => 'Targeting data', 'to_ids' => 0),
'target-external' => array('desc' => 'External Target Organizations Affected by this Attack', 'default_category' => 'Targeting data', 'to_ids' => 0),
'btc' => array('desc' => 'Bitcoin Address', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'xmr' => array('desc' => 'Monero Address', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'iban' => array('desc' => 'International Bank Account Number', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'bic' => array('desc' => 'Bank Identifier Code Number also known as SWIFT-BIC, SWIFT code or ISO 9362 code', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'bank-account-nr' => array('desc' => 'Bank account number without any routing number', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'aba-rtn' => array('desc' => 'ABA routing transit number', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'bin' => array('desc' => 'Bank Identification Number', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'cc-number' => array('desc' => 'Credit-Card Number', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'prtn' => array('desc' => 'Premium-Rate Telephone Number', 'default_category' => 'Financial fraud', 'to_ids' => 1),
'phone-number' => array('desc' => 'Telephone Number', 'default_category' => 'Person', 'to_ids' => 0),
'threat-actor' => array('desc' => 'A string identifying the threat actor', 'default_category' => 'Attribution', 'to_ids' => 0),
'campaign-name' => array('desc' => 'Associated campaign name', 'default_category' => 'Attribution', 'to_ids' => 0),
'campaign-id' => array('desc' => 'Associated campaign ID', 'default_category' => 'Attribution', 'to_ids' => 0),
'malware-type' => array('desc' => '', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'uri' => array('desc' => 'Uniform Resource Identifier', 'default_category' => 'Network activity', 'to_ids' => 1),
'authentihash' => array('desc' => 'Authenticode executable signature hash', 'formdesc' => "You are encouraged to use filename|authentihash instead. Authenticode executable signature hash, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'ssdeep' => array('desc' => 'A checksum in ssdeep format', 'formdesc' => "You are encouraged to use filename|ssdeep instead. A checksum in the SSDeep format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'imphash' => array('desc' => 'Import hash - a hash created based on the imports in the sample.', 'formdesc' => "You are encouraged to use filename|imphash instead. A hash created based on the imports in the sample, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'pehash' => array('desc' => 'PEhash - a hash calculated based of certain pieces of a PE executable file', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'impfuzzy' => array('desc' => 'A fuzzy hash of import table of Portable Executable format', 'formdesc' => "You are encouraged to use filename|impfuzzy instead. A fuzzy hash created based on the imports in the sample, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha224' => array('desc' => 'A checksum in sha-224 format', 'formdesc' => "You are encouraged to use filename|sha224 instead. A checksum in sha224 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha384' => array('desc' => 'A checksum in sha-384 format', 'formdesc' => "You are encouraged to use filename|sha384 instead. A checksum in sha384 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha512' => array('desc' => 'A checksum in sha-512 format', 'formdesc' => "You are encouraged to use filename|sha512 instead. A checksum in sha512 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha512/224' => array('desc' => 'A checksum in the sha-512/224 format', 'formdesc' => "You are encouraged to use filename|sha512/224 instead. A checksum in sha512/224 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'sha512/256' => array('desc' => 'A checksum in the sha-512/256 format', 'formdesc' => "You are encouraged to use filename|sha512/256 instead. A checksum in sha512/256 format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'tlsh' => array('desc' => 'A checksum in the Trend Micro Locality Sensitive Hash format', 'formdesc' => "You are encouraged to use filename|tlsh instead. A checksum in the Trend Micro Locality Sensitive Hash format, only use this if you don't know the correct filename", 'default_category' => 'Payload delivery', 'to_ids' => 1),
'cdhash' => array('desc' => 'An Apple Code Directory Hash, identifying a code-signed Mach-O executable file', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|authentihash' => array('desc' => 'A checksum in md5 format', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|ssdeep' => array('desc' => 'A checksum in ssdeep format', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|imphash' => array('desc' => 'Import hash - a hash created based on the imports in the sample.', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|impfuzzy' => array('desc' => 'Import fuzzy hash - a fuzzy hash created based on the imports in the sample.', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|pehash' => array('desc' => 'A filename and a PEhash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha224' => array('desc' => 'A filename and a sha-224 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha384' => array('desc' => 'A filename and a sha-384 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha512' => array('desc' => 'A filename and a sha-512 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha512/224' => array('desc' => 'A filename and a sha-512/224 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|sha512/256' => array('desc' => 'A filename and a sha-512/256 hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'filename|tlsh' => array('desc' => 'A filename and a Trend Micro Locality Sensitive Hash separated by a |', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'windows-scheduled-task' => array('desc' => 'A scheduled task in windows', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'windows-service-name' => array('desc' => 'A windows service name. This is the name used internally by windows. Not to be confused with the windows-service-displayname.', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'windows-service-displayname' => array('desc' => 'A windows service\'s displayname, not to be confused with the windows-service-name. This is the name that applications will generally display as the service\'s name in applications.', 'default_category' => 'Artifacts dropped', 'to_ids' => 0),
'whois-registrant-email' => array('desc' => 'The e-mail of a domain\'s registrant, obtained from the WHOIS information.', 'default_category' => 'Attribution', 'to_ids' => 0),
'whois-registrant-phone' => array('desc' => 'The phone number of a domain\'s registrant, obtained from the WHOIS information.', 'default_category' => 'Attribution', 'to_ids' => 0),
'whois-registrant-name' => array('desc' => 'The name of a domain\'s registrant, obtained from the WHOIS information.', 'default_category' => 'Attribution', 'to_ids' => 0),
'whois-registrant-org' => array('desc' => 'The org of a domain\'s registrant, obtained from the WHOIS information.', 'default_category' => 'Attribution', 'to_ids' => 0),
'whois-registrar' => array('desc' => 'The registrar of the domain, obtained from the WHOIS information.', 'default_category' => 'Attribution', 'to_ids' => 0),
'whois-creation-date' => array('desc' => 'The date of domain\'s creation, obtained from the WHOIS information.', 'default_category' => 'Attribution', 'to_ids' => 0),
// 'targeted-threat-index' => array('desc' => ''), // currently not mapped!
// 'mailslot' => array('desc' => 'MailSlot interprocess communication'), // currently not mapped!
// 'pipe' => array('desc' => 'Pipeline (for named pipes use the attribute type "named pipe")'), // currently not mapped!
// 'ssl-cert-attributes' => array('desc' => 'SSL certificate attributes'), // currently not mapped!
'x509-fingerprint-sha1' => array('desc' => 'X509 fingerprint in SHA-1 format', 'default_category' => 'Network activity', 'to_ids' => 1),
'x509-fingerprint-md5' => array('desc' => 'X509 fingerprint in MD5 format', 'default_category' => 'Network activity', 'to_ids' => 1),
'x509-fingerprint-sha256' => array('desc' => 'X509 fingerprint in SHA-256 format', 'default_category' => 'Network activity', 'to_ids' => 1),
'dns-soa-email' => array('desc' => 'RFC1035 mandates that DNS zones should have a SOA (Statement Of Authority) record that contains an email address where a PoC for the domain could be contacted. This can sometimes be used for attribution/linkage between different domains even if protected by whois privacy', 'default_category' => 'Attribution', 'to_ids' => 0),
'size-in-bytes' => array('desc' => 'Size expressed in bytes', 'default_category' => 'Other', 'to_ids' => 0),
'counter' => array('desc' => 'An integer counter, generally to be used in objects', 'default_category' => 'Other', 'to_ids' => 0),
'datetime' => array('desc' => 'Datetime in the ISO 8601 format', 'default_category' => 'Other', 'to_ids' => 0),
'cpe' => array('desc' => 'Common platform enumeration', 'default_category' => 'Other', 'to_ids' => 0),
'port' => array('desc' => 'Port number', 'default_category' => 'Network activity', 'to_ids' => 0),
'ip-dst|port' => array('desc' => 'IP destination and port number seperated by a |', 'default_category' => 'Network activity', 'to_ids' => 1),
'ip-src|port' => array('desc' => 'IP source and port number seperated by a |', 'default_category' => 'Network activity', 'to_ids' => 1),
'hostname|port' => array('desc' => 'Hostname and port number seperated by a |', 'default_category' => 'Network activity', 'to_ids' => 1),
'mac-address' => array('desc' => 'Mac address', 'default_category' => 'Network activity', 'to_ids' => 0),
'mac-eui-64' => array('desc' => 'Mac EUI-64 address', 'default_category' => 'Network activity', 'to_ids' => 0),
// verify IDS flag defaults for these
'email-dst-display-name' => array('desc' => 'Email destination display name', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-src-display-name' => array('desc' => 'Email source display name', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-header' => array('desc' => 'Email header', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-reply-to' => array('desc' => 'Email reply to header', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-x-mailer' => array('desc' => 'Email x-mailer header', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-mime-boundary' => array('desc' => 'The email mime boundary separating parts in a multipart email', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-thread-index' => array('desc' => 'The email thread index header', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'email-message-id' => array('desc' => 'The email message ID', 'default_category' => 'Payload delivery', 'to_ids' => 0),
'github-username' => array('desc' => 'A github user name', 'default_category' => 'Social network', 'to_ids' => 0),
'github-repository' => array('desc' => 'A github repository', 'default_category' => 'Social network', 'to_ids' => 0),
'github-organisation' => array('desc' => 'A github organisation', 'default_category' => 'Social network', 'to_ids' => 0),
'jabber-id' => array('desc' => 'Jabber ID', 'default_category' => 'Social network', 'to_ids' => 0),
'twitter-id' => array('desc' => 'Twitter ID', 'default_category' => 'Social network', 'to_ids' => 0),
'first-name' => array('desc' => 'First name of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'middle-name' => array('desc' => 'Middle name of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'last-name' => array('desc' => 'Last name of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'date-of-birth' => array('desc' => 'Date of birth of a natural person (in YYYY-MM-DD format)', 'default_category' => 'Person', 'to_ids' => 0),
'place-of-birth' => array('desc' => 'Place of birth of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'gender' => array('desc' => 'The gender of a natural person (Male, Female, Other, Prefer not to say)', 'default_category' => 'Person', 'to_ids' => 0),
'passport-number' => array('desc' => 'The passport number of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'passport-country' => array('desc' => 'The country in which the passport was issued', 'default_category' => 'Person', 'to_ids' => 0),
'passport-expiration' => array('desc' => 'The expiration date of a passport', 'default_category' => 'Person', 'to_ids' => 0),
'redress-number' => array('desc' => 'The Redress Control Number is the record identifier for people who apply for redress through the DHS Travel Redress Inquiry Program (DHS TRIP). DHS TRIP is for travelers who have been repeatedly identified for additional screening and who want to file an inquiry to have erroneous information corrected in DHS systems', 'default_category' => 'Person', 'to_ids' => 0),
'nationality' => array('desc' => 'The nationality of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'visa-number' => array('desc' => 'Visa number', 'default_category' => 'Person', 'to_ids' => 0),
'issue-date-of-the-visa' => array('desc' => 'The date on which the visa was issued', 'default_category' => 'Person', 'to_ids' => 0),
'primary-residence' => array('desc' => 'The primary residence of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'country-of-residence' => array('desc' => 'The country of residence of a natural person', 'default_category' => 'Person', 'to_ids' => 0),
'special-service-request' => array('desc' => 'A Special Service Request is a function to an airline to provide a particular facility for A Passenger or passengers. ', 'default_category' => 'Person', 'to_ids' => 0),
'frequent-flyer-number' => array('desc' => 'The frequent flyer number of a passenger', 'default_category' => 'Person', 'to_ids' => 0),
// Do we really need remarks? Or just use comment/text for this?
//'remarks' => array('desc' => '', 'default_category' => 'Person', 'to_ids' => 0),
'travel-details' => array('desc' => 'Travel details', 'default_category' => 'Person', 'to_ids' => 0),
'payment-details' => array('desc' => 'Payment details', 'default_category' => 'Person', 'to_ids' => 0),
'place-port-of-original-embarkation' => array('desc' => 'The orignal port of embarkation', 'default_category' => 'Person', 'to_ids' => 0),
'place-port-of-clearance' => array('desc' => 'The port of clearance', 'default_category' => 'Person', 'to_ids' => 0),
'place-port-of-onward-foreign-destination' => array('desc' => 'A Port where the passenger is transiting to', 'default_category' => 'Person', 'to_ids' => 0),
'passenger-name-record-locator-number' => array('desc' => 'The Passenger Name Record Locator is a key under which the reservation for a trip is stored in the system. The PNR contains, among other data, the name, flight segments and address of the passenger. It is defined by a combination of five or six letters and numbers.', 'default_category' => 'Person', 'to_ids' => 0),
'mobile-application-id' => array('desc' => 'The application id of a mobile application', 'default_category' => 'Payload delivery', 'to_ids' => 1),
'cortex' => array('desc' => 'Cortex analysis result', 'default_category' => 'External analysis', 'to_ids' => 0),
'boolean' => array('desc' => 'Boolean value - to be used in objects', 'default_category' => 'Other', 'to_ids' => 0)
// Not convinced about this.
//'url-regex' => array('desc' => '', 'default_category' => 'Person', 'to_ids' => 0),
);
// TODO i18n?
// definitions of categories
public $categoryDefinitions = array(
'Internal reference' => array(
'desc' => 'Reference used by the publishing party (e.g. ticket number)',
'types' => array('text', 'link', 'comment', 'other', 'hex')
),
'Targeting data' => array(
'desc' => 'Internal Attack Targeting and Compromise Information',
'formdesc' => 'Targeting information to include recipient email, infected machines, department, and or locations.',
'types' => array('target-user', 'target-email', 'target-machine', 'target-org', 'target-location', 'target-external', 'comment')
),
'Antivirus detection' => array(
'desc' => 'All the info about how the malware is detected by the antivirus products',
'formdesc' => 'List of anti-virus vendors detecting the malware or information on detection performance (e.g. 13/43 or 67%). Attachment with list of detection or link to VirusTotal could be placed here as well.',
'types' => array('link', 'comment', 'text', 'hex', 'attachment', 'other')
),
'Payload delivery' => array(
'desc' => 'Information about how the malware is delivered',
'formdesc' => 'Information about the way the malware payload is initially delivered, for example information about the email or web-site, vulnerability used, originating IP etc. Malware sample itself should be attached here.',
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy', 'authentihash', 'pehash', 'tlsh', 'cdhash', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash','filename|impfuzzy', 'filename|pehash', 'mac-address', 'mac-eui-64', 'ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'email-body', 'url', 'user-agent', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'stix2-pattern', 'yara', 'sigma', 'mime-type', 'attachment', 'malware-sample', 'link', 'malware-type', 'comment', 'text', 'hex', 'vulnerability', 'x509-fingerprint-sha1', 'x509-fingerprint-md5', 'x509-fingerprint-sha256', 'ja3-fingerprint-md5', 'hassh-md5', 'hasshserver-md5', 'other', 'hostname|port', 'email-dst-display-name', 'email-src-display-name', 'email-header', 'email-reply-to', 'email-x-mailer', 'email-mime-boundary', 'email-thread-index', 'email-message-id', 'mobile-application-id', 'whois-registrant-email')
),
'Artifacts dropped' => array(
'desc' => 'Any artifact (files, registry keys etc.) dropped by the malware or other modifications to the system',
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy', 'authentihash', 'cdhash', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|impfuzzy','filename|pehash', 'regkey', 'regkey|value', 'pattern-in-file', 'pattern-in-memory','pdb', 'stix2-pattern', 'yara', 'sigma', 'attachment', 'malware-sample', 'named pipe', 'mutex', 'windows-scheduled-task', 'windows-service-name', 'windows-service-displayname', 'comment', 'text', 'hex', 'x509-fingerprint-sha1', 'x509-fingerprint-md5', 'x509-fingerprint-sha256', 'other', 'cookie', 'gene', 'mime-type')
),
'Payload installation' => array(
'desc' => 'Info on where the malware gets installed in the system',
'formdesc' => 'Location where the payload was placed in the system and the way it was installed. For example, a filename|md5 type attribute can be added here like this: c:\\windows\\system32\\malicious.exe|41d8cd98f00b204e9800998ecf8427e.',
'types' => array('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy', 'authentihash', 'pehash', 'tlsh', 'cdhash', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|impfuzzy', 'filename|pehash', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'stix2-pattern', 'yara', 'sigma', 'vulnerability', 'attachment', 'malware-sample', 'malware-type', 'comment', 'text', 'hex', 'x509-fingerprint-sha1', 'x509-fingerprint-md5', 'x509-fingerprint-sha256', 'mobile-application-id', 'other', 'mime-type')
),
'Persistence mechanism' => array(
'desc' => 'Mechanisms used by the malware to start at boot',
'formdesc' => 'Mechanisms used by the malware to start at boot. This could be a registry key, legitimate driver modification, LNK file in startup',
'types' => array('filename', 'regkey', 'regkey|value', 'comment', 'text', 'other', 'hex')
),
'Network activity' => array(
'desc' => 'Information about network traffic generated by the malware',
'types' => array('ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'port', 'hostname', 'domain', 'domain|ip', 'mac-address', 'mac-eui-64', 'email-dst', 'url', 'uri', 'user-agent', 'http-method', 'AS', 'snort', 'pattern-in-file', 'stix2-pattern', 'pattern-in-traffic', 'attachment', 'comment', 'text', 'x509-fingerprint-md5', 'x509-fingerprint-sha1', 'x509-fingerprint-sha256', 'ja3-fingerprint-md5', 'hassh-md5', 'hasshserver-md5', 'other', 'hex', 'cookie', 'hostname|port', 'bro', 'zeek')
),
'Payload type' => array(
'desc' => 'Information about the final payload(s)',
'formdesc' => 'Information about the final payload(s). Can contain a function of the payload, e.g. keylogger, RAT, or a name if identified, such as Poison Ivy.',
'types' => array('comment', 'text', 'other')
),
'Attribution' => array(
'desc' => 'Identification of the group, organisation, or country behind the attack',
'types' => array('threat-actor', 'campaign-name', 'campaign-id', 'whois-registrant-phone', 'whois-registrant-email', 'whois-registrant-name', 'whois-registrant-org', 'whois-registrar', 'whois-creation-date','comment', 'text', 'x509-fingerprint-sha1','x509-fingerprint-md5', 'x509-fingerprint-sha256', 'other', 'dns-soa-email')
),
'External analysis' => array(
'desc' => 'Any other result from additional analysis of the malware like tools output',
'formdesc' => 'Any other result from additional analysis of the malware like tools output Examples: pdf-parser output, automated sandbox analysis, reverse engineering report.',
'types' => array('md5', 'sha1', 'sha256','filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'ip-src', 'ip-dst', 'ip-dst|port', 'ip-src|port', 'mac-address', 'mac-eui-64', 'hostname', 'domain', 'domain|ip', 'url', 'user-agent', 'regkey', 'regkey|value', 'AS', 'snort', 'bro', 'zeek', 'pattern-in-file', 'pattern-in-traffic', 'pattern-in-memory', 'vulnerability', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'x509-fingerprint-sha1', 'x509-fingerprint-md5', 'x509-fingerprint-sha256', 'ja3-fingerprint-md5', 'hassh-md5', 'hasshserver-md5', 'github-repository', 'other', 'cortex')
),
'Financial fraud' => array(
'desc' => 'Financial Fraud indicators',
'formdesc' => 'Financial Fraud indicators, for example: IBAN Numbers, BIC codes, Credit card numbers, etc.',
'types' => array('btc', 'xmr', 'iban', 'bic', 'bank-account-nr', 'aba-rtn', 'bin', 'cc-number', 'prtn', 'phone-number', 'comment', 'text', 'other', 'hex'),
),
'Support Tool' => array(
'desc' => 'Tools supporting analysis or detection of the event',
'types' => array('link', 'text', 'attachment', 'comment', 'other', 'hex')
),
'Social network' => array(
'desc' => 'Social networks and platforms',
// email-src and email-dst or should we go with a new email type that is neither / both?
'types' => array('github-username', 'github-repository', 'github-organisation', 'jabber-id', 'twitter-id', 'email-src', 'email-dst', 'comment', 'text', 'other', 'whois-registrant-email')
),
'Person' => array(
'desc' => 'A human being - natural person',
'types' => array('first-name', 'middle-name', 'last-name', 'date-of-birth', 'place-of-birth', 'gender', 'passport-number', 'passport-country', 'passport-expiration', 'redress-number', 'nationality', 'visa-number', 'issue-date-of-the-visa', 'primary-residence', 'country-of-residence', 'special-service-request', 'frequent-flyer-number', 'travel-details', 'payment-details', 'place-port-of-original-embarkation', 'place-port-of-clearance', 'place-port-of-onward-foreign-destination', 'passenger-name-record-locator-number', 'comment', 'text', 'other', 'phone-number', 'identity-card-number')
),
'Other' => array(
'desc' => 'Attributes that are not part of any other category or are meant to be used as a component in MISP objects in the future',
'types' => array('comment', 'text', 'other', 'size-in-bytes', 'counter', 'datetime', 'cpe', 'port', 'float', 'hex', 'phone-number', 'boolean')
)
);
// FIXME we need a better way to list the defaultCategories knowing that new attribute types will continue to appear in the future. We should generate this dynamically or use a function using the default_category of the $typeDefinitions
public $defaultCategories = array(
'md5' => 'Payload delivery',
'sha1' => 'Payload delivery',
'sha224' =>'Payload delivery',
'sha256' => 'Payload delivery',
'sha384' => 'Payload delivery',
'sha512' => 'Payload delivery',
'sha512/224' => 'Payload delivery',
'sha512/256' => 'Payload delivery',
'authentihash' => 'Payload delivery',
'imphash' => 'Payload delivery',
'impfuzzy'=> 'Payload delivery',
'pehash' => 'Payload delivery',
'cdhash' => 'Payload delivery',
'filename|md5' => 'Payload delivery',
'filename|sha1' => 'Payload delivery',
'filename|sha256' => 'Payload delivery',
'regkey' => 'Persistence mechanism',
'filename' => 'Payload delivery',
'ip-src' => 'Network activity',
'ip-dst' => 'Network activity',
'ip-dst|port' => 'Network activity',
'mac-address' => 'Network activity',
'mac-eui-64' => 'Network activity',
'hostname' => 'Network activity',
'domain' => 'Network activity',
'url' => 'Network activity',
'ja3-fingerprint-md5' => 'Network activity',
'hassh-md5' => 'Network activity',
'hasshserver-md5' => 'Network activity',
'link' => 'External analysis',
'email-src' => 'Payload delivery',
'email-dst' => 'Payload delivery',
'text' => 'Other',
'hex' => 'Other',
'attachment' => 'External analysis',
'malware-sample' => 'Payload delivery',
'cortex' => 'External analysis',
'dns-soa-email' => 'Attribution',
'boolean' => 'Other'
);
// typeGroupings are a mapping to high level groups for attributes
// for example, IP addresses, domain names, hostnames and e-mail addresses are network related attribute types
// whilst filenames and hashes are file related attribute types
// This helps generate quick filtering for the event view, but we may reuse this and enhance it in the future for other uses (such as the API?)
public $typeGroupings = array(
'file' => array('attachment', 'pattern-in-file', 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'impfuzzy', 'authentihash', 'pehash', 'tlsh', 'cdhash', 'filename', 'filename|md5', 'filename|sha1', 'filename|sha224', 'filename|sha256', 'filename|sha384', 'filename|sha512', 'filename|sha512/224', 'filename|sha512/256', 'filename|authentihash', 'filename|ssdeep', 'filename|tlsh', 'filename|imphash', 'filename|pehash', 'malware-sample', 'x509-fingerprint-sha1', 'x509-fingerprint-sha256', 'x509-fingerprint-md5'),
'network' => array('ip-src', 'ip-dst', 'ip-src|port', 'ip-dst|port', 'mac-address', 'mac-eui-64', 'hostname', 'hostname|port', 'domain', 'domain|ip', 'email-dst', 'url', 'uri', 'user-agent', 'http-method', 'AS', 'snort', 'bro', 'zeek', 'pattern-in-traffic', 'x509-fingerprint-md5', 'x509-fingerprint-sha1', 'x509-fingerprint-sha256','ja3-fingerprint-md5', 'hassh-md5', 'hasshserver-md5'),
'financial' => array('btc', 'xmr', 'iban', 'bic', 'bank-account-nr', 'aba-rtn', 'bin', 'cc-number', 'prtn', 'phone-number')
);
private $__fTool = false;
public $order = array("Attribute.event_id" => "DESC");
public $validate = array(
'event_id' => array(
'numeric' => array(
'rule' => array('numeric')
)
),
'type' => array(
'rule' => array('validateTypeValue'),
'message' => 'Options depend on the selected category.',
'required' => true
),
'category' => array(
'rule' => array('validCategory'),
'message' => 'Options : Payload delivery, Antivirus detection, Payload installation, Files dropped ...'
),
'value' => array(
'stringNotEmpty' => array(
'rule' => array('stringNotEmpty')
),
'userdefined' => array(
'rule' => array('validateAttributeValue'),
'message' => 'Value not in the right type/format. Please double check the value or select type "other".'
),
'uniqueValue' => array(
'rule' => array('valueIsUnique'),
'message' => 'A similar attribute already exists for this event.'
),
'validComposite' => array(
'rule' => array('validComposite'),
'message' => 'Composite type found but the value not in the composite (value1|value2) format.'
),
'maxTextLength' => array(
'rule' => array('maxTextLength')
)
),
'to_ids' => array(
'boolean' => array(
'rule' => array('boolean'),
'required' => false
)
),
'uuid' => array(
'uuid' => array(
'rule' => array('custom', '/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/'),
'message' => 'Please provide a valid UUID'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'The UUID provided is not unique',
'required' => 'create'
)
),
'distribution' => array(
'rule' => array('inList', array('0', '1', '2', '3', '4', '5')),
'message' => 'Options: Your organisation only, This community only, Connected communities, All communities, Sharing group, Inherit event',
'required' => true
)
);
// automatic resolution of complex types
// If the complex type "file" is chosen for example, then the system will try to categorise the values entered into a complex template field based
// on the regular expression rules
public $validTypeGroups = array(
'File' => array(
'description' => '',
'types' => array('filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'md5', 'sha1', 'sha256'),
),
'CnC' => array(
'description' => '',
'types' => array('url', 'domain', 'hostname', 'ip-dst'),
),
);
public $typeGroupCategoryMapping = array(
'Payload delivery' => array('File', 'CnC'),
'Payload installation' => array('File'),
'Artifacts dropped' => array('File'),
'Network activity' => array('CnC'),
);
public function __construct($id = false, $table = null, $ds = null)
{
parent::__construct($id, $table, $ds);
}
public $belongsTo = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'event_id',
'conditions' => '',
'fields' => '',
//'counterCache' => 'attribute_count',
//'counterScope' => array('Attribute.deleted' => 0),
'order' => ''
),
'SharingGroup' => array(
'className' => 'SharingGroup',
'foreignKey' => 'sharing_group_id'
),
'Object' => array(
'className' => 'MispObject',
'foreignKey' => 'object_id'
)
);
public $hasMany = array(
'AttributeTag' => array(
'dependent' => true
),
'Sighting' => array(
'className' => 'Sighting',
'dependent' => true,
)
);
public $hashTypes = array(
'md5' => array(
'length' => 32,
'pattern' => '#^[0-9a-f]{32}$#',
'lowerCase' => true,
),
'sha1' => array(
'length' => 40,
'pattern' => '#^[0-9a-f]{40}$#',
'lowerCase' => true,
),
'sha256' => array(
'length' => 64,
'pattern' => '#^[0-9a-f]{64}$#',
'lowerCase' => true,
)
);
public function afterFind($results, $primary = false)
{
foreach ($results as $k => $v) {
if (isset($v['Attribute']['object_relation']) && $v['Attribute']['object_relation'] === null) {
$results[$k]['Attribute']['object_relation'] = '';
}
}
return $results;
}
public function beforeSave($options = array())
{
// explode value of composite type in value1 and value2
// or copy value to value1 if not composite type
if (!empty($this->data['Attribute']['type'])) {
$compositeTypes = $this->getCompositeTypes();
// explode composite types in value1 and value2
if (in_array($this->data['Attribute']['type'], $compositeTypes)) {
$pieces = explode('|', $this->data['Attribute']['value']);
if (2 != count($pieces)) {
throw new InternalErrorException(__('Composite type, but value not explodable'));
}
$this->data['Attribute']['value1'] = $pieces[0];
$this->data['Attribute']['value2'] = $pieces[1];
} else {
$this->data['Attribute']['value1'] = $this->data['Attribute']['value'];
$this->data['Attribute']['value2'] = '';
}
}
// update correlation... (only needed here if there's an update)
if ($this->id || !empty($this->data['Attribute']['id'])) {
$this->__beforeSaveCorrelation($this->data['Attribute']);
}
// always return true after a beforeSave()
return true;
}
private function __alterAttributeCount($event_id, $increment = true)
{
$event = $this->Event->find('first', array(
'recursive' => -1,
'conditions' => array('Event.id' => $event_id)
));
if (!empty($event)) {
if ($increment) {
$event['Event']['attribute_count'] = $event['Event']['attribute_count'] + 1;
} else {
$event['Event']['attribute_count'] = $event['Event']['attribute_count'] - 1;
}
if ($event['Event']['attribute_count'] >= 0) {
$this->Event->save($event, array('callbacks' => false));
}
}
}
public function afterSave($created, $options = array())
{
$passedEvent = false;
if (isset($options['parentEvent'])) {
$passedEvent = $options['parentEvent'];
}
parent::afterSave($created, $options);
// update correlation...
if (isset($this->data['Attribute']['deleted']) && $this->data['Attribute']['deleted']) {
$this->__beforeSaveCorrelation($this->data['Attribute']);
if (isset($this->data['Attribute']['event_id'])) {
$this->__alterAttributeCount($this->data['Attribute']['event_id'], false, $passedEvent);
}
} else {
$this->__afterSaveCorrelation($this->data['Attribute'], false, $passedEvent);
}
$result = true;
// if the 'data' field is set on the $this->data then save the data to the correct file
if (isset($this->data['Attribute']['type']) && $this->typeIsAttachment($this->data['Attribute']['type']) && !empty($this->data['Attribute']['data'])) {
$result = $result && $this->saveBase64EncodedAttachment($this->data['Attribute']); // TODO : is this correct?
}
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_attribute_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$attribute = $this->fetchAttribute($this->id);
if (!empty($attribute)) {
$user = array(
'org_id' => -1,
'Role' => array(
'perm_site_admin' => 1
)
);
$attribute['Attribute']['Sighting'] = $this->Sighting->attachToEvent($attribute, $user, $this->id);
if (empty($attribute['Object']['id'])) {
unset($attribute['Object']);
}
$action = $created ? 'add' : 'edit';
if (!empty($this->data['Attribute']['deleted'])) {
$action = 'soft-delete';
}
if (Configure::read('Plugin.ZeroMQ_include_attachments') && $this->typeIsAttachment($attribute['Attribute']['type'])) {
$attribute['Attribute']['data'] = $this->base64EncodeAttachment($attribute['Attribute']);
}
$pubSubTool->attribute_save($attribute, $action);
}
}
if (Configure::read('MISP.enable_advanced_correlations') && in_array($this->data['Attribute']['type'], array('ip-src', 'ip-dst', 'domain-ip')) && strpos($this->data['Attribute']['value'], '/')) {
$this->setCIDRList();
}
if ($created && isset($this->data['Attribute']['event_id']) && empty($this->data['Attribute']['skip_auto_increment'])) {
$this->__alterAttributeCount($this->data['Attribute']['event_id']);
}
return $result;
}
public function beforeDelete($cascade = true)
{
// delete attachments from the disk
$this->read(); // first read the attribute from the db
if ($this->typeIsAttachment($this->data['Attribute']['type'])) {
// only delete the file if it exists
$attachments_dir = Configure::read('MISP.attachments_dir');
if (empty($attachments_dir)) {
$attachments_dir = $this->getDefaultAttachments_dir();
}
// Special case - If using S3, we have to delete from there
if ($this->attachmentDirIsS3()) {
// We're working in S3
$s3 = $this->getS3Client();
$s3->delete($this->data['Attribute']['event_id'] . DS . $this->data['Attribute']['id']);
} else {
// Standard delete
$filepath = $attachments_dir . DS . $this->data['Attribute']['event_id'] . DS . $this->data['Attribute']['id'];
$file = new File($filepath);
if ($file->exists()) {
if (!$file->delete()) {
throw new InternalErrorException(__('Delete of file attachment failed. Please report to administrator.'));
}
}
}
}
// update correlation..
$this->__beforeDeleteCorrelation($this->data['Attribute']['id']);
if (!empty($this->data['Attribute']['id'])) {
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_attribute_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->attribute_save($this->data, 'delete');
}
}
}
public function afterDelete()
{
if (Configure::read('MISP.enable_advanced_correlations') && in_array($this->data['Attribute']['type'], array('ip-src', 'ip-dst', 'domain-ip')) && strpos($this->data['Attribute']['value'], '/')) {
$this->setCIDRList();
}
if (isset($this->data['Attribute']['event_id'])) {
if (empty($this->data['Attribute']['deleted'])) {
$this->__alterAttributeCount($this->data['Attribute']['event_id'], false);
}
}
if (!empty($this->data['Attribute']['id'])) {
$this->Object->ObjectReference->deleteAll(
array(
'ObjectReference.referenced_type' => 0,
'ObjectReference.referenced_id' => $this->data['Attribute']['id'],
),
false
);
}
}
public function beforeValidate($options = array())
{
parent::beforeValidate();
if (!isset($this->data['Attribute']['type'])) {
return false;
}
if (is_array($this->data['Attribute']['value'])) {
return false;
}
if (!empty($this->data['Attribute']['object_id']) && empty($this->data['Attribute']['object_relation'])) {
return false;
}
// remove leading and trailing blanks
$this->data['Attribute']['value'] = trim($this->data['Attribute']['value']);
// make some last changes to the inserted value
$this->data['Attribute']['value'] = $this->modifyBeforeValidation($this->data['Attribute']['type'], $this->data['Attribute']['value']);
// set to_ids if it doesn't exist
if (empty($this->data['Attribute']['to_ids'])) {
$this->data['Attribute']['to_ids'] = 0;
}
if (empty($this->data['Attribute']['comment'])) {
$this->data['Attribute']['comment'] = "";
}
// generate UUID if it doesn't exist
if (empty($this->data['Attribute']['uuid'])) {
$this->data['Attribute']['uuid'] = CakeText::uuid();
}
// generate timestamp if it doesn't exist
if (empty($this->data['Attribute']['timestamp'])) {
$date = new DateTime();
$this->data['Attribute']['timestamp'] = $date->getTimestamp();
}
// TODO: add explanatory comment
// TODO: i18n?
$result = $this->runRegexp($this->data['Attribute']['type'], $this->data['Attribute']['value']);
if ($result === false) {
$this->invalidate('value', 'This value is blocked by a regular expression in the import filters.');
} else {
$this->data['Attribute']['value'] = $result;
}
// Set defaults for when some of the mandatory fields don't have defaults
// These fields all have sane defaults either based on another field, or due to server settings
if (!isset($this->data['Attribute']['distribution'])) {
$this->data['Attribute']['distribution'] = Configure::read('MISP.default_attribute_distribution');
if ($this->data['Attribute']['distribution'] == 'event') {
$this->data['Attribute']['distribution'] = 5;
}
}
if (!empty($this->data['Attribute']['type']) && empty($this->data['Attribute']['category'])) {
$this->data['Attribute']['category'] = $this->typeDefinitions[$this->data['Attribute']['type']]['default_category'];
}
if (!isset($this->data['Attribute']['to_ids'])) {
$this->data['Attribute']['to_ids'] = $this->typeDefinitions[$this->data['Attribute']['type']]['to_ids'];
}
if ($this->data['Attribute']['distribution'] != 4) {
$this->data['Attribute']['sharing_group_id'] = 0;
}
// return true, otherwise the object cannot be saved
if ($this->data['Attribute']['type'] == 'float' && $this->data['Attribute']['value'] == 0) {
$this->data['Attribute']['value'] = '0.0';
}
return true;
}
public function validComposite($fields)
{
$compositeTypes = $this->getCompositeTypes();
if (in_array($this->data['Attribute']['type'], $compositeTypes)) {
$pieces = explode('|', $fields['value']);
if (2 != count($pieces)) {
return false;
}
}
return true;
}
public function maxTextLength($fields)
{
if (strlen($fields['value']) > 65535) {
return __('The entered string is too long and would get truncated. Please consider adding the data as an attachment instead');
}
return true;
}
public function validCategory($fields)
{
$validCategories = array_keys($this->categoryDefinitions);
if (in_array($fields['category'], $validCategories)) {
return true;
}
return false;
}
public function valueIsUnique($fields)
{
if (isset($this->data['Attribute']['deleted']) && $this->data['Attribute']['deleted']) {
return true;
}
// We escape this rule for objects as we can have the same category/type/value combination in different objects
if (!empty($this->data['Attribute']['object_relation'])) {
return true;
}
$value = $fields['value'];
if (strpos($value, '|')) {
$value = explode('|', $value);
$value = array(
'Attribute.value1' => $value[0],
'Attribute.value2' => $value[1]
);
} else {
$value = array(
'Attribute.value1' => $value,
);
}
$eventId = $this->data['Attribute']['event_id'];
$type = $this->data['Attribute']['type'];
$category = $this->data['Attribute']['category'];
// check if the attribute already exists in the same event
$conditions = array(
'Attribute.event_id' => $eventId,
'Attribute.type' => $type,
'Attribute.category' => $category,
'Attribute.deleted' => 0,
'Attribute.object_id' => 0
);
$conditions = array_merge($conditions, $value);
if (isset($this->data['Attribute']['id'])) {
$conditions['Attribute.id !='] = $this->data['Attribute']['id'];
}
$params = array(
'recursive' => -1,
'fields' => array('id'),
'conditions' => $conditions,
);
if (!empty($this->find('first', $params))) {
// value isn't unique
return false;
}
// value is unique
return true;
}
public function validateTypeValue($fields)
{
$category = $this->data['Attribute']['category'];
if (isset($this->categoryDefinitions[$category]['types'])) {
return in_array($fields['type'], $this->categoryDefinitions[$category]['types']);
}
return false;
}
public function validateAttributeValue($fields)
{
$value = $fields['value'];
return $this->runValidation($value, $this->data['Attribute']['type']);
}
private $__hexHashLengths = array(
'authentihash' => 64,
'md5' => 32,
'imphash' => 32,
'sha1' => 40,
'x509-fingerprint-md5' => 32,
'x509-fingerprint-sha1' => 40,
'x509-fingerprint-sha256' => 64,
'ja3-fingerprint-md5' => 32,
'hassh-md5' => 32,
'hasshserver-md5' => 32,
'pehash' => 40,
'sha224' => 56,
'sha256' => 64,
'sha384' => 96,
'sha512' => 128,
'sha512/224' => 56,
'sha512/256' => 64
);
public function runValidation($value, $type)
{
$returnValue = false;
// check data validation
switch ($type) {
case 'md5':
case 'imphash':
case 'sha1':
case 'sha224':
case 'sha256':
case 'sha384':
case 'sha512':
case 'sha512/224':
case 'sha512/256':
case 'authentihash':
case 'ja3-fingerprint-md5':
case 'hassh-md5':
case 'hasshserver-md5':
case 'x509-fingerprint-md5':
case 'x509-fingerprint-sha256':
case 'x509-fingerprint-sha1':
$length = $this->__hexHashLengths[$type];
if (preg_match("#^[0-9a-f]{" . $length . "}$#", $value)) {
$returnValue = true;
} else {
$returnValue = __('Checksum has an invalid length or format (expected: %s hexadecimal characters). Please double check the value or select type "other".', $length);
}
break;
case 'tlsh':
if (preg_match("#^[0-9a-f]{35,}$#", $value)) {
$returnValue = true;
} else {
$returnValue = __('Checksum has an invalid length or format (expected: at least 35 hexadecimal characters). Please double check the value or select type "other".');
}
break;
case 'pehash':
if (preg_match("#^[0-9a-f]{40}$#", $value)) {
$returnValue = true;
} else {
$returnValue = __('The input doesn\'t match the expected sha1 format (expected: 40 hexadecimal characters). Keep in mind that MISP currently only supports SHA1 for PEhashes, if you would like to get the support extended to other hash types, make sure to create a github ticket about it at https://github.com/MISP/MISP!');
}
break;
case 'ssdeep':
if (substr_count($value, ':') == 2) {
$parts = explode(':', $value);
if (is_numeric($parts[0])) {
$returnValue = true;
}
}
if (!$returnValue) {
$returnValue = __('Invalid SSDeep hash. The format has to be blocksize:hash:hash');
}
break;
case 'impfuzzy':
if (substr_count($value, ':') == 2) {
$parts = explode(':', $value);
if (is_numeric($parts[0])) {
$returnValue = true;
}
}
if (!$returnValue) {
$returnValue = __('Invalid impfuzzy format. The format has to be imports:hash:hash');
}
break;
case 'cdhash':
if (preg_match("#^[0-9a-f]{40,}$#", $value)) {
$returnValue = true;
} else {
$returnValue = __('The input doesn\'t match the expected format (expected: 40 or more hexadecimal characters)');
}
break;
case 'http-method':
if (preg_match("#(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PROPFIND|PROPPATCH|MKCOL|COPY|MOVE|LOCK|UNLOCK|VERSION-CONTROL|REPORT|CHECKOUT|CHECKIN|UNCHECKOUT|MKWORKSPACE|UPDATE|LABEL|MERGE|BASELINE-CONTROL|MKACTIVITY|ORDERPATCH|ACL|PATCH|SEARCH)#", $value)) {
$returnValue = true;
} else {