diff --git a/lib/CyBOK/generate_scenario_index.rb b/lib/CyBOK/generate_scenario_index.rb
new file mode 100644
index 000000000..595c8bad2
--- /dev/null
+++ b/lib/CyBOK/generate_scenario_index.rb
@@ -0,0 +1,116 @@
+require 'erb'
+require 'nori'
+require 'youtube_images' # gem 'youtube_images'
+
+
+require_relative '../helpers/print.rb'
+require_relative '../helpers/constants.rb'
+
+Print.std "Reading scenarios! ***************************"
+scenarios = []
+# Get a list of all the scenarios
+scenarios_dir = "#{ROOT_DIR}/scenarios"
+Dir.chdir(scenarios_dir) do
+ scenarios = Dir["**/*.xml"].sort
+end
+
+# read in the contents of the scenarios
+
+@ka_hash = {}
+@ka_video_hash = {}
+@ka_topic_hash = {}
+
+KA_TOPIC_SCENARIOS_HASH = Hash.new { |h, k| h[k] = h.dup.clear }
+SCENARIOS_HASH = {}
+KA_TOPIC_VIDEO_HASH = Hash.new { |h, k| h[k] = h.dup.clear }
+VIDEO_HASH = {}
+parser = Nori.new()
+scenarios.each { |scenario|
+ Print.verbose "Reading #{scenario}"
+
+ scenario_hash = parser.parse(File.read("#{scenarios_dir}/#{scenario}"))
+ if scenario_hash && scenario_hash['scenario']
+ if (scenario_hash['scenario']['CyBOK'].kind_of?(Array))
+ scenario_hash['scenario']['CyBOK'].each {|cybok_entry|
+ ka = cybok_entry['@KA']
+ (@ka_hash[ka] ||= []) << scenario
+ topic = cybok_entry['@topic']
+ (@ka_topic_hash["#{ka} #{topic}"] ||= []) << scenario
+ KA_TOPIC_SCENARIOS_HASH[ka][topic][scenario] = "-"
+ (SCENARIOS_HASH[scenario] ||= []) << cybok_entry
+
+ }
+ elsif (scenario_hash['scenario']['CyBOK'])
+ # KA_HASH[scenario] << scenario
+ ka = scenario_hash['scenario']['CyBOK']['@KA']
+ (@ka_hash[ka] ||= []) << scenario
+ topic = scenario_hash['scenario']['CyBOK']['@topic']
+ (@ka_topic_hash["#{ka} #{topic}"] ||= []) << scenario
+ KA_TOPIC_SCENARIOS_HASH[ka][topic][scenario] = "-"
+ # SCENARIOS_HASH[scenario] = scenario_hash
+ (SCENARIOS_HASH[scenario] ||= []) << scenario_hash['scenario']['CyBOK']
+ else
+ # SCENARIOS_HASH[scenario]['VMs'] << scenario_hash['scenario']['system']['system_name']
+ end
+
+ if (scenario_hash['scenario']['video'].kind_of?(Array))
+ scenario_hash['scenario']['video'].each {|video_entry|
+ url = video_entry['url']
+ (VIDEO_HASH[url] ||= []) << video_entry
+
+ }
+ elsif (scenario_hash['scenario']['video'])
+ # KA_HASH[scenario] << scenario
+ url = scenario_hash['scenario']['video']['url']
+ (VIDEO_HASH[url] ||= []) << scenario_hash['scenario']['video']
+ else
+ # SCENARIOS_HASH[scenario]['VMs'] << scenario_hash['scenario']['system']['system_name']
+ end
+
+ # puts @ka_hash.to_s
+ # puts SCENARIOS_HASH.to_s
+ # SCENARIOS_HASH[scenario] = {};
+ # SCENARIOS_HASH[scenario]['name'] = scenario_hash['scenario']['name']
+ # SCENARIOS_HASH[scenario]['type'] = scenario_hash['scenario']['type']
+ # SCENARIOS_HASH[scenario]['author'] = scenario_hash['scenario']['author']
+ # SCENARIOS_HASH[scenario]['description'] = scenario_hash['scenario']['description']
+ # SCENARIOS_HASH[scenario]['difficulty'] = scenario_hash['scenario']['difficulty']
+ # SCENARIOS_HASH[scenario]['VMs'] = []
+ # # puts '>>>>>>'
+ #
+ # if (scenario_hash['scenario']['system'].kind_of?(Array))
+ # scenario_hash['scenario']['system'].each {|vm|
+ # SCENARIOS_HASH[scenario]['VMs'] << vm['system_name']
+ # }
+ #
+ # else
+ # SCENARIOS_HASH[scenario]['VMs'] << scenario_hash['scenario']['system']['system_name']
+ # end
+ else
+ puts "Error reading scenario xml: #{scenario}"
+ logger.warn "Error reading scenario xml: #{scenario}"
+ end
+
+
+}
+# puts SCENARIOS_HASH.to_s
+
+template_out = ERB.new(File.read("#{ROOT_DIR}/lib/CyBOK/template_CyBOK_scenarios.md.erb"), 0, '<>-')
+begin
+ File.open("#{ROOT_DIR}/README-CyBOK-Scenarios-Indexed.md", 'wb+') do |file|
+ file.write(template_out.result())
+ end
+rescue StandardError => e
+ Print.err "Error writing file: #{e.message}"
+ Print.err e.backtrace.inspect
+end
+
+template_out = ERB.new(File.read("#{ROOT_DIR}/lib/CyBOK/template_CyBOK_videos.md.erb"), 0, '<>-')
+begin
+ File.open("#{ROOT_DIR}/README-CyBOK-Lecture-Videos.md", 'wb+') do |file|
+ file.write(template_out.result())
+ end
+rescue StandardError => e
+ Print.err "Error writing file: #{e.message}"
+ Print.err e.backtrace.inspect
+end
diff --git a/lib/CyBOK/template_CyBOK_scenarios.md.erb b/lib/CyBOK/template_CyBOK_scenarios.md.erb
new file mode 100644
index 000000000..5dfb4d61b
--- /dev/null
+++ b/lib/CyBOK/template_CyBOK_scenarios.md.erb
@@ -0,0 +1,36 @@
+This file is an autogenerated index and cross referencing of all the scenarios that have CyBOK metadata.
+
+# By Knowledge Area
+
+<%
+KA_TOPIC_SCENARIOS_HASH.each{|ka,hash|
+%>
+
+# <%= ka %>
+
+## <%= ka %> Scenarios
+<%= @ka_hash[ka].uniq.join("") %>
+
+## <%= ka %> Scenarios by Topics
+| Topic | Scenario |
+| --- | --- |<%
+ hash.each{|topic,hash|%>
+<%= topic %> | <%= hash.keys.uniq.join("") %> <%
+ }
+}
+%>
+
+# By Scenario
+
+<%
+SCENARIOS_HASH.each{|scenario,array|
+%>
+ ## <%= scenario %>
+| KA | Topic | Keywords
+| --- | --- | --- |
+<%array.each{|arr| -%>
+| <%= arr["@KA"] %> | <%= arr["@topic"] %> | <%= arr["keyword"].to_s.gsub(/"|\[|\]/, '').gsub(',',';') %> |<%
+} %>
+
+<%
+} %>
diff --git a/lib/CyBOK/template_CyBOK_videos.md.erb b/lib/CyBOK/template_CyBOK_videos.md.erb
new file mode 100644
index 000000000..ccd3dc6ee
--- /dev/null
+++ b/lib/CyBOK/template_CyBOK_videos.md.erb
@@ -0,0 +1,32 @@
+# Lecture Videos
+
+This file is an autogenerated index of the lecture videos referenced by scenarios -- with CyBOK metadata.
+
+<%
+VIDEO_HASH.each{|url,array|
+%>
+<% array.each{|arr| %>
+ ## <%= arr['title'] %>
+ by <%= arr['by'] %>
+
+<% begin %>
+ [:high] %>)
+<%
+rescue YouTubeImages::IncorrectYouTubeID
+%>)<%
+end
+%>
+ <%= arr['url'] %>
+
+ <% unless arr['CyBOK'].kind_of?(Array)
+ arr['CyBOK'] = [arr['CyBOK']]
+ end %>
+ | KA | Topics | Keywords |
+ | --- | --- | --- |
+ <% arr['CyBOK'].each {|cybok| -%>
+ | <%= cybok["@KA"] %> | <%= cybok["@topic"] %> | <%= cybok["keyword"] %> |
+ <% } -%>
+<% } %>
+
+<%
+} %>
diff --git a/lib/CyBOK/validate_xml_all_scenarios.rb b/lib/CyBOK/validate_xml_all_scenarios.rb
new file mode 100644
index 000000000..ee50d6fb4
--- /dev/null
+++ b/lib/CyBOK/validate_xml_all_scenarios.rb
@@ -0,0 +1,41 @@
+require 'nokogiri'
+
+require_relative '../helpers/print.rb'
+require_relative '../helpers/constants.rb'
+
+Print.std "Reading scenarios! ***************************"
+scenarios = []
+# Get a list of all the scenarios
+scenarios_dir = "#{ROOT_DIR}/scenarios"
+Dir.chdir(scenarios_dir) do
+ scenarios = Dir["**/*.xml"].sort
+end
+
+scenarios.each { |scenario|
+ Print.verbose "Reading #{scenario}"
+ doc, xsd = nil
+ begin
+ doc = Nokogiri::XML(File.read("#{ROOT_DIR}/scenarios/#{scenario}"))
+ rescue
+ Print.err "Failed to read scenario configuration file (#{scenario})"
+ exit
+ end
+
+ # validate scenario XML against schema
+ begin
+ xsd = Nokogiri::XML::Schema(File.open(SCENARIO_SCHEMA_FILE))
+ xsd.validate("#{ROOT_DIR}/scenarios/#{scenario}").each do |error|
+ Print.err "Error in scenario configuration file (#{scenario}):"
+ Print.err " #{error.line}: #{error.message}"
+ exit
+ end
+ Print.verbose " Valid XML"
+ rescue Exception => e
+ Print.err "Failed to validate scenario configuration file (#{scenario}): against schema (#{SCENARIO_SCHEMA_FILE})"
+ Print.err e.message
+ # exit
+ end
+
+
+
+}
diff --git a/scenarios/labs/introducing_attacks/3_vulnerabilities.xml b/scenarios/labs/introducing_attacks/3_vulnerabilities.xml
index a9066e28d..d51ad1479 100644
--- a/scenarios/labs/introducing_attacks/3_vulnerabilities.xml
+++ b/scenarios/labs/introducing_attacks/3_vulnerabilities.xml
@@ -20,6 +20,10 @@ This week we will cover one of the major threats in computer security: software
[Lab sheet here](https://docs.google.com/document/d/11I8xMUXrT5ArJIsAhwGDtQ4RkH4l9CR4C2wh9_wz8xM/edit?usp=sharing).
+ ctf-lab
+ lab-sheet
+ easy
+
EXPLOITATION
EXPLOITATION FRAMEWORKS
@@ -29,10 +33,6 @@ This week we will cover one of the major threats in computer security: software
PENETRATION TESTING - ACTIVE PENETRATION
- ctf-lab
- lab-sheet
- easy
-
windows_victim
diff --git a/scenarios/labs/introducing_attacks/4_dns_footprinting.xml b/scenarios/labs/introducing_attacks/4_dns_footprinting.xml
index 0dc3efed1..974a29506 100644
--- a/scenarios/labs/introducing_attacks/4_dns_footprinting.xml
+++ b/scenarios/labs/introducing_attacks/4_dns_footprinting.xml
@@ -20,6 +20,9 @@ The topic of information gathering spans two weeks, and covers practical steps t
[Lab sheet here](https://docs.google.com/document/d/1Whs4c_mN7fFjtrYgg_uzmCGBH_EYjr7fTAgoM-OZTqQ/edit?usp=sharing).
+ lab-sheet
+ easy
+
PENETRATION TESTING - DNS ZONE TRANSFER
EXPLOITATION FRAMEWORKS
@@ -29,9 +32,6 @@ The topic of information gathering spans two weeks, and covers practical steps t
PENETRATION TESTING - SOFTWARE TOOLS
- lab-sheet
- easy
-
kali
diff --git a/scenarios/labs/response_and_investigation/1_integrity_protection.xml b/scenarios/labs/response_and_investigation/1_integrity_protection.xml
index 3b50d6f79..c98089f0c 100644
--- a/scenarios/labs/response_and_investigation/1_integrity_protection.xml
+++ b/scenarios/labs/response_and_investigation/1_integrity_protection.xml
@@ -21,6 +21,14 @@
Linux read only protections: ro mounts, file attributes
+
+
desktop