contentctl 4.4.7__py3-none-any.whl → 5.0.0__py3-none-any.whl

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.
Files changed (123) hide show
  1. contentctl/__init__.py +1 -1
  2. contentctl/actions/build.py +102 -57
  3. contentctl/actions/deploy_acs.py +29 -24
  4. contentctl/actions/detection_testing/DetectionTestingManager.py +66 -42
  5. contentctl/actions/detection_testing/GitService.py +134 -76
  6. contentctl/actions/detection_testing/generate_detection_coverage_badge.py +48 -30
  7. contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructure.py +192 -147
  8. contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructureContainer.py +45 -32
  9. contentctl/actions/detection_testing/progress_bar.py +9 -6
  10. contentctl/actions/detection_testing/views/DetectionTestingView.py +16 -19
  11. contentctl/actions/detection_testing/views/DetectionTestingViewCLI.py +1 -5
  12. contentctl/actions/detection_testing/views/DetectionTestingViewFile.py +2 -2
  13. contentctl/actions/detection_testing/views/DetectionTestingViewWeb.py +1 -4
  14. contentctl/actions/doc_gen.py +9 -5
  15. contentctl/actions/initialize.py +45 -33
  16. contentctl/actions/inspect.py +118 -61
  17. contentctl/actions/new_content.py +155 -108
  18. contentctl/actions/release_notes.py +276 -146
  19. contentctl/actions/reporting.py +23 -19
  20. contentctl/actions/test.py +33 -28
  21. contentctl/actions/validate.py +55 -34
  22. contentctl/api.py +54 -45
  23. contentctl/contentctl.py +124 -90
  24. contentctl/enrichments/attack_enrichment.py +112 -72
  25. contentctl/enrichments/cve_enrichment.py +34 -28
  26. contentctl/enrichments/splunk_app_enrichment.py +38 -36
  27. contentctl/helper/link_validator.py +101 -78
  28. contentctl/helper/splunk_app.py +69 -41
  29. contentctl/helper/utils.py +58 -53
  30. contentctl/input/director.py +68 -36
  31. contentctl/input/new_content_questions.py +27 -35
  32. contentctl/input/yml_reader.py +28 -18
  33. contentctl/objects/abstract_security_content_objects/detection_abstract.py +303 -259
  34. contentctl/objects/abstract_security_content_objects/security_content_object_abstract.py +115 -52
  35. contentctl/objects/alert_action.py +10 -9
  36. contentctl/objects/annotated_types.py +1 -1
  37. contentctl/objects/atomic.py +65 -54
  38. contentctl/objects/base_test.py +5 -3
  39. contentctl/objects/base_test_result.py +19 -11
  40. contentctl/objects/baseline.py +62 -30
  41. contentctl/objects/baseline_tags.py +30 -24
  42. contentctl/objects/config.py +790 -597
  43. contentctl/objects/constants.py +33 -56
  44. contentctl/objects/correlation_search.py +150 -136
  45. contentctl/objects/dashboard.py +55 -41
  46. contentctl/objects/data_source.py +16 -17
  47. contentctl/objects/deployment.py +43 -44
  48. contentctl/objects/deployment_email.py +3 -2
  49. contentctl/objects/deployment_notable.py +4 -2
  50. contentctl/objects/deployment_phantom.py +7 -6
  51. contentctl/objects/deployment_rba.py +3 -2
  52. contentctl/objects/deployment_scheduling.py +3 -2
  53. contentctl/objects/deployment_slack.py +3 -2
  54. contentctl/objects/detection.py +5 -2
  55. contentctl/objects/detection_metadata.py +1 -0
  56. contentctl/objects/detection_stanza.py +7 -2
  57. contentctl/objects/detection_tags.py +58 -103
  58. contentctl/objects/drilldown.py +66 -34
  59. contentctl/objects/enums.py +81 -100
  60. contentctl/objects/errors.py +16 -24
  61. contentctl/objects/integration_test.py +3 -3
  62. contentctl/objects/integration_test_result.py +1 -0
  63. contentctl/objects/investigation.py +59 -36
  64. contentctl/objects/investigation_tags.py +30 -19
  65. contentctl/objects/lookup.py +304 -101
  66. contentctl/objects/macro.py +55 -39
  67. contentctl/objects/manual_test.py +3 -3
  68. contentctl/objects/manual_test_result.py +1 -0
  69. contentctl/objects/mitre_attack_enrichment.py +17 -16
  70. contentctl/objects/notable_action.py +2 -1
  71. contentctl/objects/notable_event.py +1 -3
  72. contentctl/objects/playbook.py +37 -35
  73. contentctl/objects/playbook_tags.py +23 -13
  74. contentctl/objects/rba.py +96 -0
  75. contentctl/objects/risk_analysis_action.py +15 -11
  76. contentctl/objects/risk_event.py +110 -160
  77. contentctl/objects/risk_object.py +1 -0
  78. contentctl/objects/savedsearches_conf.py +9 -7
  79. contentctl/objects/security_content_object.py +5 -2
  80. contentctl/objects/story.py +54 -49
  81. contentctl/objects/story_tags.py +56 -45
  82. contentctl/objects/test_attack_data.py +2 -1
  83. contentctl/objects/test_group.py +5 -2
  84. contentctl/objects/threat_object.py +1 -0
  85. contentctl/objects/throttling.py +27 -18
  86. contentctl/objects/unit_test.py +3 -4
  87. contentctl/objects/unit_test_baseline.py +5 -5
  88. contentctl/objects/unit_test_result.py +6 -6
  89. contentctl/output/api_json_output.py +233 -220
  90. contentctl/output/attack_nav_output.py +21 -21
  91. contentctl/output/attack_nav_writer.py +29 -37
  92. contentctl/output/conf_output.py +235 -172
  93. contentctl/output/conf_writer.py +201 -125
  94. contentctl/output/data_source_writer.py +38 -26
  95. contentctl/output/doc_md_output.py +53 -27
  96. contentctl/output/jinja_writer.py +19 -15
  97. contentctl/output/json_writer.py +21 -11
  98. contentctl/output/svg_output.py +56 -38
  99. contentctl/output/templates/analyticstories_detections.j2 +2 -2
  100. contentctl/output/templates/analyticstories_stories.j2 +1 -1
  101. contentctl/output/templates/collections.j2 +1 -1
  102. contentctl/output/templates/doc_detections.j2 +0 -5
  103. contentctl/output/templates/es_investigations_investigations.j2 +1 -1
  104. contentctl/output/templates/es_investigations_stories.j2 +1 -1
  105. contentctl/output/templates/savedsearches_baselines.j2 +2 -2
  106. contentctl/output/templates/savedsearches_detections.j2 +10 -11
  107. contentctl/output/templates/savedsearches_investigations.j2 +2 -2
  108. contentctl/output/templates/transforms.j2 +6 -8
  109. contentctl/output/yml_writer.py +29 -20
  110. contentctl/templates/detections/endpoint/anomalous_usage_of_7zip.yml +16 -34
  111. contentctl/templates/stories/cobalt_strike.yml +1 -0
  112. {contentctl-4.4.7.dist-info → contentctl-5.0.0.dist-info}/METADATA +5 -4
  113. contentctl-5.0.0.dist-info/RECORD +168 -0
  114. {contentctl-4.4.7.dist-info → contentctl-5.0.0.dist-info}/WHEEL +1 -1
  115. contentctl/actions/initialize_old.py +0 -245
  116. contentctl/objects/event_source.py +0 -11
  117. contentctl/objects/observable.py +0 -37
  118. contentctl/output/detection_writer.py +0 -28
  119. contentctl/output/new_content_yml_output.py +0 -56
  120. contentctl/output/yml_output.py +0 -66
  121. contentctl-4.4.7.dist-info/RECORD +0 -173
  122. {contentctl-4.4.7.dist-info → contentctl-5.0.0.dist-info}/LICENSE.md +0 -0
  123. {contentctl-4.4.7.dist-info → contentctl-5.0.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,168 @@
1
+ contentctl/__init__.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
2
+ contentctl/actions/build.py,sha256=M68XubxTqI-LiW8P4eaNmb62pWNQtVE8cF3xKb6g44c,5669
3
+ contentctl/actions/deploy_acs.py,sha256=w3OqO8GXzB_5zHrE8lDYbadAy4Etw7F2o84Gze74RY0,3264
4
+ contentctl/actions/detection_testing/DetectionTestingManager.py,sha256=TWZpmDjMqWRWyzsLyiYol_jAovAr6ok9J_GzE9-kNN0,9079
5
+ contentctl/actions/detection_testing/GitService.py,sha256=a6y7lqCgSL1KdSVEgJDxawea8ZgEkGNfOKEf9v_BgLo,11135
6
+ contentctl/actions/detection_testing/generate_detection_coverage_badge.py,sha256=bGUVKjKv96lTw1GZ4Kw1JX-Yicu4aOJWm-IL524e9HI,2302
7
+ contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructure.py,sha256=52Xsbyq4M913kXuQ8JcjYfP2BvwRJo3chK1p2hK76o0,57281
8
+ contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructureContainer.py,sha256=qYWgRW7uc-15jzwv5xSUF2xyLDmtyGyMfuXkQK9j-aM,7221
9
+ contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructureServer.py,sha256=Q1ZfCYOp54O39bgTScZMInkmZiU-bGAM9Hiwr2mq5ms,370
10
+ contentctl/actions/detection_testing/progress_bar.py,sha256=UrpNCqxTmQ4hfoRZgxPJ1xvDVwMrTq0UnotdryHN0gM,3232
11
+ contentctl/actions/detection_testing/views/DetectionTestingView.py,sha256=E07v2VK-pyLMeTA6EtNI_04kt-T90SwSM4kN9yfp-2I,7475
12
+ contentctl/actions/detection_testing/views/DetectionTestingViewCLI.py,sha256=-4yhxGJsafcRRAIebFZebUG_qSkASDLHajN9piAPlvM,2104
13
+ contentctl/actions/detection_testing/views/DetectionTestingViewFile.py,sha256=G-6YqBtj0R1A9eiPrgHP2yvUMm7H8wopTBYjxIEIl8g,1090
14
+ contentctl/actions/detection_testing/views/DetectionTestingViewWeb.py,sha256=CXV1fByf3J-Jc4D9U6jgWSaUhNzjcMpvEgRMuusF2vU,4740
15
+ contentctl/actions/doc_gen.py,sha256=P2-RYsJoW-QuhAkSpOQespDLJBC-4Cq3-XGTmadK8Ys,936
16
+ contentctl/actions/initialize.py,sha256=KaWSbrTaJA4vNSpKc_rwdlaaERnWw_hPlWwsPOA6Gy8,3191
17
+ contentctl/actions/inspect.py,sha256=rXnrhDt59-n0Jqh_UZ0tDzpKqiOvkGzlvSypXoarKjU,18322
18
+ contentctl/actions/new_content.py,sha256=xs0QvHzlrf0g-EgdUJTkdDdFaA-uEGmzMTixDt6NcTY,8212
19
+ contentctl/actions/release_notes.py,sha256=_Rdljg0tPSAFlw34LJ7dUsHLiH8tJTQ6B95X6MvxURo,17023
20
+ contentctl/actions/reporting.py,sha256=GF32i7sHdc47bw-VWSW-nZ1QBaUl6Ni1JjV5_SOyiAU,1660
21
+ contentctl/actions/test.py,sha256=GTtvHi1yB5yDm1jPMyuc4WxczOq-O7f2N8LpTmMaWgU,6014
22
+ contentctl/actions/validate.py,sha256=thnxanLj6mfw5g17C1FrzWlkpyIT_AjnDxv_wyNdspA,5837
23
+ contentctl/api.py,sha256=6s17vNOW1E1EzQqOCXAa5uWuhwwShu-JkGSgrsOFEMs,6329
24
+ contentctl/contentctl.py,sha256=bO7jKOn9oSDQ4YncN9msu1cwyEXGdDTLcCHh8X9dzzY,11185
25
+ contentctl/enrichments/attack_enrichment.py,sha256=68C9xQ8Q3YX-luRdK2hLnwWtRFpheFA2kE4v5GOLGEo,6358
26
+ contentctl/enrichments/cve_enrichment.py,sha256=TsZ52ef2njt19lPf_VyclY_-5Z5iQ1boVOAxFbjGdSQ,2431
27
+ contentctl/enrichments/splunk_app_enrichment.py,sha256=Xynxjjkqlw0_RtQ1thGSFwy1I3HdmPAJmNKZezyqniU,3419
28
+ contentctl/helper/link_validator.py,sha256=kzEi2GdncPWSi-UKNerXm2jtTJfFQ5goS9pqyAz5U5c,7427
29
+ contentctl/helper/logger.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ contentctl/helper/splunk_app.py,sha256=Zq_C9rjNVqCjBNgm-5CWdBpXyeX5jSpbE-QTGptEZlk,14571
31
+ contentctl/helper/utils.py,sha256=rigwZzCwWzn11sKTVWDkYEtLmRSf0yBbJ671OSRQnOM,19094
32
+ contentctl/input/director.py,sha256=asK4yUlSVdv0QDUzCrTEXQUm0j9hbzVu55o_-wD-eWc,11560
33
+ contentctl/input/new_content_questions.py,sha256=z2C4Mg7-EyxtiF2z9m4SnSbi6QO4CUPB3wg__JeMXIQ,4067
34
+ contentctl/input/yml_reader.py,sha256=ymmAqsWsf9Oj56waDOhCh_E4SomkSCmu4dAx7iURFt8,2050
35
+ contentctl/objects/abstract_security_content_objects/detection_abstract.py,sha256=mtVO2cilGiLq1wpE9oF9KGiUGi0FpAFypvZREe0zsJ4,44013
36
+ contentctl/objects/abstract_security_content_objects/security_content_object_abstract.py,sha256=P1v5n8hM4XzJOjNZbJ5m3y4Bu-cQYaddLPdbE6K-4Xw,12164
37
+ contentctl/objects/alert_action.py,sha256=iEvdEOT4TrTXT0z4rQ_W5v79hPJpPhFPSzo7TuHDxwA,1376
38
+ contentctl/objects/annotated_types.py,sha256=eAMm1Nm3_C5pwfCxhzL5ynDRsC_eK614bFuwUFxPVLw,261
39
+ contentctl/objects/atomic.py,sha256=5nl-JhZnymadi8B8ZEJ8l80DnpvjG-OlRxUjVKR6ffY,7341
40
+ contentctl/objects/base_test.py,sha256=JG6qlr7xe9P71n3CzKOro8_bsmDQGYDfTG9YooHQSIE,1105
41
+ contentctl/objects/base_test_result.py,sha256=TYYzTPKWqp9rHTebWoid50uxAp_iALZouril4sFwIcA,5197
42
+ contentctl/objects/baseline.py,sha256=grzM56KCpROjMnJQIan-fG0LCYfRGA2GHui4FwBwb8A,3172
43
+ contentctl/objects/baseline_tags.py,sha256=Eomy8y3HV-E6Lym5B5ZZTtsmQJYi6Jd4y8GZpTWGYgQ,1643
44
+ contentctl/objects/config.py,sha256=5nK3EkUea-6qUvSzqAxl5UyoLRlldKsh9K8glaBup3I,48603
45
+ contentctl/objects/constants.py,sha256=P4K07PX4_pL_n5jmBVn1BxtoFpjvhT8MuHOquhnEkdA,5465
46
+ contentctl/objects/correlation_search.py,sha256=ab6v-0nbzujhTMpwaXynQiInWpRO1zB5KR4eZLCav_M,45234
47
+ contentctl/objects/dashboard.py,sha256=qMSP76hkJo7PVsWr19hQW4eYoUqGTcRejaOEjlcA_DY,4198
48
+ contentctl/objects/data_source.py,sha256=4u4JaA-Q5xa0gS61yarJuowgy4TrAYE98O2G8o9CQzA,1454
49
+ contentctl/objects/deployment.py,sha256=FRsgsX2T1gvA_0A44_sFPr22rsedxXVIhtO7o9F7eZM,2902
50
+ contentctl/objects/deployment_email.py,sha256=_Sdr_BNjvXECiFonRHLkiOrIQp3slnUaERbptqRbD0Q,206
51
+ contentctl/objects/deployment_notable.py,sha256=j5AniTRDcw32El5H91qKOXDVZvUYxnIuM4Zzlhrm9cM,258
52
+ contentctl/objects/deployment_phantom.py,sha256=Qs9UH3pYe2M3evLLgn5FblTe28QH1QojVaBGM_Ydvjw,261
53
+ contentctl/objects/deployment_rba.py,sha256=n_v79NhcLYHyABceKsI_iEziWhp3uNrqxIUrC8tdjD4,184
54
+ contentctl/objects/deployment_scheduling.py,sha256=PbyAeIEV6ShHuwfzF4LtGrv6tNt1cwNdl-VDQLj0rE8,257
55
+ contentctl/objects/deployment_slack.py,sha256=pC8-BB4qOD5fUqUi7Oj2Tre7-kKVqW2xEvCF7tZENQ4,194
56
+ contentctl/objects/detection.py,sha256=GKjjhnwyFxm7139dOlPJ4c3vIW0675-NLCPWxEB5m-c,631
57
+ contentctl/objects/detection_metadata.py,sha256=JMz8rtcn5HfeEoaAx34kw2wXa35qsRIap_mXoY0Vbss,2237
58
+ contentctl/objects/detection_stanza.py,sha256=-BRQNib5NNhY7Z2fILS5xkpjNkGSLF7qBciTmgOgLV8,3112
59
+ contentctl/objects/detection_tags.py,sha256=kOb-hb83k71m3YkfJ5l-fw3sODMgmekuES7WlT5suAQ,8573
60
+ contentctl/objects/drilldown.py,sha256=Vinw6UYlOl0YzoRA_0oBCfHA5Gvgu5p-rEsfBIgMCdI,4186
61
+ contentctl/objects/enums.py,sha256=HdaSQgEQ_T38BIlVYk1xdqMm05YyhQb0720nzBorXQw,13554
62
+ contentctl/objects/errors.py,sha256=xX_FDUaJbJiOWgjgrzjtYW5QsD41UZ2KWqH-yGkHaCU,5554
63
+ contentctl/objects/integration_test.py,sha256=TYjKyH4YinUnYXOse5BQGCa4-ez_5mtoMwvh1JJcb0o,1254
64
+ contentctl/objects/integration_test_result.py,sha256=_uUSgqgjFhEZM8UwOJI6Q9K-ekIrbKU6OPdqHZycl-s,279
65
+ contentctl/objects/investigation.py,sha256=kmvQ0grCd1YVEW5wVF4-_Rx87PnOxPiNoN_ufTLc3ZM,3659
66
+ contentctl/objects/investigation_tags.py,sha256=qDGNusrWDvCX_GcBEzag2MydSV0LIhGxoXZGgxDXfHA,1317
67
+ contentctl/objects/lookup.py,sha256=mzOPhMDyoNZKLAj8zf6Wg6i9FJKMu3qHWinATtH75I8,13015
68
+ contentctl/objects/macro.py,sha256=usbxyOPIRIJoDmvawfP2DxtFNf71GaDwffxiZsRkP5A,3594
69
+ contentctl/objects/manual_test.py,sha256=cx_XAtQ8VG8Ui_F553Xnut75vFEOtRwm1dDIIWNpOaM,952
70
+ contentctl/objects/manual_test_result.py,sha256=FyCVVf-f1DKs-qBkM4tbKfY6mkrW25NcIEBqyaDC2rE,156
71
+ contentctl/objects/mitre_attack_enrichment.py,sha256=Qzm-P-gx_j-qOe6CKaUCv7AmcNy9EFwnMkw0oYsMfAY,3314
72
+ contentctl/objects/notable_action.py,sha256=sW5XlpGznMHqyBmGXtXrl22hWLiCoKkfGCasGtK3rGo,1607
73
+ contentctl/objects/notable_event.py,sha256=2aOtmfnsdInTtN_fHAGIKmBTBritjHbS_Nc-pqL-GbY,689
74
+ contentctl/objects/playbook.py,sha256=mgYbWsD3OW86u11MbIFKvmyFueSoMJ1WBJm_rNrFvAo,2425
75
+ contentctl/objects/playbook_tags.py,sha256=O5obkQyb82YdJEii8ZJEQtrHtLOSnAvAkT1qIgpCK2s,1547
76
+ contentctl/objects/rba.py,sha256=N1i_ggXjYmHluvYZRq6OJddlbokDnS1mkUsmehmFWOg,2880
77
+ contentctl/objects/risk_analysis_action.py,sha256=v-TQktXEEzbGzmTtqwEykXoSKdGnIlK_JojnqvvAE1s,4370
78
+ contentctl/objects/risk_event.py,sha256=JQUmXriiwi5FetqVnhM0hf5cUp6LzLSNPuoecC2JKK0,12593
79
+ contentctl/objects/risk_object.py,sha256=5iUKW_UwQLjjLWiD_vlE78uwH9bkaMNCHRNmKM25W1Q,905
80
+ contentctl/objects/savedsearches_conf.py,sha256=Dn_Pxd9i3RT6DwNh6JrgmfxjsO3q15xzMksYr3wIGwQ,8624
81
+ contentctl/objects/security_content_object.py,sha256=iDnhq81P7m6Qkmc_Yi-wOyFm9gZUYnPy1GJxxyCtonA,245
82
+ contentctl/objects/story.py,sha256=jalNgK4yYGRr_yVkzuO_YHIrPhpWHF0Q79PkTJhcLzY,5048
83
+ contentctl/objects/story_tags.py,sha256=SLwgkckLxBdtgJro0LnYgj5TFHZEgMiaqDI9q6OfNE0,2364
84
+ contentctl/objects/test_attack_data.py,sha256=7p-kOJguTZtG9y5th5U3qfPFvpiAWLST_OBw8dwWl_4,488
85
+ contentctl/objects/test_group.py,sha256=r-dXyddok4yslv8SIjwOpqylbN1rdjsRi-HIijvpWD0,2602
86
+ contentctl/objects/threat_object.py,sha256=CB3igcmiq06lqnEh7h-btxFrBfgZbHaA9p8kFDKY6lQ,712
87
+ contentctl/objects/throttling.py,sha256=oupWmdtvwAXzLmD3MBJyAU18SD2L2ciEZWUcnL8MuGk,2309
88
+ contentctl/objects/unit_test.py,sha256=-rtSmZ8N2UZ4NkDsfzNXzXiF6dTDwt_jsQ_14xp0hjs,1005
89
+ contentctl/objects/unit_test_baseline.py,sha256=ezg8Ctih_3che2ln2tuVCAtRPHaf5tDMR3dGb34MqaA,287
90
+ contentctl/objects/unit_test_result.py,sha256=gqHqYN5XGBKdV-mdKhAdwfOw4_PpN3i9z_b6ciByDSc,2928
91
+ contentctl/output/api_json_output.py,sha256=QWe_KWlHHxE4Mhd3BHRfJbUJ4z2mLHZn_eMWfMVInik,8237
92
+ contentctl/output/attack_nav_output.py,sha256=2_JISJ3sL4dVAwrIfZ7c426CGz5gjUBVkWh0uFO2MXU,2276
93
+ contentctl/output/attack_nav_writer.py,sha256=FEua57vv347PjFiu1skOEGAbxIqPWMN8Iyp8nDrIvAA,2044
94
+ contentctl/output/conf_output.py,sha256=2_ofRqMro4xmFzf6ZmPRDd93pCG-LQhOiB_kE4owADc,10609
95
+ contentctl/output/conf_writer.py,sha256=9eqt2tm1xjs397pwWLz5oPJcMHbs62ejRG7KghGQQCI,15137
96
+ contentctl/output/data_source_writer.py,sha256=hjr0b5zfJ2UHcDLbCkmTrqma1ngu8F5vWFPJEwOZwU8,1860
97
+ contentctl/output/doc_md_output.py,sha256=wlgbzBD2hUbQNIW2zv5sdrq2UdAKhOZJUYSObnpWQfY,3552
98
+ contentctl/output/jinja_writer.py,sha256=5PbFrc8KuLWrlNIHDvMTyvJ18u_mtjd5Led6-9sn2Eo,1204
99
+ contentctl/output/json_writer.py,sha256=waw73wOmalSrUFcr2K1CWR-xz5oW8il10zDAn56mtMg,1041
100
+ contentctl/output/svg_output.py,sha256=5s9fjmKullMV6cCCGwP7_xvQwg9EZLOKRKMw_IyO6hY,2988
101
+ contentctl/output/templates/analyticstories_detections.j2,sha256=6ZiQO8np6KkX8skVoIB0BN9_s8SBW3qeo8IBA8r8GQk,923
102
+ contentctl/output/templates/analyticstories_investigations.j2,sha256=kqy9lR6W3avqETCM2tSZ8WWOlfiyOtFv6G5N4SZWSaQ,527
103
+ contentctl/output/templates/analyticstories_stories.j2,sha256=MxkmwsgW1oge2YJhbgAzXVcTplSr5JjKIDxX4SBZV0E,676
104
+ contentctl/output/templates/app.conf.j2,sha256=UL80Px4IUGPD-DgcAiUrS4emHBIY7DxleSNyNXCH5tQ,623
105
+ contentctl/output/templates/app.manifest.j2,sha256=Q1803mcfgNvUs8s4e1zD1J3_mxfPYVtLkD8fhCO6d-I,1103
106
+ contentctl/output/templates/collections.j2,sha256=w2hkY7Yfm7AmY1O_7DP-znLS_whgKX79VbnW7QlvrNU,151
107
+ contentctl/output/templates/content-version.j2,sha256=2-it0TF5BvqUcmUXVFB4DEh0I01igQGDxZNJpdtDFIA,54
108
+ contentctl/output/templates/detection_count.j2,sha256=9U3o-P_ECkMknsooj_L3B9GZqjnsbaEzr59s3-DOK0I,670
109
+ contentctl/output/templates/detection_coverage.j2,sha256=guE4fow9BqGoCCrQ3b6-EZqWJcThb58V9khuIH7nhT0,631
110
+ contentctl/output/templates/doc_detection_page.j2,sha256=kATedDq0Z8tzxKiD3nD0_-7YiOrjssUMYSDenRYTh6A,1012
111
+ contentctl/output/templates/doc_detections.j2,sha256=tjTQh6R5zMMmBm9hk-8dFG5p0PyhWSGkrYeRxe9gfPU,6500
112
+ contentctl/output/templates/doc_navigation.j2,sha256=h25ITC3xcAM17uZGIyyDFURmEdYtQSPvNeWN3RH7j4Q,1471
113
+ contentctl/output/templates/doc_navigation_pages.j2,sha256=ptfjbD4F0Ob7dze9at2q5gqOslcbL3eteUO1zsblDJo,203
114
+ contentctl/output/templates/doc_playbooks.j2,sha256=CWsnm8F097oYT8anW3CE7JaX1haAJTfylThP1ic0UIw,1681
115
+ contentctl/output/templates/doc_playbooks_page.j2,sha256=2d5UNDSOxyMtxKGxGHzJ2Ny_UrqTq267NO1h-lmNduc,679
116
+ contentctl/output/templates/doc_stories.j2,sha256=0J3dAbfSZz-Ma1-C9B6vYPKGwrxoZryYoudy3wUIT4s,1827
117
+ contentctl/output/templates/doc_story_page.j2,sha256=jrf-As8GbqLarRoiDipfM9ZUVRl_bhdNsy-XaCrBaXE,874
118
+ contentctl/output/templates/es_investigations_investigations.j2,sha256=vIWiQ6hNsb_-w8ChlWWbQXxGIx5jjWaQ6VoeBJxpHJk,1026
119
+ contentctl/output/templates/es_investigations_stories.j2,sha256=E-OvO7EFdqO3HKyfAY1jBS6VMsDVKuiVqg8SrDVXwls,401
120
+ contentctl/output/templates/header.j2,sha256=3usV7jm1q6J-QNnQrZzII9cN0XEGQjg_eVKrEQwfOG0,201
121
+ contentctl/output/templates/macros.j2,sha256=SLcQQ5X7TZS8j-2qP06BTXqdIcnwoYqTAaBLX2Dge7Y,390
122
+ contentctl/output/templates/panel.j2,sha256=Cw_W6p-14n6UivVfpS75KKJiJ2VpdGsSBceYsUYe9gk,221
123
+ contentctl/output/templates/savedsearches_baselines.j2,sha256=WHZB4e0vmeym8832VxRmuUfDJ-YRYt6emcYaJrghI58,1709
124
+ contentctl/output/templates/savedsearches_detections.j2,sha256=B7_b8aBjEKAV7mJm0DxUS_HyCt63bQZtpacCQfDgDqc,6033
125
+ contentctl/output/templates/savedsearches_investigations.j2,sha256=KH2r8SgyAMiettSHypSbA2-1XmQ_8_8xzk3BkbZ1Re4,1196
126
+ contentctl/output/templates/server.conf.j2,sha256=sPZUkiuJNGm9R8rpjfRKyuAvmmQb0C4w9Q6hpmvmPeU,127
127
+ contentctl/output/templates/transforms.j2,sha256=mM9vIIGqxlhLk1W8sHoUgppfK1FO3ESQD1WCVAewhBw,1386
128
+ contentctl/output/templates/workflow_actions.j2,sha256=DFoZVnCa8dMRHjW2AdpoydBC0THgiH_W-Nx7WI4-uR4,925
129
+ contentctl/output/yml_writer.py,sha256=gGgbamHWunHKjj47TcqB04k0xliX6w3H7iajZtUZRSU,2124
130
+ contentctl/templates/README.md,sha256=GoRmywUqwnjaehY_GLmGqxsFXCLP9plpDYwB6W6nVPs,428
131
+ contentctl/templates/app_default.yml,sha256=kDeYdJbfMADQPcho8iH1nqgTFrHNt4EXnIJjPHc2unI,6390
132
+ contentctl/templates/app_template/README/essoc_story_detail.txt,sha256=7hFPBfPpRH28TFl7QchKceZLewQqgFjRWDlmxZzwpmo,897
133
+ contentctl/templates/app_template/README/essoc_summary.txt,sha256=u6wYNYBqmmm7Kn_g_Uex8rRzMQ995MUXCavla95Y1dw,2538
134
+ contentctl/templates/app_template/README/essoc_usage_dashboard.txt,sha256=xYUKKVtdgzPyT3mqdTccaBZuwWnC63lbc9zyYpmHN4o,2432
135
+ contentctl/templates/app_template/README.md,sha256=RT-J9bgRSFsEFgNr9qV6yc2LkfUH_uiMJ2RV4NM9Ymo,366
136
+ contentctl/templates/app_template/default/analytic_stories.conf,sha256=zWuCOOl8SiP7Kit2s-de4KRu3HySLtBSXcp1QnJx0ec,168
137
+ contentctl/templates/app_template/default/commands.conf,sha256=U2ccwUeGXKKKt5jo14QY5swi-p9_TSJtaNquOkeF3Yk,319
138
+ contentctl/templates/app_template/default/data/ui/nav/default.xml,sha256=fKN53HZCtNJbQqq_5pP8e5-5m30DRrJittr6q5s6V_0,236
139
+ contentctl/templates/app_template/default/data/ui/views/escu_summary.xml,sha256=jQhkIthPgEEptCJ2wUCj2lWGHBvUl6JGsKkDfONloxI,8635
140
+ contentctl/templates/app_template/default/data/ui/views/feedback.xml,sha256=uM71EMK2uFz8h68nOTNKGnYxob3HhE_caSL6yA-3H-k,696
141
+ contentctl/templates/app_template/default/use_case_library.conf,sha256=zWuCOOl8SiP7Kit2s-de4KRu3HySLtBSXcp1QnJx0ec,168
142
+ contentctl/templates/app_template/lookups/mitre_enrichment.csv,sha256=tifPQjFoQHtvpb78hxSP2fKHnHeehNbZDwUjdvc0aEM,66072
143
+ contentctl/templates/app_template/metadata/default.meta,sha256=h66ea1l3qMzDRgDUAXsJvGKeJnp5w-s2unYMZ9dJLzM,433
144
+ contentctl/templates/app_template/static/appIcon.png,sha256=jcJ1PNdkBX7Kl_y9Tf0SZ55OJYA2PpwjvkVvBt9_OoE,3658
145
+ contentctl/templates/app_template/static/appIconAlt.png,sha256=uRXjoHQQjs0-BxcK-3KNBEdck1adDNTHMvV14xR4W0g,2656
146
+ contentctl/templates/app_template/static/appIconAlt_2x.png,sha256=I0m-CPRqq7ak9NJQZGGmz6Ac4pmzFV_SonOUxOEDOFs,7442
147
+ contentctl/templates/app_template/static/appIcon_2x.png,sha256=XEpqQzDvzuEV5StzD05XRgxwySqHHLes1hMPy2v5Vdk,3657
148
+ contentctl/templates/data_sources/sysmon_eventid_1.yml,sha256=7PIcLr1e9Ql-wu_Dk9D4JAZs1OWDby-tY77nDDUZ1CQ,6079
149
+ contentctl/templates/datamodels_cim.conf,sha256=RB_SCtpQG_KaC_0lKTCKexVOlEq_ShGwpGlg95aqOfs,9381
150
+ contentctl/templates/datamodels_custom.conf,sha256=6BANthXdqg3fYpYmEqiGZnv4cWheNfXz1uQ_I1JePXc,480
151
+ contentctl/templates/deployments/escu_default_configuration_anomaly.yml,sha256=j_H2wovWBj1EKxVwj3mMoJVQnVm-2Imt7xnB9U1Tun4,418
152
+ contentctl/templates/deployments/escu_default_configuration_baseline.yml,sha256=NzUvaotkk7hatx9EBjROFIwsvSOZXgfAJUvGS8JrUMg,334
153
+ contentctl/templates/deployments/escu_default_configuration_correlation.yml,sha256=iWLqvJnUKVhpKaLBc_w_W65d9HVZgOZfGA-RIpxsH6M,519
154
+ contentctl/templates/deployments/escu_default_configuration_hunting.yml,sha256=hHmM8u7zncpb-32Qv74UoNs0HKwZwCMoKAq2ygDJZbo,329
155
+ contentctl/templates/deployments/escu_default_configuration_ttp.yml,sha256=1D-pvzaH1v3_yCZXaY6njmdvV4S2_Ak8uzzCOsnj9XY,548
156
+ contentctl/templates/detections/application/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
+ contentctl/templates/detections/cloud/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
+ contentctl/templates/detections/endpoint/anomalous_usage_of_7zip.yml,sha256=VQ8mxkOOm7RfnBomtOXF9XGE8fV-j5j-4pFtpocQ17Y,3875
159
+ contentctl/templates/detections/network/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
+ contentctl/templates/detections/web/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
+ contentctl/templates/macros/security_content_ctime.yml,sha256=Gg1YNllHVsX_YB716H1SJLWzxXZEfuJlnsgB2fuyoHU,159
162
+ contentctl/templates/macros/security_content_summariesonly.yml,sha256=9BYUxAl2E4Nwh8K19F3AJS8Ka7ceO6ZDBjFiO3l3LY0,162
163
+ contentctl/templates/stories/cobalt_strike.yml,sha256=uj8idtDNOAIqpZ9p8usQg6mop1CQkJ5TlB4Q7CJdTIE,3082
164
+ contentctl-5.0.0.dist-info/LICENSE.md,sha256=hQWUayRk-pAiOZbZnuy8djmoZkjKBx8MrCFpW-JiOgo,11344
165
+ contentctl-5.0.0.dist-info/METADATA,sha256=99Dsj6xpEKa3kGWPD2uxqttJyHlzYJbpzn_VqgedaIc,21539
166
+ contentctl-5.0.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
167
+ contentctl-5.0.0.dist-info/entry_points.txt,sha256=5bjZ2NkbQfSwK47uOnA77yCtjgXhvgxnmCQiynRF_-U,57
168
+ contentctl-5.0.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.0.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,245 +0,0 @@
1
- '''
2
- Initializes a Splunk Content Project
3
- '''
4
-
5
- from pathlib import Path
6
- import yaml
7
- import sys
8
- import questionary
9
- import os
10
- from contentctl.objects.enums import LogLevel
11
-
12
- import abc
13
- from pydantic import BaseModel, Field
14
-
15
- from contentctl.objects.config import Config
16
-
17
- DEFAULT_FOLDERS = ['detections', 'stories', 'lookups', 'macros', 'baselines', 'dist']
18
-
19
-
20
- def create_folders(path):
21
-
22
- for folder in DEFAULT_FOLDERS:
23
- folder_path = path + "/" + folder
24
- if not os.path.exists(folder_path):
25
- os.makedirs(folder_path)
26
-
27
-
28
-
29
- def NewContentPack(args, default_config):
30
- """
31
- new function creates a new configuration file based on the user input on the terminal.
32
- :param config: python dictionary having the configuration
33
- :return: No return value
34
- """
35
- contentctl_config_file = Path(args.config)
36
- if contentctl_config_file.is_file():
37
- questions = [
38
- {
39
- 'type': 'confirm',
40
- 'message': 'File {0} already exist, are you sure you want to continue?\nTHIS WILL OVERWRITE YOUR CURRENT CONFIG!'.format(contentctl_config_file),
41
- 'name': 'continue',
42
- 'default': True,
43
- },
44
- ]
45
-
46
- answers = questionary.prompt(questions)
47
- if answers['continue']:
48
- print("> continuing with contentctl configuration...")
49
- else:
50
- print("> exiting, to create a unique configuration file in another location use the --config flag")
51
- sys.exit(0)
52
-
53
-
54
- # configuration parameters
55
- if os.path.exists(args.output):
56
- config_path = args.output + "/" + str(contentctl_config_file)
57
- else:
58
- print("ERROR, output folder: {0} does not exist".format(args.output))
59
- sys.exit(1)
60
-
61
- # deal with skipping configuration
62
- if args.skip_configuration:
63
- print("initializing with default configuration: {0}".format(config_path))
64
- # write config file
65
- with open(config_path, 'w') as outfile:
66
- yaml.dump(default_config, outfile, default_flow_style=False, sort_keys=False)
67
-
68
- # write folder structure
69
- create_folders(args.output)
70
- sys.exit(0)
71
-
72
-
73
- questions = [
74
- {
75
- "type": "select",
76
- "message": "Which build format should we use for this content pack? Builds will be created under the dist/ folder.",
77
- "name": "product",
78
- "choices": ["Splunk App", "JSON API Objects", "BA Objects", "All"],
79
- "default": "Splunk App"
80
- },
81
- {
82
- 'type': 'text',
83
- 'message': 'What should the Splunk App for this content pack be called?',
84
- 'name': 'product_app_name',
85
- 'default': 'Capybara Splunk Content Pack',
86
- 'when': lambda answers: answers['product'] == "Splunk App" or answers['product'] == "All",
87
-
88
- },
89
- {
90
- 'type': 'confirm',
91
- 'message': 'Should this content pack be deployed to a (Cloud) Splunk Enterprise Server?',
92
- 'name': 'deploy_to_splunk',
93
- 'default': False,
94
-
95
- },
96
- {
97
- 'type': 'text',
98
- 'message': 'What is the <host>:<port> of the (Cloud) Splunk Enterprise Server?',
99
- 'name': 'deploy_to_splunk_server',
100
- 'default': '127.0.0.1:8089',
101
- 'when': lambda answers: answers['deploy_to_splunk'],
102
-
103
- },
104
- {
105
- 'type': 'text',
106
- 'message': 'What is the username of the (Cloud) Splunk Enterprise Server?',
107
- 'name': 'deploy_to_splunk_username',
108
- 'default': 'admin',
109
- 'when': lambda answers: answers['deploy_to_splunk'],
110
-
111
- },
112
- {
113
- 'type': 'text',
114
- 'message': 'What is the password of the (Cloud) Splunk Enterprise Server?',
115
- 'name': 'deploy_to_splunk_password',
116
- 'default': 'xxx',
117
- 'when': lambda answers: answers['deploy_to_splunk'],
118
-
119
- },
120
- {
121
- 'type': 'text',
122
- 'message': 'How often should analytics run? The schedule is on cron format (https://crontab.guru/).',
123
- 'name': 'scheduling_cron_schedule',
124
- 'default': '0 * * * *',
125
- },
126
- {
127
- 'type': 'text',
128
- 'message': 'What is the earliest time for analytics? Uses Splunk time modifiers (https://docs.splunk.com/Documentation/SCS/current/Search/Timemodifiers).',
129
- 'name': 'scheduling_earliest_time',
130
- 'default': '-70m@m',
131
- },
132
- {
133
- 'type': 'text',
134
- 'message': 'What is the latest time for analytics? Uses Splunk time modifiers (https://docs.splunk.com/Documentation/SCS/current/Search/Timemodifiers).',
135
- 'name': 'scheduling_latest_time',
136
- 'default': '-10m@m',
137
- },
138
- {
139
- 'type': 'checkbox',
140
- 'message': 'What should the default action be when an analytic triggers?',
141
- 'name': 'default_actions',
142
- 'choices': ["notable", "risk_event", "email"],
143
- 'default': 'notable',
144
- },
145
- {
146
- 'type': 'text',
147
- 'message': 'What email address should we send the alerts to?',
148
- 'name': 'to_email',
149
- 'default': 'geralt@monsterkiller.com',
150
- 'when': lambda answers: 'email' in answers['default_actions'],
151
- },
152
- {
153
- 'type': 'confirm',
154
- 'message': 'Should we include some example content? This will add a detection and its test with supporting components like lookups and macros.',
155
- 'name': 'pre_populate',
156
- 'default': True,
157
- },
158
- ]
159
-
160
- answers = questionary.prompt(questions)
161
-
162
- # create a custom config object to store answers
163
- custom_config = default_config
164
-
165
- # remove other product settings
166
- if answers['product'] == 'Splunk App':
167
- # pop other configs out
168
- custom_config['build'].pop('json_objects')
169
- custom_config['build'].pop('ba_objects')
170
- # capture configs
171
- custom_config['build']['splunk_app']['name'] = answers['product_app_name']
172
- custom_config['build']['splunk_app']['path'] = 'dist/' + answers['product_app_name'].lower().replace(" ", "_")
173
- custom_config['build']['splunk_app']['prefix'] = answers['product_app_name'].upper()[0: 3]
174
-
175
- elif answers['product'] == 'JSON API Objects':
176
- custom_config['build'].pop('splunk_app')
177
- custom_config['build'].pop('ba_objects')
178
- elif answers['product'] == 'BA Objects':
179
- custom_config['build'].pop('splunk_app')
180
- custom_config['build'].pop('json_objects')
181
- else:
182
- # splunk app config
183
- custom_config['build']['splunk_app']['name'] = answers['product_app_name']
184
- custom_config['build']['splunk_app']['path'] = 'dist/' + answers['product_app_name'].lower().replace(" ", "_")
185
- custom_config['build']['splunk_app']['prefix'] = answers['product_app_name'].upper()[0: 3]
186
-
187
- if answers['deploy_to_splunk']:
188
- custom_config['deploy']['server'] = answers['deploy_to_splunk_server']
189
- custom_config['deploy']['username'] = answers['deploy_to_splunk_username']
190
- custom_config['deploy']['password'] = answers['deploy_to_splunk_password']
191
- else:
192
- custom_config.pop('deploy')
193
-
194
- custom_config['scheduling']['cron_schedule'] = answers['scheduling_cron_schedule']
195
- custom_config['scheduling']['earliest_time'] = answers['scheduling_earliest_time']
196
- custom_config['scheduling']['latest_time'] = answers['scheduling_latest_time']
197
-
198
- if 'notable' in answers['default_actions']:
199
- custom_config['alert_actions']['notable']['rule_description'] = '%description%'
200
- custom_config['alert_actions']['notable']['rule_title'] = '%name%'
201
- custom_config['alert_actions']['notable']['nes_fields'] = ['user','dest','src']
202
- else:
203
- custom_config['alert_actions'].pop('notable')
204
- if 'risk_event' in answers['default_actions']:
205
- rba = dict()
206
- custom_config['alert_actions']['rba'] = rba
207
- custom_config['alert_actions']['rba']['enabled'] = 'true'
208
-
209
- if 'email' in answers['default_actions']:
210
- email = dict()
211
- custom_config['alert_actions']['email'] = email
212
- custom_config['alert_actions']['email']['subject'] = 'Alert %name% triggered'
213
- custom_config['alert_actions']['email']['message'] = 'The rule %name% triggered base on %description%'
214
- custom_config['alert_actions']['email']['to'] = answers['to_email']
215
-
216
-
217
- # write config file
218
- with open(config_path, 'w') as outfile:
219
- yaml.dump(custom_config, outfile, default_flow_style=False, sort_keys=False)
220
- print('Content pack configuration created under: {0} .. edit to fine tune details before building'.format(config_path))
221
-
222
- # write folder structure
223
- create_folders(args.output)
224
- print('The following folders were created: {0} under {1}.\nContent pack has been initialized, please run `new` to create new content.'.format(DEFAULT_FOLDERS, args.output))
225
-
226
- print("Load the custom_config into the pydantic model we have created")
227
- cfg = ContentPackConfig().parse_obj(custom_config)
228
- import pprint
229
- pprint.pprint(cfg.__dict__)
230
- print("********************")
231
- pprint.pprint(custom_config)
232
- print("done")
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
@@ -1,11 +0,0 @@
1
- from __future__ import annotations
2
- from typing import Union, Optional, List
3
- from pydantic import BaseModel, Field
4
-
5
- from contentctl.objects.security_content_object import SecurityContentObject
6
-
7
- class EventSource(SecurityContentObject):
8
- fields: Optional[list[str]] = None
9
- field_mappings: Optional[list[dict]] = None
10
- convert_to_log_source: Optional[list[dict]] = None
11
- example_log: Optional[str] = None
@@ -1,37 +0,0 @@
1
- from pydantic import BaseModel, field_validator
2
- from contentctl.objects.constants import SES_OBSERVABLE_TYPE_MAPPING, RBA_OBSERVABLE_ROLE_MAPPING
3
-
4
-
5
- class Observable(BaseModel):
6
- name: str
7
- type: str
8
- role: list[str]
9
-
10
- @field_validator('name')
11
- def check_name(cls, v: str):
12
- if v == "":
13
- raise ValueError("No name provided for observable")
14
- return v
15
-
16
- @field_validator('type')
17
- def check_type(cls, v: str):
18
- if v not in SES_OBSERVABLE_TYPE_MAPPING.keys():
19
- raise ValueError(
20
- f"Invalid type '{v}' provided for observable. Valid observable types are "
21
- f"{SES_OBSERVABLE_TYPE_MAPPING.keys()}"
22
- )
23
- return v
24
-
25
- @field_validator('role')
26
- def check_roles(cls, v: list[str]):
27
- if len(v) == 0:
28
- raise ValueError("Error, at least 1 role must be listed for Observable.")
29
- if len(v) > 1:
30
- raise ValueError("Error, each Observable can only have one role.")
31
- for role in v:
32
- if role not in RBA_OBSERVABLE_ROLE_MAPPING.keys():
33
- raise ValueError(
34
- f"Invalid role '{role}' provided for observable. Valid observable types are "
35
- f"{RBA_OBSERVABLE_ROLE_MAPPING.keys()}"
36
- )
37
- return v
@@ -1,28 +0,0 @@
1
-
2
- import yaml
3
-
4
-
5
- class DetectionWriter:
6
-
7
- @staticmethod
8
- def writeYmlFile(file_path : str, obj : dict) -> None:
9
-
10
- new_obj = dict()
11
- new_obj["name"] = obj["name"]
12
- new_obj["id"] = obj["id"]
13
- new_obj["version"] = obj["version"]
14
- new_obj["date"] = obj["date"]
15
- new_obj["author"] = obj["author"]
16
- new_obj["type"] = obj["type"]
17
- new_obj["status"] = obj["status"]
18
- new_obj["description"] = obj["description"]
19
- new_obj["data_source"] = obj["data_source"]
20
- new_obj["search"] = obj["search"]
21
- new_obj["how_to_implement"] = obj["how_to_implement"]
22
- new_obj["known_false_positives"] = obj["known_false_positives"]
23
- new_obj["references"] = obj["references"]
24
- new_obj["tags"] = obj["tags"]
25
- new_obj["tests"] = obj["tests"]
26
-
27
- with open(file_path, 'w') as outfile:
28
- yaml.safe_dump(new_obj, outfile, default_flow_style=False, sort_keys=False)
@@ -1,56 +0,0 @@
1
- import os
2
- import pathlib
3
- from contentctl.objects.enums import SecurityContentType
4
- from contentctl.output.yml_writer import YmlWriter
5
- import pathlib
6
- from contentctl.objects.config import NewContentType
7
- class NewContentYmlOutput():
8
- output_path: pathlib.Path
9
-
10
- def __init__(self, output_path:pathlib.Path):
11
- self.output_path = output_path
12
-
13
-
14
- def writeObjectNewContent(self, object: dict, subdirectory_name: str, type: NewContentType) -> None:
15
- if type == NewContentType.detection:
16
-
17
- file_path = os.path.join(self.output_path, 'detections', subdirectory_name, self.convertNameToFileName(object['name'], object['tags']['product']))
18
- output_folder = pathlib.Path(self.output_path)/'detections'/subdirectory_name
19
- #make sure the output folder exists for this detection
20
- output_folder.mkdir(exist_ok=True)
21
-
22
- YmlWriter.writeYmlFile(file_path, object)
23
- print("Successfully created detection " + file_path)
24
-
25
- elif type == NewContentType.story:
26
- file_path = os.path.join(self.output_path, 'stories', self.convertNameToFileName(object['name'], object['tags']['product']))
27
- YmlWriter.writeYmlFile(file_path, object)
28
- print("Successfully created story " + file_path)
29
-
30
- else:
31
- raise(Exception(f"Object Must be Story or Detection, but is not: {object}"))
32
-
33
-
34
-
35
- def convertNameToFileName(self, name: str, product: list):
36
- file_name = name \
37
- .replace(' ', '_') \
38
- .replace('-','_') \
39
- .replace('.','_') \
40
- .replace('/','_') \
41
- .lower()
42
-
43
- file_name = file_name + '.yml'
44
- return file_name
45
-
46
-
47
- def convertNameToTestFileName(self, name: str, product: list):
48
- file_name = name \
49
- .replace(' ', '_') \
50
- .replace('-','_') \
51
- .replace('.','_') \
52
- .replace('/','_') \
53
- .lower()
54
-
55
- file_name = file_name + '.test.yml'
56
- return file_name
@@ -1,66 +0,0 @@
1
- import os
2
-
3
- from contentctl.output.detection_writer import DetectionWriter
4
- from contentctl.objects.detection import Detection
5
-
6
-
7
- class YmlOutput():
8
-
9
-
10
- def writeDetections(self, objects: list, output_path : str) -> None:
11
- for obj in objects:
12
- file_path = obj.file_path
13
- obj.id = str(obj.id)
14
-
15
- DetectionWriter.writeYmlFile(os.path.join(output_path, file_path), obj.dict(
16
- exclude_none=True,
17
- include =
18
- {
19
- "name": True,
20
- "id": True,
21
- "version": True,
22
- "date": True,
23
- "author": True,
24
- "type": True,
25
- "status": True,
26
- "description": True,
27
- "data_source": True,
28
- "search": True,
29
- "how_to_implement": True,
30
- "known_false_positives": True,
31
- "references": True,
32
- "tags":
33
- {
34
- "analytic_story": True,
35
- "asset_type": True,
36
- "atomic_guid": True,
37
- "confidence": True,
38
- "impact": True,
39
- "drilldown_search": True,
40
- "mappings": True,
41
- "message": True,
42
- "mitre_attack_id": True,
43
- "kill_chain_phases:": True,
44
- "observable": True,
45
- "product": True,
46
- "required_fields": True,
47
- "risk_score": True,
48
- "security_domain": True
49
- },
50
- "tests":
51
- {
52
- '__all__':
53
- {
54
- "name": True,
55
- "attack_data": {
56
- '__all__':
57
- {
58
- "data": True,
59
- "source": True,
60
- "sourcetype": True
61
- }
62
- }
63
- }
64
- }
65
- }
66
- ))