Files
atomic-red-team-gs/bin/generate-atomic-docs.rb
T

538 lines
27 KiB
Ruby
Raw Normal View History

2018-05-10 13:26:34 -06:00
#! /usr/bin/env ruby
$LOAD_PATH << "#{File.dirname(File.dirname(__FILE__))}/atomic_red_team" unless $LOAD_PATH.include? "#{File.dirname(File.dirname(__FILE__))}/atomic_red_team"
2018-05-10 13:26:34 -06:00
require 'erb'
2018-05-11 07:29:16 +02:00
require 'fileutils'
require 'json'
require 'atomic_red_team'
require 'csv'
2018-05-11 05:38:02 +02:00
class AtomicRedTeamDocs
ATTACK_API = Attack.new
ATOMIC_RED_TEAM = AtomicRedTeam.new
ATOMIC_RED_TEAM_DIR = "#{File.dirname(File.dirname(__FILE__))}/atomic_red_team"
2018-05-11 05:38:02 +02:00
2018-05-11 05:59:03 +02:00
#
# Generates all the documentation used by Atomic Red Team
#
2018-05-11 05:38:02 +02:00
def generate_all_the_docs!
oks = []
fails = []
ATOMIC_RED_TEAM.atomic_tests.each do |atomic_yaml|
2020-05-14 18:53:36 -06:00
begin
print "Generating docs for #{atomic_yaml['atomic_yaml_path']}"
generate_technique_docs! atomic_yaml, atomic_yaml['atomic_yaml_path'].gsub(/.yaml/, '.md')
# generate_technique_execution_docs! atomic_yaml, "#{File.dirname(File.dirname(__FILE__))}/atomic-red-team-execution/#{atomic_yaml['attack_technique'].downcase}.html"
2020-05-14 18:52:16 -06:00
2020-05-14 18:53:36 -06:00
oks << atomic_yaml['atomic_yaml_path']
puts "OK"
rescue => ex
fails << atomic_yaml['atomic_yaml_path']
puts "FAIL\n#{ex}\n#{ex.backtrace.join("\n")}"
end
2018-05-11 04:09:32 +02:00
end
2020-05-14 18:53:36 -06:00
puts
puts "Generated docs for #{oks.count} techniques, #{fails.count} failures"
2020-05-14 18:53:36 -06:00
generate_attack_matrix! 'All', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Matrices/matrix.md"
generate_attack_matrix! 'Windows', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Matrices/windows-matrix.md", only_platform: /windows/
generate_attack_matrix! 'macOS', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Matrices/macos-matrix.md", only_platform: /macos/
2022-09-09 11:12:47 -06:00
generate_attack_matrix! 'Linux', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Matrices/linux-matrix.md", only_platform: /linux/
2025-05-01 11:12:40 -04:00
generate_attack_matrix! 'ESXi', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Matrices/esxi-matrix.md", only_platform: /esxi/
2020-05-14 18:52:16 -06:00
2020-05-14 18:53:36 -06:00
generate_index! 'All', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/index.md"
2024-11-19 20:34:41 -05:00
generate_index! 'Windows', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/windows-index.md", only_platform: /windows/, attack_platform: /windows/
generate_index! 'macOS', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/macos-index.md", only_platform: /macos/, attack_platform: /windows/
generate_index! 'Linux', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/linux-index.md", only_platform: /linux/, attack_platform: /windows/
generate_index! 'IaaS', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/iaas-index.md", only_platform: /iaas/, attack_platform: /windows/
generate_index! 'Containers', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/containers-index.md", only_platform: /containers/, attack_platform: /windows/
generate_index! 'Office 365', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/office-365-index.md", only_platform: /office-365/, attack_platform: /office/
generate_index! 'Google Workspace', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/google-workspace-index.md", only_platform: /google-workspace/, attack_platform: /office/
generate_index! 'Azure AD', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/azure-ad-index.md", only_platform: /azure-ad/, attack_platform: /identity/
2025-05-01 11:12:40 -04:00
generate_index! 'ESXi', "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-Markdown/esxi-index.md", only_platform: /esxi/, attack_platform: /esxi/
2020-05-14 18:52:16 -06:00
2020-05-14 18:53:36 -06:00
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/index.csv"
2024-11-19 20:34:41 -05:00
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/windows-index.csv", only_platform: /windows/, attack_platform: /windows/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/macos-index.csv", only_platform: /macos/, attack_platform: /macos/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/linux-index.csv", only_platform: /linux/, attack_platform: /linux/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/iaas-index.csv", only_platform: /iaas/, attack_platform: /iaas/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/containers-index.csv", only_platform: /containers/, attack_platform: /containers/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/office-365-index.csv", only_platform: /office-365/, attack_platform: /office/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/google-workspace-index.csv", only_platform: /google-workspace/, attack_platform: /identity/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/azure-ad-index.csv", only_platform: /azure-ad/, attack_platform: /identity/
generate_index_csv! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Indexes-CSV/esxi-index.csv", only_platform: /esxi/, attack_platform: /esxi/
2020-05-14 18:52:16 -06:00
2020-05-14 18:53:36 -06:00
generate_yaml_index! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/index.yaml"
2025-05-01 11:12:40 -04:00
["windows", "macos", "linux", "office-365", "azure-ad", "google-workspace", "saas", "iaas", "containers", "iaas:gcp", "iaas:azure", "iaas:aws", "esxi"].each do | platform|
generate_yaml_index_by_platform! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/#{platform.gsub(':','_')}-index.yaml", platform: "#{platform}"
2023-02-06 12:36:25 -06:00
end
2020-05-14 18:53:36 -06:00
generate_navigator_layer! "#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-windows.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-macos.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-linux.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-iaas.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-iaas-aws.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-iaas-azure.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-iaas-gcp.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-containers.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-saas.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-google-workspace.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-azure-ad.json", \
2025-05-01 11:12:40 -04:00
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-office-365.json", \
"#{File.dirname(File.dirname(__FILE__))}/atomics/Indexes/Attack-Navigator-Layers/art-navigator-layer-esxi.json"
2020-05-14 18:52:16 -06:00
2020-05-14 18:53:36 -06:00
return oks, fails
2018-05-10 14:10:12 -06:00
end
2018-05-10 13:26:34 -06:00
2018-05-11 05:59:03 +02:00
#
# Generates Markdown documentation for a specific technique from its YAML source
#
def generate_technique_docs!(atomic_yaml, output_doc_path)
2018-05-11 05:38:02 +02:00
technique = ATTACK_API.technique_info(atomic_yaml.fetch('attack_technique'))
technique['identifier'] = atomic_yaml.fetch('attack_technique').upcase
2022-09-23 18:56:48 -04:00
technique['name'] = atomic_yaml.fetch('display_name')
template = ERB.new File.read("#{ATOMIC_RED_TEAM_DIR}/atomic_doc_template.md.erb"), nil, "-"
2018-05-11 05:38:02 +02:00
generated_doc = template.result(binding)
2018-05-10 13:26:34 -06:00
2018-05-11 05:38:02 +02:00
print " => #{output_doc_path} => "
File.write output_doc_path, generated_doc
2018-05-11 04:09:32 +02:00
end
2018-05-11 07:29:16 +02:00
#
# Generates Markdown documentation for a specific technique from its YAML source
#
def generate_technique_execution_docs!(atomic_yaml, output_doc_path)
FileUtils.mkdir_p File.dirname(output_doc_path)
technique = ATTACK_API.technique_info(atomic_yaml.fetch('attack_technique'))
technique['identifier'] = atomic_yaml.fetch('attack_technique').upcase
template = ERB.new File.read("#{ATOMIC_RED_TEAM_DIR}/atomic_execution_template.html.erb"), nil, "-"
2018-05-11 07:29:16 +02:00
generated_doc = template.result(binding)
print " => #{output_doc_path} => "
File.write output_doc_path, generated_doc
end
2018-05-11 05:59:03 +02:00
#
# Generates a Markdown ATT&CK documentation matrix for all techniques
#
def generate_attack_matrix!(title_prefix, output_doc_path, only_platform: /.*/)
result = ''
result += "# #{title_prefix} Atomic Tests by ATT&CK Tactic & Technique\n"
result += "| #{ATTACK_API.ordered_tactics.join(' | ')} |\n"
2018-05-11 05:38:02 +02:00
result += "|#{'-----|' * ATTACK_API.ordered_tactics.count}\n"
2018-05-11 04:09:32 +02:00
ATTACK_API.ordered_tactic_to_technique_matrix(only_platform: only_platform).each do |row_of_techniques|
row_values = row_of_techniques.collect do |technique|
2018-05-11 05:38:02 +02:00
if technique
2020-05-11 13:15:27 -06:00
ATOMIC_RED_TEAM.github_link_to_technique(technique, include_identifier: false, only_platform: only_platform)
2018-05-11 05:38:02 +02:00
end
end
result += "| #{row_values.join(' | ')} |\n"
end
2018-05-11 05:59:03 +02:00
File.write output_doc_path, result
puts "Generated ATT&CK matrix at #{output_doc_path}"
2018-05-11 04:09:32 +02:00
end
2018-05-11 05:59:03 +02:00
#
# Generates a master Markdown index of ATT&CK Tactic -> Technique -> Atomic Tests
#
2024-11-19 20:34:41 -05:00
def generate_index!(title_prefix, output_doc_path, only_platform: /.*/, attack_platform: /.*/)
2018-05-11 05:38:02 +02:00
result = ''
result += "# #{title_prefix} Atomic Tests by ATT&CK Tactic & Technique\n"
2018-05-11 04:09:32 +02:00
2024-11-19 20:34:41 -05:00
ATTACK_API.techniques_by_tactic(only_platform: attack_platform).each do |tactic, techniques|
2018-05-11 05:38:02 +02:00
result += "# #{tactic}\n"
techniques.each do |technique|
2020-05-11 13:15:27 -06:00
result += "- #{ATOMIC_RED_TEAM.github_link_to_technique(technique, include_identifier: true, only_platform: only_platform)}\n"
2018-05-11 05:38:02 +02:00
ATOMIC_RED_TEAM.atomic_tests_for_technique(technique).each_with_index do |atomic_test, i|
next unless atomic_test['supported_platforms'].any? {|platform| platform.downcase =~ only_platform}
result += " - Atomic Test ##{i+1}: #{atomic_test['name']} [#{atomic_test['supported_platforms'].join(', ')}]\n"
2018-05-11 05:38:02 +02:00
end
end
result += "\n"
end
2018-05-11 04:09:32 +02:00
2018-05-11 05:59:03 +02:00
File.write output_doc_path, result
puts "Generated Atomic Red Team index at #{output_doc_path}"
2018-05-10 13:26:34 -06:00
end
#
# Generates a master Markdown index of ATT&CK Tactic -> Technique -> Atomic Tests
#
2024-11-19 20:34:41 -05:00
def generate_index_csv!(output_doc_path_by_tactic, only_platform: /.*/, attack_platform: /.*/)
rows = Array.new
2020-05-14 17:07:39 -06:00
rows << ["Tactic", "Technique #", "Technique Name", "Test #", "Test Name", "Test GUID", "Executor Name"]
2024-11-19 20:34:41 -05:00
ATTACK_API.techniques_by_tactic(only_platform: attack_platform).each do |tactic, techniques|
techniques.each do |technique|
ATOMIC_RED_TEAM.atomic_tests_for_technique(technique).each_with_index do |atomic_test, i|
next unless atomic_test['supported_platforms'].any? {|platform| platform.downcase =~ only_platform}
2020-05-14 17:07:39 -06:00
rows << [tactic, technique['identifier'], technique['name'], i+1, atomic_test['name'], atomic_test['auto_generated_guid'], atomic_test['executor']['name']]
end
end
end
File.write(output_doc_path_by_tactic, rows.map(&:to_csv).join)
puts "Generated Atomic Red Team CSV indexes at #{output_doc_path_by_tactic}"
end
2023-02-06 12:36:25 -06:00
#
# Generates a master YAML index of ATT&CK Tactic -> Technique -> Atomic Tests
#
def generate_yaml_index_by_platform!(output_doc_path, platform)
result = {}
ATTACK_API.techniques_by_tactic.each do |tactic, techniques|
result[tactic] = techniques.collect do |technique|
[
technique['external_references'][0]['external_id'],
{
'technique' => technique,
'atomic_tests' => ATOMIC_RED_TEAM.atomic_tests_for_technique_by_platform(technique, platform)
}
]
end.to_h
end
File.write output_doc_path, JSON.parse(result.to_json).to_yaml # shenanigans to eliminate YAML aliases
puts "Generated Atomic Red Team YAML index at #{output_doc_path}"
end
#
# Generates a master YAML index of ATT&CK Tactic -> Technique -> Atomic Tests
#
def generate_yaml_index!(output_doc_path)
result = {}
ATTACK_API.techniques_by_tactic.each do |tactic, techniques|
result[tactic] = techniques.collect do |technique|
[
2020-05-14 18:52:16 -06:00
technique['external_references'][0]['external_id'],
{
'technique' => technique,
'atomic_tests' => ATOMIC_RED_TEAM.atomic_tests_for_technique(technique)
}
]
end.to_h
end
File.write output_doc_path, JSON.parse(result.to_json).to_yaml # shenanigans to eliminate YAML aliases
puts "Generated Atomic Red Team YAML index at #{output_doc_path}"
end
2020-10-24 08:12:17 -06:00
def get_layer(techniques, layer_name)
filters = { }
if layer_name.include? "Windows"
filters = { "platforms": [ "Windows"]}
elsif layer_name.include? "macOS"
filters = { "platforms": [ "macOS"]}
elsif layer_name.include? "Linux"
filters = { "platforms": [ "Linux"]}
end
layer = {
2020-10-24 08:12:17 -06:00
"name" => layer_name,
"versions" => { "attack": "18", "navigator": "5.3.0", "layer": "4.5" },
2020-10-24 08:12:17 -06:00
"description" => layer_name + " MITRE ATT&CK Navigator Layer",
"domain" => "enterprise-attack",
"filters"=> filters,
"gradient" => {
"colors" => ["#ffffff",
"#ce232e"
],
"minValue" => 0,
"maxValue" => 10
},
2019-11-05 14:02:36 -05:00
"legendItems" => [
{
"label" => "10 or more tests",
"color" => "#ce232e"
},
{
"label" => "1 or more tests",
"color" => "#ffffff"
}
2019-11-05 14:02:36 -05:00
],
"techniques" => techniques
}
end
#
# Process the current technique and update the list
#
def update_techniquesList(current_technique, current_techniqueParent, techniques_list, atomic_yaml, comments)
if not atomic_yaml['attack_technique'].include?(".") then
tech_parent = techniques_list.find { |h| h["techniqueID"] == atomic_yaml['attack_technique'].split('.')[0] }
if tech_parent then
tech_parent['score'] += current_technique['score']
if comments then
tech_parent.merge!("comment": current_technique['comment'])
end
else
if not comments then
current_technique.delete("comment")
end
techniques_list.push(current_technique)
end
else
if tech_parent = techniques_list.find { |h| h["techniqueID"] == atomic_yaml['attack_technique'].split('.')[0] }
puts tech_parent
tech_parent['score'] += current_technique['score']
else
current_techniqueParent['score'] += current_technique['score']
techniques_list.push(current_techniqueParent)
end
if not comments then
current_technique.delete("comment")
end
techniques_list.push(current_technique)
end
end
#
# Generates a MITRE ATT&CK Navigator Layer based on contributed techniques
#
def generate_navigator_layer!(output_layer_path, output_layer_path_win, output_layer_path_mac, output_layer_path_lin, output_layer_path_iaas, \
output_layer_path_iaas_aws, output_layer_path_iaas_azure, output_layer_path_iaas_gcp, output_layer_path_containers, output_layer_path_saas, \
2025-05-01 11:12:40 -04:00
output_layer_path_google_workspace, output_layer_path_azure_ad, output_layer_path_office_365, output_layer_path_esxi)
techniques = []
techniques_win = []
techniques_mac = []
techniques_lin = []
techniques_iaas = []
techniques_iaas_aws = []
techniques_iaas_azure = []
techniques_iaas_gcp = []
techniques_containers = []
techniques_saas = []
techniques_google_workspace = []
techniques_azure_ad = []
techniques_office_365 = []
2025-05-01 11:12:40 -04:00
techniques_esxi = []
ATOMIC_RED_TEAM.atomic_tests.each do |atomic_yaml|
begin
technique = {
"techniqueID" => atomic_yaml['attack_technique'],
"score" => 0,
"enabled" => true,
"comment" => "\n",
2022-01-31 15:32:50 -05:00
"links" => ["label" => "View Atomic", "url" => "https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/" + atomic_yaml['attack_technique'] + "/" + atomic_yaml['attack_technique'] + ".md"]
}
2022-01-31 15:32:50 -05:00
2020-10-21 10:48:21 -06:00
techniqueParent = {
"techniqueID" => atomic_yaml['attack_technique'].split('.')[0],
"score" => 0,
"enabled" => true,
"links" => ["label" => "View Atomic", "url" => "https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/" + atomic_yaml['attack_technique'].split('.')[0] + "/" + atomic_yaml['attack_technique'].split('.')[0] + ".md"]
2020-10-21 10:48:21 -06:00
}
has_windows_tests = false
win_technique = technique.clone
win_techniqueParent = techniqueParent.clone
has_macos_tests = false
macos_technique = technique.clone
macos_techniqueParent = techniqueParent.clone
has_linux_tests = false
linux_technique = technique.clone
linux_techniqueParent = techniqueParent.clone
has_iaas_tests = false
iaas_technique = technique.clone
iaas_techniqueParent = techniqueParent.clone
has_iaas_aws_tests = false
iaas_aws_technique = technique.clone
iaas_aws_techniqueParent = techniqueParent.clone
has_iaas_azure_tests = false
iaas_azure_technique = technique.clone
iaas_azure_techniqueParent = techniqueParent.clone
has_iaas_gcp_tests = false
iaas_gcp_technique = technique.clone
iaas_gcp_techniqueParent = techniqueParent.clone
has_containers_tests = false
containers_technique = technique.clone
containers_techniqueParent = techniqueParent.clone
has_saas_tests = false
saas_technique = technique.clone
saas_techniqueParent = techniqueParent.clone
has_google_workspace_tests = false
google_workspace_technique = technique.clone
google_workspace_techniqueParent = techniqueParent.clone
has_azure_ad_tests = false
azure_ad_technique = technique.clone
azure_ad_techniqueParent = techniqueParent.clone
has_office_365_tests = false
office_365_technique = technique.clone
office_365_techniqueParent = techniqueParent.clone
2025-05-01 11:12:40 -04:00
has_esxi_tests = false
esxi_technique = technique.clone
esxi_techniqueParent = techniqueParent.clone
atomic_yaml['atomic_tests'].each do |atomic|
technique['score'] += 1
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /windows/} then
has_windows_tests = true
win_technique['score'] += 1
win_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /macos/} then
has_macos_tests = true
macos_technique['score'] += 1
macos_technique['comment'] += "- " + atomic['name'] + "\n"
end
2022-09-09 11:12:47 -06:00
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /linux/} then
has_linux_tests = true
linux_technique['score'] += 1
linux_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^iaas/} then
has_iaas_tests = true
iaas_technique['score'] += 1
iaas_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^iaas:aws/} then
has_iaas_aws_tests = true
iaas_aws_technique['score'] += 1
iaas_aws_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^iaas:azure/} then
has_iaas_azure_tests = true
iaas_azure_technique['score'] += 1
iaas_azure_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^iaas:gcp/} then
has_iaas_gcp_tests = true
iaas_gcp_technique['score'] += 1
iaas_gcp_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^containers/} then
has_containers_tests = true
containers_technique['score'] += 1
containers_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^google-workspace/} then
has_google_workspace_tests = true
google_workspace_technique['score'] += 1
google_workspace_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^azure-ad/} then
has_azure_ad_tests = true
azure_ad_technique['score'] += 1
azure_ad_technique['comment'] += "- " + atomic['name'] + "\n"
end
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^office-365/} then
has_office_365_tests = true
office_365_technique['score'] += 1
office_365_technique['comment'] += "- " + atomic['name'] + "\n"
end
2025-05-01 11:12:40 -04:00
if atomic['supported_platforms'].any? {|platform| platform.downcase =~ /^esxi/} then
has_esxi_tests = true
esxi_technique['score'] += 1
esxi_technique['comment'] += "- " + atomic['name'] + "\n"
end
end
# Update full Atomic Layer
update_techniquesList(technique, techniqueParent, techniques, atomic_yaml, false)
# Update all other Atomic Layers
if has_windows_tests then
update_techniquesList(win_technique, win_techniqueParent, techniques_win, atomic_yaml, true)
2020-10-24 08:39:37 -06:00
end
if has_macos_tests then
update_techniquesList(macos_technique, macos_techniqueParent, techniques_mac, atomic_yaml, true)
2020-10-24 08:39:37 -06:00
end
if has_linux_tests then
update_techniquesList(linux_technique, linux_techniqueParent, techniques_lin, atomic_yaml, true)
2020-10-24 08:39:37 -06:00
end
if has_iaas_tests then
update_techniquesList(iaas_technique, iaas_techniqueParent, techniques_iaas, atomic_yaml, true)
end
if has_iaas_aws_tests then
update_techniquesList(iaas_aws_technique, iaas_aws_techniqueParent, techniques_iaas_aws, atomic_yaml, true)
end
if has_iaas_azure_tests then
update_techniquesList(iaas_azure_technique, iaas_azure_techniqueParent, techniques_iaas_azure, atomic_yaml, true)
end
if has_iaas_gcp_tests then
update_techniquesList(iaas_gcp_technique, iaas_gcp_techniqueParent, techniques_iaas_gcp, atomic_yaml, true)
end
if has_containers_tests then
update_techniquesList(containers_technique, containers_techniqueParent, techniques_containers, atomic_yaml, true)
end
if has_google_workspace_tests then
update_techniquesList(google_workspace_technique, google_workspace_techniqueParent, techniques_google_workspace, atomic_yaml, true)
end
if has_azure_ad_tests then
update_techniquesList(azure_ad_technique, azure_ad_techniqueParent, techniques_azure_ad, atomic_yaml, true)
end
if has_office_365_tests then
update_techniquesList(office_365_technique, office_365_techniqueParent, techniques_office_365, atomic_yaml, true)
end
2025-05-01 11:12:40 -04:00
if has_esxi_tests then
update_techniquesList(esxi_technique, esxi_techniqueParent, techniques_esxi, atomic_yaml, true)
end
end
end
puts techniques_iaas_gcp
2020-10-24 08:12:17 -06:00
layer = get_layer techniques, "Atomic Red Team"
layer_win = get_layer techniques_win, "Atomic Red Team (Windows)"
layer_mac = get_layer techniques_mac, "Atomic Red Team (macOS)"
layer_lin = get_layer techniques_lin, "Atomic Red Team (Linux)"
layer_iaas = get_layer techniques_iaas, "Atomic Red Team (Iaas)"
layer_iaas_aws = get_layer techniques_iaas_aws, "Atomic Red Team (Iaas:AWS)"
layer_iaas_azure = get_layer techniques_iaas_azure, "Atomic Red Team (Iaas:Azure)"
layer_iaas_gcp = get_layer techniques_iaas_gcp, "Atomic Red Team (Iaas:GCP)"
layer_containers = get_layer techniques_containers, "Atomic Red Team (Containers)"
layer_google_workspace = get_layer techniques_google_workspace, "Atomic Red Team (Google-Workspace)"
layer_azure_ad = get_layer techniques_azure_ad, "Atomic Red Team (Azure-AD)"
layer_office_365 = get_layer techniques_office_365, "Atomic Red Team (Office-365)"
2025-05-01 11:12:40 -04:00
layer_esxi = get_layer techniques_esxi, "Atomic Red Team (ESXi)"
File.write output_layer_path,layer.to_json
File.write output_layer_path_win,layer_win.to_json
File.write output_layer_path_mac,layer_mac.to_json
File.write output_layer_path_lin,layer_lin.to_json
File.write output_layer_path_iaas,layer_iaas.to_json
File.write output_layer_path_iaas_aws,layer_iaas_aws.to_json
File.write output_layer_path_iaas_azure,layer_iaas_azure.to_json
File.write output_layer_path_iaas_gcp,layer_iaas_gcp.to_json
File.write output_layer_path_containers,layer_containers.to_json
File.write output_layer_path_google_workspace,layer_google_workspace.to_json
File.write output_layer_path_azure_ad,layer_azure_ad.to_json
File.write output_layer_path_office_365,layer_office_365.to_json
2025-05-01 11:12:40 -04:00
File.write output_layer_path_esxi,layer_esxi.to_json
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_win}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_mac}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_lin}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_iaas}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_iaas_aws}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_iaas_azure}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_iaas_gcp}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_containers}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_google_workspace}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_azure_ad}"
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_office_365}"
2025-05-01 11:12:40 -04:00
puts "Generated Atomic Red Team ATT&CK Navigator Layers at #{output_layer_path_esxi}"
end
2018-05-10 13:26:34 -06:00
end
2018-05-11 05:59:03 +02:00
#
# MAIN
#
2018-05-11 05:38:02 +02:00
oks, fails = AtomicRedTeamDocs.new.generate_all_the_docs!
2018-05-10 13:26:34 -06:00
exit fails.count