@cyvest/cyvest-js 5.4.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +496 -196
- package/dist/index.d.cts +165 -107
- package/dist/index.d.ts +165 -107
- package/dist/index.js +477 -179
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -36,30 +36,30 @@ __export(index_exports, {
|
|
|
36
36
|
areConnected: () => areConnected,
|
|
37
37
|
compareLevels: () => compareLevels,
|
|
38
38
|
countRelationshipsByType: () => countRelationshipsByType,
|
|
39
|
-
findCheckByName: () => findCheckByName,
|
|
40
|
-
findChecksAtLeast: () => findChecksAtLeast,
|
|
41
|
-
findChecksByLevel: () => findChecksByLevel,
|
|
42
|
-
findChecksForObservable: () => findChecksForObservable,
|
|
43
|
-
findChecksForTag: () => findChecksForTag,
|
|
44
39
|
findExternalObservables: () => findExternalObservables,
|
|
45
|
-
|
|
40
|
+
findFindingByName: () => findFindingByName,
|
|
41
|
+
findFindingsAtLeast: () => findFindingsAtLeast,
|
|
42
|
+
findFindingsByLevel: () => findFindingsByLevel,
|
|
43
|
+
findFindingsForObservable: () => findFindingsForObservable,
|
|
44
|
+
findFindingsForTag: () => findFindingsForTag,
|
|
45
|
+
findHighestScoringFindings: () => findHighestScoringFindings,
|
|
46
46
|
findHighestScoringObservables: () => findHighestScoringObservables,
|
|
47
47
|
findInternalObservables: () => findInternalObservables,
|
|
48
48
|
findLeafObservables: () => findLeafObservables,
|
|
49
|
-
|
|
49
|
+
findMaliciousFindings: () => findMaliciousFindings,
|
|
50
50
|
findMaliciousObservables: () => findMaliciousObservables,
|
|
51
51
|
findObservablesAtLeast: () => findObservablesAtLeast,
|
|
52
52
|
findObservablesByLevel: () => findObservablesByLevel,
|
|
53
53
|
findObservablesByType: () => findObservablesByType,
|
|
54
54
|
findObservablesByValue: () => findObservablesByValue,
|
|
55
55
|
findObservablesContaining: () => findObservablesContaining,
|
|
56
|
-
|
|
56
|
+
findObservablesForFinding: () => findObservablesForFinding,
|
|
57
57
|
findObservablesMatching: () => findObservablesMatching,
|
|
58
58
|
findObservablesWithThreatIntel: () => findObservablesWithThreatIntel,
|
|
59
59
|
findOrphanObservables: () => findOrphanObservables,
|
|
60
60
|
findPath: () => findPath,
|
|
61
61
|
findSourceObservables: () => findSourceObservables,
|
|
62
|
-
|
|
62
|
+
findSuspiciousFindings: () => findSuspiciousFindings,
|
|
63
63
|
findSuspiciousObservables: () => findSuspiciousObservables,
|
|
64
64
|
findTagsAtLeast: () => findTagsAtLeast,
|
|
65
65
|
findTagsByLevel: () => findTagsByLevel,
|
|
@@ -69,22 +69,21 @@ __export(index_exports, {
|
|
|
69
69
|
findThreatIntelBySource: () => findThreatIntelBySource,
|
|
70
70
|
findThreatIntelsForObservable: () => findThreatIntelsForObservable,
|
|
71
71
|
findWhitelistedObservables: () => findWhitelistedObservables,
|
|
72
|
-
generateCheckKey: () => generateCheckKey,
|
|
73
72
|
generateEnrichmentKey: () => generateEnrichmentKey,
|
|
73
|
+
generateFindingKey: () => generateFindingKey,
|
|
74
74
|
generateObservableKey: () => generateObservableKey,
|
|
75
75
|
generateTagKey: () => generateTagKey,
|
|
76
76
|
generateThreatIntelKey: () => generateThreatIntelKey,
|
|
77
|
-
getAllCheckKeys: () => getAllCheckKeys,
|
|
78
|
-
getAllChecks: () => getAllChecks,
|
|
79
77
|
getAllEnrichments: () => getAllEnrichments,
|
|
78
|
+
getAllEvidences: () => getAllEvidences,
|
|
79
|
+
getAllFindingKeys: () => getAllFindingKeys,
|
|
80
|
+
getAllFindings: () => getAllFindings,
|
|
80
81
|
getAllObservableTypes: () => getAllObservableTypes,
|
|
81
82
|
getAllObservables: () => getAllObservables,
|
|
82
83
|
getAllRelationshipTypes: () => getAllRelationshipTypes,
|
|
83
84
|
getAllTags: () => getAllTags,
|
|
84
85
|
getAllThreatIntelSources: () => getAllThreatIntelSources,
|
|
85
86
|
getAllThreatIntels: () => getAllThreatIntels,
|
|
86
|
-
getCheck: () => getCheck,
|
|
87
|
-
getCheckByName: () => getCheckByName,
|
|
88
87
|
getColorForLevel: () => getColorForLevel,
|
|
89
88
|
getColorForScore: () => getColorForScore,
|
|
90
89
|
getCounts: () => getCounts,
|
|
@@ -92,6 +91,9 @@ __export(index_exports, {
|
|
|
92
91
|
getEnrichment: () => getEnrichment,
|
|
93
92
|
getEnrichmentByName: () => getEnrichmentByName,
|
|
94
93
|
getEntityLevel: () => getEntityLevel,
|
|
94
|
+
getEvidence: () => getEvidence,
|
|
95
|
+
getFinding: () => getFinding,
|
|
96
|
+
getFindingByName: () => getFindingByName,
|
|
95
97
|
getLevelFromScore: () => getLevelFromScore,
|
|
96
98
|
getObservable: () => getObservable,
|
|
97
99
|
getObservableByTypeValue: () => getObservableByTypeValue,
|
|
@@ -127,13 +129,13 @@ __export(index_exports, {
|
|
|
127
129
|
maxLevel: () => maxLevel,
|
|
128
130
|
minLevel: () => minLevel,
|
|
129
131
|
normalizeLevel: () => normalizeLevel,
|
|
130
|
-
parseCheckKey: () => parseCheckKey,
|
|
131
132
|
parseCyvest: () => parseCyvest,
|
|
133
|
+
parseFindingKey: () => parseFindingKey,
|
|
132
134
|
parseKeyType: () => parseKeyType,
|
|
133
135
|
parseObservableKey: () => parseObservableKey,
|
|
134
136
|
parseThreatIntelKey: () => parseThreatIntelKey,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
sortFindingsByLevel: () => sortFindingsByLevel,
|
|
138
|
+
sortFindingsByScore: () => sortFindingsByScore,
|
|
137
139
|
sortObservablesByLevel: () => sortObservablesByLevel,
|
|
138
140
|
sortObservablesByScore: () => sortObservablesByScore,
|
|
139
141
|
validateKey: () => validateKey
|
|
@@ -238,69 +240,6 @@ var cyvest_schema_default = {
|
|
|
238
240
|
title: "AuditEvent",
|
|
239
241
|
type: "object"
|
|
240
242
|
},
|
|
241
|
-
Check: {
|
|
242
|
-
description: "Represents a verification step in the investigation.\n\nA check validates a specific aspect of the data under investigation\nand contributes to the overall investigation score.",
|
|
243
|
-
properties: {
|
|
244
|
-
check_name: {
|
|
245
|
-
title: "Check Name",
|
|
246
|
-
type: "string"
|
|
247
|
-
},
|
|
248
|
-
description: {
|
|
249
|
-
title: "Description",
|
|
250
|
-
type: "string"
|
|
251
|
-
},
|
|
252
|
-
comment: {
|
|
253
|
-
title: "Comment",
|
|
254
|
-
type: "string"
|
|
255
|
-
},
|
|
256
|
-
extra: {
|
|
257
|
-
additionalProperties: true,
|
|
258
|
-
title: "Extra",
|
|
259
|
-
type: "object"
|
|
260
|
-
},
|
|
261
|
-
score: {
|
|
262
|
-
title: "Score",
|
|
263
|
-
type: "number"
|
|
264
|
-
},
|
|
265
|
-
level: {
|
|
266
|
-
$ref: "#/$defs/Level"
|
|
267
|
-
},
|
|
268
|
-
origin_investigation_id: {
|
|
269
|
-
title: "Origin Investigation Id",
|
|
270
|
-
type: "string"
|
|
271
|
-
},
|
|
272
|
-
observable_links: {
|
|
273
|
-
items: {
|
|
274
|
-
$ref: "#/$defs/ObservableLink"
|
|
275
|
-
},
|
|
276
|
-
title: "Observable Links",
|
|
277
|
-
type: "array"
|
|
278
|
-
},
|
|
279
|
-
key: {
|
|
280
|
-
title: "Key",
|
|
281
|
-
type: "string"
|
|
282
|
-
},
|
|
283
|
-
score_display: {
|
|
284
|
-
readOnly: true,
|
|
285
|
-
title: "Score Display",
|
|
286
|
-
type: "string"
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
required: [
|
|
290
|
-
"check_name",
|
|
291
|
-
"description",
|
|
292
|
-
"comment",
|
|
293
|
-
"extra",
|
|
294
|
-
"score",
|
|
295
|
-
"level",
|
|
296
|
-
"origin_investigation_id",
|
|
297
|
-
"observable_links",
|
|
298
|
-
"key",
|
|
299
|
-
"score_display"
|
|
300
|
-
],
|
|
301
|
-
title: "Check",
|
|
302
|
-
type: "object"
|
|
303
|
-
},
|
|
304
243
|
DataExtractionSchema: {
|
|
305
244
|
additionalProperties: false,
|
|
306
245
|
description: "Schema for data extraction metadata.",
|
|
@@ -361,6 +300,182 @@ var cyvest_schema_default = {
|
|
|
361
300
|
title: "Enrichment",
|
|
362
301
|
type: "object"
|
|
363
302
|
},
|
|
303
|
+
Evidence: {
|
|
304
|
+
description: "Structured material supporting one or more findings.",
|
|
305
|
+
properties: {
|
|
306
|
+
type: {
|
|
307
|
+
title: "Type",
|
|
308
|
+
type: "string"
|
|
309
|
+
},
|
|
310
|
+
title: {
|
|
311
|
+
title: "Title",
|
|
312
|
+
type: "string"
|
|
313
|
+
},
|
|
314
|
+
description: {
|
|
315
|
+
title: "Description",
|
|
316
|
+
type: "string"
|
|
317
|
+
},
|
|
318
|
+
source: {
|
|
319
|
+
title: "Source",
|
|
320
|
+
type: "string"
|
|
321
|
+
},
|
|
322
|
+
external_id: {
|
|
323
|
+
anyOf: [
|
|
324
|
+
{
|
|
325
|
+
type: "string"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
type: "null"
|
|
329
|
+
}
|
|
330
|
+
],
|
|
331
|
+
title: "External Id"
|
|
332
|
+
},
|
|
333
|
+
content: {
|
|
334
|
+
anyOf: [
|
|
335
|
+
{},
|
|
336
|
+
{
|
|
337
|
+
type: "null"
|
|
338
|
+
}
|
|
339
|
+
],
|
|
340
|
+
title: "Content"
|
|
341
|
+
},
|
|
342
|
+
uri: {
|
|
343
|
+
anyOf: [
|
|
344
|
+
{
|
|
345
|
+
type: "string"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
type: "null"
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
title: "Uri"
|
|
352
|
+
},
|
|
353
|
+
captured_at: {
|
|
354
|
+
format: "date-time",
|
|
355
|
+
title: "Captured At",
|
|
356
|
+
type: "string"
|
|
357
|
+
},
|
|
358
|
+
extra: {
|
|
359
|
+
additionalProperties: true,
|
|
360
|
+
title: "Extra",
|
|
361
|
+
type: "object"
|
|
362
|
+
},
|
|
363
|
+
key: {
|
|
364
|
+
title: "Key",
|
|
365
|
+
type: "string"
|
|
366
|
+
},
|
|
367
|
+
finding_links: {
|
|
368
|
+
description: "Findings that currently link to this evidence (navigation-only).",
|
|
369
|
+
items: {
|
|
370
|
+
type: "string"
|
|
371
|
+
},
|
|
372
|
+
readOnly: true,
|
|
373
|
+
title: "Finding Links",
|
|
374
|
+
type: "array"
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
required: [
|
|
378
|
+
"type",
|
|
379
|
+
"title",
|
|
380
|
+
"description",
|
|
381
|
+
"source",
|
|
382
|
+
"external_id",
|
|
383
|
+
"content",
|
|
384
|
+
"uri",
|
|
385
|
+
"captured_at",
|
|
386
|
+
"extra",
|
|
387
|
+
"key",
|
|
388
|
+
"finding_links"
|
|
389
|
+
],
|
|
390
|
+
title: "Evidence",
|
|
391
|
+
type: "object"
|
|
392
|
+
},
|
|
393
|
+
EvidenceLink: {
|
|
394
|
+
additionalProperties: false,
|
|
395
|
+
description: "Edge metadata for a Finding\u2194Evidence association.",
|
|
396
|
+
properties: {
|
|
397
|
+
evidence_key: {
|
|
398
|
+
title: "Evidence Key",
|
|
399
|
+
type: "string"
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
required: [
|
|
403
|
+
"evidence_key"
|
|
404
|
+
],
|
|
405
|
+
title: "EvidenceLink",
|
|
406
|
+
type: "object"
|
|
407
|
+
},
|
|
408
|
+
Finding: {
|
|
409
|
+
description: "Represents a verification step in the investigation.\n\nA finding validates a specific aspect of the data under investigation\nand contributes to the overall investigation score.",
|
|
410
|
+
properties: {
|
|
411
|
+
finding_name: {
|
|
412
|
+
title: "Finding Name",
|
|
413
|
+
type: "string"
|
|
414
|
+
},
|
|
415
|
+
description: {
|
|
416
|
+
title: "Description",
|
|
417
|
+
type: "string"
|
|
418
|
+
},
|
|
419
|
+
comment: {
|
|
420
|
+
title: "Comment",
|
|
421
|
+
type: "string"
|
|
422
|
+
},
|
|
423
|
+
extra: {
|
|
424
|
+
additionalProperties: true,
|
|
425
|
+
title: "Extra",
|
|
426
|
+
type: "object"
|
|
427
|
+
},
|
|
428
|
+
score: {
|
|
429
|
+
title: "Score",
|
|
430
|
+
type: "number"
|
|
431
|
+
},
|
|
432
|
+
level: {
|
|
433
|
+
$ref: "#/$defs/Level"
|
|
434
|
+
},
|
|
435
|
+
origin_investigation_id: {
|
|
436
|
+
title: "Origin Investigation Id",
|
|
437
|
+
type: "string"
|
|
438
|
+
},
|
|
439
|
+
observable_links: {
|
|
440
|
+
items: {
|
|
441
|
+
$ref: "#/$defs/ObservableLink"
|
|
442
|
+
},
|
|
443
|
+
title: "Observable Links",
|
|
444
|
+
type: "array"
|
|
445
|
+
},
|
|
446
|
+
evidence_links: {
|
|
447
|
+
items: {
|
|
448
|
+
$ref: "#/$defs/EvidenceLink"
|
|
449
|
+
},
|
|
450
|
+
title: "Evidence Links",
|
|
451
|
+
type: "array"
|
|
452
|
+
},
|
|
453
|
+
key: {
|
|
454
|
+
title: "Key",
|
|
455
|
+
type: "string"
|
|
456
|
+
},
|
|
457
|
+
score_display: {
|
|
458
|
+
readOnly: true,
|
|
459
|
+
title: "Score Display",
|
|
460
|
+
type: "string"
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
required: [
|
|
464
|
+
"finding_name",
|
|
465
|
+
"description",
|
|
466
|
+
"comment",
|
|
467
|
+
"extra",
|
|
468
|
+
"score",
|
|
469
|
+
"level",
|
|
470
|
+
"origin_investigation_id",
|
|
471
|
+
"observable_links",
|
|
472
|
+
"evidence_links",
|
|
473
|
+
"key",
|
|
474
|
+
"score_display"
|
|
475
|
+
],
|
|
476
|
+
title: "Finding",
|
|
477
|
+
type: "object"
|
|
478
|
+
},
|
|
364
479
|
InvestigationWhitelist: {
|
|
365
480
|
description: "Represents a whitelist entry on an investigation.",
|
|
366
481
|
properties: {
|
|
@@ -395,7 +510,7 @@ var cyvest_schema_default = {
|
|
|
395
510
|
type: "object"
|
|
396
511
|
},
|
|
397
512
|
Level: {
|
|
398
|
-
description: "Security level classification for
|
|
513
|
+
description: "Security level classification for findings, observables, and threat intelligence.\n\nLevels are ordered from lowest (NONE) to highest (MALICIOUS) severity.",
|
|
399
514
|
enum: [
|
|
400
515
|
"NONE",
|
|
401
516
|
"TRUSTED",
|
|
@@ -409,12 +524,35 @@ var cyvest_schema_default = {
|
|
|
409
524
|
type: "string"
|
|
410
525
|
},
|
|
411
526
|
Observable: {
|
|
412
|
-
description: "Represents a cyber observable (IP, URL, domain, hash, etc.).\n\nObservables can be linked to threat intelligence,
|
|
527
|
+
description: "Represents a cyber observable (IP, URL, domain, hash, etc.).\n\nObservables can be linked to threat intelligence, findings, and other observables\nthrough relationships.",
|
|
413
528
|
properties: {
|
|
414
529
|
type: {
|
|
415
530
|
title: "Type",
|
|
416
531
|
type: "string"
|
|
417
532
|
},
|
|
533
|
+
subtype: {
|
|
534
|
+
anyOf: [
|
|
535
|
+
{
|
|
536
|
+
type: "string"
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
type: "null"
|
|
540
|
+
}
|
|
541
|
+
],
|
|
542
|
+
title: "Subtype"
|
|
543
|
+
},
|
|
544
|
+
namespace: {
|
|
545
|
+
anyOf: [
|
|
546
|
+
{
|
|
547
|
+
type: "string"
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
type: "null"
|
|
551
|
+
}
|
|
552
|
+
],
|
|
553
|
+
default: null,
|
|
554
|
+
title: "Namespace"
|
|
555
|
+
},
|
|
418
556
|
value: {
|
|
419
557
|
title: "Value",
|
|
420
558
|
type: "string"
|
|
@@ -461,13 +599,13 @@ var cyvest_schema_default = {
|
|
|
461
599
|
title: "Key",
|
|
462
600
|
type: "string"
|
|
463
601
|
},
|
|
464
|
-
|
|
465
|
-
description: "
|
|
602
|
+
finding_links: {
|
|
603
|
+
description: "Findings that currently link to this observable (navigation-only).",
|
|
466
604
|
items: {
|
|
467
605
|
type: "string"
|
|
468
606
|
},
|
|
469
607
|
readOnly: true,
|
|
470
|
-
title: "
|
|
608
|
+
title: "Finding Links",
|
|
471
609
|
type: "array"
|
|
472
610
|
},
|
|
473
611
|
score_display: {
|
|
@@ -488,7 +626,7 @@ var cyvest_schema_default = {
|
|
|
488
626
|
"threat_intels",
|
|
489
627
|
"relationships",
|
|
490
628
|
"key",
|
|
491
|
-
"
|
|
629
|
+
"finding_links",
|
|
492
630
|
"score_display"
|
|
493
631
|
],
|
|
494
632
|
title: "Observable",
|
|
@@ -496,7 +634,7 @@ var cyvest_schema_default = {
|
|
|
496
634
|
},
|
|
497
635
|
ObservableLink: {
|
|
498
636
|
additionalProperties: false,
|
|
499
|
-
description: "Edge metadata for a
|
|
637
|
+
description: "Edge metadata for a Finding\u2194Observable association.",
|
|
500
638
|
properties: {
|
|
501
639
|
observable_key: {
|
|
502
640
|
title: "Observable Key",
|
|
@@ -514,7 +652,7 @@ var cyvest_schema_default = {
|
|
|
514
652
|
type: "object"
|
|
515
653
|
},
|
|
516
654
|
PropagationMode: {
|
|
517
|
-
description: "Controls how a
|
|
655
|
+
description: "Controls how a Finding\u2194Observable link propagates across merged investigations.",
|
|
518
656
|
enum: [
|
|
519
657
|
"LOCAL_ONLY",
|
|
520
658
|
"GLOBAL"
|
|
@@ -615,24 +753,45 @@ var cyvest_schema_default = {
|
|
|
615
753
|
title: "Observables By Type And Level",
|
|
616
754
|
type: "object"
|
|
617
755
|
},
|
|
618
|
-
|
|
756
|
+
total_findings: {
|
|
619
757
|
minimum: 0,
|
|
620
|
-
title: "Total
|
|
758
|
+
title: "Total Findings",
|
|
621
759
|
type: "integer"
|
|
622
760
|
},
|
|
623
|
-
|
|
761
|
+
applied_findings: {
|
|
624
762
|
minimum: 0,
|
|
625
|
-
title: "Applied
|
|
763
|
+
title: "Applied Findings",
|
|
626
764
|
type: "integer"
|
|
627
765
|
},
|
|
628
|
-
|
|
766
|
+
findings_by_level: {
|
|
629
767
|
additionalProperties: {
|
|
630
768
|
items: {
|
|
631
769
|
type: "string"
|
|
632
770
|
},
|
|
633
771
|
type: "array"
|
|
634
772
|
},
|
|
635
|
-
title: "
|
|
773
|
+
title: "Findings By Level",
|
|
774
|
+
type: "object"
|
|
775
|
+
},
|
|
776
|
+
total_evidences: {
|
|
777
|
+
minimum: 0,
|
|
778
|
+
title: "Total Evidences",
|
|
779
|
+
type: "integer"
|
|
780
|
+
},
|
|
781
|
+
evidences_by_type: {
|
|
782
|
+
additionalProperties: {
|
|
783
|
+
minimum: 0,
|
|
784
|
+
type: "integer"
|
|
785
|
+
},
|
|
786
|
+
title: "Evidences By Type",
|
|
787
|
+
type: "object"
|
|
788
|
+
},
|
|
789
|
+
evidences_by_source: {
|
|
790
|
+
additionalProperties: {
|
|
791
|
+
minimum: 0,
|
|
792
|
+
type: "integer"
|
|
793
|
+
},
|
|
794
|
+
title: "Evidences By Source",
|
|
636
795
|
type: "object"
|
|
637
796
|
},
|
|
638
797
|
total_threat_intel: {
|
|
@@ -667,8 +826,9 @@ var cyvest_schema_default = {
|
|
|
667
826
|
"internal_observables",
|
|
668
827
|
"external_observables",
|
|
669
828
|
"whitelisted_observables",
|
|
670
|
-
"
|
|
671
|
-
"
|
|
829
|
+
"total_findings",
|
|
830
|
+
"applied_findings",
|
|
831
|
+
"total_evidences",
|
|
672
832
|
"total_threat_intel",
|
|
673
833
|
"total_tags"
|
|
674
834
|
],
|
|
@@ -677,7 +837,7 @@ var cyvest_schema_default = {
|
|
|
677
837
|
},
|
|
678
838
|
Tag: {
|
|
679
839
|
additionalProperties: false,
|
|
680
|
-
description: 'Groups
|
|
840
|
+
description: 'Groups findings for categorical organization.\n\nTags allow structuring the investigation into logical sections\nwith aggregated scores and levels. Hierarchy is automatic based on\nthe ":" delimiter in tag names (e.g., "header:auth:dkim").',
|
|
681
841
|
properties: {
|
|
682
842
|
name: {
|
|
683
843
|
title: "Name",
|
|
@@ -688,11 +848,11 @@ var cyvest_schema_default = {
|
|
|
688
848
|
title: "Description",
|
|
689
849
|
type: "string"
|
|
690
850
|
},
|
|
691
|
-
|
|
851
|
+
findings: {
|
|
692
852
|
items: {
|
|
693
853
|
type: "string"
|
|
694
854
|
},
|
|
695
|
-
title: "
|
|
855
|
+
title: "Findings",
|
|
696
856
|
type: "array"
|
|
697
857
|
},
|
|
698
858
|
key: {
|
|
@@ -700,20 +860,20 @@ var cyvest_schema_default = {
|
|
|
700
860
|
type: "string"
|
|
701
861
|
},
|
|
702
862
|
direct_score: {
|
|
703
|
-
description: "Calculate the score from direct
|
|
863
|
+
description: "Calculate the score from direct findings only (no hierarchy).\n\nFor hierarchical aggregation (including descendant tags), use\nInvestigation.get_tag_aggregated_score() or TagProxy.get_aggregated_score().\n\nReturns:\n Total score from direct findings",
|
|
704
864
|
readOnly: true,
|
|
705
865
|
title: "Direct Score",
|
|
706
866
|
type: "number"
|
|
707
867
|
},
|
|
708
868
|
direct_level: {
|
|
709
869
|
$ref: "#/$defs/Level",
|
|
710
|
-
description: "Calculate the level from direct
|
|
870
|
+
description: "Calculate the level from direct findings only (no hierarchy).\n\nFor hierarchical aggregation (including descendant tags), use\nInvestigation.get_tag_aggregated_level() or TagProxy.get_aggregated_level().\n\nReturns:\n Level based on direct score",
|
|
711
871
|
readOnly: true
|
|
712
872
|
}
|
|
713
873
|
},
|
|
714
874
|
required: [
|
|
715
875
|
"name",
|
|
716
|
-
"
|
|
876
|
+
"findings",
|
|
717
877
|
"key",
|
|
718
878
|
"direct_score",
|
|
719
879
|
"direct_level"
|
|
@@ -809,6 +969,12 @@ var cyvest_schema_default = {
|
|
|
809
969
|
additionalProperties: false,
|
|
810
970
|
description: "Schema for a complete serialized investigation.\n\nThis model describes the output of `serialize_investigation()` from\n`cyvest.io_serialization`. It is the top-level schema for exported investigations.\n\nEntity types reference the runtime models directly. When generating schemas with\n`mode='serialization'`, Pydantic respects field_serializer decorators and produces\nschemas matching the actual model_dump() output.",
|
|
811
971
|
properties: {
|
|
972
|
+
schema_version: {
|
|
973
|
+
const: "6.0.0",
|
|
974
|
+
default: "6.0.0",
|
|
975
|
+
title: "Schema Version",
|
|
976
|
+
type: "string"
|
|
977
|
+
},
|
|
812
978
|
investigation_id: {
|
|
813
979
|
description: "Stable investigation identity (ULID).",
|
|
814
980
|
title: "Investigation Id",
|
|
@@ -872,12 +1038,20 @@ var cyvest_schema_default = {
|
|
|
872
1038
|
title: "Observables",
|
|
873
1039
|
type: "object"
|
|
874
1040
|
},
|
|
875
|
-
|
|
1041
|
+
findings: {
|
|
1042
|
+
additionalProperties: {
|
|
1043
|
+
$ref: "#/$defs/Finding"
|
|
1044
|
+
},
|
|
1045
|
+
description: "Findings keyed by their unique key.",
|
|
1046
|
+
title: "Findings",
|
|
1047
|
+
type: "object"
|
|
1048
|
+
},
|
|
1049
|
+
evidences: {
|
|
876
1050
|
additionalProperties: {
|
|
877
|
-
$ref: "#/$defs/
|
|
1051
|
+
$ref: "#/$defs/Evidence"
|
|
878
1052
|
},
|
|
879
|
-
description: "
|
|
880
|
-
title: "
|
|
1053
|
+
description: "Evidence objects keyed by their unique key.",
|
|
1054
|
+
title: "Evidences",
|
|
881
1055
|
type: "object"
|
|
882
1056
|
},
|
|
883
1057
|
threat_intels: {
|
|
@@ -926,7 +1100,8 @@ var cyvest_schema_default = {
|
|
|
926
1100
|
"whitelisted",
|
|
927
1101
|
"whitelists",
|
|
928
1102
|
"observables",
|
|
929
|
-
"
|
|
1103
|
+
"findings",
|
|
1104
|
+
"evidences",
|
|
930
1105
|
"threat_intels",
|
|
931
1106
|
"enrichments",
|
|
932
1107
|
"tags",
|
|
@@ -965,6 +1140,108 @@ function isCyvest(json) {
|
|
|
965
1140
|
function normalizeValue(value) {
|
|
966
1141
|
return value.trim().toLowerCase();
|
|
967
1142
|
}
|
|
1143
|
+
function normalizeObservableValue(obsType, value, subtype) {
|
|
1144
|
+
const normalizedType = normalizeValue(obsType);
|
|
1145
|
+
const normalizedSubtype = subtype ? normalizeValue(subtype) : void 0;
|
|
1146
|
+
const stripped = value.trim();
|
|
1147
|
+
if (normalizedType === "command_line") return stripped;
|
|
1148
|
+
if (normalizedType === "email" || normalizedType === "host") {
|
|
1149
|
+
return stripped.toLowerCase();
|
|
1150
|
+
}
|
|
1151
|
+
if (normalizedType === "user" && (normalizedSubtype === "email" || normalizedSubtype === "upn")) {
|
|
1152
|
+
return stripped.toLowerCase();
|
|
1153
|
+
}
|
|
1154
|
+
if (normalizedSubtype === "uid" || normalizedSubtype === "pid") {
|
|
1155
|
+
if (!/^[+-]?\d+$/.test(stripped)) {
|
|
1156
|
+
throw new Error(`${normalizedSubtype} observable values must be base-10 integers`);
|
|
1157
|
+
}
|
|
1158
|
+
return BigInt(stripped).toString(10);
|
|
1159
|
+
}
|
|
1160
|
+
return stripped;
|
|
1161
|
+
}
|
|
1162
|
+
function sha256(content) {
|
|
1163
|
+
const bytes = new TextEncoder().encode(content);
|
|
1164
|
+
const words = [];
|
|
1165
|
+
const bitLength = bytes.length * 8;
|
|
1166
|
+
for (const byte of bytes) {
|
|
1167
|
+
words.push(byte);
|
|
1168
|
+
}
|
|
1169
|
+
words.push(128);
|
|
1170
|
+
while (words.length % 64 !== 56) words.push(0);
|
|
1171
|
+
for (let i = 7; i >= 0; i--) {
|
|
1172
|
+
words.push(Math.floor(bitLength / 2 ** (i * 8)) & 255);
|
|
1173
|
+
}
|
|
1174
|
+
const h = [
|
|
1175
|
+
1779033703,
|
|
1176
|
+
3144134277,
|
|
1177
|
+
1013904242,
|
|
1178
|
+
2773480762,
|
|
1179
|
+
1359893119,
|
|
1180
|
+
2600822924,
|
|
1181
|
+
528734635,
|
|
1182
|
+
1541459225
|
|
1183
|
+
];
|
|
1184
|
+
const k = Array.from({ length: 64 }, (_, index) => {
|
|
1185
|
+
let primeCount = 0;
|
|
1186
|
+
let candidate = 2;
|
|
1187
|
+
while (true) {
|
|
1188
|
+
let prime = true;
|
|
1189
|
+
for (let divisor = 2; divisor * divisor <= candidate; divisor++) {
|
|
1190
|
+
if (candidate % divisor === 0) {
|
|
1191
|
+
prime = false;
|
|
1192
|
+
break;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
if (prime && primeCount++ === index) {
|
|
1196
|
+
return Math.floor(Math.cbrt(candidate) % 1 * 2 ** 32) >>> 0;
|
|
1197
|
+
}
|
|
1198
|
+
candidate++;
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
const rotateRight = (value, amount) => value >>> amount | value << 32 - amount;
|
|
1202
|
+
for (let offset = 0; offset < words.length; offset += 64) {
|
|
1203
|
+
const schedule = new Array(64);
|
|
1204
|
+
for (let i = 0; i < 16; i++) {
|
|
1205
|
+
const base = offset + i * 4;
|
|
1206
|
+
schedule[i] = (words[base] << 24 | words[base + 1] << 16 | words[base + 2] << 8 | words[base + 3]) >>> 0;
|
|
1207
|
+
}
|
|
1208
|
+
for (let i = 16; i < 64; i++) {
|
|
1209
|
+
const s0 = rotateRight(schedule[i - 15], 7) ^ rotateRight(schedule[i - 15], 18) ^ schedule[i - 15] >>> 3;
|
|
1210
|
+
const s1 = rotateRight(schedule[i - 2], 17) ^ rotateRight(schedule[i - 2], 19) ^ schedule[i - 2] >>> 10;
|
|
1211
|
+
schedule[i] = schedule[i - 16] + s0 + schedule[i - 7] + s1 >>> 0;
|
|
1212
|
+
}
|
|
1213
|
+
let [a, b, c, d, e, f, g, hh] = h;
|
|
1214
|
+
for (let i = 0; i < 64; i++) {
|
|
1215
|
+
const s1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);
|
|
1216
|
+
const choice = e & f ^ ~e & g;
|
|
1217
|
+
const temp1 = hh + s1 + choice + k[i] + schedule[i] >>> 0;
|
|
1218
|
+
const s0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);
|
|
1219
|
+
const majority = a & b ^ a & c ^ b & c;
|
|
1220
|
+
const temp2 = s0 + majority >>> 0;
|
|
1221
|
+
hh = g;
|
|
1222
|
+
g = f;
|
|
1223
|
+
f = e;
|
|
1224
|
+
e = d + temp1 >>> 0;
|
|
1225
|
+
d = c;
|
|
1226
|
+
c = b;
|
|
1227
|
+
b = a;
|
|
1228
|
+
a = temp1 + temp2 >>> 0;
|
|
1229
|
+
}
|
|
1230
|
+
[a, b, c, d, e, f, g, hh].forEach((value, index) => {
|
|
1231
|
+
h[index] = h[index] + value >>> 0;
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
return h.map((value) => value.toString(16).padStart(8, "0")).join("");
|
|
1235
|
+
}
|
|
1236
|
+
function encodeKeyPart(value, keepSlash = false) {
|
|
1237
|
+
let encoded = encodeURIComponent(value).replace(
|
|
1238
|
+
/[!'()*]/g,
|
|
1239
|
+
(char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`
|
|
1240
|
+
);
|
|
1241
|
+
encoded = encoded.replace(/%40/gi, "@");
|
|
1242
|
+
if (keepSlash) encoded = encoded.replace(/%2F/gi, "/").replace(/%5C/gi, "\\");
|
|
1243
|
+
return encoded;
|
|
1244
|
+
}
|
|
968
1245
|
function hashString(content, length = 16) {
|
|
969
1246
|
let hash = 0;
|
|
970
1247
|
for (let i = 0; i < content.length; i++) {
|
|
@@ -974,14 +1251,35 @@ function hashString(content, length = 16) {
|
|
|
974
1251
|
const hex = Math.abs(hash).toString(16).padStart(8, "0");
|
|
975
1252
|
return hex.slice(0, length);
|
|
976
1253
|
}
|
|
977
|
-
function generateObservableKey(obsType, value) {
|
|
1254
|
+
function generateObservableKey(obsType, value, subtype, namespace) {
|
|
978
1255
|
const normalizedType = normalizeValue(obsType);
|
|
979
|
-
const
|
|
980
|
-
|
|
1256
|
+
const normalizedSubtype = subtype ? normalizeValue(subtype) : void 0;
|
|
1257
|
+
const normalizedNamespace = namespace?.trim().toLowerCase() || void 0;
|
|
1258
|
+
const normalizedValue = normalizeObservableValue(
|
|
1259
|
+
normalizedType,
|
|
1260
|
+
value,
|
|
1261
|
+
normalizedSubtype
|
|
1262
|
+
);
|
|
1263
|
+
const identity = JSON.stringify({
|
|
1264
|
+
namespace: normalizedNamespace ?? null,
|
|
1265
|
+
subtype: normalizedSubtype ?? null,
|
|
1266
|
+
type: normalizedType,
|
|
1267
|
+
value: normalizedValue
|
|
1268
|
+
});
|
|
1269
|
+
if (normalizedType === "command_line" || new TextEncoder().encode(identity).length > 128) {
|
|
1270
|
+
return `obs:${normalizedType}:sha256:${sha256(identity)}`;
|
|
1271
|
+
}
|
|
1272
|
+
if (!normalizedSubtype && !normalizedNamespace) {
|
|
1273
|
+
return `obs:${normalizedType}:${normalizedValue.toLowerCase()}`;
|
|
1274
|
+
}
|
|
1275
|
+
const parts = ["obs", encodeKeyPart(normalizedType), normalizedSubtype ? encodeKeyPart(normalizedSubtype) : "_"];
|
|
1276
|
+
if (normalizedNamespace) parts.push(encodeKeyPart(normalizedNamespace));
|
|
1277
|
+
parts.push(encodeKeyPart(normalizedValue, true));
|
|
1278
|
+
return parts.join(":");
|
|
981
1279
|
}
|
|
982
|
-
function
|
|
983
|
-
const normalizedName = normalizeValue(
|
|
984
|
-
return `
|
|
1280
|
+
function generateFindingKey(findingName) {
|
|
1281
|
+
const normalizedName = normalizeValue(findingName);
|
|
1282
|
+
return `fnd:${normalizedName}`;
|
|
985
1283
|
}
|
|
986
1284
|
function generateThreatIntelKey(source, observableKey) {
|
|
987
1285
|
const normalizedSource = normalizeValue(source);
|
|
@@ -1020,7 +1318,7 @@ function isTagDescendantOf(descendantName, ancestorName) {
|
|
|
1020
1318
|
function parseKeyType(key) {
|
|
1021
1319
|
if (key.includes(":")) {
|
|
1022
1320
|
const prefix = key.split(":", 1)[0];
|
|
1023
|
-
if (["obs", "
|
|
1321
|
+
if (["obs", "fnd", "evd", "ti", "enr", "tag"].includes(prefix)) {
|
|
1024
1322
|
return prefix;
|
|
1025
1323
|
}
|
|
1026
1324
|
}
|
|
@@ -1053,14 +1351,14 @@ function parseObservableKey(key) {
|
|
|
1053
1351
|
}
|
|
1054
1352
|
return null;
|
|
1055
1353
|
}
|
|
1056
|
-
function
|
|
1057
|
-
if (!validateKey(key, "
|
|
1354
|
+
function parseFindingKey(key) {
|
|
1355
|
+
if (!validateKey(key, "fnd")) {
|
|
1058
1356
|
return null;
|
|
1059
1357
|
}
|
|
1060
1358
|
const parts = key.split(":");
|
|
1061
1359
|
if (parts.length >= 2) {
|
|
1062
1360
|
return {
|
|
1063
|
-
|
|
1361
|
+
findingName: parts.slice(1).join(":")
|
|
1064
1362
|
};
|
|
1065
1363
|
}
|
|
1066
1364
|
return null;
|
|
@@ -1193,15 +1491,8 @@ function getEntityLevel(entity) {
|
|
|
1193
1491
|
function getObservable(inv, key) {
|
|
1194
1492
|
return inv.observables[key];
|
|
1195
1493
|
}
|
|
1196
|
-
function getObservableByTypeValue(inv, type, value) {
|
|
1197
|
-
|
|
1198
|
-
const normalizedValue = value.trim().toLowerCase();
|
|
1199
|
-
for (const obs of Object.values(inv.observables)) {
|
|
1200
|
-
if (obs.type.toLowerCase() === normalizedType && obs.value.toLowerCase() === normalizedValue) {
|
|
1201
|
-
return obs;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
return void 0;
|
|
1494
|
+
function getObservableByTypeValue(inv, type, value, subtype, namespace) {
|
|
1495
|
+
return inv.observables[generateObservableKey(type, value, subtype, namespace)];
|
|
1205
1496
|
}
|
|
1206
1497
|
function getRootObservable(inv) {
|
|
1207
1498
|
const rootType = inv.data_extraction.root_type;
|
|
@@ -1211,15 +1502,21 @@ function getRootObservable(inv) {
|
|
|
1211
1502
|
const rootKey = generateObservableKey(rootType, "root");
|
|
1212
1503
|
return inv.observables[rootKey];
|
|
1213
1504
|
}
|
|
1214
|
-
function
|
|
1215
|
-
return inv.
|
|
1505
|
+
function getFinding(inv, key) {
|
|
1506
|
+
return inv.findings[key];
|
|
1507
|
+
}
|
|
1508
|
+
function getFindingByName(inv, findingName) {
|
|
1509
|
+
const key = generateFindingKey(findingName);
|
|
1510
|
+
return inv.findings[key];
|
|
1511
|
+
}
|
|
1512
|
+
function getAllFindings(inv) {
|
|
1513
|
+
return Object.values(inv.findings);
|
|
1216
1514
|
}
|
|
1217
|
-
function
|
|
1218
|
-
|
|
1219
|
-
return inv.checks[key];
|
|
1515
|
+
function getEvidence(inv, key) {
|
|
1516
|
+
return inv.evidences[key];
|
|
1220
1517
|
}
|
|
1221
|
-
function
|
|
1222
|
-
return Object.values(inv.
|
|
1518
|
+
function getAllEvidences(inv) {
|
|
1519
|
+
return Object.values(inv.evidences);
|
|
1223
1520
|
}
|
|
1224
1521
|
function getThreatIntel(inv, key) {
|
|
1225
1522
|
return inv.threat_intels[key];
|
|
@@ -1276,7 +1573,8 @@ function getDataExtraction(inv) {
|
|
|
1276
1573
|
function getCounts(inv) {
|
|
1277
1574
|
return {
|
|
1278
1575
|
observables: Object.keys(inv.observables).length,
|
|
1279
|
-
|
|
1576
|
+
findings: getAllFindings(inv).length,
|
|
1577
|
+
evidences: getAllEvidences(inv).length,
|
|
1280
1578
|
threatIntels: Object.keys(inv.threat_intels).length,
|
|
1281
1579
|
enrichments: Object.keys(inv.enrichments).length,
|
|
1282
1580
|
tags: getAllTags(inv).length,
|
|
@@ -1358,18 +1656,18 @@ function findObservablesWithThreatIntel(inv) {
|
|
|
1358
1656
|
(obs) => obs.threat_intels.length > 0
|
|
1359
1657
|
);
|
|
1360
1658
|
}
|
|
1361
|
-
function
|
|
1362
|
-
return Object.values(inv.
|
|
1659
|
+
function findFindingsByLevel(inv, level) {
|
|
1660
|
+
return Object.values(inv.findings).filter((finding) => finding.level === level);
|
|
1363
1661
|
}
|
|
1364
|
-
function
|
|
1365
|
-
return Object.values(inv.
|
|
1366
|
-
(
|
|
1662
|
+
function findFindingsAtLeast(inv, minLevel2) {
|
|
1663
|
+
return Object.values(inv.findings).filter(
|
|
1664
|
+
(finding) => isLevelAtLeast(finding.level, minLevel2)
|
|
1367
1665
|
);
|
|
1368
1666
|
}
|
|
1369
|
-
function
|
|
1370
|
-
const normalizedName =
|
|
1371
|
-
return Object.values(inv.
|
|
1372
|
-
(
|
|
1667
|
+
function findFindingByName(inv, findingName) {
|
|
1668
|
+
const normalizedName = findingName.trim().toLowerCase();
|
|
1669
|
+
return Object.values(inv.findings).find(
|
|
1670
|
+
(finding) => finding.finding_name.toLowerCase() === normalizedName
|
|
1373
1671
|
);
|
|
1374
1672
|
}
|
|
1375
1673
|
function findThreatIntelBySource(inv, source) {
|
|
@@ -1397,26 +1695,26 @@ function findTagsAtLeast(inv, minLevel2) {
|
|
|
1397
1695
|
function findTagsByNamePattern(inv, pattern) {
|
|
1398
1696
|
return Object.values(inv.tags).filter((tag) => pattern.test(tag.name));
|
|
1399
1697
|
}
|
|
1400
|
-
function
|
|
1698
|
+
function findFindingsForObservable(inv, observableKey) {
|
|
1401
1699
|
const result = [];
|
|
1402
1700
|
const seen = /* @__PURE__ */ new Set();
|
|
1403
1701
|
const observable = inv.observables[observableKey];
|
|
1404
1702
|
if (observable) {
|
|
1405
|
-
for (const
|
|
1406
|
-
const
|
|
1407
|
-
if (
|
|
1408
|
-
result.push(
|
|
1409
|
-
seen.add(
|
|
1703
|
+
for (const findingKey of observable.finding_links) {
|
|
1704
|
+
const finding = inv.findings[findingKey];
|
|
1705
|
+
if (finding && !seen.has(finding.key)) {
|
|
1706
|
+
result.push(finding);
|
|
1707
|
+
seen.add(finding.key);
|
|
1410
1708
|
}
|
|
1411
1709
|
}
|
|
1412
1710
|
}
|
|
1413
|
-
for (const
|
|
1414
|
-
if (seen.has(
|
|
1711
|
+
for (const finding of Object.values(inv.findings)) {
|
|
1712
|
+
if (seen.has(finding.key)) {
|
|
1415
1713
|
continue;
|
|
1416
1714
|
}
|
|
1417
|
-
if (
|
|
1418
|
-
result.push(
|
|
1419
|
-
seen.add(
|
|
1715
|
+
if (finding.observable_links.some((link) => link.observable_key === observableKey)) {
|
|
1716
|
+
result.push(finding);
|
|
1717
|
+
seen.add(finding.key);
|
|
1420
1718
|
}
|
|
1421
1719
|
}
|
|
1422
1720
|
return result;
|
|
@@ -1430,37 +1728,37 @@ function findThreatIntelsForObservable(inv, observableKey) {
|
|
|
1430
1728
|
(ti) => ti.observable_key === observableKey
|
|
1431
1729
|
);
|
|
1432
1730
|
}
|
|
1433
|
-
function
|
|
1434
|
-
const
|
|
1435
|
-
if (
|
|
1731
|
+
function findObservablesForFinding(inv, findingKey) {
|
|
1732
|
+
const finding = inv.findings[findingKey];
|
|
1733
|
+
if (finding) {
|
|
1436
1734
|
const keys = /* @__PURE__ */ new Set();
|
|
1437
|
-
for (const link of
|
|
1735
|
+
for (const link of finding.observable_links) {
|
|
1438
1736
|
keys.add(link.observable_key);
|
|
1439
1737
|
}
|
|
1440
1738
|
return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
|
|
1441
1739
|
}
|
|
1442
1740
|
return [];
|
|
1443
1741
|
}
|
|
1444
|
-
function
|
|
1742
|
+
function findFindingsForTag(inv, tagKey, recursive = false) {
|
|
1445
1743
|
const result = [];
|
|
1446
1744
|
const tag = inv.tags[tagKey];
|
|
1447
1745
|
if (!tag) {
|
|
1448
1746
|
return result;
|
|
1449
1747
|
}
|
|
1450
|
-
for (const
|
|
1451
|
-
const
|
|
1452
|
-
if (
|
|
1453
|
-
result.push(
|
|
1748
|
+
for (const findingKey of tag.findings) {
|
|
1749
|
+
const finding = inv.findings[findingKey];
|
|
1750
|
+
if (finding) {
|
|
1751
|
+
result.push(finding);
|
|
1454
1752
|
}
|
|
1455
1753
|
}
|
|
1456
1754
|
if (recursive) {
|
|
1457
1755
|
const prefix = tag.name + ":";
|
|
1458
1756
|
for (const otherTag of Object.values(inv.tags)) {
|
|
1459
1757
|
if (otherTag.name.startsWith(prefix)) {
|
|
1460
|
-
for (const
|
|
1461
|
-
const
|
|
1462
|
-
if (
|
|
1463
|
-
result.push(
|
|
1758
|
+
for (const findingKey of otherTag.findings) {
|
|
1759
|
+
const finding = inv.findings[findingKey];
|
|
1760
|
+
if (finding) {
|
|
1761
|
+
result.push(finding);
|
|
1464
1762
|
}
|
|
1465
1763
|
}
|
|
1466
1764
|
}
|
|
@@ -1471,24 +1769,24 @@ function findChecksForTag(inv, tagKey, recursive = false) {
|
|
|
1471
1769
|
function sortObservablesByScore(observables) {
|
|
1472
1770
|
return [...observables].sort((a, b) => b.score - a.score);
|
|
1473
1771
|
}
|
|
1474
|
-
function
|
|
1475
|
-
return [...
|
|
1772
|
+
function sortFindingsByScore(findings) {
|
|
1773
|
+
return [...findings].sort((a, b) => b.score - a.score);
|
|
1476
1774
|
}
|
|
1477
1775
|
function sortObservablesByLevel(observables) {
|
|
1478
1776
|
return [...observables].sort(
|
|
1479
1777
|
(a, b) => LEVEL_VALUES[b.level] - LEVEL_VALUES[a.level]
|
|
1480
1778
|
);
|
|
1481
1779
|
}
|
|
1482
|
-
function
|
|
1483
|
-
return [...
|
|
1780
|
+
function sortFindingsByLevel(findings) {
|
|
1781
|
+
return [...findings].sort(
|
|
1484
1782
|
(a, b) => LEVEL_VALUES[b.level] - LEVEL_VALUES[a.level]
|
|
1485
1783
|
);
|
|
1486
1784
|
}
|
|
1487
1785
|
function findHighestScoringObservables(inv, n = 10) {
|
|
1488
1786
|
return sortObservablesByScore(Object.values(inv.observables)).slice(0, n);
|
|
1489
1787
|
}
|
|
1490
|
-
function
|
|
1491
|
-
return
|
|
1788
|
+
function findHighestScoringFindings(inv, n = 10) {
|
|
1789
|
+
return sortFindingsByScore(Object.values(inv.findings)).slice(0, n);
|
|
1492
1790
|
}
|
|
1493
1791
|
function findMaliciousObservables(inv) {
|
|
1494
1792
|
return findObservablesByLevel(inv, "MALICIOUS");
|
|
@@ -1496,14 +1794,14 @@ function findMaliciousObservables(inv) {
|
|
|
1496
1794
|
function findSuspiciousObservables(inv) {
|
|
1497
1795
|
return findObservablesByLevel(inv, "SUSPICIOUS");
|
|
1498
1796
|
}
|
|
1499
|
-
function
|
|
1500
|
-
return
|
|
1797
|
+
function findMaliciousFindings(inv) {
|
|
1798
|
+
return findFindingsByLevel(inv, "MALICIOUS");
|
|
1501
1799
|
}
|
|
1502
|
-
function
|
|
1503
|
-
return
|
|
1800
|
+
function findSuspiciousFindings(inv) {
|
|
1801
|
+
return findFindingsByLevel(inv, "SUSPICIOUS");
|
|
1504
1802
|
}
|
|
1505
|
-
function
|
|
1506
|
-
return Object.keys(inv.
|
|
1803
|
+
function getAllFindingKeys(inv) {
|
|
1804
|
+
return Object.keys(inv.findings);
|
|
1507
1805
|
}
|
|
1508
1806
|
function getAllObservableTypes(inv) {
|
|
1509
1807
|
const types = /* @__PURE__ */ new Set();
|
|
@@ -1788,30 +2086,30 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1788
2086
|
areConnected,
|
|
1789
2087
|
compareLevels,
|
|
1790
2088
|
countRelationshipsByType,
|
|
1791
|
-
findCheckByName,
|
|
1792
|
-
findChecksAtLeast,
|
|
1793
|
-
findChecksByLevel,
|
|
1794
|
-
findChecksForObservable,
|
|
1795
|
-
findChecksForTag,
|
|
1796
2089
|
findExternalObservables,
|
|
1797
|
-
|
|
2090
|
+
findFindingByName,
|
|
2091
|
+
findFindingsAtLeast,
|
|
2092
|
+
findFindingsByLevel,
|
|
2093
|
+
findFindingsForObservable,
|
|
2094
|
+
findFindingsForTag,
|
|
2095
|
+
findHighestScoringFindings,
|
|
1798
2096
|
findHighestScoringObservables,
|
|
1799
2097
|
findInternalObservables,
|
|
1800
2098
|
findLeafObservables,
|
|
1801
|
-
|
|
2099
|
+
findMaliciousFindings,
|
|
1802
2100
|
findMaliciousObservables,
|
|
1803
2101
|
findObservablesAtLeast,
|
|
1804
2102
|
findObservablesByLevel,
|
|
1805
2103
|
findObservablesByType,
|
|
1806
2104
|
findObservablesByValue,
|
|
1807
2105
|
findObservablesContaining,
|
|
1808
|
-
|
|
2106
|
+
findObservablesForFinding,
|
|
1809
2107
|
findObservablesMatching,
|
|
1810
2108
|
findObservablesWithThreatIntel,
|
|
1811
2109
|
findOrphanObservables,
|
|
1812
2110
|
findPath,
|
|
1813
2111
|
findSourceObservables,
|
|
1814
|
-
|
|
2112
|
+
findSuspiciousFindings,
|
|
1815
2113
|
findSuspiciousObservables,
|
|
1816
2114
|
findTagsAtLeast,
|
|
1817
2115
|
findTagsByLevel,
|
|
@@ -1821,22 +2119,21 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1821
2119
|
findThreatIntelBySource,
|
|
1822
2120
|
findThreatIntelsForObservable,
|
|
1823
2121
|
findWhitelistedObservables,
|
|
1824
|
-
generateCheckKey,
|
|
1825
2122
|
generateEnrichmentKey,
|
|
2123
|
+
generateFindingKey,
|
|
1826
2124
|
generateObservableKey,
|
|
1827
2125
|
generateTagKey,
|
|
1828
2126
|
generateThreatIntelKey,
|
|
1829
|
-
getAllCheckKeys,
|
|
1830
|
-
getAllChecks,
|
|
1831
2127
|
getAllEnrichments,
|
|
2128
|
+
getAllEvidences,
|
|
2129
|
+
getAllFindingKeys,
|
|
2130
|
+
getAllFindings,
|
|
1832
2131
|
getAllObservableTypes,
|
|
1833
2132
|
getAllObservables,
|
|
1834
2133
|
getAllRelationshipTypes,
|
|
1835
2134
|
getAllTags,
|
|
1836
2135
|
getAllThreatIntelSources,
|
|
1837
2136
|
getAllThreatIntels,
|
|
1838
|
-
getCheck,
|
|
1839
|
-
getCheckByName,
|
|
1840
2137
|
getColorForLevel,
|
|
1841
2138
|
getColorForScore,
|
|
1842
2139
|
getCounts,
|
|
@@ -1844,6 +2141,9 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1844
2141
|
getEnrichment,
|
|
1845
2142
|
getEnrichmentByName,
|
|
1846
2143
|
getEntityLevel,
|
|
2144
|
+
getEvidence,
|
|
2145
|
+
getFinding,
|
|
2146
|
+
getFindingByName,
|
|
1847
2147
|
getLevelFromScore,
|
|
1848
2148
|
getObservable,
|
|
1849
2149
|
getObservableByTypeValue,
|
|
@@ -1879,13 +2179,13 @@ function getRelationshipsForObservable(inv, observableKey) {
|
|
|
1879
2179
|
maxLevel,
|
|
1880
2180
|
minLevel,
|
|
1881
2181
|
normalizeLevel,
|
|
1882
|
-
parseCheckKey,
|
|
1883
2182
|
parseCyvest,
|
|
2183
|
+
parseFindingKey,
|
|
1884
2184
|
parseKeyType,
|
|
1885
2185
|
parseObservableKey,
|
|
1886
2186
|
parseThreatIntelKey,
|
|
1887
|
-
|
|
1888
|
-
|
|
2187
|
+
sortFindingsByLevel,
|
|
2188
|
+
sortFindingsByScore,
|
|
1889
2189
|
sortObservablesByLevel,
|
|
1890
2190
|
sortObservablesByScore,
|
|
1891
2191
|
validateKey
|