diff --git a/filecreator.rb b/filecreator.rb
index e27c96c9d..44918ad07 100644
--- a/filecreator.rb
+++ b/filecreator.rb
@@ -13,6 +13,7 @@ class FileCreator
def initialize(systems)
@systems = systems
end
+
def generate(system)
Dir::mkdir("#{PROJECTS_DIR}") unless File.exists?("#{PROJECTS_DIR}")
@@ -20,7 +21,7 @@ class FileCreator
build_number = count.next
- p "the system is now creating the Project#{build_number}"
+ puts "The system is now creating the Project#{build_number}"
Dir::mkdir("#{PROJECTS_DIR}/Project#{build_number}") unless File.exists?("#{PROJECTS_DIR}/#{build_number}")
# initialises box before creation
@@ -29,13 +30,14 @@ class FileCreator
controller = ERBController.new
controller.systems = system
- vagrant_template = ERB.new(File.read(VAGRANT_TEMPLATE_FILE))
- p "#{PROJECTS_DIR}/Project#{build_number}/VagrantFile file has been created"
- File.open("#{PROJECTS_DIR}/Project#{build_number}/VagrantFile", 'w') { |file| file.write(vagrant_template.result(controller.get_binding)) }
+ vagrant_template = ERB.new(File.read(VAGRANT_TEMPLATE_FILE), 0, '<>')
+ File.delete("#{PROJECTS_DIR}/Project#{build_number}/Vagrantfile")
+ puts "#{PROJECTS_DIR}/Project#{build_number}/Vagrantfile file has been created"
+ File.open("#{PROJECTS_DIR}/Project#{build_number}/Vagrantfile", 'w') { |file| file.write(vagrant_template.result(controller.get_binding)) }
- report_template = ERB.new(File.read(REPORT_TEMPLATE_FILE))
- p "#{PROJECTS_DIR}/Project#{build_number}/Report file has been created"
+ report_template = ERB.new(File.read(REPORT_TEMPLATE_FILE), 0, '<>')
+ puts "#{PROJECTS_DIR}/Project#{build_number}/Report file has been created"
File.open("#{PROJECTS_DIR}/Project#{build_number}/Report", 'w'){ |file| file.write(report_template.result(controller.get_binding)) }
return build_number
@@ -53,4 +55,4 @@ class ERBController
def get_binding
return binding
end
-end
\ No newline at end of file
+end
diff --git a/lib/commandui/logo/logo.txt b/lib/commandui/logo/logo.txt
index 9d45a97a7..b397b1108 100644
--- a/lib/commandui/logo/logo.txt
+++ b/lib/commandui/logo/logo.txt
@@ -1,6 +1,10 @@
- ______________________________________________________________________________
-| |
-| Security Simulator |
-| Created By Lewis Ardern |
-| Leeds Met Final Year Project |
-|______________________________________________________________________________|
\ No newline at end of file
+ _____ _ _ _____ _ _ _
+ / ____| (_) | / ____(_) | | | |
+| (___ ___ ___ _ _ _ __ _| |_ _ _| (___ _ _ __ ___ _ _| | __ _| |_ ___ _ __
+ \___ \ / _ \/ __| | | | '__| | __| | | |\___ \| | '_ ` _ \| | | | |/ _` | __| / _ \| '__|
+ ____) | __/ (__| |_| | | | | |_| |_| |____) | | | | | | | |_| | | (_| | |_ | (_) | |
+|_____/ \___|\___|\__,_|_| |_|\__|\__, |_____/|_|_| |_| |_|\__,_|_|\__,_|\__| \___/|_|
+ __/ |
+ Licensed GPLv3 |___/ Creates virtualised security scenarios
+ 2014-15 By Lewis Ardern and Z.Cliffe.S
+
diff --git a/lib/templates/report.erb b/lib/templates/report.erb
index cf44561d4..f610d5f01 100644
--- a/lib/templates/report.erb
+++ b/lib/templates/report.erb
@@ -1,37 +1,43 @@
-This document has been automated for build
<%if systems.count == 1%>
There was only 1 system generated for this project.
<%else %>
-There were <%systems.count%> systems generated for this project.
-<%end%>
+There were <%systems.count%> systems generated for this project. <%end%>
- The module files for puppet can be found here: "<%=ROOT_DIR%>/mount/puppet/modules"
- The manifest files for puppet can be found here: "<%=ROOT_DIR%>/mount/puppet/manifests"
+The module files for puppet can be found here: "<%=ROOT_DIR%>/mount/puppet/modules"
+The manifest files for puppet can be found here: "<%=ROOT_DIR%>/mount/puppet/manifests"
<% systems.each do |s| %>
+====System: <%=s.id%>====
+ <%=s.id%> uses <%=s.basebox%> a distro of <%=s.os%> which can be downloaded from <%=s.url%>
+<% s.networks.each do |n| %> <%grab_system_number = s.id.gsub(/[^0-9]/i, "") %> <% n.range[9..9] = grab_system_number %>
+ ip address for <%=s.id%> = <%=n.range%>0 <% end %>
+ ==Secure services==
+<% s.services.each do |v| %>
+ Here is a summary of the service <%=v.name%>:
+ Type: <%=v.type%>.
+ Name: <%= v.name %>.
+ Details: <%= v.details %>.
+<% v.puppets.each do |p| %>
+ Puppet "<%=p%>.pp" has been used to create this service.
+<% end %>
+<% end %>
-<%=s.id%> uses <%=s.basebox%> a distro of <%=s.os%> which can be downloaded from <%=s.url%>
- <% s.networks.each do |n| %>
- <%grab_system_number = s.id.gsub(/[^0-9]/i, "") %>
- <% n.range[9..9] = grab_system_number %>
- ip address for <%=s.id%> = <%=n.range%>0
- <% end %>
- <% s.vulns.each do |v| %>
-Here is a summary of the vulnerability <%=v.type%>:
- Type: <%=v.type%>
- Details: <%= v.details %>
- privilege: <%= v.privilege %>
- access: <%= v.access %>
- <%if not v.cve == ""%>
- cve: <%= v.cve %>
- <% end %>
- <% v.puppets.each do |p| %>
- Puppet "<%=p%>.pp" has been used to create these vulnerabiliies
- <% end %>
- <% v.ports.each do |port| %>
- Web server runs on port <%=port%>
- <% end %>
- <% end %>
-
+ ==Vulnerabilities==
+<% s.vulns.each do |v| %>
+ Here is a summary of the vulnerability <%=v.type%>:
+ Type: <%=v.type%>.
+ Details: <%= v.details %>.
+ privilege: <%= v.privilege %>.
+ access: <%= v.access %>.
+<%if not v.cve == ""%>
+ cve: <%= v.cve %>.
+<% end %>
+<% v.puppets.each do |p| %>
+ Puppet "<%=p%>.pp" has been used to create this vulnerability.
+<% end %>
+<% v.ports.each do |port| %>
+ Runs on port <%=port%>
+<% end %>
+<% end %>
<% end %>
diff --git a/lib/templates/vagrantbase.erb b/lib/templates/vagrantbase.erb
index 212358fd7..3f5fdcb47 100644
--- a/lib/templates/vagrantbase.erb
+++ b/lib/templates/vagrantbase.erb
@@ -5,43 +5,52 @@
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
- <% systems.each do |s| %>
-
+<% systems.each do |s| %>
config.vm.define "<%=s.id%>" do |<%=s.id%>|
<%=s.id%>.vm.box = "<%=s.basebox%>"
<%=s.id%>.vm.box_url = "<%=s.url%>"
- <% s.networks.each do |n| %>
- <%grab_system_number = s.id.gsub(/[^0-9]/i, "") %>
- <% n.range[9..9] = grab_system_number %>
- <%=s.id%>.vm.network :public_network
- <%=s.id%>.vm.network :private_network, :ip => "<%=n.range%>0"
- <% end %>
+<% s.networks.each do |n| %>
+<%grab_system_number = s.id.gsub(/[^0-9]/i, "") %>
+<% n.range[9..9] = grab_system_number %>
+ <%=s.id%>.vm.network :public_network
+ <%=s.id%>.vm.network :private_network, :ip => "<%=n.range%>0"
+<% end %>
<%=s.id%>.vm.synced_folder "<%=MOUNT_DIR%>", "/mount"
end
config.vm.provision :shell, :inline => "apt-get update --fix-missing"
- <%s.vulns.each do |v|%>
- <%v.puppets.each do |p|%>
- config.vm.provision "puppet" do |<%=p%>|
- <%=p%>.module_path = "<%=ROOT_DIR%>/mount/puppet/modules"
- <%=p%>.manifests_path = "<%=ROOT_DIR%>/mount/puppet/manifests"
+ # Add secure services
+<%s.services.each do |v|%>
+<%v.puppets.each do |p|%>
+ config.vm.provision "puppet" do |<%=p%>|
+ <%=p%>.module_path = "<%=ROOT_DIR%>/mount/puppet/modules"
+ <%=p%>.manifests_path = "<%=ROOT_DIR%>/mount/puppet/manifests"
+ <%=p%>.manifest_file = "<%=p%>.pp"
+ end
+<% end %>
+<% end %>
- <%=p%>.manifest_file = "<%=p%>.pp"
- end
- <% end %>
- <% end %>
+ # Add vulnerabilities
+<%s.vulns.each do |v|%>
+<%v.puppets.each do |p|%>
+ config.vm.provision "puppet" do |<%=p%>|
+ <%=p%>.module_path = "<%=ROOT_DIR%>/mount/puppet/modules"
+ <%=p%>.manifests_path = "<%=ROOT_DIR%>/mount/puppet/manifests"
+ <%=p%>.manifest_file = "<%=p%>.pp"
+ end
+<% end %>
+<% end %>
+ # clean up script which clears history from the VMs and clobs files together
config.vm.provision "puppet" do |cleanup|
cleanup.module_path = "<%=ROOT_DIR%>/mount/puppet/modules"
cleanup.manifests_path = "<%=ROOT_DIR%>/mount/puppet/manifests"
-
cleanup.manifest_file = "cleanup.pp"
end
- # clean up script which clears history and clobs files together
-
config.vm.provision :shell, :inline => "history -c && history -w"
config.vm.provision :shell, :inline => "umount /mount/"
- <% end %>
+
+<% end %>
end
diff --git a/lib/xml/boxes.xml b/lib/xml/boxes.xml
index 4ac1d505a..897ca6108 100644
--- a/lib/xml/boxes.xml
+++ b/lib/xml/boxes.xml
@@ -1,10 +1,30 @@
-
+
+
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/xml/vulns.xml b/lib/xml/vulns.xml
index 39840a0b1..04199e3f8 100644
--- a/lib/xml/vulns.xml
+++ b/lib/xml/vulns.xml
@@ -10,7 +10,7 @@
writeableshadow
@@ -62,8 +62,8 @@
distcc
-
0
+ puts "Searching for service matching type: " + service_query.type
+ search_list.delete_if{|x| x.type != service_query.type}
+ end
+
+ if search_list.length == 0
+ STDERR.puts "Matching service was not found please check the xml boxes.xml"
+ STDERR.puts "(note: you can only have one of each type of service per system)"
+ exit
+ else
+ # use from the top of the top of the randomised list
+ return_services[service_query.id] = search_list[0]
+ if search_list[0].type.length > 0
+ puts "Selected secure service : " + search_list[0].type
+ end
+
+ # enforce only one of any service type (remove from available)
+ legal_services.delete_if{|x| x.type == service_query.type}
+ end
+ end
+ return return_services.values
+ end
+end
+
class NetworkManager
# the user will either specify a blank network type or a knownnetwork type
def self.process(networks,valid_network)
@@ -136,46 +210,50 @@ class Vulnerability
end
class VulnerabilityManager
- # the user will either specify a blank vulnerability or will check it against vulns.xml and will append
- # specific information to system if the system information is empty
- def self.process(vulns,valid_vulns)
- new_vulns = {}
+ # vulnerabilities are randomly selected from the definitions in vulns.xml (all_vulns)
+ # based on the attributes optionally specified in boxes.xml (want_vulns)
+ def self.process(want_vulns, all_vulns)
+ return_vulns = {}
-
- legal_vulns = valid_vulns & vulns
- vulns.each do |vuln|
+ legal_vulns = all_vulns.clone
+ want_vulns.each do |vulnerability_query|
+ # select based on selected type, access, cve...
- if vuln.type == ""
- random = valid_vulns.sample
- # valid vulnerability into a new hash map of vulnerabilities
- new_vulns[random.id] = random
- else
- has_found = false
- # shuffle randomly selects first match of ftp or nfs and then abandon
- legal_vulns.shuffle.each do |valid|
- if vuln.type == valid.type
- vuln.puppets = valid.puppets unless not vuln.puppets.empty?
- vuln.ports = valid.ports unless not vuln.ports.empty?
- vuln.cve = valid.cve unless not vuln.cve.empty?
- vuln.privilege = valid.privilege unless not vuln.privilege.empty?
- vuln.access = valid.access unless not vuln.access.empty?
- vuln.details = valid.details
- # valid vulnerability into a new hash map of vulnerabilities
- new_vulns[vuln.id] = vuln
- has_found = true
- break
- end
- end
- if not has_found
- STDERR.puts "vulnerability was not found please check the xml boxes.xml"
- exit
- end
- end
- end
- return new_vulns.values
- end
+ # copy vulns array
+ search_list = legal_vulns.clone
+ # shuffle order of available vulnerabilities
+ search_list.shuffle!
+ # remove all the vulns that don't match the current selection (type, etc)
+ if vulnerability_query.type.length > 0
+ puts "Searching for vulnerability matching type: " + vulnerability_query.type
+ search_list.delete_if{|x| x.type != vulnerability_query.type}
+ end
+ if vulnerability_query.access.length > 0
+ puts "Searching for vulnerability matching access: " + vulnerability_query.access
+ search_list.delete_if{|x| x.access != vulnerability_query.access}
+ end
+ if vulnerability_query.cve.length > 0
+ puts "Searching for vulnerability matching CVE: " + vulnerability_query.cve
+ search_list.delete_if{|x| x.cve != vulnerability_query.cve}
+ end
- #loop through vulns, fill in missing details if not enough info, choose one at random fill in vulns..
+ if search_list.length == 0
+ STDERR.puts "Matching vulnerability was not found please check the xml boxes.xml"
+ STDERR.puts "(note: you can only have one of each type of vulnerability per system)"
+ exit
+ else
+ # use from the top of the top of the randomised list
+ return_vulns[vulnerability_query.id] = search_list[0]
+ if search_list[0].type.length > 0
+ puts "Selected vulnerability : " + search_list[0].type
+ end
+
+ # enforce only one of any vulnerability type (remove from available)
+ legal_vulns.delete_if{|x| x.type == vulnerability_query.type}
+ end
+ end
+ return return_vulns.values
+ end
end
class Conf
@@ -202,15 +280,22 @@ class Conf
return @@vulnerabilities = self._get_list(VULN_XML, "//vulnerabilities/vulnerability", Vulnerability)
end
+ def self.services
+ if defined? @@services
+ return @@services
+ end
+ return @@services = self._get_list(SERVICES_XML, "//services/service", Service)
+ end
+
def self._get_list(xmlfile, xpath, cls)
itemlist = []
doc = Nokogiri::XML(File.read(xmlfile))
doc.xpath(xpath).each do |item|
# new class e.g networks
- obj = cls.new
+ obj = cls.new
# checks to see if there are children puppet and add string to obj.puppets
- # move this to vulnerabilities class
+ # move this to vulnerabilities/services classes?
if defined? obj.puppets
item.xpath("puppets/puppet").each { |c| obj.puppets << c.text.strip if not c.text.strip.empty? }
item.xpath("ports/port").each { |c| obj.ports << c.text.strip if not c.text.strip.empty? }
@@ -225,4 +310,4 @@ class Conf
end
return itemlist
end
-end
\ No newline at end of file
+end
diff --git a/systemreader.rb b/systemreader.rb
index ca8788553..4b9d0d103 100644
--- a/systemreader.rb
+++ b/systemreader.rb
@@ -18,6 +18,7 @@ class SystemReader
url = system["url"]
vulns = []
networks = []
+ services = []
system.css('vulnerabilities vulnerability').each do |v|
vulnerability = Vulnerability.new
@@ -28,23 +29,37 @@ class SystemReader
vulns << vulnerability
end
+ system.css('services service').each do |v|
+ service = Service.new
+ service.name = v['name']
+ service.details = v['details']
+ service.type = v['type']
+ services << service
+ end
+
system.css('networks network').each do |n|
network = Network.new
network.name = n['name']
networks << network
end
- # vulns / networks are passed through to their manager and the program will create valid vulnerabilities / networks
- # depending on what the user has specified these two will return valid vulns to be used in vagrant file creation.
- new_vulns = VulnerabilityManager.process(vulns, Conf.vulnerabilities)
- new_networks = NetworkManager.process(networks, Conf.networks)
+
+ puts "Processing system: " + id
+ # vulns / networks are passed through to their manager and the program will create valid vulnerabilities / networks
+ # depending on what the user has specified these two will return valid vulns to be used in vagrant file creation.
+ new_vulns = VulnerabilityManager.process(vulns, Conf.vulnerabilities)
+ #puts new_vulns.inspect
+
+ new_networks = NetworkManager.process(networks, Conf.networks)
+ # pass in the already selected set of vulnerabilities, and additional secure services to find
+ new_services = ServiceManager.process(services, Conf.services, new_vulns)
- s = System.new(id, os, basebox, url, new_vulns, new_networks)
- if s.is_valid_base == false
- BaseManager.generate_base(s,Conf.bases)
- end
+ s = System.new(id, os, basebox, url, new_vulns, new_networks, new_services)
+ if s.is_valid_base == false
+ BaseManager.generate_base(s,Conf.bases)
+ end
- systems << s
+ systems << s
end
return systems
end
-end
\ No newline at end of file
+end
diff --git a/vagrant.rb b/vagrant.rb
index a5cc15aaf..5a3b5fbd1 100644
--- a/vagrant.rb
+++ b/vagrant.rb
@@ -4,8 +4,8 @@ class VagrantController
def vagrant_up(build_number)
#executes vagrant up from the current build.
- p 'building now.....'
+ puts 'Building now.....'
command = "cd #{PROJECTS_DIR}/Project#{build_number}/; vagrant up"
exec command
end
-end
\ No newline at end of file
+end