parameterisation - work in progress

This commit is contained in:
Z. Cliffe Schreuders
2016-06-12 00:21:12 +01:00
parent 7fde39e020
commit 8293403135
8 changed files with 149 additions and 3 deletions

View File

@@ -1,4 +1,6 @@
require_relative '../helpers/constants.rb'
require 'digest/md5'
require 'securerandom'
class Module
#Vulnerability attributes hash
@@ -9,6 +11,8 @@ class Module
# For module *selectors*, filters are stored directly in the attributes hash rather than as an array of values.
# XML validity ensures valid and complete information.
attr_accessor :inputs
attr_accessor :conflicts
attr_accessor :puppet_file
attr_accessor :puppet_other_path
@@ -16,6 +20,7 @@ class Module
# @param [Object] module_type: such as 'vulnerability', 'base', 'service', 'network'
def initialize(module_type)
self.module_type = module_type
self.inputs = []
self.conflicts = []
self.attributes = {}
self.attributes[:module_type] = module_type # add as an attribute for filtering
@@ -26,6 +31,7 @@ class Module
(<<-END)
#{module_type}: #{module_path}
attributes: #{attributes.inspect}
inputs: #{inputs.inspect}
conflicts: #{conflicts.inspect}
puppet file: #{puppet_file}
puppet path: #{puppet_other_path}
@@ -37,6 +43,7 @@ class Module
(<<-END)
# #{module_type}: #{module_path}
# attributes: #{attributes.inspect}
# inputs: #{inputs.inspect}
# conflicts: #{conflicts.inspect}
END
end
@@ -67,6 +74,62 @@ class Module
attr_flattened
end
# resolve randomisation of inputs
def select_inputs
inputs.each do |input|
# TODO TODO
Print.verbose "Input #{input["name"][0]}"
Print.verbose "Rand type: #{input["randomisation_type"][0]}"
case input["randomisation_type"][0]
when "one_from_list"
if input["value"].size == 0
Print.err "Randomisation not possible for #{module_path} (one_from_list with no values)"
exit
end
one_value = [input["value"].shuffle![0]]
input["value"] = one_value
when "flag_value"
# if no value suppied, generate one
unless input["value"]
input["value"] = ["THE_FLAG_IS:#{SecureRandom.hex}"]
else
input["value"] = ["THE_FLAG_IS:#{input["value"][0]}"]
end
when "none"
# nothing...
end
# if an encoding is specified
if input["encoding"]
if input["encoding"].size > 1
input["encoding"] = [input["encoding"].shuffle![0]]
else
enc = input["encoding"][0]
end
#
# TODO?? case enc
# when "base64_encode"
# require "base64"
# unless input["value"]
# input["value"] = [Base64.encode64(SecureRandom.hex)]
# else
# input["value"] = [Base64.encode64(input["value"][0])]
# end
# when "MD5_calc_hash"
# unless input["value"]
# input["value"] = [Digest::MD5.hexdigest(SecureRandom.hex)]
# else
# input["value"] = [Digest::MD5.hexdigest(input["value"][0])]
# end
# end
end
end
Print.err inputs.inspect
end
# A one directional test for conflicts
# Returns whether this module specifies it conflicts with the other_module.
# Each conflict can have multiple conditions which must all be met for this

View File

@@ -87,9 +87,14 @@ class System
end
# use from the top of the randomised list
selected = search_list[0]
selected_modules.push selected
Print.std "Selected module: #{selected.attributes['name'][0]} (#{selected.module_path})"
to_add = selected.clone
to_add.select_inputs
# resolve randomness of inputs
selected_modules.push to_add
end
selected_modules
end

View File

@@ -100,6 +100,18 @@ class ModuleReader
end
# TODO: function to abstract repeated logic here
# for each input to the module
doc.xpath("/#{module_type}/input").each do |input_doc|
input = {}
input_doc.elements.each {|node|
(input[node.name] ||= []).push(node.content)
}
new_module.inputs.push(input)
end
Print.err new_module.inputs.inspect
# for each conflict in the module
doc.xpath("/#{module_type}/conflict").each do |conflict_doc|
conflict = {}
@@ -107,7 +119,6 @@ class ModuleReader
(conflict[node.name] ||= []).push(node.content)
}
new_module.conflicts.push(conflict)
end
modules.push(new_module)

View File

@@ -46,6 +46,14 @@
</xs:complexType>
<xs:complexType name="VulnerabilityType">
<xs:sequence>
<xs:element name="input" type='xs:string' minOccurs="1" maxOccurs="unbounded">
<!--TODO<xs:attribute name="name" type="xs:string"/>-->
</xs:element>
</xs:sequence>
<xs:attribute name="module_path" type="xs:string"/>
<xs:attribute name="name" type="xs:string"/>

View File

@@ -57,6 +57,19 @@
<xs:pattern value="exploit/[a-zA-Z0-9_\-/]+"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="randType">
<xs:restriction base="xs:string">
<xs:enumeration value="one_from_list"/>
<xs:enumeration value="flag_value"/>
<xs:enumeration value="none"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="encodeType">
<xs:restriction base="xs:string">
<xs:enumeration value="MD5"/>
<xs:enumeration value="base64"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="vulnerability">
<xs:complexType>
@@ -95,6 +108,19 @@
<xs:element name="hint" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="solution" type="xs:string" minOccurs="0" maxOccurs="1"/>
<!--input-->
<xs:element name="input" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="randomisation_type" type="randType" minOccurs="1" maxOccurs="1"/>
<xs:element name="value" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="encoding" type="encodeType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- cannot co-exist with a system matching ALL of the optionally specified values (can be repeated for OR)-->
<xs:element name="conflict" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>

View File

@@ -36,6 +36,12 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
<%=module_name%>.environment = "production"
<%=module_name%>.manifests_path = "<%="#{ROOT_DIR}/#{selected_module.module_path}/"%>"
<%=module_name%>.manifest_file = "<%="#{selected_module.module_path_end}.pp"%>"
<%=module_name%>.facter = {
<% selected_module.inputs.each do |input| -%>
"<%="#{module_name}_#{input["name"][0]}"%>" => "<%=input["value"][0]%>",
<% end -%>
}
end
<% end -%>
<% end -%>

View File

@@ -26,11 +26,34 @@
<!--optional breadcrumb (info that is leaked and required to exploit)-->
<!--<breadcrumb></breadcrumb>-->
<breadcrumb>This is a secret</breadcrumb>
<!--optional hints-->
<!--<msf_module></msf_module>-->
<hint>An access control misconfiguration</hint>
<solution>Edit the shadow file to set a password for root</solution>
<input>
<name>files</name>
<randomisation_type>one_from_list</randomisation_type>
<value>/etc/shadow</value>
<value>/etc/gshadow</value>
</input>
<input>
<name>flag</name>
<randomisation_type>flag_value</randomisation_type>
<encoding>base64</encoding>
</input>
<input>
<name>leaked</name>
<randomisation_type>none</randomisation_type>
<value>This will be leaked</value>
<encoding>base64</encoding>
<encoding>MD5</encoding>
</input>
<conflict>
<name>Writeable Shadow File</name>
<author>Lewis Ardern</author>
@@ -39,4 +62,5 @@
<type>ftp</type>
</conflict>
</vulnerability>

View File

@@ -8,7 +8,10 @@
<system_name>server</system_name>
<base platform="linux"/>
<vulnerability module_path=".*writeable_shadow"></vulnerability>
<vulnerability module_path=".*writeable_shadow">
<!--TODO:<input name="files">/etc/shadow</input>-->
<input>/etc/shadow</input>
</vulnerability>
<network type="private_network" range="dhcp"></network>
</system>