├── frontend ├── .nojekyll ├── .gitignore ├── assets │ ├── images │ │ └── flags │ │ │ └── doc.png │ └── icons │ │ ├── logo.svg │ │ └── states │ │ ├── usa.svg │ │ └── world.svg ├── dist │ ├── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.ttf │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ └── fa-solid-900.woff2 │ └── js │ │ ├── about.js │ │ ├── navAction.js │ │ ├── main.js │ │ └── sidebar.js ├── package.json ├── scss │ ├── _header.scss │ ├── _legend.scss │ ├── _colors.scss │ ├── _buttons.scss │ ├── style.scss │ └── _sidebar.scss ├── package-lock.json ├── index.html └── data │ └── ex_groups.json ├── images ├── ex0_header.png ├── ex1_header.png ├── ex2_header.png ├── ex3_header.png ├── preview_header.png ├── showcase_header.png └── wip_pics │ ├── duplicates.png │ ├── group30_tools.png │ ├── initial_mess.png │ ├── group_tool_teq.png │ ├── more_duplicates.png │ ├── group10_tool_teq.png │ ├── relevant_nodes_fix.png │ ├── unique_nodes_fixed.png │ ├── unwarranted_nodes.png │ ├── only_relevant_nodes.png │ └── group_tool_teq_thumbnail.png ├── requirements.txt ├── examples ├── example0 │ └── group30.html ├── example1 │ └── group30-tools.html ├── example2 │ └── group10-tool-teq.html └── example3 │ └── all-group-tool-teqs.html ├── LICENSE ├── .gitignore ├── README.md └── graph_generator.py /frontend/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* -------------------------------------------------------------------------------- /images/ex0_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/ex0_header.png -------------------------------------------------------------------------------- /images/ex1_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/ex1_header.png -------------------------------------------------------------------------------- /images/ex2_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/ex2_header.png -------------------------------------------------------------------------------- /images/ex3_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/ex3_header.png -------------------------------------------------------------------------------- /images/preview_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/preview_header.png -------------------------------------------------------------------------------- /images/showcase_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/showcase_header.png -------------------------------------------------------------------------------- /images/wip_pics/duplicates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/duplicates.png -------------------------------------------------------------------------------- /images/wip_pics/group30_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/group30_tools.png -------------------------------------------------------------------------------- /images/wip_pics/initial_mess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/initial_mess.png -------------------------------------------------------------------------------- /images/wip_pics/group_tool_teq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/group_tool_teq.png -------------------------------------------------------------------------------- /images/wip_pics/more_duplicates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/more_duplicates.png -------------------------------------------------------------------------------- /frontend/assets/images/flags/doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/assets/images/flags/doc.png -------------------------------------------------------------------------------- /images/wip_pics/group10_tool_teq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/group10_tool_teq.png -------------------------------------------------------------------------------- /images/wip_pics/relevant_nodes_fix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/relevant_nodes_fix.png -------------------------------------------------------------------------------- /images/wip_pics/unique_nodes_fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/unique_nodes_fixed.png -------------------------------------------------------------------------------- /images/wip_pics/unwarranted_nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/unwarranted_nodes.png -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /images/wip_pics/only_relevant_nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/only_relevant_nodes.png -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /frontend/dist/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/frontend/dist/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /images/wip_pics/group_tool_teq_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/ATTACK-Force-Graph/main/images/wip_pics/group_tool_teq_thumbnail.png -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@fortawesome/fontawesome-free": "^5.15.3", 4 | "@iconfu/svg-inject": "^1.2.3", 5 | "bootstrap": "^5.0.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | antlr4-python3-runtime==4.8 2 | attackcti==0.3.4.4 3 | certifi==2021.5.30 4 | chardet==4.0.0 5 | idna==2.10 6 | pytz==2021.1 7 | requests==2.25.1 8 | simplejson==3.17.2 9 | six==1.16.0 10 | stix2==2.1.0 11 | stix2-patterns==1.3.2 12 | taxii2-client==2.3.0 13 | urllib3==1.26.6 14 | -------------------------------------------------------------------------------- /frontend/dist/js/about.js: -------------------------------------------------------------------------------- 1 | import { setNodeColor, setNodeType, setNodeName, updateSideBar } from './sidebar.js'; 2 | 3 | document.getElementById("btn-about").addEventListener("click", () => { 4 | setNodeColor("default"); 5 | 6 | // change node type text 7 | setNodeType("about"); 8 | setNodeName("About This Awesome Sauce"); 9 | 10 | updateSideBar(); 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /frontend/scss/_header.scss: -------------------------------------------------------------------------------- 1 | .header-main { 2 | position: fixed; 3 | display: flex; 4 | z-index: 6; 5 | width: 100%; 6 | padding: .8rem; 7 | color: $white-dove; 8 | background-color: $header-background; 9 | border-bottom: solid #4BDFFF .2px; 10 | 11 | .logo-box { 12 | align-items: center; 13 | 14 | .logo { 15 | width: 3.5rem; 16 | padding-left: 1rem; 17 | padding-right: 0; 18 | // margin-left: 1rem; 19 | } 20 | } 21 | 22 | h2 { 23 | width: auto; 24 | margin: 0rem; 25 | margin-top: .3rem; 26 | } 27 | } -------------------------------------------------------------------------------- /frontend/assets/icons/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/example0/group30.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 29 | -------------------------------------------------------------------------------- /examples/example1/group30-tools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 29 | -------------------------------------------------------------------------------- /examples/example2/group10-tool-teq.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 29 | -------------------------------------------------------------------------------- /examples/example3/all-group-tool-teqs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 29 | -------------------------------------------------------------------------------- /frontend/scss/_legend.scss: -------------------------------------------------------------------------------- 1 | .legend { 2 | position: fixed; 3 | bottom: 2rem; 4 | padding: .5rem; 5 | z-index: 7; 6 | color: #00B273; 7 | letter-spacing: 1px; 8 | 9 | .node-key { 10 | display: flex; 11 | align-items: center; 12 | } 13 | 14 | .circle { 15 | display: block; 16 | margin-right: .5rem; 17 | width: 20px; 18 | height: 20px; 19 | border-radius: 50%; 20 | } 21 | .circle-group { 22 | @extend .circle; 23 | background: -webkit-radial-gradient(1px 1px, circle, $group-color, $group-dark); 24 | } 25 | .circle-tool { 26 | @extend .circle; 27 | background: -webkit-radial-gradient(1px 1px, circle, $tool-color, $tool-dark); 28 | } 29 | .circle-technique { 30 | @extend .circle; 31 | background: -webkit-radial-gradient(1px 1px, circle, $technique-color, $technique-dark); 32 | } 33 | 34 | p { 35 | margin: 0; 36 | } 37 | } -------------------------------------------------------------------------------- /frontend/scss/_colors.scss: -------------------------------------------------------------------------------- 1 | 2 | $primary: #4BDFFF; 3 | $primary-disabled: rgba(4, 211, 255, .40); 4 | $primary-dark: #00a6b2; 5 | 6 | $white-dove: #c7d4dd; 7 | $primary-blue: #00b9e4; 8 | 9 | $retro-green: #4BFFBE; 10 | $retro-green-disabled: #2bffbf6b; 11 | $retro-dark: #00B273; 12 | 13 | $contraband-yellow: #ffc600; 14 | $contraband-disabled: rgba(255, 209, 4, 0.4); 15 | $contraband-dark: #c49900; 16 | 17 | $dark-text: #3a3a3a; 18 | $dark-noir: rgba(23, 30, 45, 0.60); 19 | 20 | $dark-background: rgba(12, 14, 23, 0.9); 21 | $header-background: rgba(23, 30, 45, 0.60); 22 | 23 | $group-color: #FF585B; 24 | $group-disabled: rgba(255, 88, 91, .15); 25 | $group-dark: #910000; 26 | 27 | $tool-color: #4BDFFF; 28 | $tool-disabled: rgba(4, 211, 255, .15); 29 | $tool-dark: #00a6b2; 30 | 31 | 32 | $technique-color: #9157EB; 33 | $technique-disabled: rgba(91, 116, 231, .15); 34 | $technique-dark: #4b0091; 35 | 36 | -------------------------------------------------------------------------------- /frontend/dist/js/navAction.js: -------------------------------------------------------------------------------- 1 | let open = false; 2 | 3 | function openSidebar() { 4 | open = true; 5 | document.getElementById("infoSidebar").style.width = "28%"; 6 | document.getElementById("info-toggle-icon").setAttribute("class", "fas fa-chevron-right"); 7 | } 8 | 9 | function sidebarCalled() { 10 | if (!open) { 11 | openSidebar(); 12 | document.getElementById("info-toggle-icon").setAttribute("class", "fas fa-chevron-right"); 13 | document.getElementById("toggle-info-btn").classList.remove("toggle-info-btn-closed"); 14 | document.getElementById("toggle-info-btn").classList.add("toggle-info-btn"); 15 | } else { 16 | open = false; 17 | document.getElementById("infoSidebar").style.width = "0%"; 18 | document.getElementById("info-toggle-icon").setAttribute("class", "fas fa-chevron-left"); 19 | document.getElementById("toggle-info-btn").classList.remove("toggle-info-btn"); 20 | document.getElementById("toggle-info-btn").classList.add("toggle-info-btn-closed"); 21 | } 22 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ed 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /frontend/scss/_buttons.scss: -------------------------------------------------------------------------------- 1 | .btn-outline-primary { 2 | font-family: "Roboto", sans-serif; 3 | color: $white-dove; 4 | background-color: $dark-noir; 5 | padding: 0.5rem 1rem; 6 | border: 0; 7 | 8 | i { 9 | color: $primary-blue; 10 | margin-right: .7rem; 11 | } 12 | } 13 | 14 | .btn-icon { 15 | color: $white-dove; 16 | padding: 0 1rem; 17 | 18 | &:hover { 19 | color: $primary-blue; 20 | } 21 | } 22 | 23 | .link-outline-primary { 24 | @extend .btn-outline-primary; 25 | text-decoration: none; 26 | } 27 | 28 | .toggle-info-btn { 29 | position: absolute; 30 | top: 40%; 31 | left: -2.1rem; 32 | height: 4rem; 33 | color: white; 34 | background-color: $retro-green; 35 | align-items: center; 36 | 37 | .fas { 38 | padding: .6rem; 39 | } 40 | } 41 | 42 | .toggle-info-btn-closed { 43 | @extend .toggle-info-btn; 44 | background-color: $retro-green-disabled; 45 | } 46 | 47 | .btn-group-connection { 48 | display: flex; 49 | align-items: center; 50 | 51 | .btn-hi-viz { 52 | color: white; 53 | font-size: 1.2rem; 54 | letter-spacing: 1px; 55 | padding: 0 1.5rem; 56 | margin: .5rem 0; 57 | border: none; 58 | border-radius: 0; 59 | background-color: $dark-noir; 60 | border-left: solid $primary-disabled 5px; 61 | 62 | &:hover, &:focus { 63 | color: $dark-text; 64 | border-color: $retro-dark; 65 | background-color: $retro-green; 66 | 67 | &:focus { 68 | box-shadow: 0 0 0 0.25rem $primary-dark; 69 | } 70 | } 71 | } 72 | 73 | .active { 74 | color: white; 75 | border-left: solid $primary 5px; 76 | background-color: $primary-disabled; 77 | } 78 | 79 | i { 80 | margin: 0 1rem; 81 | } 82 | } 83 | 84 | .camera-reset { 85 | position: fixed; 86 | display: flex; 87 | align-items: center; 88 | z-index: 2; 89 | bottom: 2.6rem; 90 | justify-content: center; 91 | width: 100%; 92 | 93 | .btn-light { 94 | background-color: $dark-noir; 95 | padding: 1rem; 96 | color: white; 97 | border: none; 98 | border-top: $primary solid 2px; 99 | } 100 | } 101 | 102 | .btn-mitre { 103 | background-color: $dark-noir; 104 | padding: 1rem 1.5rem; 105 | border: 0 $contraband-disabled solid; 106 | border-bottom-width: 5px; 107 | 108 | &:hover { 109 | background-color: $contraband-disabled; 110 | border-color: $contraband-yellow; 111 | 112 | a { 113 | color: $contraband-yellow; 114 | } 115 | } 116 | 117 | a { 118 | text-decoration: none; 119 | color: $contraband-yellow; 120 | } 121 | 122 | h4 { 123 | margin: 0; 124 | } 125 | } 126 | 127 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | downloads/ 14 | eggs/ 15 | .eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | wheels/ 22 | share/python-wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .nox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | *.py,cover 49 | .hypothesis/ 50 | .pytest_cache/ 51 | cover/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | db.sqlite3-journal 62 | 63 | # Flask stuff: 64 | instance/ 65 | .webassets-cache 66 | 67 | # Scrapy stuff: 68 | .scrapy 69 | 70 | # Sphinx documentation 71 | docs/_build/ 72 | 73 | # PyBuilder 74 | .pybuilder/ 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | # For a library or package, you might want to ignore these files since the code is 86 | # intended to run in multiple environments; otherwise, check them in: 87 | # .python-version 88 | 89 | # pipenv 90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 93 | # install all needed dependencies. 94 | #Pipfile.lock 95 | 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # pytype static type analyzer 135 | .pytype/ 136 | 137 | # Cython debug symbols 138 | cython_debug/ 139 | -------------------------------------------------------------------------------- /frontend/scss/style.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Teko:wght@300&display=swap'); 2 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swap'); 3 | 4 | @import "../node_modules/bootstrap/scss/bootstrap"; 5 | 6 | @import "../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss"; 7 | @import "../node_modules/@fortawesome/fontawesome-free/scss/solid.scss"; 8 | @import "../node_modules/@fortawesome/fontawesome-free/scss/brands.scss"; 9 | @import "../node_modules/@fortawesome/fontawesome-free/scss/regular.scss"; 10 | 11 | @import "_colors.scss"; 12 | @import "_buttons.scss"; 13 | 14 | @import "_header.scss"; 15 | @import "_sidebar.scss"; 16 | @import "_legend.scss"; 17 | 18 | * { 19 | margin: 0; 20 | } 21 | 22 | * div { 23 | color: white; 24 | } 25 | 26 | 27 | body { 28 | margin: 0; 29 | font-family: "Teko", sans-serif; 30 | } 31 | 32 | .parent { 33 | position: relative; 34 | } 35 | 36 | .group-text { 37 | color: $group-color; 38 | } 39 | 40 | .tool-text { 41 | color: $tool-color; 42 | } 43 | 44 | .technique-text { 45 | color: $technique-color; 46 | } 47 | 48 | .divider { 49 | height: 2.5rem; 50 | margin: 0 1rem; 51 | border-right: $primary-blue solid 1px; 52 | } 53 | 54 | 55 | .about-box { 56 | display: flex; 57 | align-items: center; 58 | justify-content: flex-end; 59 | } 60 | 61 | .control-box { 62 | position: absolute; 63 | z-index: 7; 64 | top: 5rem; 65 | left: 1rem; 66 | } 67 | 68 | .bottom-bar { 69 | opacity: .5; 70 | position: fixed; 71 | display: flex; 72 | justify-content: space-between; 73 | bottom: 0; 74 | z-index: 7; 75 | color: white; 76 | margin-top: 1rem; 77 | 78 | .made-by { 79 | margin-left: .5rem; 80 | font-size: .8rem; 81 | font-family: Roboto, sans-serif; 82 | i { 83 | color: $group-color; 84 | } 85 | 86 | a { 87 | color: $retro-green; 88 | text-decoration: none; 89 | } 90 | } 91 | 92 | .control-guide { 93 | border-top: $primary-blue solid 1px; 94 | margin: 0; 95 | background-color: $header-background; 96 | 97 | p { 98 | text-align: center; 99 | margin: 0; 100 | letter-spacing: 1px; 101 | } 102 | } 103 | } 104 | 105 | .affiliation-avatar { 106 | height: 80px; 107 | width: 80px; 108 | } 109 | 110 | .white-space { 111 | hr { 112 | color: $retro-green; 113 | margin: 4rem 0; 114 | } 115 | } 116 | 117 | .control-section-title { 118 | @extend .info-section-title; 119 | margin-top: 1rem; 120 | 121 | hr { 122 | margin-bottom: 0; 123 | } 124 | } 125 | 126 | .warning-box { 127 | margin-top: 1rem; 128 | padding: .5rem; 129 | color: $group-color; 130 | border-left: 5px solid $group-color; 131 | background-color: $group-disabled; 132 | 133 | p { 134 | font-size: 1.1rem; 135 | margin: 0; 136 | } 137 | } 138 | 139 | .guide-box { 140 | @extend .warning-box; 141 | color: $retro-green; 142 | border-color: $retro-green; 143 | background-color: $retro-green-disabled; 144 | 145 | letter-spacing: 1px; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /frontend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Frontend", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "@fortawesome/fontawesome-free": "^5.15.3", 9 | "@iconfu/svg-inject": "^1.2.3", 10 | "bootstrap": "^5.0.2" 11 | } 12 | }, 13 | "node_modules/@fortawesome/fontawesome-free": { 14 | "version": "5.15.3", 15 | "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz", 16 | "integrity": "sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w==", 17 | "hasInstallScript": true, 18 | "engines": { 19 | "node": ">=6" 20 | } 21 | }, 22 | "node_modules/@iconfu/svg-inject": { 23 | "version": "1.2.3", 24 | "resolved": "https://registry.npmjs.org/@iconfu/svg-inject/-/svg-inject-1.2.3.tgz", 25 | "integrity": "sha512-3v1MUAJqmJS4jmhHoCkSxt+EdJrjPHlLXrWocCT25kCxnxJto8028Z6CC406EL11KA53SDZgI/QQA5GEJAoiRw==" 26 | }, 27 | "node_modules/@popperjs/core": { 28 | "version": "2.9.2", 29 | "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", 30 | "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", 31 | "peer": true, 32 | "funding": { 33 | "type": "opencollective", 34 | "url": "https://opencollective.com/popperjs" 35 | } 36 | }, 37 | "node_modules/bootstrap": { 38 | "version": "5.0.2", 39 | "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.2.tgz", 40 | "integrity": "sha512-1Ge963tyEQWJJ+8qtXFU6wgmAVj9gweEjibUdbmcCEYsn38tVwRk8107rk2vzt6cfQcRr3SlZ8aQBqaD8aqf+Q==", 41 | "funding": { 42 | "type": "opencollective", 43 | "url": "https://opencollective.com/bootstrap" 44 | }, 45 | "peerDependencies": { 46 | "@popperjs/core": "^2.9.2" 47 | } 48 | } 49 | }, 50 | "dependencies": { 51 | "@fortawesome/fontawesome-free": { 52 | "version": "5.15.3", 53 | "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz", 54 | "integrity": "sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w==" 55 | }, 56 | "@iconfu/svg-inject": { 57 | "version": "1.2.3", 58 | "resolved": "https://registry.npmjs.org/@iconfu/svg-inject/-/svg-inject-1.2.3.tgz", 59 | "integrity": "sha512-3v1MUAJqmJS4jmhHoCkSxt+EdJrjPHlLXrWocCT25kCxnxJto8028Z6CC406EL11KA53SDZgI/QQA5GEJAoiRw==" 60 | }, 61 | "@popperjs/core": { 62 | "version": "2.9.2", 63 | "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", 64 | "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", 65 | "peer": true 66 | }, 67 | "bootstrap": { 68 | "version": "5.0.2", 69 | "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.2.tgz", 70 | "integrity": "sha512-1Ge963tyEQWJJ+8qtXFU6wgmAVj9gweEjibUdbmcCEYsn38tVwRk8107rk2vzt6cfQcRr3SlZ8aQBqaD8aqf+Q==", 71 | "requires": {} 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /frontend/scss/_sidebar.scss: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | height: 100%; 3 | width: 0; 4 | position: fixed; 5 | z-index: 10; 6 | top: 4.4rem; 7 | right: 0; 8 | background-color: $dark-background; 9 | transition: 0.5s; 10 | border-left: solid $retro-green 5px; 11 | padding: 0; 12 | 13 | .inner-sidebar { 14 | overflow-y: scroll; 15 | height: 85%; 16 | } 17 | 18 | .node-type { 19 | position: relative; 20 | height: 5rem; 21 | width: 2rem; 22 | background-color: $retro-green; 23 | display: flex; 24 | align-items: center; 25 | 26 | .header-input { 27 | font-size: 1.5rem; 28 | color: white; 29 | width: 5rem; 30 | background-color: transparent; 31 | text-transform: uppercase; 32 | letter-spacing: 2px; 33 | transform: rotate(270deg); 34 | border: none; 35 | position: relative; 36 | text-align: center; 37 | left: -1.4rem; 38 | } 39 | 40 | } 41 | 42 | .node-title { 43 | width: 100%; 44 | background-color: $retro-green-disabled; 45 | display: flex; 46 | align-items: center; 47 | 48 | h2 { 49 | color: $retro-green; 50 | padding-left: 1rem; 51 | margin-top: .8rem; 52 | } 53 | } 54 | 55 | .backdrop-noir-box { 56 | background-color: $dark-noir; 57 | height: 6.7rem; 58 | margin-top: .5rem; 59 | justify-content: center; 60 | text-align: center; 61 | display: grid; 62 | } 63 | 64 | .dual-text-box-sm { 65 | text-align: center; 66 | 67 | .element-sub-header { 68 | font-size: 1rem; 69 | font-weight: bold; 70 | } 71 | 72 | .element-sub-text { 73 | font-size: .9rem; 74 | } 75 | 76 | img { 77 | height: 3.5rem; 78 | margin: .3rem 0; 79 | } 80 | 81 | .custom-svg { 82 | @extend img; 83 | 84 | svg { 85 | @extend img; 86 | width: 4rem; 87 | 88 | path { 89 | transform: scale(0.07); 90 | } 91 | 92 | } 93 | } 94 | } 95 | 96 | .vertical-box { 97 | @extend .node-type; 98 | background-color: transparent; 99 | font-family: "Teko", sans-serif; 100 | 101 | input { 102 | @extend .header-input; 103 | width: 6.3rem; 104 | } 105 | 106 | } 107 | 108 | .vertical-noir-box { 109 | display: grid; 110 | background-color: $dark-noir; 111 | text-align: center; 112 | padding: .3rem 1rem; 113 | } 114 | } 115 | 116 | .info-element { 117 | display: flex; 118 | align-items: center; 119 | justify-content: center; 120 | 121 | .stat-number { 122 | text-align: center; 123 | 124 | p { 125 | font-family: "Teko", sans-serif; 126 | font-size: 2.5rem; 127 | margin: 0; 128 | height: 3.3rem; 129 | } 130 | 131 | } 132 | } 133 | 134 | .more-information { 135 | display: grid; 136 | align-items: center; 137 | justify-content: center; 138 | text-align: center; 139 | margin-top: 1rem; 140 | } 141 | 142 | .info-box { 143 | padding: 1rem; 144 | font-family: "Roboto", sans-serif; 145 | overflow: hidden; 146 | 147 | .info-subtitle { 148 | padding-top: 1rem; 149 | text-align: center; 150 | font-weight: bold; 151 | } 152 | 153 | .credits { 154 | a { 155 | color: $primary; 156 | text-decoration: none; 157 | } 158 | } 159 | } 160 | 161 | .info-section-title { 162 | font-family: "Roboto", sans-serif; 163 | font-weight: bold; 164 | margin: 0; 165 | 166 | p { 167 | margin: 0; 168 | } 169 | 170 | hr { 171 | color: $retro-green; 172 | margin-top: .4rem; 173 | margin-bottom: 1rem; 174 | } 175 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # ATTACK-Force-Graph 3 | - Generate and visualize MITRE's ATTACK data in a 3D force-directed graph with a UI made specifically for the ATTACK data 4 | 5 | ![Showcase Header](/images/showcase_header.png) 6 | 7 | ## DEMO: 8 | 9 | - ## [View Demo (GitHub Pages)](https://osv22.github.io/ATTACK-Force-Graph/main-site/index.html) 10 | 11 | ## Preview: 12 | ![Preview](/images/preview_header.png) 13 | 14 | 15 | ## TODO: 16 | - [ ] Add affiliation template 17 | - [ ] Add speciality template 18 | - [ ] Add attacks/ targets template 19 | - [ ] Optimize time complexity for certain sections 20 | 21 | ## What? 22 | - Generate JSON force-graph data nodes and links from the MITRE ATTACK Framework based on your preferences. (`graph_generator.py`) 23 | - Use that data to visualize your results with a UI tailored around the ATTACK data. (`frontend` directory) 24 | 25 | - The JSON data generated is formatted for use with @vasturiano's awesome various force-directed graph projects. (Tested and works on both 2D and 3D versions) 26 | - At the moment you can do the following combinations: 27 | 1. Group -> Group Tools -> Group Tool Techniques: 28 | - Each group (APT) node will be linked to the corresponding tools/ software the group uses along. 29 | - Total node connections: **(group * *n* group tools * *n* tool techniques)** 30 | 2. Group -> Group Tools/ Software: 31 | - Links just the tools without fetching tool techniques data 32 | - Total node connections: **(group * *n* group tools)** 33 | 3. Groups Only 34 | - A node for each group will be generated but no links. (What would you link a group to?!) 35 | - Total node connections: 0 36 | 4. Other 37 | - You can generate standalone nodes of groups or group tools/ software. 38 | 39 | ## Why? 40 | - Draw conclusions and spot patterns fast thanks to the power of data visualization. 41 | - Present compelling data stakeholders can easily understand and interact with. 42 | - Force-directed graphs are seriously... :sunglasses: *cool* 43 | 44 | ## How? 45 | - The graph generator script uses [@Cyb3rWard0g's](https://github.com/Cyb3rWard0g) [ATTACK-Python-Client](https://github.com/OTRF/ATTACK-Python-Client) to build the ATTACK graph data. Having used MITRE's STIX... just use Roberto's package. 46 | - Lift requests are network requests and can be time-consuming. Efficiency improvements planned after the main portion is done. 47 | - The 3D graph in the UI is the [3D version](https://github.com/vasturiano/3d-force-graph) of [vasturiano's](https://github.com/vasturiano) awesome JS force-directed graphs. 48 | 49 | ## Example Demos 50 | - ## [Full ATTACK data demo with UI](https://osv22.github.io/ATTACK-Force-Graph/main-site/index.html) 51 | - Graphs Only: 52 | - [Example 0: Only Group Nodes](https://osv22.github.io/ATTACK-Force-Graph/show-example/example0/group30.html) 53 | - [Example 1: Group -> Tool(s)](https://osv22.github.io/ATTACK-Force-Graph/show-example/example1/group30-tools.html) 54 | - [Example 2: Group -> Group Tool(s) -> Tool Technique(s)](https://osv22.github.io/ATTACK-Force-Graph/show-example/example2/group10-tool-teq.html) 55 | - [Example 3 - ALL Group -> Tools -> Techniques (1MB of JSON Data)](https://osv22.github.io/ATTACK-Force-Graph/show-example/example3/all-group-tool-teqs.html) 56 | 57 | ## Examples 58 | ![Example0 Header](/images/ex0_header.png) 59 | ![Example1 Header](/images/ex1_header.png) 60 | ![Example1 Header](/images/ex2_header.png) 61 | ![Example1 Header](/images/ex3_header.png) 62 | 63 | ## Data Preview 64 | - NOTE: Specific values are not part of the MITRE ATTACK Framework: 65 | - Group: `affiliation` - This is subjective and can be *problematic*, so it is up to your assessment to evaluate which group is affiliated with whom. 66 | - Group: `targets` - Work-in-progress for defaults but hard to maintain over time given that it is not part of the ATTACK framework. 67 | - Group: `speciality` - Work-in-progress and is much easier to maintain. 68 | 69 | 70 | - `val` - This is can be used to determine how big you want a node element to be. 71 | - For groups: The `val` is based on the number of tools the group uses 72 | - For tools: The `val` is based on the number of techniques the tool makes possible 73 | - For techniques: Set to `None` by default, leaving it up to you 74 | 75 | ### Group Node 76 | ``` 77 | "id": "MITRE GROUP ID HERE. EX: G0005", 78 | "type": "group", 79 | "val": 2, 80 | "attributes": { 81 | "name": "Cool Group/ APT Name Here", 82 | "aliases": [ 83 | "Group alias", 84 | "Operation Golden Kitty", 85 | ], 86 | "description": "Cleaned description. Do not use `get_desc()` if you want raw desc...", 87 | "affiliation": "You have to assign this value yourself, read the NOTE above :)", 88 | "targets": ["Also you have to", "set this. Read NOTE above"], 89 | "speciality": ["set this based on your assessment", "Read NOTE above"], 90 | "tools": { 91 | "tool_id_here": "tool_name_here", 92 | "S0225": "sqlmap", 93 | }, 94 | "techniques": { 95 | "technique_id_here": "technique_name_here", 96 | "T1566.003": "Spearphishing via Service", 97 | } 98 | } 99 | ``` 100 | ### Tool Node 101 | ``` 102 | "id": "MITRE Software ID HERE. EX: S0084", 103 | "type": "tool", 104 | "val": 1 105 | "attributes": { 106 | "name": "tool_name_here", 107 | "aliases": [], 108 | "labels": [ 109 | "tool" 110 | ], 111 | "description": "Cleaned description. Do not use `get_desc()` if you want raw desc...", 112 | "platforms": [ 113 | "Linux", 114 | ... 115 | ], 116 | "techniques": { 117 | "T1190": "Exploit Public-Facing Application" 118 | } 119 | } 120 | ``` 121 | 122 | ### Technique Node 123 | - `val` is set to `None` by default, you can set it to length of platforms or whatever your preference is. 124 | ``` 125 | "id": "MITRE Technique ID HERE. EX: T1190", 126 | "type": "technique", 127 | "val": null, 128 | "attributes": { 129 | "name": "Exploit Public-Facing Application", 130 | "chain_phase": "initial-access", 131 | "description": "Cleaned description. Do not use `get_desc()` if you want raw desc.", 132 | "detection": "Cleaned detection. Do not use `get_desc()` if you want raw detection paragraph...", 133 | "is_subtype": false, 134 | "platforms": [ 135 | "Windows", 136 | ... 137 | ] 138 | } 139 | ``` 140 | -------------------------------------------------------------------------------- /frontend/dist/js/main.js: -------------------------------------------------------------------------------- 1 | import { 2 | updateSideBar 3 | } from "./sidebar.js"; 4 | 5 | // --------------------------------- 6 | // GRAPH 7 | // --------------------------------- 8 | 9 | const defaultData = "entry_ex_groups_tools.json" 10 | 11 | const groupNodeColor = "red"; 12 | const toolNodeColor = "cyan"; 13 | const techniqueNodeColor = "#9157EB"; 14 | const defaultNodeColor = "yellow"; 15 | 16 | const graphElement = document.getElementById("3d-graph"); 17 | 18 | const Graph = ForceGraph3D({ 19 | extraRenderers: [new THREE.CSS2DRenderer()] 20 | }) 21 | (graphElement) 22 | .jsonUrl(defaultData) 23 | .nodeLabel(node => { 24 | return node.attributes.name 25 | }) 26 | .nodeLabel(node => { 27 | return node.attributes.name 28 | }) 29 | .nodeColor(node => { 30 | switch (node.type) { 31 | case "group": 32 | return groupNodeColor; 33 | case "tool": 34 | return toolNodeColor; 35 | case "technique": 36 | return techniqueNodeColor; 37 | default: 38 | return defaultNodeColor; 39 | } 40 | }) 41 | .linkDirectionalArrowLength(3.5) 42 | .linkDirectionalArrowRelPos(1) 43 | .linkCurvature(0.25) 44 | .onNodeClick(node => { 45 | // Aim at node from outside it 46 | const distance = 80; 47 | const distRatio = 1 + distance / Math.hypot(node.x, node.y, node.z); 48 | 49 | Graph.cameraPosition({ 50 | x: node.x * distRatio, 51 | y: node.y * distRatio, 52 | z: node.z * distRatio 53 | }, // new position 54 | node, // lookAt ({ x, y, z }) 55 | 3000 // ms transition duration 56 | ); 57 | 58 | updateSideBar(node); 59 | hideGuide(true); 60 | 61 | // Will be moved later on 62 | // document.getElementById("affiliation-avatar").src = `assets/icons/states/doc.png`; 63 | }) 64 | .showNavInfo(false); 65 | 66 | 67 | // Make Graph Responsive 68 | window.addEventListener("resize", () => { 69 | Graph.width(innerWidth); 70 | Graph.height(innerHeight); 71 | }); 72 | 73 | 74 | // --------------------------------- 75 | // GRAPH OPTIONS 76 | // --------------------------------- 77 | 78 | Graph.d3Force("charge").strength(-120); 79 | 80 | Graph 81 | .warmupTicks(0) // Adjust number of iterations to taste 82 | .cooldownTicks(1000) 83 | .nodeThreeObject(node => { 84 | if (node.type === "group") { 85 | const nodeEl = document.createElement('div'); 86 | nodeEl.textContent = node.attributes.name; 87 | nodeEl.style.color = "#FF585B"; 88 | nodeEl.style.backgroundColor = "rgba(0, 0, 0, .30)"; 89 | nodeEl.style.padding = "0 10px"; 90 | nodeEl.className = "node-label"; 91 | return new THREE.CSS2DObject(nodeEl); 92 | } else if (node.type === "tool") { 93 | const nodeEl = document.createElement('div'); 94 | nodeEl.textContent = node.attributes.name; 95 | nodeEl.style.color = "cyan"; 96 | nodeEl.className = "node-label"; 97 | return new THREE.CSS2DObject(nodeEl); 98 | } 99 | 100 | }) 101 | .nodeThreeObjectExtend(true) 102 | // A few feaures that will be added later 103 | 104 | 105 | // .nodeThreeObject(node => { 106 | // const sprite = new SpriteText(node.id); 107 | // sprite.material.depthWrite = false; // make sprite background transparent 108 | // sprite.color = "#90ff00"; 109 | // sprite.textHeight = 8; 110 | // return sprite; 111 | // }) 112 | 113 | 114 | // --------------------------------- 115 | // CAMERA 116 | // --------------------------------- 117 | function resetCamera() { 118 | Graph.cameraPosition({ 119 | x: 0, 120 | y: 0, 121 | z: 500 122 | }) 123 | } 124 | 125 | document.getElementById("btn-camera").addEventListener("click", () => { 126 | resetCamera(); 127 | }); 128 | 129 | 130 | // --------------------------------- 131 | // GENERAL 132 | // --------------------------------- 133 | function changeGraphData(newGraph) { 134 | Graph.jsonUrl(`${newGraph}.json`); 135 | } 136 | 137 | function hideFullDataWarning(bool) { 138 | document.getElementById("warning-box").hidden = bool; 139 | } 140 | 141 | function hideGuide(bool) { 142 | bool === true ? document.getElementById("guide-box").hidden = true : false; 143 | } 144 | 145 | function disableLinks(graph, bool) { 146 | bool === true ? graph.linkVisibility(false) : graph.linkVisibility(true); 147 | } 148 | 149 | // --------------------------------- 150 | // DATA INPUT 151 | // --------------------------------- 152 | function setDataBtnActive(dataButtonId) { 153 | document.getElementById(dataButtonId).classList.add("active"); 154 | } 155 | 156 | function setDataBtnInactive(dataButtonId) { 157 | document.getElementById(dataButtonId).classList.remove("active"); 158 | } 159 | 160 | function deactivateBtnGroup(btnGroup) { 161 | if (btnGroup === "mitre") { 162 | setDataBtnInactive("full-groups"); 163 | setDataBtnInactive("full-group-tools"); 164 | setDataBtnInactive("full-group-tools-teqs"); 165 | 166 | hideFullDataWarning(true); 167 | } else if (btnGroup === "examples") { 168 | setDataBtnInactive("example-groups"); 169 | setDataBtnInactive("example-group-tools"); 170 | setDataBtnInactive("example-group-tools-teqs"); 171 | 172 | } 173 | 174 | } 175 | 176 | // EXAMPLES 177 | document.getElementById("example-groups").addEventListener("click", () => { 178 | changeGraphData("data/ex_groups"); 179 | 180 | setDataBtnActive("example-groups"); 181 | setDataBtnInactive("example-group-tools"); 182 | setDataBtnInactive("example-group-tools-teqs"); 183 | 184 | deactivateBtnGroup("mitre"); 185 | }); 186 | 187 | document.getElementById("example-group-tools").addEventListener("click", () => { 188 | changeGraphData("data/ex_groups_tools"); 189 | 190 | setDataBtnActive("example-groups"); 191 | setDataBtnActive("example-group-tools"); 192 | setDataBtnInactive("example-group-tools-teqs"); 193 | 194 | deactivateBtnGroup("mitre"); 195 | }); 196 | 197 | document.getElementById("example-group-tools-teqs").addEventListener("click", () => { 198 | changeGraphData("data/ex_groups_tools_teqs"); 199 | 200 | setDataBtnActive("example-groups"); 201 | setDataBtnActive("example-group-tools"); 202 | setDataBtnActive("example-group-tools-teqs"); 203 | 204 | deactivateBtnGroup("mitre"); 205 | }); 206 | 207 | // MITRE 208 | document.getElementById("full-groups").addEventListener("click", () => { 209 | changeGraphData("data/all_groups"); 210 | setDataBtnActive("full-groups"); 211 | setDataBtnInactive("full-group-tools"); 212 | setDataBtnInactive("full-group-tools-teqs"); 213 | 214 | deactivateBtnGroup("examples"); 215 | }); 216 | 217 | document.getElementById("full-group-tools").addEventListener("click", () => { 218 | changeGraphData("data/all_groups_tools"); 219 | setDataBtnActive("full-groups"); 220 | setDataBtnActive("full-group-tools"); 221 | setDataBtnInactive("full-group-tools-teqs"); 222 | 223 | deactivateBtnGroup("examples"); 224 | hideFullDataWarning(false); 225 | 226 | }); 227 | 228 | document.getElementById("full-group-tools-teqs").addEventListener("click", () => { 229 | changeGraphData("data/all_groups_tools_teqs"); 230 | 231 | setDataBtnActive("full-groups"); 232 | setDataBtnActive("full-group-tools"); 233 | setDataBtnActive("full-group-tools-teqs"); 234 | 235 | deactivateBtnGroup("examples"); 236 | hideFullDataWarning(false); 237 | }); 238 | 239 | // Links Visibility 240 | const miterWrapper = document.getElementById('mitre-data-wrapper'); 241 | 242 | miterWrapper.addEventListener('click', (event) => { 243 | const isButton = event.target.nodeName === 'BUTTON'; 244 | if (isButton) { 245 | disableLinks(Graph, true); 246 | } 247 | }) 248 | 249 | const examplesWrapper = document.getElementById('examples-data-wrapper'); 250 | examplesWrapper.addEventListener('click', (event) => { 251 | const isButton = event.target.nodeName === 'BUTTON'; 252 | if (isButton) { 253 | disableLinks(Graph, false); 254 | } 255 | }) -------------------------------------------------------------------------------- /graph_generator.py: -------------------------------------------------------------------------------- 1 | from os import link 2 | from attackcti import attack_client 3 | import json 4 | import re 5 | 6 | 7 | lift = attack_client() 8 | groups = lift.get_groups() 9 | groups = lift.remove_revoked(groups) 10 | 11 | json_data = { 12 | "nodes": [], 13 | "links": [] 14 | } 15 | 16 | all_tools = [] 17 | all_techniques = [] 18 | 19 | 20 | def remove_dupe(group_list, verbose=False): 21 | """ 22 | Sometimes certain groups turn out to be a single group 23 | and are then merged, resulting in duplicates with different names. 24 | This is on top of `remove_revoked`, just to be safe 25 | """ 26 | for idx, group in enumerate(group_list): 27 | group = group_list[idx] 28 | 29 | try: 30 | group.aliases 31 | except AttributeError: 32 | if verbose: 33 | print(f"[+] {group.name}: NO aliases found") 34 | 35 | for inner_group in group_list: 36 | try: 37 | if group.name in inner_group.aliases: 38 | if verbose: 39 | print(f"\t Found {group.name} as an alias for: {inner_group.name}\n") 40 | group_list.remove(group) 41 | except AttributeError: 42 | continue 43 | 44 | if verbose: 45 | print(f"[!] Done Cleaning Duplicate Groups\n") 46 | 47 | 48 | def get_desc(md_text): 49 | #! Can run remove_dupe here if we really wanted 50 | try: 51 | rm_citations = re.sub(r"\(Citation([^\)]+)\)", "", md_text) 52 | rm_mitre_links = re.sub(r"\(https([^\)]+)\)", "", rm_citations) 53 | clean_desc = rm_mitre_links.translate(str.maketrans({'[':None, ']':None})).strip() 54 | return clean_desc 55 | # In case a dupe with no desc makes it through 56 | except AttributeError: 57 | return "No Description Available Yet" 58 | 59 | 60 | def get_item_ids(item_list): 61 | return [item.external_references[0].external_id for item in item_list] 62 | 63 | def get_item_names(item_list): 64 | return [item["name"] for item in item_list] 65 | 66 | def get_id_name(item_list): 67 | items_dict = {} 68 | for item in item_list: 69 | items_dict[item.external_references[0].external_id] = item.name 70 | return items_dict 71 | 72 | def make_group_node(group, group_software, group_techniques, link_tool=False, 73 | link_tool_techniques=False, lift_tool_techniques=False): 74 | 75 | group_id = group.external_references[0].external_id 76 | group_name = group.name 77 | group_description = get_desc(group.description) 78 | node_type = "group" 79 | 80 | # For you to decide/ evaluate 81 | group_affiliation = "" 82 | group_targets = [] 83 | group_speciality = [] 84 | 85 | if len(group_software) > 200: # Invalid groups return a list of all 500+(all) tools 86 | group_val = 0 87 | group_tools = [] 88 | else: 89 | # group_tools = list(set(get_item_ids(group_software))) # To get unique tools only 90 | group_tools = get_id_name(group_software) 91 | group_val = len(group_tools) 92 | 93 | try: 94 | group_aliases = group.aliases 95 | # We already know the group's actual name is an "alias" 96 | group_aliases.remove(group_name) 97 | except: 98 | group_aliases = [] 99 | 100 | try: 101 | group_techniques = get_id_name(group_techniques) 102 | except: 103 | group_techniques = [] 104 | 105 | new_group_node = { 106 | "id": group_id, 107 | "type": node_type, 108 | "val": group_val, 109 | "attributes": { 110 | "name": group_name, 111 | "aliases": group_aliases, 112 | "description": group_description, 113 | "affiliation": group_affiliation, 114 | "targets": group_targets, 115 | "speciality": group_speciality, 116 | "tools": group_tools, 117 | "techniques": group_techniques, 118 | } 119 | }, 120 | 121 | 122 | json_data["nodes"] += new_group_node 123 | 124 | if link_tool and (len(group_software) < 150): 125 | for tool in group_software: 126 | tool_id = tool.external_references[0].external_id 127 | 128 | if tool_id not in all_tools: 129 | make_tool_node(tool, link_techniques=link_tool_techniques, lift_techniques=lift_tool_techniques) 130 | all_tools.append(tool_id) 131 | 132 | new_link = { 133 | "source": group_id, 134 | "target": tool_id, 135 | }, 136 | 137 | json_data["links"] += new_link 138 | 139 | 140 | def make_tool_node(tool, link_techniques=False, lift_techniques=False): 141 | 142 | tool_name = tool.name 143 | tool_id = tool.external_references[0].external_id 144 | tool_description = get_desc(tool.description) 145 | node_type = "tool" 146 | 147 | try: 148 | tool_platforms = tool.x_mitre_platforms 149 | except: 150 | tool_platforms = [] 151 | 152 | try: 153 | tool_labels = tool.labels 154 | except: 155 | tool_labels = [] 156 | 157 | try: 158 | tool_aliases = tool.x_mitre_aliases 159 | # We already know the tool's actual name is an "alias" 160 | tool_aliases.remove(tool_name) 161 | except: 162 | tool_aliases = [] 163 | 164 | new_tool_node = { 165 | "id": tool_id, 166 | "type": node_type, 167 | "attributes": { 168 | "name": tool_name, 169 | "aliases": tool_aliases, 170 | "labels": tool_labels, 171 | "description": tool_description, 172 | "platforms": tool_platforms, 173 | } 174 | }, 175 | 176 | if lift_techniques or link_techniques: 177 | lift_teqs = lift.get_techniques_used_by_software(tool) 178 | 179 | if len(lift_teqs) < 100: 180 | tool_techniques = get_id_name(lift_teqs) 181 | else: 182 | tool_techniques = [] 183 | 184 | new_tool_node[0]["val"] = len(tool_techniques) 185 | new_tool_node[0]["attributes"]["techniques"] = tool_techniques 186 | 187 | if link_techniques: 188 | 189 | for technique in lift_teqs: 190 | technique_id = technique.external_references[0].external_id 191 | 192 | if technique_id not in all_techniques: 193 | make_technique_node(technique) 194 | all_techniques.append(technique_id) 195 | 196 | new_link = { 197 | "source": tool_id, 198 | "target": technique_id, 199 | }, 200 | json_data["links"] += new_link 201 | 202 | json_data["nodes"] += new_tool_node 203 | 204 | 205 | def make_technique_node(technique): 206 | technique_id = technique.external_references[0].external_id 207 | technique_name = technique.name 208 | technique_val = None 209 | node_type = "technique" 210 | 211 | try: 212 | chain_phase = technique.kill_chain_phases[0].phase_name 213 | except: 214 | chain_phase = None 215 | 216 | try: 217 | technique_description = get_desc(technique.description) 218 | except: 219 | technique_description = "No Description Available Yet" 220 | 221 | try: 222 | technique_detection = technique.x_mitre_detection 223 | except: 224 | technique_detection = [] 225 | 226 | try: 227 | technique_platforms = technique.x_mitre_platforms 228 | except: 229 | technique_platforms = [] 230 | 231 | try: 232 | is_sub_technique = technique.x_mitre_is_subtechnique 233 | except: 234 | is_sub_technique = False 235 | 236 | new_technique_node = { 237 | "id": technique_id, 238 | "type": node_type, 239 | "val": technique_val, 240 | "attributes": { 241 | "name": technique_name, 242 | "chain_phase": chain_phase, 243 | "description": technique_detection, 244 | "detection": technique_description, 245 | "is_subtype": is_sub_technique, 246 | "platforms": technique_platforms, 247 | } 248 | }, 249 | 250 | json_data["nodes"] += new_technique_node 251 | 252 | 253 | def main(): 254 | for group in groups: 255 | group_software = lift.get_software_used_by_group(group) 256 | group_techniques = lift.get_techniques_used_by_group(group) 257 | make_group_node(group, group_software, group_techniques, link_tool=True, lift_tool_techniques=True) 258 | 259 | print(f"Finished Group: {group.name}") 260 | 261 | with open('force_graph_data.json', 'w') as f: 262 | json.dump(json_data, f, ensure_ascii=False, indent=4) 263 | 264 | 265 | if __name__ == "__main__": 266 | main() -------------------------------------------------------------------------------- /frontend/dist/js/sidebar.js: -------------------------------------------------------------------------------- 1 | // --------------------------------- 2 | // INFO BAR - Sidebar 3 | // --------------------------------- 4 | 5 | // General 6 | 7 | function nodeColors(regualrColor, disabledColor) { 8 | document.getElementById("infoSidebar").style.borderLeft = "5px solid " + regualrColor; 9 | document.getElementById("set-name").style.color = regualrColor; 10 | document.getElementById("set-type").style.backgroundColor = regualrColor; 11 | document.getElementById("set-node-title").style.backgroundColor = disabledColor; 12 | document.getElementById("toggle-info-btn").style.backgroundColor = regualrColor; 13 | } 14 | 15 | export function setNodeColor(nodeType) { 16 | 17 | const groupColor = "#FF585B"; 18 | const groupDisabled = "rgba(255, 88, 91, .15)"; 19 | 20 | const toolColor = "#4BDFFF"; 21 | const toolDisabled = "rgba(4, 211, 255, .15)"; 22 | 23 | const techniqueColor = "#9157EB"; 24 | const techniqueDisabled = "rgba(91, 116, 231, .15)"; 25 | 26 | const defaultColor = "#4BFFBE"; 27 | const defaultDisabled = "#2bffbf6b"; 28 | 29 | 30 | if (nodeType === "group") { 31 | nodeColors(groupColor, groupDisabled); 32 | 33 | } else if (nodeType === "tool") { 34 | nodeColors(toolColor, toolDisabled); 35 | 36 | } else if (nodeType === "technique") { 37 | nodeColors(techniqueColor, techniqueDisabled); 38 | 39 | } else { 40 | nodeColors(defaultColor, defaultDisabled); 41 | } 42 | } 43 | 44 | function setMitreLink(nodeID, nodeType) { 45 | if (nodeID) { 46 | let mitreUrl = "" 47 | if (nodeID.indexOf(".") > -1) { 48 | const idToUrl = nodeID.replace(".", "/"); 49 | mitreUrl = `https://attack.mitre.org/${(nodeType != "tool") ? nodeType+"s" : "software"}/${idToUrl}/`; 50 | } else { 51 | mitreUrl = `https://attack.mitre.org/${(nodeType != "tool") ? nodeType+"s" : "software"}/${nodeID}/`; 52 | } 53 | document.getElementById("set-mitre-link").href = mitreUrl; 54 | document.getElementById("set-mitre-id").innerHTML = ` | ${nodeID}`; 55 | 56 | } else { 57 | document.getElementById("set-mitre-link").href = "https://attack.mitre.org/"; 58 | document.getElementById("set-mitre-id").innerHTML = " ATT&CK"; 59 | 60 | } 61 | 62 | } 63 | 64 | export function setNodeName(nodeName) { 65 | document.getElementById("set-name").innerHTML = nodeName; 66 | } 67 | 68 | export function setNodeType(nodeType) { 69 | document.getElementById("set-type").value = (nodeType != "technique") ? nodeType : "Techn." 70 | } 71 | 72 | function setChainPhase(nodeChainPhase) { 73 | document.getElementById("set-chain-phase").innerHTML = nodeChainPhase; 74 | } 75 | 76 | 77 | function setDescription(nodeDescription) { 78 | document.getElementById("set-description").innerHTML = nodeDescription; 79 | } 80 | 81 | // NODE SPECIFIC 82 | function setDetection(nodeDeteciton) { 83 | document.getElementById("set-detection").innerHTML = nodeDeteciton; 84 | } 85 | 86 | 87 | function setAliases(nodeAliases) { 88 | if (nodeAliases) { 89 | const aliases = nodeAliases; 90 | const aliasesList = document.getElementById("set-aliases"); 91 | aliasesList.innerHTML = ""; 92 | aliases.forEach(alias => { 93 | const li = document.createElement("li"); 94 | li.innerHTML = alias; 95 | aliasesList.appendChild(li); 96 | }); 97 | } 98 | } 99 | 100 | 101 | function setPlatformsTargeted(nodePlatforms) { 102 | if (nodePlatforms) { 103 | const platforms = nodePlatforms; 104 | const platformsList = document.getElementById("set-platforms-targeted"); 105 | platformsList.innerHTML = ""; 106 | platforms.forEach(platform => { 107 | const li = document.createElement("li"); 108 | li.innerHTML = platform; 109 | platformsList.appendChild(li); 110 | }); 111 | } 112 | 113 | } 114 | 115 | 116 | function setGroupTools(groupTools) { 117 | if (groupTools) { 118 | const toolsDiv = document.getElementById("set-group-tools"); 119 | toolsDiv.innerHTML = ""; 120 | for (const tool in groupTools) { 121 | const li = document.createElement("li"); 122 | li.innerHTML = groupTools[tool]; 123 | toolsDiv.appendChild(li); 124 | } 125 | } 126 | } 127 | 128 | 129 | function setGroupTechniques(groupTechniques) { 130 | if (groupTechniques) { 131 | const technqiuesList = document.getElementById("set-group-techniques"); 132 | technqiuesList.innerHTML = ""; 133 | for (const teq in groupTechniques) { 134 | const li = document.createElement("li"); 135 | li.innerHTML = groupTechniques[teq]; 136 | technqiuesList.appendChild(li); 137 | } 138 | } 139 | } 140 | 141 | 142 | function setToolTechniques(toolTechniques) { 143 | if (toolTechniques) { 144 | const techniquesList = document.getElementById("set-tool-techniques"); 145 | techniquesList.innerHTML = ""; 146 | for (const teq in toolTechniques) { 147 | const li = document.createElement("li"); 148 | li.innerHTML = toolTechniques[teq]; 149 | techniquesList.appendChild(li); 150 | } 151 | } 152 | } 153 | 154 | 155 | function setQuickStats(node, nodeType) { 156 | if (nodeType === "group") { 157 | const toolCount = document.getElementById("tools-count"); 158 | const techniqueCount = document.getElementById("technique-count"); 159 | 160 | const nodeToolCount = Object.keys(node.attributes.tools).length; 161 | toolCount.innerHTML = nodeToolCount; 162 | 163 | const nodeTechniqueCount = Object.keys(node.attributes.techniques).length; 164 | techniqueCount.innerHTML = nodeTechniqueCount; 165 | } 166 | 167 | } 168 | 169 | 170 | function showInfoSection(sectionID) { 171 | document.getElementById(`${sectionID}`).hidden = false; 172 | } 173 | 174 | function hideInfoSection(sectionID) { 175 | document.getElementById(`${sectionID}`).hidden = true; 176 | } 177 | 178 | 179 | function isValid(obj) { 180 | if (obj && ((obj.length > 0) || (Object.keys(obj).length > 0))) { 181 | return true 182 | } 183 | return false 184 | } 185 | 186 | function showGroupSpecifics(node) { 187 | if (node.type === "group") { 188 | setQuickStats(node, "group"); 189 | showInfoSection("group-quick-stats-box"); 190 | 191 | // GROUP TOOLS 192 | if (isValid(node.attributes.tools)) { 193 | showInfoSection("group-tools-box"); 194 | setGroupTools(node.attributes.tools); 195 | } 196 | // GROUP TECHNIQUES 197 | if (isValid(node.attributes.techniques)) { 198 | showInfoSection("group-techniques-box"); 199 | setGroupTechniques(node.attributes.techniques); 200 | } 201 | } else { 202 | hideInfoSection("group-quick-stats-box"); 203 | hideInfoSection("group-tools-box"); 204 | hideInfoSection("group-techniques-box"); 205 | } 206 | } 207 | 208 | function showToolSpecifics(node) { 209 | if (node.type === "tool") { 210 | // TOOL TECHNIQUES 211 | if (isValid(node.attributes.techniques)) { 212 | showInfoSection("tool-techniques-box"); 213 | setToolTechniques(node.attributes.techniques); 214 | } 215 | // PLATFORMS 216 | if (isValid(node.attributes.platforms)) { 217 | showInfoSection("platforms-targeted-box"); 218 | setPlatformsTargeted(node.attributes.platforms); 219 | } 220 | } else { 221 | hideInfoSection("tool-techniques-box"); 222 | hideInfoSection("platforms-targeted-box"); 223 | } 224 | } 225 | 226 | function showTechniqueSpecifics(node) { 227 | if (node.type == "technique") { 228 | // CHAIN PHASE 229 | if (isValid(node.attributes.chain_phase)) { 230 | showInfoSection("chain-phase-box"); 231 | setChainPhase(node.attributes.chain_phase); 232 | } 233 | // DETECTION 234 | if (isValid(node.attributes.detection)) { 235 | showInfoSection("detection-box"); 236 | setDetection(node.attributes.detection); 237 | } 238 | } else { 239 | hideInfoSection("chain-phase-box"); 240 | hideInfoSection("detection-box"); 241 | } 242 | } 243 | 244 | export function updateSideBar(node) { 245 | if (node) { 246 | setMitreLink(node.id, node.type); 247 | setNodeName(node.attributes.name); 248 | setNodeColor(node.type); 249 | setNodeType(node.type); 250 | 251 | // ALIASES 252 | if (isValid(node.attributes.aliases)) { 253 | showInfoSection("aliases-box"); 254 | setAliases(node.attributes.aliases); 255 | } else { 256 | hideInfoSection("aliases-box"); 257 | } 258 | 259 | // DESCRIPTION 260 | if (isValid(node.attributes.description)) { 261 | showInfoSection("description-box"); 262 | setDescription(node.attributes.description); 263 | } 264 | 265 | showGroupSpecifics(node); 266 | showToolSpecifics(node); 267 | showTechniqueSpecifics(node); 268 | 269 | hideInfoSection("about-what-box"); 270 | hideInfoSection("about-why-box"); 271 | hideInfoSection("about-credits-box"); 272 | 273 | 274 | } else { 275 | setMitreLink(); 276 | 277 | hideInfoSection("description-box"); 278 | hideInfoSection("aliases-box"); 279 | hideInfoSection("chain-phase-box"); 280 | hideInfoSection("detection-box"); 281 | hideInfoSection("platforms-targeted-box"); 282 | hideInfoSection("group-quick-stats-box"); 283 | hideInfoSection("group-tools-box"); 284 | hideInfoSection("group-techniques-box"); 285 | hideInfoSection("tool-techniques-box"); 286 | 287 | showInfoSection("about-what-box") 288 | showInfoSection("about-why-box") 289 | showInfoSection("about-credits-box") 290 | } 291 | 292 | openSidebar(); 293 | } -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 | 16 |

ATTACK-Force-Graph

17 |
18 |
19 |
20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 33 |
34 |
35 | Small Examples 36 |
37 |
38 |
39 | 42 | 43 | 44 | 47 | 48 | 51 |
52 | 53 | 54 |
55 | Full ATT&CK Data 56 |
57 |
58 |
59 | 62 | 63 | 66 | 67 | 70 |
71 | 72 |
73 |

Click a node to learn more about the group, tool, or technique!

74 |
75 | 78 |
79 | 80 | 81 | 319 | 320 |
321 |
322 |
323 |
324 |

Group

325 |
326 |
327 |
328 |

Tool

329 |
330 |
331 |
332 |

Technique

333 |
334 |
335 | 336 |
337 | 338 |
339 |
340 | 343 |
344 |
345 | 346 |
347 |
348 | Made with by osV22 349 |
350 |
351 |
352 |
353 |

354 | Left-click: rotate 355 |

356 | 357 |
358 |
359 |

360 | Mouse-wheel/ Middle-click: zoom 361 |

362 | 363 |
364 |
365 |

366 | Right-click: pan 367 |

368 |
369 |
370 | 371 |
372 |
373 |
374 |
375 | 376 |
377 | 378 | 379 | 380 | 381 | 382 | -------------------------------------------------------------------------------- /frontend/assets/icons/states/usa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/data/ex_groups.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": [ 3 | { 4 | "id": "G0123", 5 | "type": "group", 6 | "attributes": { 7 | "val": 2, 8 | "name": "Volatile Cedar", 9 | "aliases": [ 10 | "Lebanese Cedar" 11 | ], 12 | "description": "Volatile Cedar is a Lebanese threat group that has targeted individuals, companies, and institutions worldwide. Volatile Cedar has been operating since 2012 and is motivated by political and ideological interests.", 13 | "affiliation": "", 14 | "targets": [], 15 | "speciality": [], 16 | "tools": { 17 | "S0572": "Caterpillar WebShell", 18 | "S0569": "Explosive" 19 | }, 20 | "techniques": { 21 | "T1595.002": "Vulnerability Scanning", 22 | "T1505.003": "Web Shell", 23 | "T1190": "Exploit Public-Facing Application", 24 | "T1105": "Ingress Tool Transfer" 25 | } 26 | } 27 | }, 28 | { 29 | "id": "G0095", 30 | "type": "group", 31 | "attributes": { 32 | "val": 1, 33 | "name": "Machete", 34 | "aliases": [ 35 | "APT-C-43", 36 | "El Machete" 37 | ], 38 | "description": "Machete is a suspected Spanish-speaking cyber espionage group that has been active since at least 2010. It has primarily focused its operations within Latin America, with a particular emphasis on Venezuela, but also in the US, Europe, Russia, and parts of Asia. Machete generally targets high-profile organizations such as government institutions, intelligence services, and military units, as well as telecommunications and power companies.", 39 | "affiliation": "", 40 | "targets": [], 41 | "speciality": [], 42 | "tools": { 43 | "S0409": "Machete" 44 | }, 45 | "techniques": { 46 | "T1204.002": "Malicious File", 47 | "T1204.001": "Malicious Link", 48 | "T1059.006": "Python", 49 | "T1059.005": "Visual Basic", 50 | "T1059.003": "Windows Command Shell", 51 | "T1566.002": "Spearphishing Link", 52 | "T1566.001": "Spearphishing Attachment", 53 | "T1036.005": "Match Legitimate Name or Location", 54 | "T1218.007": "Msiexec", 55 | "T1053.005": "Scheduled Task", 56 | "T1189": "Drive-by Compromise", 57 | "T1032": "Standard Cryptographic Protocol" 58 | } 59 | } 60 | }, 61 | { 62 | "id": "G0086", 63 | "type": "group", 64 | "attributes": { 65 | "val": 2, 66 | "name": "Stolen Pencil", 67 | "aliases": [], 68 | "description": "Stolen Pencil is a threat group likely originating from DPRK that has been active since at least May 2018. The group appears to have targeted academic institutions, but its motives remain unclear.", 69 | "affiliation": "", 70 | "targets": [], 71 | "speciality": [], 72 | "tools": { 73 | "S0029": "PsExec", 74 | "S0002": "Mimikatz" 75 | }, 76 | "techniques": { 77 | "T1078.003": "Local Accounts", 78 | "T1566.002": "Spearphishing Link", 79 | "T1555.003": "Credentials from Web Browsers", 80 | "T1056.001": "Keylogging", 81 | "T1003.001": "LSASS Memory", 82 | "T1021.001": "Remote Desktop Protocol", 83 | "T1552.001": "Credentials In Files", 84 | "T1176": "Browser Extensions", 85 | "T1040": "Network Sniffing" 86 | } 87 | } 88 | }, 89 | { 90 | "id": "G0075", 91 | "type": "group", 92 | "attributes": { 93 | "val": 4, 94 | "name": "Rancor", 95 | "aliases": [], 96 | "description": "Rancor is a threat group that has led targeted campaigns against the South East Asia region. Rancor uses politically-motivated lures to entice victims to open malicious documents.", 97 | "affiliation": "", 98 | "targets": [], 99 | "speciality": [], 100 | "tools": { 101 | "S0254": "PLAINTEE", 102 | "S0255": "DDKONG", 103 | "S0160": "certutil", 104 | "S0075": "Reg" 105 | }, 106 | "techniques": { 107 | "T1071.001": "Web Protocols", 108 | "T1204.002": "Malicious File", 109 | "T1059.005": "Visual Basic", 110 | "T1059.003": "Windows Command Shell", 111 | "T1566.001": "Spearphishing Attachment", 112 | "T1218.007": "Msiexec", 113 | "T1053.005": "Scheduled Task", 114 | "T1105": "Ingress Tool Transfer" 115 | } 116 | } 117 | }, 118 | { 119 | "id": "G0059", 120 | "type": "group", 121 | "attributes": { 122 | "val": 4, 123 | "name": "Magic Hound", 124 | "aliases": [ 125 | "COBALT ILLUSION", 126 | "Charming Kitten", 127 | "ITG18", 128 | "Phosphorus", 129 | "Newscaster", 130 | "APT35" 131 | ], 132 | "description": "Magic Hound is an Iranian-sponsored threat group that conducts long term, resource-intensive cyber espionage operations, dating back as early as 2014. The group typically targets U.S. and Middle Eastern military organizations, as well as other government personnel, via complex social engineering campaigns.", 133 | "affiliation": "", 134 | "targets": [], 135 | "speciality": [], 136 | "tools": { 137 | "S0192": "Pupy", 138 | "S0186": "DownPaper", 139 | "S0029": "PsExec", 140 | "S0002": "Mimikatz" 141 | }, 142 | "techniques": { 143 | "T1589.001": "Credentials", 144 | "T1586.002": "Email Accounts", 145 | "T1585.002": "Email Accounts", 146 | "T1071.001": "Web Protocols", 147 | "T1102.002": "Bidirectional Communication", 148 | "T1571": "Non-Standard Port", 149 | "T1564.003": "Hidden Window", 150 | "T1059.005": "Visual Basic", 151 | "T1059.003": "Windows Command Shell", 152 | "T1059.001": "PowerShell", 153 | "T1566.003": "Spearphishing via Service", 154 | "T1566.002": "Spearphishing Link", 155 | "T1560.001": "Archive via Utility", 156 | "T1114.001": "Local Email Collection", 157 | "T1056.001": "Keylogging", 158 | "T1003.001": "LSASS Memory", 159 | "T1070.004": "File Deletion", 160 | "T1547.001": "Registry Run Keys / Startup Folder", 161 | "T1098.002": "Exchange Email Delegate Permissions", 162 | "T1113": "Screen Capture", 163 | "T1105": "Ingress Tool Transfer", 164 | "T1083": "File and Directory Discovery", 165 | "T1082": "System Information Discovery", 166 | "T1071": "Application Layer Protocol", 167 | "T1065": "Uncommonly Used Port", 168 | "T1057": "Process Discovery", 169 | "T1043": "Commonly Used Port", 170 | "T1033": "System Owner/User Discovery", 171 | "T1027": "Obfuscated Files or Information", 172 | "T1016": "System Network Configuration Discovery" 173 | } 174 | } 175 | }, 176 | { 177 | "id": "G0055", 178 | "type": "group", 179 | "attributes": { 180 | "val": 1, 181 | "name": "NEODYMIUM", 182 | "aliases": [], 183 | "description": "NEODYMIUM is an activity group that conducted a campaign in May 2016 and has heavily targeted Turkish victims. The group has demonstrated similarity to another activity group called PROMETHIUM due to overlapping victim and campaign characteristics. NEODYMIUM is reportedly associated closely with BlackOasis operations, but evidence that the group names are aliases has not been identified.", 184 | "affiliation": "", 185 | "targets": [], 186 | "speciality": [], 187 | "tools": { 188 | "S0176": "Wingbird" 189 | }, 190 | "techniques": {} 191 | } 192 | }, 193 | { 194 | "id": "G0049", 195 | "type": "group", 196 | "attributes": { 197 | "val": 20, 198 | "name": "OilRig", 199 | "aliases": [ 200 | "COBALT GYPSY", 201 | "IRN2", 202 | "HELIX KITTEN", 203 | "APT34" 204 | ], 205 | "description": "OilRig is a suspected Iranian threat group that has targeted Middle Eastern and international victims since at least 2014. The group has targeted a variety of industries, including financial, government, energy, chemical, and telecommunications, and has largely focused its operations within the Middle East. It appears the group carries out supply chain attacks, leveraging the trust relationship between organizations to attack their primary targets. FireEye assesses that the group works on behalf of the Iranian government based on infrastructure details that contain references to Iran, use of Iranian infrastructure, and targeting that aligns with nation-state interests. This group was previously tracked under two distinct groups, APT34 and OilRig, but was combined due to additional reporting giving higher confidence about the overlap of the activity.", 206 | "affiliation": "", 207 | "targets": [], 208 | "speciality": [], 209 | "tools": { 210 | "S0495": "RDAT", 211 | "S0360": "BONDUPDATER", 212 | "S0349": "LaZagne", 213 | "S0264": "OopsIE", 214 | "S0269": "QUADAGENT", 215 | "S0258": "RGDoor", 216 | "S0185": "SEASHARPEE", 217 | "S0189": "ISMInjector", 218 | "S0184": "POWRUNER", 219 | "S0170": "Helminth", 220 | "S0160": "certutil", 221 | "S0104": "netstat", 222 | "S0100": "ipconfig", 223 | "S0096": "Systeminfo", 224 | "S0095": "FTP", 225 | "S0075": "Reg", 226 | "S0057": "Tasklist", 227 | "S0039": "Net", 228 | "S0029": "PsExec", 229 | "S0002": "Mimikatz" 230 | }, 231 | "techniques": { 232 | "T1555.004": "Windows Credential Manager", 233 | "T1027.005": "Indicator Removal from Tools", 234 | "T1573.002": "Asymmetric Cryptography", 235 | "T1071.004": "DNS", 236 | "T1071.001": "Web Protocols", 237 | "T1572": "Protocol Tunneling", 238 | "T1048.003": "Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol", 239 | "T1069.001": "Local Groups", 240 | "T1204.002": "Malicious File", 241 | "T1204.001": "Malicious Link", 242 | "T1059.003": "Windows Command Shell", 243 | "T1059.001": "PowerShell", 244 | "T1566.003": "Spearphishing via Service", 245 | "T1566.002": "Spearphishing Link", 246 | "T1566.001": "Spearphishing Attachment", 247 | "T1069.002": "Domain Groups", 248 | "T1087.002": "Domain Account", 249 | "T1087.001": "Local Account", 250 | "T1003.004": "LSA Secrets", 251 | "T1003.005": "Cached Domain Credentials", 252 | "T1555.003": "Credentials from Web Browsers", 253 | "T1056.001": "Keylogging", 254 | "T1555": "Credentials from Password Stores", 255 | "T1003.001": "LSASS Memory", 256 | "T1021.004": "SSH", 257 | "T1021.001": "Remote Desktop Protocol", 258 | "T1552.001": "Credentials In Files", 259 | "T1070.004": "File Deletion", 260 | "T1218.001": "Compiled HTML File", 261 | "T1505.003": "Web Shell", 262 | "T1053.005": "Scheduled Task", 263 | "T1137.004": "Outlook Home Page", 264 | "T1201": "Password Policy Discovery", 265 | "T1140": "Deobfuscate/Decode Files or Information", 266 | "T1133": "External Remote Services", 267 | "T1119": "Automated Collection", 268 | "T1113": "Screen Capture", 269 | "T1110": "Brute Force", 270 | "T1105": "Ingress Tool Transfer", 271 | "T1094": "Custom Command and Control Protocol", 272 | "T1082": "System Information Discovery", 273 | "T1078": "Valid Accounts", 274 | "T1059": "Command and Scripting Interpreter", 275 | "T1057": "Process Discovery", 276 | "T1049": "System Network Connections Discovery", 277 | "T1047": "Windows Management Instrumentation", 278 | "T1046": "Network Service Scanning", 279 | "T1043": "Commonly Used Port", 280 | "T1033": "System Owner/User Discovery", 281 | "T1027": "Obfuscated Files or Information", 282 | "T1016": "System Network Configuration Discovery", 283 | "T1012": "Query Registry", 284 | "T1008": "Fallback Channels", 285 | "T1007": "System Service Discovery", 286 | "T0853": "Scripting", 287 | "T0869": "Standard Application Layer Protocol", 288 | "T0859": "Valid Accounts", 289 | "T0865": "Spearphishing Attachment", 290 | "T0817": "Drive-by Compromise" 291 | } 292 | } 293 | }, 294 | { 295 | "id": "G0034", 296 | "type": "group", 297 | "attributes": { 298 | "val": 10, 299 | "name": "Sandworm Team", 300 | "aliases": [ 301 | "ELECTRUM", 302 | "Telebots", 303 | "IRON VIKING", 304 | "BlackEnergy (Group)", 305 | "Quedagh", 306 | "VOODOO BEAR" 307 | ], 308 | "description": "Sandworm Team is a destructive threat group that has been attributed to Russia's General Staff Main Intelligence Directorate (GRU) Main Center for Special Technologies (GTsST) military unit 74455. This group has been active since at least 2009.\n\nIn October 2020, the US indicted six GRU Unit 74455 officers associated with Sandworm Team for the following cyber operations: the 2015 and 2016 attacks against Ukrainian electrical companies and government organizations, the 2017 worldwide NotPetya attack, targeting of the 2017 French presidential campaign, the 2018 Olympic Destroyer attack against the Winter Olympic Games, the 2018 operation against the Organisation for the Prohibition of Chemical Weapons, and attacks against the country of Georgia in 2018 and 2019. Some of these were conducted with the assistance of GRU Unit 26165, which is also referred to as APT28.", 309 | "affiliation": "", 310 | "targets": [], 311 | "speciality": [], 312 | "tools": { 313 | "S0598": "P.A.S. Webshell", 314 | "S0401": "Exaramel for Linux", 315 | "S0368": "NotPetya", 316 | "S0365": "Olympic Destroyer", 317 | "S0343": "Exaramel for Windows", 318 | "S0231": "Invoke-PSImage", 319 | "S0089": "BlackEnergy", 320 | "S0555": "CHEMISTGAMES", 321 | "S1004": "Industroyer", 322 | "S1005": "Killdisk" 323 | }, 324 | "techniques": { 325 | "T1588.006": "Vulnerabilities", 326 | "T1598.003": "Spearphishing Link", 327 | "T1595.002": "Vulnerability Scanning", 328 | "T1594": "Search Victim-Owned Websites", 329 | "T1593": "Search Open Websites/Domains", 330 | "T1592.002": "Software", 331 | "T1591.002": "Business Relationships", 332 | "T1590.001": "Domain Properties", 333 | "T1589.003": "Employee Names", 334 | "T1589.002": "Email Addresses", 335 | "T1588.002": "Tool", 336 | "T1587.001": "Malware", 337 | "T1585.002": "Email Accounts", 338 | "T1585.001": "Social Media Accounts", 339 | "T1583.004": "Server", 340 | "T1583.001": "Domains", 341 | "T1071.001": "Web Protocols", 342 | "T1132.001": "Standard Encoding", 343 | "T1102.002": "Bidirectional Communication", 344 | "T1571": "Non-Standard Port", 345 | "T1078.002": "Domain Accounts", 346 | "T1204.002": "Malicious File", 347 | "T1204.001": "Malicious Link", 348 | "T1195.002": "Compromise Software Supply Chain", 349 | "T1059.005": "Visual Basic", 350 | "T1059.001": "PowerShell", 351 | "T1566.002": "Spearphishing Link", 352 | "T1566.001": "Spearphishing Attachment", 353 | "T1087.003": "Email Account", 354 | "T1087.002": "Domain Account", 355 | "T1561.002": "Disk Structure Wipe", 356 | "T1491.002": "External Defacement", 357 | "T1555.003": "Credentials from Web Browsers", 358 | "T1056.001": "Keylogging", 359 | "T1003.001": "LSASS Memory", 360 | "T1036.005": "Match Legitimate Name or Location", 361 | "T1070.004": "File Deletion", 362 | "T1218.011": "Rundll32", 363 | "T1505.003": "Web Shell", 364 | "T1499": "Endpoint Denial of Service", 365 | "T1485": "Data Destruction", 366 | "T1219": "Remote Access Software", 367 | "T1203": "Exploitation for Client Execution", 368 | "T1199": "Trusted Relationship", 369 | "T1140": "Deobfuscate/Decode Files or Information", 370 | "T1133": "External Remote Services", 371 | "T1105": "Ingress Tool Transfer", 372 | "T1090": "Proxy", 373 | "T1083": "File and Directory Discovery", 374 | "T1082": "System Information Discovery", 375 | "T1078": "Valid Accounts", 376 | "T1049": "System Network Connections Discovery", 377 | "T1041": "Exfiltration Over C2 Channel", 378 | "T1040": "Network Sniffing", 379 | "T1033": "System Owner/User Discovery", 380 | "T1027": "Obfuscated Files or Information", 381 | "T1018": "Remote System Discovery", 382 | "T1016": "System Network Configuration Discovery", 383 | "T1005": "Data from Local System", 384 | "T0886": "Remote Services", 385 | "T0822": "External Remote Services", 386 | "T0859": "Valid Accounts", 387 | "T0819": "Exploit Public-Facing Application", 388 | "T0823": "Graphical User Interface", 389 | "T0857": "System Firmware", 390 | "T0803": "Block Command Message", 391 | "T0816": "Device Restart/Shutdown", 392 | "T0865": "Spearphishing Attachment", 393 | "T0804": "Block Reporting Message", 394 | "T0855": "Unauthorized Command Message" 395 | } 396 | } 397 | }, 398 | { 399 | "id": "G0032", 400 | "type": "group", 401 | "attributes": { 402 | "val": 23, 403 | "name": "Lazarus Group", 404 | "aliases": [ 405 | "HIDDEN COBRA", 406 | "Guardians of Peace", 407 | "ZINC", 408 | "NICKEL ACADEMY" 409 | ], 410 | "description": "Lazarus Group is a threat group that has been attributed to the North Korean government. The group has been active since at least 2009 and was reportedly responsible for the November 2014 destructive wiper attack against Sony Pictures Entertainment as part of a campaign named Operation Blockbuster by Novetta. Malware used by Lazarus Group correlates to other reported campaigns, including Operation Flame, Operation 1Mission, Operation Troy, DarkSeoul, and Ten Days of Rain. In late 2017, Lazarus Group used KillDisk, a disk-wiping tool, in an attack against an online casino based in Central America. \n\nNorth Korean group definitions are known to have significant overlap, and the name Lazarus Group is known to encompass a broad range of activity. Some organizations use the name Lazarus Group to refer to any activity attributed to North Korea. Some organizations track North Korean clusters or groups such as Bluenoroff, APT37, and APT38 separately, while other organizations may track some activity associated with those group names by the name Lazarus Group.", 411 | "affiliation": "", 412 | "targets": [], 413 | "speciality": [], 414 | "tools": { 415 | "S0593": "ECCENTRICBANDWAGON", 416 | "S0586": "TAINTEDSCRIBE", 417 | "S0584": "AppleJeus", 418 | "S0567": "Dtrack", 419 | "S0520": "BLINDINGCAN", 420 | "S0498": "Cryptoistic", 421 | "S0497": "Dacls", 422 | "S0431": "HotCroissant", 423 | "S0376": "HOPLIGHT", 424 | "S0366": "WannaCry", 425 | "S0364": "RawDisk", 426 | "S0347": "AuditCred", 427 | "S0245": "BADCALL", 428 | "S0246": "HARDRAIN", 429 | "S0241": "RATANKBA", 430 | "S0239": "Bankshot", 431 | "S0271": "KEYMARBLE", 432 | "S0238": "Proxysvc", 433 | "S0263": "TYPEFRAME", 434 | "S0180": "Volgmer", 435 | "S0181": "FALLCHILL", 436 | "S0108": "netsh", 437 | "S0002": "Mimikatz" 438 | }, 439 | "techniques": { 440 | "T1588.004": "Digital Certificates", 441 | "T1587.001": "Malware", 442 | "T1583.006": "Web Services", 443 | "T1583.001": "Domains", 444 | "T1573.001": "Symmetric Cryptography", 445 | "T1071.001": "Web Protocols", 446 | "T1048.003": "Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol", 447 | "T1001.003": "Protocol Impersonation", 448 | "T1132.001": "Standard Encoding", 449 | "T1090.002": "External Proxy", 450 | "T1571": "Non-Standard Port", 451 | "T1074.001": "Local Data Staging", 452 | "T1204.002": "Malicious File", 453 | "T1059.005": "Visual Basic", 454 | "T1059.003": "Windows Command Shell", 455 | "T1059.001": "PowerShell", 456 | "T1566.003": "Spearphishing via Service", 457 | "T1566.001": "Spearphishing Attachment", 458 | "T1564.001": "Hidden Files and Directories", 459 | "T1562.004": "Disable or Modify System Firewall", 460 | "T1562.001": "Disable or Modify Tools", 461 | "T1561.002": "Disk Structure Wipe", 462 | "T1561.001": "Disk Content Wipe", 463 | "T1560.003": "Archive via Custom Method", 464 | "T1560.002": "Archive via Library", 465 | "T1560": "Archive Collected Data", 466 | "T1491.001": "Internal Defacement", 467 | "T1134.002": "Create Process with Token", 468 | "T1056.001": "Keylogging", 469 | "T1003.001": "LSASS Memory", 470 | "T1110.003": "Password Spraying", 471 | "T1021.002": "SMB/Windows Admin Shares", 472 | "T1021.001": "Remote Desktop Protocol", 473 | "T1036.005": "Match Legitimate Name or Location", 474 | "T1036.004": "Masquerade Task or Service", 475 | "T1027.002": "Software Packing", 476 | "T1070.006": "Timestomp", 477 | "T1070.004": "File Deletion", 478 | "T1547.009": "Shortcut Modification", 479 | "T1547.005": "Security Support Provider", 480 | "T1547.001": "Registry Run Keys / Startup Folder", 481 | "T1218.005": "Mshta", 482 | "T1218.001": "Compiled HTML File", 483 | "T1543.003": "Windows Service", 484 | "T1055.001": "Dynamic-link Library Injection", 485 | "T1542.003": "Bootkit", 486 | "T1529": "System Shutdown/Reboot", 487 | "T1496": "Resource Hijacking", 488 | "T1489": "Service Stop", 489 | "T1485": "Data Destruction", 490 | "T1189": "Drive-by Compromise", 491 | "T1203": "Exploitation for Client Execution", 492 | "T1124": "System Time Discovery", 493 | "T1112": "Modify Registry", 494 | "T1105": "Ingress Tool Transfer", 495 | "T1098": "Account Manipulation", 496 | "T1083": "File and Directory Discovery", 497 | "T1082": "System Information Discovery", 498 | "T1065": "Uncommonly Used Port", 499 | "T1057": "Process Discovery", 500 | "T1047": "Windows Management Instrumentation", 501 | "T1043": "Commonly Used Port", 502 | "T1041": "Exfiltration Over C2 Channel", 503 | "T1033": "System Owner/User Discovery", 504 | "T1027": "Obfuscated Files or Information", 505 | "T1026": "Multiband Communication", 506 | "T1016": "System Network Configuration Discovery", 507 | "T1012": "Query Registry", 508 | "T1010": "Application Window Discovery", 509 | "T1008": "Fallback Channels", 510 | "T1005": "Data from Local System", 511 | "T0865": "Spearphishing Attachment" 512 | } 513 | } 514 | }, 515 | { 516 | "id": "G0020", 517 | "type": "group", 518 | "attributes": { 519 | "val": 0, 520 | "name": "Equation", 521 | "aliases": [], 522 | "description": "Equation is a sophisticated threat group that employs multiple remote access tools. The group is known to use zero-day exploits and has developed the capability to overwrite the firmware of hard disk drives.", 523 | "affiliation": "", 524 | "targets": [], 525 | "speciality": [], 526 | "tools": [], 527 | "techniques": { 528 | "T1564.005": "Hidden File System", 529 | "T1480.001": "Environmental Keying", 530 | "T1542.002": "Component Firmware", 531 | "T1120": "Peripheral Device Discovery", 532 | "T1109": "Component Firmware" 533 | } 534 | } 535 | }, 536 | { 537 | "id": "G0016", 538 | "type": "group", 539 | "attributes": { 540 | "val": 34, 541 | "name": "APT29", 542 | "aliases": [ 543 | "Dark Halo", 544 | "StellarParticle", 545 | "NOBELIUM", 546 | "UNC2452", 547 | "YTTRIUM", 548 | "The Dukes", 549 | "Cozy Bear", 550 | "CozyDuke" 551 | ], 552 | "description": "APT29 is threat group that has been attributed to Russia's Foreign Intelligence Service (SVR). They have operated since at least 2008, often targeting government networks in Europe and NATO member countries, research institutes, and think tanks. APT29 reportedly compromised the Democratic National Committee starting in the summer of 2015.\n\nIn April 2021, the US and UK governments attributed the SolarWinds supply chain compromise cyber operation to the SVR; public statements included citations to APT29, Cozy Bear, and The Dukes. Victims of this campaign included government, consulting, technology, telecom, and other organizations in North America, Europe, Asia, and the Middle East. Industry reporting referred to the actors involved in this campaign as UNC2452, NOBELIUM, StellarParticle, and Dark Halo.", 553 | "affiliation": "", 554 | "targets": [], 555 | "speciality": [], 556 | "tools": { 557 | "S0597": "GoldFinder", 558 | "S0589": "Sibot", 559 | "S0588": "GoldMax", 560 | "S0565": "Raindrop", 561 | "S0562": "SUNSPOT", 562 | "S0560": "TEARDROP", 563 | "S0559": "SUNBURST", 564 | "S0552": "AdFind", 565 | "S0516": "SoreFang", 566 | "S0515": "WellMail", 567 | "S0514": "WellMess", 568 | "S0511": "RegDuke", 569 | "S0518": "PolyglotDuke", 570 | "S0195": "SDelete", 571 | "S0183": "Tor", 572 | "S0175": "meek", 573 | "S0154": "Cobalt Strike", 574 | "S0150": "POSHSPY", 575 | "S0139": "PowerDuke", 576 | "S0100": "ipconfig", 577 | "S0096": "Systeminfo", 578 | "S0057": "Tasklist", 579 | "S0054": "CloudDuke", 580 | "S0053": "SeaDuke", 581 | "S0052": "OnionDuke", 582 | "S0051": "MiniDuke", 583 | "S0050": "CosmicDuke", 584 | "S0049": "GeminiDuke", 585 | "S0048": "PinchDuke", 586 | "S0046": "CozyCar", 587 | "S0039": "Net", 588 | "S0037": "HAMMERTOSS", 589 | "S0029": "PsExec", 590 | "S0002": "Mimikatz" 591 | }, 592 | "techniques": { 593 | "T1016.001": "Internet Connection Discovery", 594 | "T1484.002": "Domain Trust Modification", 595 | "T1606.002": "SAML Tokens", 596 | "T1606.001": "Web Cookies", 597 | "T1587.003": "Digital Certificates", 598 | "T1587.001": "Malware", 599 | "T1584.001": "Domains", 600 | "T1583.006": "Web Services", 601 | "T1583.001": "Domains", 602 | "T1071.001": "Web Protocols", 603 | "T1048.002": "Exfiltration Over Asymmetric Encrypted Non-C2 Protocol", 604 | "T1001.002": "Steganography", 605 | "T1090.004": "Domain Fronting", 606 | "T1090.003": "Multi-hop Proxy", 607 | "T1090.001": "Internal Proxy", 608 | "T1102.002": "Bidirectional Communication", 609 | "T1074.002": "Remote Data Staging", 610 | "T1078.002": "Domain Accounts", 611 | "T1204.002": "Malicious File", 612 | "T1204.001": "Malicious Link", 613 | "T1195.002": "Compromise Software Supply Chain", 614 | "T1568": "Dynamic Resolution", 615 | "T1059.006": "Python", 616 | "T1059.003": "Windows Command Shell", 617 | "T1059.001": "PowerShell", 618 | "T1566.002": "Spearphishing Link", 619 | "T1566.001": "Spearphishing Attachment", 620 | "T1562.004": "Disable or Modify System Firewall", 621 | "T1562.002": "Disable Windows Event Logging", 622 | "T1562.001": "Disable or Modify Tools", 623 | "T1560.001": "Archive via Utility", 624 | "T1114.002": "Remote Email Collection", 625 | "T1555": "Credentials from Password Stores", 626 | "T1003.006": "DCSync", 627 | "T1558.003": "Kerberoasting", 628 | "T1021.006": "Windows Remote Management", 629 | "T1036.005": "Match Legitimate Name or Location", 630 | "T1036.004": "Masquerade Task or Service", 631 | "T1553.002": "Code Signing", 632 | "T1027.002": "Software Packing", 633 | "T1552.004": "Private Keys", 634 | "T1070.006": "Timestomp", 635 | "T1070.004": "File Deletion", 636 | "T1550.004": "Web Session Cookie", 637 | "T1550.003": "Pass the Ticket", 638 | "T1550": "Use Alternate Authentication Material", 639 | "T1548.002": "Bypass User Account Control", 640 | "T1547.009": "Shortcut Modification", 641 | "T1546.008": "Accessibility Features", 642 | "T1546.003": "Windows Management Instrumentation Event Subscription", 643 | "T1547.001": "Registry Run Keys / Startup Folder", 644 | "T1218.011": "Rundll32", 645 | "T1098.002": "Exchange Email Delegate Permissions", 646 | "T1098.001": "Additional Cloud Credentials", 647 | "T1053.005": "Scheduled Task", 648 | "T1482": "Domain Trust Discovery", 649 | "T1190": "Exploit Public-Facing Application", 650 | "T1203": "Exploitation for Client Execution", 651 | "T1140": "Deobfuscate/Decode Files or Information", 652 | "T1133": "External Remote Services", 653 | "T1105": "Ingress Tool Transfer", 654 | "T1095": "Non-Application Layer Protocol", 655 | "T1087": "Account Discovery", 656 | "T1083": "File and Directory Discovery", 657 | "T1082": "System Information Discovery", 658 | "T1078": "Valid Accounts", 659 | "T1070": "Indicator Removal on Host", 660 | "T1069": "Permission Groups Discovery", 661 | "T1057": "Process Discovery", 662 | "T1047": "Windows Management Instrumentation", 663 | "T1043": "Commonly Used Port", 664 | "T1036": "Masquerading", 665 | "T1027": "Obfuscated Files or Information", 666 | "T1018": "Remote System Discovery", 667 | "T1005": "Data from Local System" 668 | } 669 | } 670 | }, 671 | { 672 | "id": "G0006", 673 | "type": "group", 674 | "attributes": { 675 | "val": 17, 676 | "name": "APT1", 677 | "aliases": [ 678 | "Comment Crew", 679 | "Comment Group", 680 | "Comment Panda" 681 | ], 682 | "description": "APT1 is a Chinese threat group that has been attributed to the 2nd Bureau of the People’s Liberation Army (PLA) General Staff Department’s (GSD) 3rd Department, commonly known by its Military Unit Cover Designator (MUCD) as Unit 61398.", 683 | "affiliation": "", 684 | "targets": [], 685 | "speciality": [], 686 | "tools": { 687 | "S0345": "Seasalt", 688 | "S0123": "xCmd", 689 | "S0122": "Pass-The-Hash Toolkit", 690 | "S0121": "Lslsass", 691 | "S0119": "Cachedump", 692 | "S0109": "WEBC2", 693 | "S0100": "ipconfig", 694 | "S0057": "Tasklist", 695 | "S0039": "Net", 696 | "S0029": "PsExec", 697 | "S0026": "GLOOXMAIL", 698 | "S0025": "CALENDAR", 699 | "S0017": "BISCUIT", 700 | "S0012": "PoisonIvy", 701 | "S0008": "gsecdump", 702 | "S0006": "pwdump", 703 | "S0002": "Mimikatz" 704 | }, 705 | "techniques": { 706 | "T1588.001": "Malware", 707 | "T1585.002": "Email Accounts", 708 | "T1584.001": "Domains", 709 | "T1583.001": "Domains", 710 | "T1059.003": "Windows Command Shell", 711 | "T1566.002": "Spearphishing Link", 712 | "T1566.001": "Spearphishing Attachment", 713 | "T1087.001": "Local Account", 714 | "T1560.001": "Archive via Utility", 715 | "T1114.002": "Remote Email Collection", 716 | "T1114.001": "Local Email Collection", 717 | "T1003.001": "LSASS Memory", 718 | "T1021.001": "Remote Desktop Protocol", 719 | "T1036.005": "Match Legitimate Name or Location", 720 | "T1550.002": "Pass the Hash", 721 | "T1135": "Network Share Discovery", 722 | "T1119": "Automated Collection", 723 | "T1057": "Process Discovery", 724 | "T1049": "System Network Connections Discovery", 725 | "T1016": "System Network Configuration Discovery", 726 | "T1007": "System Service Discovery", 727 | "T1005": "Data from Local System", 728 | "T1346": "Obtain/re-use payloads", 729 | "T1330": "Acquire and/or use 3rd party software services", 730 | "T1312": "Compromise 3rd party infrastructure to support delivery", 731 | "T1333": "Dynamic DNS", 732 | "T1326": "Domain registration hijacking" 733 | } 734 | } 735 | } 736 | ], 737 | "links": [] 738 | } -------------------------------------------------------------------------------- /frontend/assets/icons/states/world.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --------------------------------------------------------------------------------