├── .gitignore ├── README.md ├── README ├── commands.conf.spec ├── restmap.conf.spec └── transforms.conf.spec ├── appserver ├── assets │ ├── NavigatorLayerFileFormatv1.pdf │ ├── NavigatorLayerFileFormatv1_1.pdf │ ├── NavigatorLayerFileFormatv1_2.pdf │ ├── NavigatorLayerFileFormatv1_3.pdf │ ├── NavigatorLayerFileFormatv2.pdf │ ├── NavigatorLayerFileFormatv2_1.pdf │ ├── NavigatorLayerFileFormatv2_2.pdf │ ├── NavigatorLayerFileFormatv3.pdf │ ├── config.json │ ├── icons │ │ ├── baseline-grid_on-24px.svg │ │ ├── ic_camera_alt_black_24px.svg │ │ ├── ic_check_box_black_24px.svg │ │ ├── ic_check_box_outline_blank_black_24px.svg │ │ ├── ic_clear_black_24px.svg │ │ ├── ic_clear_gray_24px.svg │ │ ├── ic_close_black_24px.svg │ │ ├── ic_color_lens_black_24px.svg │ │ ├── ic_content_copy_black_24px.svg │ │ ├── ic_description_black_24px.svg │ │ ├── ic_done_black_24px.svg │ │ ├── ic_done_gray_24px.svg │ │ ├── ic_file_download_black_24px.svg │ │ ├── ic_file_upload_black_24px.svg │ │ ├── ic_file_upload_gray_24px.svg │ │ ├── ic_filter_list_black_24px.svg │ │ ├── ic_format_color_fill_black_24px.svg │ │ ├── ic_format_color_fill_black_nobottom_24px.svg │ │ ├── ic_format_color_fill_gray_nobottom_24px.svg │ │ ├── ic_format_size_black_24px.svg │ │ ├── ic_insert_chart_black_24px.svg │ │ ├── ic_insert_chart_gray_24px.svg │ │ ├── ic_insert_comment_black_24px.svg │ │ ├── ic_insert_comment_gray_24px.svg │ │ ├── ic_keyboard_arrow_down_black_24px.svg │ │ ├── ic_keyboard_arrow_right_black_24px.svg │ │ ├── ic_keyboard_arrow_up_black_24px.svg │ │ ├── ic_layers_clear_black_24px.svg │ │ ├── ic_layers_clear_gray_24px.svg │ │ ├── ic_lock_black_24px.svg │ │ ├── ic_lock_open_black_24px.svg │ │ ├── ic_palette_black_24px.svg │ │ ├── ic_photo_size_select_large_black_24px.svg │ │ ├── ic_playlist_add_black_24px.svg │ │ ├── ic_playlist_add_gray_24px.svg │ │ ├── ic_refresh_lg_off_24px.svg │ │ ├── ic_refresh_lg_on_24px.svg │ │ ├── ic_remove_circle_black_24px.svg │ │ ├── ic_save_black_24px.svg │ │ ├── ic_save_gray_24px.svg │ │ ├── ic_search_black_24px.svg │ │ ├── ic_search_gray_24px.svg │ │ ├── ic_sort_alphabetically_ascending_black_24px.svg │ │ ├── ic_sort_alphabetically_black_24px.svg │ │ ├── ic_sort_alphabetically_descending_black_24px.svg │ │ ├── ic_sort_numerically_ascending_black_24px.svg │ │ ├── ic_sort_numerically_black_24px.svg │ │ ├── ic_sort_numerically_descending_black_24px.svg │ │ ├── ic_texture_black_24px.svg │ │ ├── ic_texture_gray_24px.svg │ │ ├── ic_view_large_black_24px.svg │ │ ├── ic_view_list_black_24px.svg │ │ ├── ic_view_list_grey_24px.svg │ │ ├── ic_view_medium_black_24px.svg │ │ ├── ic_view_small_black_24px.svg │ │ ├── ic_visibility_black_24px.svg │ │ ├── ic_visibility_gray_24px.svg │ │ ├── ic_visibility_off_black_24px.svg │ │ ├── unfold_less_black_24px.svg │ │ ├── unfold_less_gray_24px.svg │ │ ├── unfold_more_black_24px.svg │ │ └── unfold_more_gray_24px.svg │ └── image_scoreVariableExample.png ├── favicon.ico ├── index.html ├── static │ ├── 3rdpartylicenses.txt │ ├── assets │ │ ├── NavigatorLayerFileFormatv1.pdf │ │ ├── NavigatorLayerFileFormatv1_1.pdf │ │ ├── NavigatorLayerFileFormatv1_2.pdf │ │ ├── NavigatorLayerFileFormatv1_3.pdf │ │ ├── NavigatorLayerFileFormatv2.pdf │ │ ├── NavigatorLayerFileFormatv2_1.pdf │ │ ├── NavigatorLayerFileFormatv2_2.pdf │ │ ├── NavigatorLayerFileFormatv3.pdf │ │ ├── config.json │ │ ├── enterprise-attack.json │ │ ├── icons │ │ │ ├── baseline-grid_on-24px.svg │ │ │ ├── ic_camera_alt_black_24px.svg │ │ │ ├── ic_check_box_black_24px.svg │ │ │ ├── ic_check_box_outline_blank_black_24px.svg │ │ │ ├── ic_clear_black_24px.svg │ │ │ ├── ic_clear_gray_24px.svg │ │ │ ├── ic_close_black_24px.svg │ │ │ ├── ic_color_lens_black_24px.svg │ │ │ ├── ic_content_copy_black_24px.svg │ │ │ ├── ic_description_black_24px.svg │ │ │ ├── ic_done_black_24px.svg │ │ │ ├── ic_done_gray_24px.svg │ │ │ ├── ic_file_download_black_24px.svg │ │ │ ├── ic_file_upload_black_24px.svg │ │ │ ├── ic_file_upload_gray_24px.svg │ │ │ ├── ic_filter_list_black_24px.svg │ │ │ ├── ic_format_color_fill_black_24px.svg │ │ │ ├── ic_format_color_fill_black_nobottom_24px.svg │ │ │ ├── ic_format_color_fill_gray_nobottom_24px.svg │ │ │ ├── ic_format_size_black_24px.svg │ │ │ ├── ic_insert_chart_black_24px.svg │ │ │ ├── ic_insert_chart_gray_24px.svg │ │ │ ├── ic_insert_comment_black_24px.svg │ │ │ ├── ic_insert_comment_gray_24px.svg │ │ │ ├── ic_keyboard_arrow_down_black_24px.svg │ │ │ ├── ic_keyboard_arrow_right_black_24px.svg │ │ │ ├── ic_keyboard_arrow_up_black_24px.svg │ │ │ ├── ic_layers_clear_black_24px.svg │ │ │ ├── ic_layers_clear_gray_24px.svg │ │ │ ├── ic_lock_black_24px.svg │ │ │ ├── ic_lock_open_black_24px.svg │ │ │ ├── ic_palette_black_24px.svg │ │ │ ├── ic_photo_size_select_large_black_24px.svg │ │ │ ├── ic_playlist_add_black_24px.svg │ │ │ ├── ic_playlist_add_gray_24px.svg │ │ │ ├── ic_refresh_lg_off_24px.svg │ │ │ ├── ic_refresh_lg_on_24px.svg │ │ │ ├── ic_remove_circle_black_24px.svg │ │ │ ├── ic_save_black_24px.svg │ │ │ ├── ic_save_gray_24px.svg │ │ │ ├── ic_search_black_24px.svg │ │ │ ├── ic_search_gray_24px.svg │ │ │ ├── ic_sort_alphabetically_ascending_black_24px.svg │ │ │ ├── ic_sort_alphabetically_black_24px.svg │ │ │ ├── ic_sort_alphabetically_descending_black_24px.svg │ │ │ ├── ic_sort_numerically_ascending_black_24px.svg │ │ │ ├── ic_sort_numerically_black_24px.svg │ │ │ ├── ic_sort_numerically_descending_black_24px.svg │ │ │ ├── ic_texture_black_24px.svg │ │ │ ├── ic_texture_gray_24px.svg │ │ │ ├── ic_view_large_black_24px.svg │ │ │ ├── ic_view_list_black_24px.svg │ │ │ ├── ic_view_list_grey_24px.svg │ │ │ ├── ic_view_medium_black_24px.svg │ │ │ ├── ic_view_small_black_24px.svg │ │ │ ├── ic_visibility_black_24px.svg │ │ │ ├── ic_visibility_gray_24px.svg │ │ │ ├── ic_visibility_off_black_24px.svg │ │ │ ├── unfold_less_black_24px.svg │ │ │ ├── unfold_less_gray_24px.svg │ │ │ ├── unfold_more_black_24px.svg │ │ │ └── unfold_more_gray_24px.svg │ │ ├── image_scoreVariableExample.png │ │ ├── mobile-attack.json │ │ ├── pre-attack.json │ │ └── tacticsData.json │ ├── favicon.ico │ ├── index.html │ ├── main.js │ ├── main.js.map │ ├── pages │ │ ├── Mainpage.jsx.js │ │ ├── MainpageStyles.js.js │ │ ├── attack.js │ │ ├── attack.js.backup │ │ ├── config.js │ │ ├── start.css.js │ │ ├── themes.js │ │ └── themes.js.js │ ├── polyfills-es5.js │ ├── polyfills-es5.js.map │ ├── polyfills.js │ ├── polyfills.js.map │ ├── runtime.js │ ├── runtime.js.map │ ├── scripts.js │ ├── scripts.js.map │ ├── styles.js │ ├── styles.js.map │ ├── vendor.js │ └── vendor.js.map └── templates │ ├── attack.html │ └── config.html ├── bin ├── README ├── __pycache__ │ ├── base_layer.cpython-37.pyc │ └── manage_app_config.cpython-37.pyc ├── base_layer.py ├── generate_attack_layer.py ├── manage_app_config.py └── readme.txt ├── default ├── app.conf ├── collections.conf ├── commands.conf ├── data │ └── ui │ │ ├── nav │ │ └── default.xml │ │ └── views │ │ ├── README │ │ ├── attack.xml │ │ ├── config.xml │ │ ├── overview.xml │ │ └── simulation_runner.xml ├── restmap.conf ├── searchbnf.conf ├── transforms.conf └── web.conf ├── lib └── splunklib │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-37.pyc │ ├── binding.cpython-37.pyc │ ├── client.cpython-37.pyc │ ├── data.cpython-37.pyc │ └── six.cpython-37.pyc │ ├── binding.py │ ├── client.py │ ├── data.py │ ├── modularinput │ ├── __init__.py │ ├── argument.py │ ├── event.py │ ├── event_writer.py │ ├── input_definition.py │ ├── scheme.py │ ├── script.py │ ├── utils.py │ └── validation_definition.py │ ├── ordereddict.py │ ├── results.py │ ├── searchcommands │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-37.pyc │ │ ├── decorators.cpython-37.pyc │ │ ├── environment.cpython-37.pyc │ │ ├── eventing_command.cpython-37.pyc │ │ ├── external_search_command.cpython-37.pyc │ │ ├── generating_command.cpython-37.pyc │ │ ├── internals.cpython-37.pyc │ │ ├── reporting_command.cpython-37.pyc │ │ ├── search_command.cpython-37.pyc │ │ ├── streaming_command.cpython-37.pyc │ │ └── validators.cpython-37.pyc │ ├── decorators.py │ ├── environment.py │ ├── eventing_command.py │ ├── external_search_command.py │ ├── generating_command.py │ ├── internals.py │ ├── reporting_command.py │ ├── search_command.py │ ├── streaming_command.py │ └── validators.py │ └── six.py ├── lookups └── attck_assets.csv ├── metadata └── default.meta └── static ├── appIcon.png ├── appIconAlt.png ├── appIconAlt_2x.png ├── appIcon_2x.png └── attack_splunk_logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_* 2 | .vscode* 3 | bin/*.pyc 4 | lib/splunklib/*.pyc 5 | lib/splunklib/searchcommands/__init__.pyc 6 | lib/splunklib/__init__.pyc 7 | lib/splunklib/binding.pyc 8 | lib/splunklib/client.pyc 9 | lib/splunklib/data.pyc 10 | lib/splunklib/six.pyc 11 | lib/splunklib/searchcommands/decorators.pyc 12 | lib/splunklib/searchcommands/environment.pyc 13 | lib/splunklib/searchcommands/eventing_command.pyc 14 | lib/splunklib/searchcommands/external_search_command.pyc 15 | lib/splunklib/searchcommands/generating_command.pyc 16 | lib/splunklib/searchcommands/internals.pyc 17 | lib/splunklib/searchcommands/reporting_command.pyc 18 | lib/splunklib/searchcommands/search_command.pyc 19 | lib/splunklib/searchcommands/streaming_command.pyc 20 | lib/splunklib/searchcommands/validators.pyc 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository is part of a larger [Adversary Simulation project](https://github.com/timfrazier1/AdversarySimulation). The main page includes some installation guidance and information about other components. Please refer there for more information. 2 | 3 | 4 | This Splunk App is intended to implement the [ATT&CK navigator](https://github.com/mitre/attack-navigator) inside of Splunkweb as an "app". 5 | It also includes a REST handler to read and update the "Custom Context Menu Options" 6 | 7 | GET example (read) 8 | ``` 9 | curl -k -u 'admin:changeme' https://localhost:8089/services/app_config 10 | ``` 11 | 12 | POST example (update) 13 | ``` 14 | curl -k -u 'admin:changeme' https://localhost:8089/services/app_config -d '[{"label" : "splunkonline" , "url" : "https://www.splunk.com"},{"label" : "simulate attck", "url" : "/splunkd/__raw/services/run_simulation?attack=~Technique_Name~&id=~Technique_ID~"}]' 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /README/commands.conf.spec: -------------------------------------------------------------------------------- 1 | [] 2 | python.version = {default|python|python2|python3} 3 | * Optional setting. Requires 8.0+ 4 | * For Python scripts only, selects which Python version to use. 5 | * Set to either "default" or "python" to use the system-wide default Python 6 | version. 7 | * Optional. 8 | * Default: Not set; uses the system-wide Python version. -------------------------------------------------------------------------------- /README/restmap.conf.spec: -------------------------------------------------------------------------------- 1 | [admin_external:] 2 | python.version={default|python|python2|python3} 3 | * Optional setting. Requires 8.0+ 4 | * For Python scripts only, selects which Python version to use. 5 | * Either "default" or "python" select the system-wide default Python version. 6 | * Optional. 7 | * Default: not set; uses the system-wide Python version. 8 | 9 | [script:] 10 | python.version={default|python|python2|python3} 11 | * Optional setting. Requires 8.0+ 12 | * For Python scripts only, selects which Python version to use. 13 | * Set to either "default" or "python" to use the system-wide default Python 14 | version. 15 | * Optional. 16 | * Default: Not set; uses the system-wide Python version. -------------------------------------------------------------------------------- /README/transforms.conf.spec: -------------------------------------------------------------------------------- 1 | [] 2 | python.version = {default|python|python2|python3} 3 | * Optional setting. Requires 8.0+ 4 | * For Python scripts only, selects which Python version to use. 5 | * Set to either "default" or "python" to use the system-wide default Python 6 | version. 7 | * Optional. 8 | * Default: Not set; uses the system-wide Python version. -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv1.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv1_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv1_1.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv1_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv1_2.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv1_3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv1_3.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv2.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv2_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv2_1.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv2_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv2_2.pdf -------------------------------------------------------------------------------- /appserver/assets/NavigatorLayerFileFormatv3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/NavigatorLayerFileFormatv3.pdf -------------------------------------------------------------------------------- /appserver/assets/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "enterprise_attack_url": "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json", 3 | "pre_attack_url": "https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json", 4 | "mobile_data_url": "https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json", 5 | "taxii_server": { 6 | "enabled": false, 7 | "url": "https://cti-taxii.mitre.org/", 8 | "collections": { 9 | "enterprise_attack": "95ecc380-afe9-11e4-9b6c-751b66dd541e", 10 | "pre_attack": "062767bd-02d2-4b72-84ba-56caef0f8658", 11 | "mobile_attack": "2f669986-b40b-4423-b720-4396ca6a462b" 12 | } 13 | }, 14 | 15 | "domain": "mitre-enterprise", 16 | 17 | "custom_context_menu_items": [ 18 | 19 | ], 20 | 21 | "default_layers": { 22 | "enabled": false, 23 | "urls": ["assets/example.json", "https://raw.githubusercontent.com/mitre-attack/attack-navigator/master/layers/data/samples/Bear_APT.json"] 24 | }, 25 | 26 | "comment_color": "yellow", 27 | 28 | "features": [ 29 | {"name": "tabs", "enabled": true, "description": "Disable to remove the ability to open new tabs."}, 30 | {"name": "selecting_techniques", "enabled": true, "description": "Disable to remove the ability to select techniques."}, 31 | {"name": "header", "enabled": true, "description": "Disable to remove the header containing 'MITRE ATT&CK Navigator' and the link to the help page. The help page can still be accessed from the new tab menu."}, 32 | {"name": "subtechniques", "enabled": true, "description": "Disable to remove all sub-technique features from the interface."}, 33 | {"name": "selection_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ 34 | {"name": "search", "enabled": true, "description": "Disable to remove the technique search panel from the interface."}, 35 | {"name": "multiselect", "enabled": true, "description": "Disable to remove the multiselect panel from interface."}, 36 | {"name": "deselect_all", "enabled": true, "description": "Disable to remove the deselect all button from the interface."} 37 | ]}, 38 | {"name": "layer_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ 39 | {"name": "layer_info", "enabled": true, "description": "Disable to remove the layer info (name, description and metadata) panel from the interface. Note that the layer can still be renamed in the tab."}, 40 | {"name": "download_layer", "enabled": true, "description": "Disable to remove the button to download the layer."}, 41 | {"name": "export_render", "enabled": true, "description": "Disable to the remove the button to render the current layer."}, 42 | {"name": "export_excel", "enabled": true, "description": "Disable to the remove the button to export the current layer to MS Excel (.xlsx) format."}, 43 | {"name": "filters", "enabled": true, "description": "Disable to the remove the filters panel from interface."}, 44 | {"name": "sorting", "enabled": true, "description": "Disable to the remove the sorting button from the interface."}, 45 | {"name": "color_setup", "enabled": true, "description": "Disable to the remove the color setup panel from interface, containing customization controls for scoring gradient and tactic row color."}, 46 | {"name": "toggle_hide_disabled", "enabled": true, "description": "Disable to the remove the hide disabled techniques button from the interface."}, 47 | {"name": "layout_controls", "enabled": true, "description": "Disable to the remove the ability to change the current matrix layout."}, 48 | {"name": "legend", "enabled": true, "description": "Disable to the remove the legend panel from the interface."} 49 | ]}, 50 | {"name": "technique_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ 51 | {"name": "disable_techniques", "enabled": true, "description": "Disable to the remove the ability to disable techniques."}, 52 | {"name": "manual_color", "enabled": true, "description": "Disable to the remove the ability to assign manual colors to techniques."}, 53 | {"name": "scoring", "enabled": true, "description": "Disable to the remove the ability to score techniques."}, 54 | {"name": "comments", "enabled": true, "description": "Disable to the remove the ability to add comments to techniques."}, 55 | {"name": "clear_annotations", "enabled": true, "description": "Disable to remove the button to clear all annotations on the selected techniques."} 56 | ]} 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /appserver/assets/icons/baseline-grid_on-24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_camera_alt_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_check_box_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_check_box_outline_blank_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_clear_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_clear_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_close_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_color_lens_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_content_copy_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_description_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_done_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_done_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_file_download_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_file_upload_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_file_upload_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_filter_list_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_format_color_fill_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_format_color_fill_black_nobottom_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_format_color_fill_gray_nobottom_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_format_size_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_insert_chart_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_insert_chart_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_insert_comment_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_insert_comment_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_keyboard_arrow_down_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_keyboard_arrow_right_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_keyboard_arrow_up_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_layers_clear_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_layers_clear_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_lock_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_lock_open_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_palette_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_photo_size_select_large_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_playlist_add_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_playlist_add_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_refresh_lg_off_24px.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_refresh_lg_on_24px.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_remove_circle_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_save_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_save_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_search_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_search_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_sort_alphabetically_ascending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | A 7 | Z 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_sort_alphabetically_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | A 7 | 8 | 9 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_sort_alphabetically_descending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Z 7 | A 8 | 9 | 10 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_sort_numerically_ascending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 1 7 | 2 8 | 9 | 10 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_sort_numerically_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | # 7 | 8 | 9 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_sort_numerically_descending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 2 7 | 1 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_texture_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_texture_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_view_large_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_view_list_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_view_list_grey_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_view_medium_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_view_small_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_visibility_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_visibility_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/assets/icons/ic_visibility_off_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/unfold_less_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/unfold_less_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/unfold_more_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/icons/unfold_more_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/assets/image_scoreVariableExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/assets/image_scoreVariableExample.png -------------------------------------------------------------------------------- /appserver/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/favicon.ico -------------------------------------------------------------------------------- /appserver/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ATT&CK® Navigator 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv1.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv1_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv1_1.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv1_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv1_2.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv1_3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv1_3.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv2.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv2_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv2_1.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv2_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv2_2.pdf -------------------------------------------------------------------------------- /appserver/static/assets/NavigatorLayerFileFormatv3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/NavigatorLayerFileFormatv3.pdf -------------------------------------------------------------------------------- /appserver/static/assets/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "enterprise_attack_url": "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json", 3 | "pre_attack_url": "https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json", 4 | "mobile_data_url": "https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json", 5 | "taxii_server": { 6 | "enabled": false, 7 | "url": "https://cti-taxii.mitre.org/", 8 | "collections": { 9 | "enterprise_attack": "95ecc380-afe9-11e4-9b6c-751b66dd541e", 10 | "pre_attack": "062767bd-02d2-4b72-84ba-56caef0f8658", 11 | "mobile_attack": "2f669986-b40b-4423-b720-4396ca6a462b" 12 | } 13 | }, 14 | 15 | "domain": "mitre-enterprise", 16 | 17 | "custom_context_menu_items": [ 18 | {"label": "run test", "url": "/app/SA-attck_nav/simulation_runner?form.tech_name={{technique_name}}&form.test_id={{technique_attackID}}"}, 19 | {"label": "view executor", "url": "https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/{{technique_attackID}}"} 20 | ], 21 | 22 | "default_layers": { 23 | "enabled": true, 24 | "urls": ["/splunkd/__raw/servicesNS/Nobody/SA-attck_nav/storage/collections/data/attack_layers/default_layer"] 25 | }, 26 | 27 | "comment_color": "yellow", 28 | 29 | "features": [ 30 | {"name": "tabs", "enabled": true, "description": "Disable to remove the ability to open new tabs."}, 31 | {"name": "selecting_techniques", "enabled": true, "description": "Disable to remove the ability to select techniques."}, 32 | {"name": "header", "enabled": true, "description": "Disable to remove the header containing 'MITRE ATT&CK Navigator' and the link to the help page. The help page can still be accessed from the new tab menu."}, 33 | {"name": "subtechniques", "enabled": true, "description": "Disable to remove all sub-technique features from the interface."}, 34 | {"name": "selection_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ 35 | {"name": "search", "enabled": true, "description": "Disable to remove the technique search panel from the interface."}, 36 | {"name": "multiselect", "enabled": true, "description": "Disable to remove the multiselect panel from interface."}, 37 | {"name": "deselect_all", "enabled": true, "description": "Disable to remove the deselect all button from the interface."} 38 | ]}, 39 | {"name": "layer_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ 40 | {"name": "layer_info", "enabled": true, "description": "Disable to remove the layer info (name, description and metadata) panel from the interface. Note that the layer can still be renamed in the tab."}, 41 | {"name": "download_layer", "enabled": true, "description": "Disable to remove the button to download the layer."}, 42 | {"name": "export_render", "enabled": true, "description": "Disable to the remove the button to render the current layer."}, 43 | {"name": "export_excel", "enabled": true, "description": "Disable to the remove the button to export the current layer to MS Excel (.xlsx) format."}, 44 | {"name": "filters", "enabled": true, "description": "Disable to the remove the filters panel from interface."}, 45 | {"name": "sorting", "enabled": true, "description": "Disable to the remove the sorting button from the interface."}, 46 | {"name": "color_setup", "enabled": true, "description": "Disable to the remove the color setup panel from interface, containing customization controls for scoring gradient and tactic row color."}, 47 | {"name": "toggle_hide_disabled", "enabled": true, "description": "Disable to the remove the hide disabled techniques button from the interface."}, 48 | {"name": "layout_controls", "enabled": true, "description": "Disable to the remove the ability to change the current matrix layout."}, 49 | {"name": "legend", "enabled": true, "description": "Disable to the remove the legend panel from the interface."} 50 | ]}, 51 | {"name": "technique_controls", "enabled": true, "description": "Disable to to disable all subfeatures", "subfeatures": [ 52 | {"name": "disable_techniques", "enabled": true, "description": "Disable to the remove the ability to disable techniques."}, 53 | {"name": "manual_color", "enabled": true, "description": "Disable to the remove the ability to assign manual colors to techniques."}, 54 | {"name": "scoring", "enabled": true, "description": "Disable to the remove the ability to score techniques."}, 55 | {"name": "comments", "enabled": true, "description": "Disable to the remove the ability to add comments to techniques."}, 56 | {"name": "clear_annotations", "enabled": true, "description": "Disable to remove the button to clear all annotations on the selected techniques."} 57 | ]} 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/baseline-grid_on-24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_camera_alt_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_check_box_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_check_box_outline_blank_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_clear_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_clear_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_close_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_color_lens_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_content_copy_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_description_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_done_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_done_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_file_download_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_file_upload_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_file_upload_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_filter_list_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_format_color_fill_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_format_color_fill_black_nobottom_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_format_color_fill_gray_nobottom_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_format_size_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_insert_chart_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_insert_chart_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_insert_comment_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_insert_comment_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_keyboard_arrow_down_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_keyboard_arrow_right_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_keyboard_arrow_up_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_layers_clear_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_layers_clear_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_lock_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_lock_open_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_palette_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_photo_size_select_large_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_playlist_add_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_playlist_add_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_refresh_lg_off_24px.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_refresh_lg_on_24px.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_remove_circle_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_save_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_save_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_search_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_search_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_sort_alphabetically_ascending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | A 7 | Z 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_sort_alphabetically_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | A 7 | 8 | 9 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_sort_alphabetically_descending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Z 7 | A 8 | 9 | 10 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_sort_numerically_ascending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 1 7 | 2 8 | 9 | 10 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_sort_numerically_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | # 7 | 8 | 9 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_sort_numerically_descending_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 2 7 | 1 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_texture_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_texture_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_view_large_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_view_list_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_view_list_grey_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_view_medium_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_view_small_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_visibility_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_visibility_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/ic_visibility_off_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/unfold_less_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/unfold_less_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/unfold_more_black_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/icons/unfold_more_gray_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appserver/static/assets/image_scoreVariableExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/assets/image_scoreVariableExample.png -------------------------------------------------------------------------------- /appserver/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/appserver/static/favicon.ico -------------------------------------------------------------------------------- /appserver/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ATT&CK® Navigator 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /appserver/static/runtime.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // install a JSONP callback for chunk loading 3 | /******/ function webpackJsonpCallback(data) { 4 | /******/ var chunkIds = data[0]; 5 | /******/ var moreModules = data[1]; 6 | /******/ var executeModules = data[2]; 7 | /******/ 8 | /******/ // add "moreModules" to the modules object, 9 | /******/ // then flag all "chunkIds" as loaded and fire callback 10 | /******/ var moduleId, chunkId, i = 0, resolves = []; 11 | /******/ for(;i < chunkIds.length; i++) { 12 | /******/ chunkId = chunkIds[i]; 13 | /******/ if(installedChunks[chunkId]) { 14 | /******/ resolves.push(installedChunks[chunkId][0]); 15 | /******/ } 16 | /******/ installedChunks[chunkId] = 0; 17 | /******/ } 18 | /******/ for(moduleId in moreModules) { 19 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 20 | /******/ modules[moduleId] = moreModules[moduleId]; 21 | /******/ } 22 | /******/ } 23 | /******/ if(parentJsonpFunction) parentJsonpFunction(data); 24 | /******/ 25 | /******/ while(resolves.length) { 26 | /******/ resolves.shift()(); 27 | /******/ } 28 | /******/ 29 | /******/ // add entry modules from loaded chunk to deferred list 30 | /******/ deferredModules.push.apply(deferredModules, executeModules || []); 31 | /******/ 32 | /******/ // run deferred modules when all chunks ready 33 | /******/ return checkDeferredModules(); 34 | /******/ }; 35 | /******/ function checkDeferredModules() { 36 | /******/ var result; 37 | /******/ for(var i = 0; i < deferredModules.length; i++) { 38 | /******/ var deferredModule = deferredModules[i]; 39 | /******/ var fulfilled = true; 40 | /******/ for(var j = 1; j < deferredModule.length; j++) { 41 | /******/ var depId = deferredModule[j]; 42 | /******/ if(installedChunks[depId] !== 0) fulfilled = false; 43 | /******/ } 44 | /******/ if(fulfilled) { 45 | /******/ deferredModules.splice(i--, 1); 46 | /******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); 47 | /******/ } 48 | /******/ } 49 | /******/ return result; 50 | /******/ } 51 | /******/ 52 | /******/ // The module cache 53 | /******/ var installedModules = {}; 54 | /******/ 55 | /******/ // object to store loaded and loading chunks 56 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 57 | /******/ // Promise = chunk loading, 0 = chunk loaded 58 | /******/ var installedChunks = { 59 | /******/ "runtime": 0 60 | /******/ }; 61 | /******/ 62 | /******/ var deferredModules = []; 63 | /******/ 64 | /******/ // The require function 65 | /******/ function __webpack_require__(moduleId) { 66 | /******/ 67 | /******/ // Check if module is in cache 68 | /******/ if(installedModules[moduleId]) { 69 | /******/ return installedModules[moduleId].exports; 70 | /******/ } 71 | /******/ // Create a new module (and put it into the cache) 72 | /******/ var module = installedModules[moduleId] = { 73 | /******/ i: moduleId, 74 | /******/ l: false, 75 | /******/ exports: {} 76 | /******/ }; 77 | /******/ 78 | /******/ // Execute the module function 79 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 80 | /******/ 81 | /******/ // Flag the module as loaded 82 | /******/ module.l = true; 83 | /******/ 84 | /******/ // Return the exports of the module 85 | /******/ return module.exports; 86 | /******/ } 87 | /******/ 88 | /******/ 89 | /******/ // expose the modules object (__webpack_modules__) 90 | /******/ __webpack_require__.m = modules; 91 | /******/ 92 | /******/ // expose the module cache 93 | /******/ __webpack_require__.c = installedModules; 94 | /******/ 95 | /******/ // define getter function for harmony exports 96 | /******/ __webpack_require__.d = function(exports, name, getter) { 97 | /******/ if(!__webpack_require__.o(exports, name)) { 98 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 99 | /******/ } 100 | /******/ }; 101 | /******/ 102 | /******/ // define __esModule on exports 103 | /******/ __webpack_require__.r = function(exports) { 104 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 105 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 106 | /******/ } 107 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 108 | /******/ }; 109 | /******/ 110 | /******/ // create a fake namespace object 111 | /******/ // mode & 1: value is a module id, require it 112 | /******/ // mode & 2: merge all properties of value into the ns 113 | /******/ // mode & 4: return value when already ns object 114 | /******/ // mode & 8|1: behave like require 115 | /******/ __webpack_require__.t = function(value, mode) { 116 | /******/ if(mode & 1) value = __webpack_require__(value); 117 | /******/ if(mode & 8) return value; 118 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 119 | /******/ var ns = Object.create(null); 120 | /******/ __webpack_require__.r(ns); 121 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 122 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 123 | /******/ return ns; 124 | /******/ }; 125 | /******/ 126 | /******/ // getDefaultExport function for compatibility with non-harmony modules 127 | /******/ __webpack_require__.n = function(module) { 128 | /******/ var getter = module && module.__esModule ? 129 | /******/ function getDefault() { return module['default']; } : 130 | /******/ function getModuleExports() { return module; }; 131 | /******/ __webpack_require__.d(getter, 'a', getter); 132 | /******/ return getter; 133 | /******/ }; 134 | /******/ 135 | /******/ // Object.prototype.hasOwnProperty.call 136 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 137 | /******/ 138 | /******/ // __webpack_public_path__ 139 | /******/ __webpack_require__.p = ""; 140 | /******/ 141 | /******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; 142 | /******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); 143 | /******/ jsonpArray.push = webpackJsonpCallback; 144 | /******/ jsonpArray = jsonpArray.slice(); 145 | /******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); 146 | /******/ var parentJsonpFunction = oldJsonpFunction; 147 | /******/ 148 | /******/ 149 | /******/ // run deferred modules from other chunks 150 | /******/ checkDeferredModules(); 151 | /******/ }) 152 | /************************************************************************/ 153 | /******/ ([]); 154 | //# sourceMappingURL=runtime.js.map -------------------------------------------------------------------------------- /appserver/static/runtime.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/bootstrap"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAiB,4BAA4B;AAC7C;AACA;AACA,0BAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;AACA;AACA;AACA,wBAAgB,uBAAuB;AACvC;;;AAGA;AACA","file":"runtime.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"runtime\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// run deferred modules from other chunks\n \tcheckDeferredModules();\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /appserver/templates/attack.html: -------------------------------------------------------------------------------- 1 | <%! 2 | from splunk.appserver.mrsparkle.lib import util 3 | 4 | %>\ 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ATT&CK BOARD 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 |
36 |
37 | 38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /appserver/templates/config.html: -------------------------------------------------------------------------------- 1 | <%! 2 | from splunk.appserver.mrsparkle.lib import util 3 | 4 | %>\ 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Attack Navigator 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /bin/README: -------------------------------------------------------------------------------- 1 | This Splunk App is intended to implement the [ATTCK navigator](https://github.com/mitre/attack-navigator) inside of Splunkweb as an "app" 2 | It also includes a REST handler to read and update the "Custom Context Menu Options" 3 | 4 | GET example (read) 5 | ``` 6 | curl -k -u 'admin:changeme' https://localhost:8089/services/app_config 7 | ``` 8 | 9 | POST example (update) 10 | ``` 11 | curl -k -u 'admin:changeme' https://localhost:8089/services/app_config -d '[{"label" : "splunkonline" , "url" : "https://www.splunk.com"},{"label" : "simulate attck", "url" : "/splunkd/__raw/services/run_simulation?attack=~Technique_Name~&id=~Technique_ID~"}]' 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /bin/__pycache__/base_layer.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/bin/__pycache__/base_layer.cpython-37.pyc -------------------------------------------------------------------------------- /bin/__pycache__/manage_app_config.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/bin/__pycache__/manage_app_config.cpython-37.pyc -------------------------------------------------------------------------------- /bin/manage_app_config.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import traceback 5 | import splunk.rest as rest 6 | #just set up reference to our apps on-disk location explicitly 7 | #so we can import local libs as needed 8 | from splunk.clilib.bundle_paths import make_splunkhome_path 9 | assets_path = make_splunkhome_path(["etc", "apps", "SA-attck_nav","appserver","static","assets"]) 10 | config_file = "/config.json" 11 | 12 | if sys.platform == "win32": 13 | import msvcrt 14 | # Binary mode is required for persistent mode on Windows. 15 | msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) 16 | msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) 17 | msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY) 18 | 19 | 20 | #Splunk's Persistent REST handler class 21 | from splunk.persistconn.application import PersistentServerConnectionApplication 22 | 23 | 24 | class ConfHandler(PersistentServerConnectionApplication): 25 | def __init__(self, command_line, command_arg): 26 | PersistentServerConnectionApplication.__init__(self) 27 | 28 | def handle(self, in_string): 29 | ''' 30 | config = open(assets_path+config_file,'r') 31 | config_json = json.loads(config.read()) 32 | config.close() 33 | return {'payload': config_json["custom_context_menu_items"] , # Payload of the request. 34 | 'status': 200 # HTTP status code 35 | } 36 | ''' 37 | #in_string is a string...go figure 38 | #need to turn into dict to work with more easily 39 | in_string = json.loads(in_string) 40 | session_key = in_string["session"]["authtoken"] 41 | try: 42 | #get command - simply returns the values w/in the config.json 43 | # 44 | if in_string['method'] == "GET": 45 | config = open(assets_path+config_file,'r') 46 | config_json = json.loads(config.read()) 47 | config.close() 48 | return {'payload': config_json, # Payload of the request. 49 | 'status': 200 # HTTP status code 50 | } 51 | 52 | if in_string['method'] == "POST": 53 | post_data = in_string["payload"] 54 | #decode the data POSTed to the endpoint as a dict 55 | #the underlying data in payload is treated like a string w/in the 56 | #overall dict 57 | post_data = json.loads(post_data) 58 | #if our payload is larger than 5 items, lets just return an error 59 | #as we want to limit the number of menu items stored in the Config file 60 | if len(post_data) > 5: 61 | return {'payload': {"error" : "max number of items is 5, you sent {}".format(len(post_data)) } , # Payload of the request. 62 | 'status': 500 # HTTP status code 63 | } 64 | 65 | #placeholder code for doing input sanitzation 66 | #will need to compile regexes for this at some point and test 67 | #commenting out for now 68 | ''' 69 | urls = {} 70 | urls["urls"] = [] 71 | urls["menus"] = [] 72 | 73 | for item in post_data: 74 | urls["urls"].append(item["url"]) 75 | urls["menus"].append(item["label"]) 76 | ''' 77 | #lets open the file, and then replace it with the updated dict info 78 | config = open(assets_path+config_file,'r+') 79 | config_json = json.loads(config.read()) 80 | config_json["custom_context_menu_items"]=post_data 81 | config.seek(0) 82 | config.truncate() 83 | config.write(json.dumps(config_json)) 84 | config.close() 85 | 86 | return {'payload': {'success' : 'configuration file updated'} , # Payload of the request. 87 | 'status': 200 # HTTP status code 88 | } 89 | 90 | 91 | 92 | except Exception as e: 93 | exc_type, exc_value, exc_traceback = sys.exc_info() 94 | tb = repr(traceback.format_exception(exc_type, exc_value, exc_traceback)) 95 | return {'payload' : {'error':e.message , 'tb' : str(tb) } ,'status': 500} -------------------------------------------------------------------------------- /bin/readme.txt: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. -------------------------------------------------------------------------------- /default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Att&ckSim 11 | 12 | [launcher] 13 | author = Tim Frazier & Kyle Champlin 14 | description = run simulations to test your Att&ck saavy 15 | version = 0.0.2 16 | 17 | -------------------------------------------------------------------------------- /default/collections.conf: -------------------------------------------------------------------------------- 1 | # layer file definition as a KVStore collection 2 | # types supported number, bool, string, time 3 | [attack_layers] 4 | enforceTypes = false 5 | field.name = string 6 | field.version = string 7 | field.domain = string 8 | field.description = string 9 | field.sorting = number 10 | field.viewMode = number 11 | field.hideDisabled = bool 12 | field.techniques.techniqueID = string 13 | field.techniques.tactic = string 14 | field.techniques.color = string 15 | field.techniques.comment = string 16 | field.techniques.score = number 17 | field.techniques.enabled = bool 18 | field.techniques.metadata.name = string 19 | field.techniques.metadata.value = string 20 | field.gradient.colors = string 21 | field.gradient.minValue = number 22 | field.gradient.maxValue = number -------------------------------------------------------------------------------- /default/commands.conf: -------------------------------------------------------------------------------- 1 | [genatklayer] 2 | python.version = python3 3 | chunked = true 4 | filename = generate_attack_layer.py 5 | -------------------------------------------------------------------------------- /default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /default/data/ui/views/README: -------------------------------------------------------------------------------- 1 | Add all the views that your app needs in this directory 2 | -------------------------------------------------------------------------------- /default/data/ui/views/attack.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /default/data/ui/views/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /default/data/ui/views/overview.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | This app is designed to provide a fully functional import of the MITRE ATT&CK Navigator directly into Splunk. This app and its associated project provide a way to execute Atomic Red Team on workstations using Phantom as the automation harness. Upon loading the nav the first time, you will get an error if you do not "Reset" the master layer using the radio selector and submit button below. 4 | 5 | 6 | 7 | Once you've reset the master layer (if necessary), this button will take you back to the ATT&CK Navigator. 8 | 9 | ATT&CK Nav 10 | 11 | 12 | 13 | 14 | 15 | 16 |

Additional help can be found at this github site:

17 | AdvSim Project Home 18 | 19 |
20 |
21 |
22 | 23 | 24 | Reset 25 | 26 |
27 | 28 | 29 | 30 | 31 | | makeresults 1 | genatklayer reset=$reset$ 32 | -24h@h 33 | now 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 |
42 |
43 | -------------------------------------------------------------------------------- /default/restmap.conf: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # rest handler to handle updating and editing the configuration file6 3 | ############################################################################# 4 | [script:app_config] 5 | python.version = python3 6 | match = /attck/app_config 7 | script = manage_app_config.py 8 | scripttype = persist 9 | handler = manage_app_config.ConfHandler 10 | requireAuthentication = true 11 | output_modes = JSON 12 | passPayload = true 13 | passHttpHeaders = true 14 | passHttpCookies = true 15 | -------------------------------------------------------------------------------- /default/searchbnf.conf: -------------------------------------------------------------------------------- 1 | [genatklayer-command] 2 | syntax = genatklayer ()* 3 | shortdesc = Generate AttackNav Layers 4 | description = Scans results for mitre attack techniques and generates a layer file in KVstore 5 | usage = public 6 | example1 = genatklayer atkfield="mitre_technique" 7 | comment1 = Reads the values in the field "mitre_technique" to manipulate the layer file 8 | example2 = genatklayer reset=true 9 | comment2 = Resets the default layer in kvstore 10 | example3 = genatklayer atkfield="mtire_technique" layername="mynewlayer" 11 | comment3 = Creates a new layer in kvstore with the name value 12 | 13 | [genatklayer-options] 14 | syntax = atkfield= | layername= | reset= 15 | -------------------------------------------------------------------------------- /default/transforms.conf: -------------------------------------------------------------------------------- 1 | [attck_assets] 2 | filename = attck_assets.csv -------------------------------------------------------------------------------- /default/web.conf: -------------------------------------------------------------------------------- 1 | # Expose the configuration endpoint via Splunkweb on port 8000. 2 | [expose:attckappconfig] 3 | methods = GET, POST 4 | pattern = /attck/app_config 5 | -------------------------------------------------------------------------------- /lib/splunklib/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2015 Splunk, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | """Python library for Splunk.""" 16 | 17 | from __future__ import absolute_import 18 | from splunklib.six.moves import map 19 | __version_info__ = (1, 6, 6) 20 | __version__ = ".".join(map(str, __version_info__)) 21 | -------------------------------------------------------------------------------- /lib/splunklib/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/lib/splunklib/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /lib/splunklib/__pycache__/binding.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/lib/splunklib/__pycache__/binding.cpython-37.pyc -------------------------------------------------------------------------------- /lib/splunklib/__pycache__/client.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/lib/splunklib/__pycache__/client.cpython-37.pyc -------------------------------------------------------------------------------- /lib/splunklib/__pycache__/data.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/lib/splunklib/__pycache__/data.cpython-37.pyc -------------------------------------------------------------------------------- /lib/splunklib/__pycache__/six.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daveherrald/SA-attck_nav/cb3db0f06a83860fb7f72f59696d7e6ea099371c/lib/splunklib/__pycache__/six.cpython-37.pyc -------------------------------------------------------------------------------- /lib/splunklib/data.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2015 Splunk, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | """The **splunklib.data** module reads the responses from splunkd in Atom Feed 16 | format, which is the format used by most of the REST API. 17 | """ 18 | 19 | from __future__ import absolute_import 20 | import sys 21 | from xml.etree.ElementTree import XML 22 | from splunklib import six 23 | 24 | __all__ = ["load"] 25 | 26 | # LNAME refers to element names without namespaces; XNAME is the same 27 | # name, but with an XML namespace. 28 | LNAME_DICT = "dict" 29 | LNAME_ITEM = "item" 30 | LNAME_KEY = "key" 31 | LNAME_LIST = "list" 32 | 33 | XNAMEF_REST = "{http://dev.splunk.com/ns/rest}%s" 34 | XNAME_DICT = XNAMEF_REST % LNAME_DICT 35 | XNAME_ITEM = XNAMEF_REST % LNAME_ITEM 36 | XNAME_KEY = XNAMEF_REST % LNAME_KEY 37 | XNAME_LIST = XNAMEF_REST % LNAME_LIST 38 | 39 | # Some responses don't use namespaces (eg: search/parse) so we look for 40 | # both the extended and local versions of the following names. 41 | 42 | def isdict(name): 43 | return name == XNAME_DICT or name == LNAME_DICT 44 | 45 | def isitem(name): 46 | return name == XNAME_ITEM or name == LNAME_ITEM 47 | 48 | def iskey(name): 49 | return name == XNAME_KEY or name == LNAME_KEY 50 | 51 | def islist(name): 52 | return name == XNAME_LIST or name == LNAME_LIST 53 | 54 | def hasattrs(element): 55 | return len(element.attrib) > 0 56 | 57 | def localname(xname): 58 | rcurly = xname.find('}') 59 | return xname if rcurly == -1 else xname[rcurly+1:] 60 | 61 | def load(text, match=None): 62 | """This function reads a string that contains the XML of an Atom Feed, then 63 | returns the 64 | data in a native Python structure (a ``dict`` or ``list``). If you also 65 | provide a tag name or path to match, only the matching sub-elements are 66 | loaded. 67 | 68 | :param text: The XML text to load. 69 | :type text: ``string`` 70 | :param match: A tag name or path to match (optional). 71 | :type match: ``string`` 72 | """ 73 | if text is None: return None 74 | text = text.strip() 75 | if len(text) == 0: return None 76 | nametable = { 77 | 'namespaces': [], 78 | 'names': {} 79 | } 80 | 81 | # Convert to unicode encoding in only python 2 for xml parser 82 | if(sys.version_info < (3, 0, 0) and isinstance(text, unicode)): 83 | text = text.encode('utf-8') 84 | 85 | root = XML(text) 86 | items = [root] if match is None else root.findall(match) 87 | count = len(items) 88 | if count == 0: 89 | return None 90 | elif count == 1: 91 | return load_root(items[0], nametable) 92 | else: 93 | return [load_root(item, nametable) for item in items] 94 | 95 | # Load the attributes of the given element. 96 | def load_attrs(element): 97 | if not hasattrs(element): return None 98 | attrs = record() 99 | for key, value in six.iteritems(element.attrib): 100 | attrs[key] = value 101 | return attrs 102 | 103 | # Parse a element and return a Python dict 104 | def load_dict(element, nametable = None): 105 | value = record() 106 | children = list(element) 107 | for child in children: 108 | assert iskey(child.tag) 109 | name = child.attrib["name"] 110 | value[name] = load_value(child, nametable) 111 | return value 112 | 113 | # Loads the given elements attrs & value into single merged dict. 114 | def load_elem(element, nametable=None): 115 | name = localname(element.tag) 116 | attrs = load_attrs(element) 117 | value = load_value(element, nametable) 118 | if attrs is None: return name, value 119 | if value is None: return name, attrs 120 | # If value is simple, merge into attrs dict using special key 121 | if isinstance(value, six.string_types): 122 | attrs["$text"] = value 123 | return name, attrs 124 | # Both attrs & value are complex, so merge the two dicts, resolving collisions. 125 | collision_keys = [] 126 | for key, val in six.iteritems(attrs): 127 | if key in value and key in collision_keys: 128 | value[key].append(val) 129 | elif key in value and key not in collision_keys: 130 | value[key] = [value[key], val] 131 | collision_keys.append(key) 132 | else: 133 | value[key] = val 134 | return name, value 135 | 136 | # Parse a element and return a Python list 137 | def load_list(element, nametable=None): 138 | assert islist(element.tag) 139 | value = [] 140 | children = list(element) 141 | for child in children: 142 | assert isitem(child.tag) 143 | value.append(load_value(child, nametable)) 144 | return value 145 | 146 | # Load the given root element. 147 | def load_root(element, nametable=None): 148 | tag = element.tag 149 | if isdict(tag): return load_dict(element, nametable) 150 | if islist(tag): return load_list(element, nametable) 151 | k, v = load_elem(element, nametable) 152 | return Record.fromkv(k, v) 153 | 154 | # Load the children of the given element. 155 | def load_value(element, nametable=None): 156 | children = list(element) 157 | count = len(children) 158 | 159 | # No children, assume a simple text value 160 | if count == 0: 161 | text = element.text 162 | if text is None: 163 | return None 164 | text = text.strip() 165 | if len(text) == 0: 166 | return None 167 | return text 168 | 169 | # Look for the special case of a single well-known structure 170 | if count == 1: 171 | child = children[0] 172 | tag = child.tag 173 | if isdict(tag): return load_dict(child, nametable) 174 | if islist(tag): return load_list(child, nametable) 175 | 176 | value = record() 177 | for child in children: 178 | name, item = load_elem(child, nametable) 179 | # If we have seen this name before, promote the value to a list 180 | if name in value: 181 | current = value[name] 182 | if not isinstance(current, list): 183 | value[name] = [current] 184 | value[name].append(item) 185 | else: 186 | value[name] = item 187 | 188 | return value 189 | 190 | # A generic utility that enables "dot" access to dicts 191 | class Record(dict): 192 | """This generic utility class enables dot access to members of a Python 193 | dictionary. 194 | 195 | Any key that is also a valid Python identifier can be retrieved as a field. 196 | So, for an instance of ``Record`` called ``r``, ``r.key`` is equivalent to 197 | ``r['key']``. A key such as ``invalid-key`` or ``invalid.key`` cannot be 198 | retrieved as a field, because ``-`` and ``.`` are not allowed in 199 | identifiers. 200 | 201 | Keys of the form ``a.b.c`` are very natural to write in Python as fields. If 202 | a group of keys shares a prefix ending in ``.``, you can retrieve keys as a 203 | nested dictionary by calling only the prefix. For example, if ``r`` contains 204 | keys ``'foo'``, ``'bar.baz'``, and ``'bar.qux'``, ``r.bar`` returns a record 205 | with the keys ``baz`` and ``qux``. If a key contains multiple ``.``, each 206 | one is placed into a nested dictionary, so you can write ``r.bar.qux`` or 207 | ``r['bar.qux']`` interchangeably. 208 | """ 209 | sep = '.' 210 | 211 | def __call__(self, *args): 212 | if len(args) == 0: return self 213 | return Record((key, self[key]) for key in args) 214 | 215 | def __getattr__(self, name): 216 | try: 217 | return self[name] 218 | except KeyError: 219 | raise AttributeError(name) 220 | 221 | def __delattr__(self, name): 222 | del self[name] 223 | 224 | def __setattr__(self, name, value): 225 | self[name] = value 226 | 227 | @staticmethod 228 | def fromkv(k, v): 229 | result = record() 230 | result[k] = v 231 | return result 232 | 233 | def __getitem__(self, key): 234 | if key in self: 235 | return dict.__getitem__(self, key) 236 | key += self.sep 237 | result = record() 238 | for k,v in six.iteritems(self): 239 | if not k.startswith(key): 240 | continue 241 | suffix = k[len(key):] 242 | if '.' in suffix: 243 | ks = suffix.split(self.sep) 244 | z = result 245 | for x in ks[:-1]: 246 | if x not in z: 247 | z[x] = record() 248 | z = z[x] 249 | z[ks[-1]] = v 250 | else: 251 | result[suffix] = v 252 | if len(result) == 0: 253 | raise KeyError("No key or prefix: %s" % key) 254 | return result 255 | 256 | 257 | def record(value=None): 258 | """This function returns a :class:`Record` instance constructed with an 259 | initial value that you provide. 260 | 261 | :param `value`: An initial record value. 262 | :type `value`: ``dict`` 263 | """ 264 | if value is None: value = {} 265 | return Record(value) 266 | 267 | -------------------------------------------------------------------------------- /lib/splunklib/modularinput/__init__.py: -------------------------------------------------------------------------------- 1 | """The following imports allow these classes to be imported via 2 | the splunklib.modularinput package like so: 3 | 4 | from splunklib.modularinput import * 5 | """ 6 | from .argument import Argument 7 | from .event import Event 8 | from .event_writer import EventWriter 9 | from .input_definition import InputDefinition 10 | from .scheme import Scheme 11 | from .script import Script 12 | from .validation_definition import ValidationDefinition 13 | -------------------------------------------------------------------------------- /lib/splunklib/modularinput/argument.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2015 Splunk, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from __future__ import absolute_import 16 | try: 17 | import xml.etree.ElementTree as ET 18 | except ImportError: 19 | import xml.etree.cElementTree as ET 20 | 21 | class Argument(object): 22 | """Class representing an argument to a modular input kind. 23 | 24 | ``Argument`` is meant to be used with ``Scheme`` to generate an XML 25 | definition of the modular input kind that Splunk understands. 26 | 27 | ``name`` is the only required parameter for the constructor. 28 | 29 | **Example with least parameters**:: 30 | 31 | arg1 = Argument(name="arg1") 32 | 33 | **Example with all parameters**:: 34 | 35 | arg2 = Argument( 36 | name="arg2", 37 | description="This is an argument with lots of parameters", 38 | validation="is_pos_int('some_name')", 39 | data_type=Argument.data_type_number, 40 | required_on_edit=True, 41 | required_on_create=True 42 | ) 43 | """ 44 | 45 | # Constant values, do not change. 46 | # These should be used for setting the value of an Argument object's data_type field. 47 | data_type_boolean = "BOOLEAN" 48 | data_type_number = "NUMBER" 49 | data_type_string = "STRING" 50 | 51 | def __init__(self, name, description=None, validation=None, 52 | data_type=data_type_string, required_on_edit=False, required_on_create=False, title=None): 53 | """ 54 | :param name: ``string``, identifier for this argument in Splunk. 55 | :param description: ``string``, human-readable description of the argument. 56 | :param validation: ``string`` specifying how the argument should be validated, if using internal validation. 57 | If using external validation, this will be ignored. 58 | :param data_type: ``string``, data type of this field; use the class constants. 59 | "data_type_boolean", "data_type_number", or "data_type_string". 60 | :param required_on_edit: ``Boolean``, whether this arg is required when editing an existing modular input of this kind. 61 | :param required_on_create: ``Boolean``, whether this arg is required when creating a modular input of this kind. 62 | :param title: ``String``, a human-readable title for the argument. 63 | """ 64 | self.name = name 65 | self.description = description 66 | self.validation = validation 67 | self.data_type = data_type 68 | self.required_on_edit = required_on_edit 69 | self.required_on_create = required_on_create 70 | self.title = title 71 | 72 | def add_to_document(self, parent): 73 | """Adds an ``Argument`` object to this ElementTree document. 74 | 75 | Adds an subelement to the parent element, typically 76 | and sets up its subelements with their respective text. 77 | 78 | :param parent: An ``ET.Element`` to be the parent of a new subelement 79 | :returns: An ``ET.Element`` object representing this argument. 80 | """ 81 | arg = ET.SubElement(parent, "arg") 82 | arg.set("name", self.name) 83 | 84 | if self.title is not None: 85 | ET.SubElement(arg, "title").text = self.title 86 | 87 | if self.description is not None: 88 | ET.SubElement(arg, "description").text = self.description 89 | 90 | if self.validation is not None: 91 | ET.SubElement(arg, "validation").text = self.validation 92 | 93 | # add all other subelements to this Argument, represented by (tag, text) 94 | subelements = [ 95 | ("data_type", self.data_type), 96 | ("required_on_edit", self.required_on_edit), 97 | ("required_on_create", self.required_on_create) 98 | ] 99 | 100 | for name, value in subelements: 101 | ET.SubElement(arg, name).text = str(value).lower() 102 | 103 | return arg -------------------------------------------------------------------------------- /lib/splunklib/modularinput/event.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2015 Splunk, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from __future__ import absolute_import 16 | try: 17 | import xml.etree.cElementTree as ET 18 | except ImportError as ie: 19 | import xml.etree.ElementTree as ET 20 | 21 | class Event(object): 22 | """Represents an event or fragment of an event to be written by this modular input to Splunk. 23 | 24 | To write an input to a stream, call the ``write_to`` function, passing in a stream. 25 | """ 26 | def __init__(self, data=None, stanza=None, time=None, host=None, index=None, source=None, 27 | sourcetype=None, done=True, unbroken=True): 28 | """There are no required parameters for constructing an Event 29 | 30 | **Example with minimal configuration**:: 31 | 32 | my_event = Event( 33 | data="This is a test of my new event.", 34 | stanza="myStanzaName", 35 | time="%.3f" % 1372187084.000 36 | ) 37 | 38 | **Example with full configuration**:: 39 | 40 | excellent_event = Event( 41 | data="This is a test of my excellent event.", 42 | stanza="excellenceOnly", 43 | time="%.3f" % 1372274622.493, 44 | host="localhost", 45 | index="main", 46 | source="Splunk", 47 | sourcetype="misc", 48 | done=True, 49 | unbroken=True 50 | ) 51 | 52 | :param data: ``string``, the event's text. 53 | :param stanza: ``string``, name of the input this event should be sent to. 54 | :param time: ``float``, time in seconds, including up to 3 decimal places to represent milliseconds. 55 | :param host: ``string``, the event's host, ex: localhost. 56 | :param index: ``string``, the index this event is specified to write to, or None if default index. 57 | :param source: ``string``, the source of this event, or None to have Splunk guess. 58 | :param sourcetype: ``string``, source type currently set on this event, or None to have Splunk guess. 59 | :param done: ``boolean``, is this a complete ``Event``? False if an ``Event`` fragment. 60 | :param unbroken: ``boolean``, Is this event completely encapsulated in this ``Event`` object? 61 | """ 62 | self.data = data 63 | self.done = done 64 | self.host = host 65 | self.index = index 66 | self.source = source 67 | self.sourceType = sourcetype 68 | self.stanza = stanza 69 | self.time = time 70 | self.unbroken = unbroken 71 | 72 | def write_to(self, stream): 73 | """Write an XML representation of self, an ``Event`` object, to the given stream. 74 | 75 | The ``Event`` object will only be written if its data field is defined, 76 | otherwise a ``ValueError`` is raised. 77 | 78 | :param stream: stream to write XML to. 79 | """ 80 | if self.data is None: 81 | raise ValueError("Events must have at least the data field set to be written to XML.") 82 | 83 | event = ET.Element("event") 84 | if self.stanza is not None: 85 | event.set("stanza", self.stanza) 86 | event.set("unbroken", str(int(self.unbroken))) 87 | 88 | # if a time isn't set, let Splunk guess by not creating a