From 055ef5b77b66f62a9d5132f9bc746c353b90ca29 Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 24 Jan 2019 12:25:34 +0000 Subject: [PATCH 01/47] explicitly set file permissions for flags leaked by ::secgen_functions::leak_file --- .../unix/ctf/misc/hidden_file/manifests/install.pp | 1 + .../unix/ctf/reverse/java/java_decompile/manifests/install.pp | 1 + .../vulnerabilities/unix/local/chkrootkit/manifests/install.pp | 1 + modules/vulnerabilities/unix/local/setuid_nmap/manifests/init.pp | 1 + 4 files changed, 4 insertions(+) diff --git a/modules/vulnerabilities/unix/ctf/misc/hidden_file/manifests/install.pp b/modules/vulnerabilities/unix/ctf/misc/hidden_file/manifests/install.pp index f6939b0a8..e982a60f6 100644 --- a/modules/vulnerabilities/unix/ctf/misc/hidden_file/manifests/install.pp +++ b/modules/vulnerabilities/unix/ctf/misc/hidden_file/manifests/install.pp @@ -30,6 +30,7 @@ class hidden_file::install { storage_directory => $challenge_directory, strings_to_leak => $strings_to_leak, leaked_from => "$challenge_directory-hidden_file", + mode => '0644' } } diff --git a/modules/vulnerabilities/unix/ctf/reverse/java/java_decompile/manifests/install.pp b/modules/vulnerabilities/unix/ctf/reverse/java/java_decompile/manifests/install.pp index d33eae229..63fdba171 100644 --- a/modules/vulnerabilities/unix/ctf/reverse/java/java_decompile/manifests/install.pp +++ b/modules/vulnerabilities/unix/ctf/reverse/java/java_decompile/manifests/install.pp @@ -36,6 +36,7 @@ class java_decompile::install { leaked_filenames => $leaked_filenames, strings_to_leak => $strings_to_leak, leaked_from => "java_decompile_instructions", + mode => '0644' } # Run the template to generate a .java file diff --git a/modules/vulnerabilities/unix/local/chkrootkit/manifests/install.pp b/modules/vulnerabilities/unix/local/chkrootkit/manifests/install.pp index 3cf0df123..0ceda4ac2 100644 --- a/modules/vulnerabilities/unix/local/chkrootkit/manifests/install.pp +++ b/modules/vulnerabilities/unix/local/chkrootkit/manifests/install.pp @@ -40,5 +40,6 @@ class chkrootkit::install { leaked_filenames => $leaked_filenames, strings_to_leak => $strings_to_leak, leaked_from => "chkrootkit_vuln", + mode => '0600' } } \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/setuid_nmap/manifests/init.pp b/modules/vulnerabilities/unix/local/setuid_nmap/manifests/init.pp index 54f0aca52..56c685a09 100644 --- a/modules/vulnerabilities/unix/local/setuid_nmap/manifests/init.pp +++ b/modules/vulnerabilities/unix/local/setuid_nmap/manifests/init.pp @@ -14,5 +14,6 @@ class setuid_nmap::init { leaked_filenames => $leaked_filenames, strings_to_leak => $strings_to_leak, leaked_from => "setuid_nmap", + mode => '0600' } } \ No newline at end of file From 372e1361a050e80bb66019c6dce98a80aa2e20aa Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 24 Jan 2019 12:47:43 +0000 Subject: [PATCH 02/47] basic_narrative.xml: removed sqlmap from the onlinestore vm as we've got an attacker vm within the scenario --- scenarios/ctf/basic_narrative.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/scenarios/ctf/basic_narrative.xml b/scenarios/ctf/basic_narrative.xml index 5cefcf581..c081e4b5c 100644 --- a/scenarios/ctf/basic_narrative.xml +++ b/scenarios/ctf/basic_narrative.xml @@ -437,8 +437,6 @@ - - IP_addresses From 115002fe0866ed9234660aa5f9e0f42b019b77d0 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 1 Feb 2019 22:18:43 +0000 Subject: [PATCH 03/47] gitignore update --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 48fc02156..9a4aeb302 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ modules/generators/challenges/exif/secgen_local/tmp.jpg modules/generators/challenges/compression/zip/tmp modules/generators/challenges/image/random_jpg/secgen_local/tmp.jpg secgen.conf -modules/encoders/compression/huffman/tmp \ No newline at end of file +modules/encoders/compression/huffman/tmp +.rakeTasks +modules/**/Gemfile.lock From 1c4a9aebf10a442f34b49a8893ec0361f7e4d0b9 Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 00:17:06 +0000 Subject: [PATCH 04/47] randomly generated json_inputs filenames now include module_name --- lib/templates/Vagrantfile.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/templates/Vagrantfile.erb b/lib/templates/Vagrantfile.erb index 1babe9dfd..93d706ea2 100644 --- a/lib/templates/Vagrantfile.erb +++ b/lib/templates/Vagrantfile.erb @@ -161,14 +161,14 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| b64_json_inputs = Base64.strict_encode64(json_inputs) # save the inputs in a randomly named file in the # project out directory of the secgen_functions module - rand = SecureRandom.hex().to_s + json_inputs_filename = "#{module_name}_#{SecureRandom.hex(15).to_s}" dir = "#{@out_dir}/puppet/#{system.name}/modules/secgen_functions/files/json_inputs" FileUtils.mkdir_p(dir) unless File.exists?(dir) - Print.verbose "Writing #{selected_module.module_path_name} input to: #{dir}/#{rand}" - File.write("#{dir}/#{rand}", b64_json_inputs) + Print.verbose "Writing #{selected_module.module_path_name} input to: #{dir}/#{json_inputs_filename}" + File.write("#{dir}/#{json_inputs_filename}", b64_json_inputs) -%> <%= module_name%>.facter = { - "base64_inputs_file" => '<%= rand %>', + "base64_inputs_file" => '<%= json_inputs_filename %>', } <% end -%> <%=module_name%>.module_path = "<%="puppet/#{system.name}/modules"%>" From 1fffa4b05c8bdc092300f71438d79130f87a704b Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 01:27:50 +0000 Subject: [PATCH 05/47] (WiP) Created proftpd_133c_backdoor testing script - Needs testing! --- lib/objects/post_provision_test.rb | 91 +++++++++++++++++++ lib/output/project_files_creator.rb | 4 + lib/templates/Vagrantfile.erb | 2 +- .../secgen_test/proftpd_133c_backdoor.rb | 30 ++++++ scenarios/tests/test_scenario.xml | 6 +- secgen.rb | 28 ++++++ 6 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 lib/objects/post_provision_test.rb create mode 100644 modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb new file mode 100644 index 000000000..b7bf537f7 --- /dev/null +++ b/lib/objects/post_provision_test.rb @@ -0,0 +1,91 @@ +# Post Provision Testing +# +# This file will be copied into each project folder at creation time. +# It will be required from each of the modules/secgen_tests/module_name.rb test scripts +# +# Test classes must: require_relative '../../../../../lib/post_provision_test' + +require_relative "../../../lib/helpers/print.rb" +require 'json' +require 'base64' + +require 'socket' +require 'timeout' + +class PostProvisionTest + attr_accessor :project_path + attr_accessor :system_ip + attr_accessor :module_name + attr_accessor :module_path + attr_accessor :json_inputs + + def initialize + # self.project_path = + end + + def run + Print.info "Running tests for #{self.module_name}" + test_module + end + + def test_module + # Override me with testing details + end + + def get_system_ip(module_file_path) + # Get Vagrantfile + + end + + def get_json_inputs + json_inputs_path = "#{File.expand_path('../', self.module_path)}/secgen_functions/files/json_inputs/*" + Print.info "json_inputs_path: #{json_inputs_path}" + json_inputs_files = Dir.glob(json_inputs_path) + Print.info "json_input_files (pre delete): #{json_inputs_files}" + json_inputs_files.delete_if { |path| !path.include?(self.module_name) } + Print.info "json_input_files (post delete): #{json_inputs_files}" + JSON.parse(Base64.strict_decode64(File.read(json_inputs_files.first))) + end + + # Pass __FILE__ in from subclasses + def get_module_path(file_path) + "#{File.expand_path('..', File.dirname(file_path))}" + end + + # Note: returns proftpd_testing + def get_system_name + get_system_path.match(/.*?([^\/]*)$/i).captures[0] + end + + # Note: returns /home/thomashaw/git/SecGen/projects/SecGen20190202_010552/puppet/proftpd_testing + def get_system_path + "#{File.expand_path('../../', self.module_path)}" + end + + # Note: returns /home/thomashaw/git/SecGen/projects/SecGen20190202_010552/ + def get_project_path + "#{File.expand_path('../../../../', self.module_path)}" + end + + ############################## + ## Useful testing functions ## + ############################## + + def is_port_open?(ip, port) + begin + Timeout::timeout(1) do + begin + s = TCPSocket.new(ip, port) + s.close + return true + rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH + return false + end + end + rescue Timeout::Error + # ignored + end + false + end + +end \ No newline at end of file diff --git a/lib/output/project_files_creator.rb b/lib/output/project_files_creator.rb index 6f2e0a4b7..475e06abb 100644 --- a/lib/output/project_files_creator.rb +++ b/lib/output/project_files_creator.rb @@ -172,6 +172,10 @@ class ProjectFilesCreator abort end + # Copy the test superclass into the project/lib directory + Print.std "Copying post-provision testing class" + FileUtils.mkdir("#{@out_dir}/lib") + FileUtils.cp("#{ROOT_DIR}/lib/objects/post_provision_test.rb", "#{@out_dir}/lib/post_provision_test.rb") Print.std "VM(s) can be built using 'vagrant up' in #{@out_dir}" diff --git a/lib/templates/Vagrantfile.erb b/lib/templates/Vagrantfile.erb index 93d706ea2..ede0f1522 100644 --- a/lib/templates/Vagrantfile.erb +++ b/lib/templates/Vagrantfile.erb @@ -161,7 +161,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| b64_json_inputs = Base64.strict_encode64(json_inputs) # save the inputs in a randomly named file in the # project out directory of the secgen_functions module - json_inputs_filename = "#{module_name}_#{SecureRandom.hex(15).to_s}" + json_inputs_filename = "#{selected_module.module_path_end}_#{SecureRandom.hex(15).to_s}" dir = "#{@out_dir}/puppet/#{system.name}/modules/secgen_functions/files/json_inputs" FileUtils.mkdir_p(dir) unless File.exists?(dir) Print.verbose "Writing #{selected_module.module_path_name} input to: #{dir}/#{json_inputs_filename}" diff --git a/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb b/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb new file mode 100644 index 000000000..92bd87158 --- /dev/null +++ b/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb @@ -0,0 +1,30 @@ +require_relative '../../../../../lib/post_provision_test' + +class Proftpd133cBackdoorTest < PostProvisionTest + + attr_accessor :ftp_port + def initialize + super + self.module_name = 'proftpd_133c_backdoor' + self.module_path = get_module_path(__FILE__) + self.json_inputs = get_json_inputs + self.ftp_port = get_json_inputs['port'].to_i + # Print.info self.json_inputs + # Print.info "get_system_name: #{get_system_name}" + # Print.info "get_system_path: #{get_system_path}" + # Print.info "get_project_path: #{get_project_path}" + end + + def test_module + # TODO: Need to determine how to handle the output... see other Open3.capture3 module and stdout print pass/fail perhaps? + # TODO: Raise an exception? Return false? Print the PASSED / FAILED only? + + if is_port_open? "172.16.0.5", "21" + Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" + else + Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" + end + end +end + +Proftpd133cBackdoorTest.new.run \ No newline at end of file diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index 3c84e680c..e3ef57c74 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -4,8 +4,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario"> - empty_stretch - + proftpd_testing + + + 172.16.0.5 diff --git a/secgen.rb b/secgen.rb index 817dfac89..fb67ac42a 100644 --- a/secgen.rb +++ b/secgen.rb @@ -118,6 +118,8 @@ def build_vms(scenario, project_dir, options) while retry_count and !successful_creation vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") if vagrant_output[:status] == 0 + shutdown_cycle(project_dir) + post_provision_tests(project_dir) Print.info 'VMs created.' successful_creation = true if options[:shutdown] or OVirtFunctions::provider_ovirt?(options) @@ -329,6 +331,32 @@ def get_vm_names(scenario) vm_names end +def shutdown_cycle(project_dir) + Print.info 'Shutting down VMs.' + sleep(30) + GemExec.exe('vagrant', project_dir, 'halt') + sleep 5 + GemExec.exe('vagrant',project_dir,'up') + sleep 30 +end + +def post_provision_tests(project_dir) + # Get project files + Print.err "project_dir: #{project_dir}" + + # Get system names + test_script_paths = Dir.glob("#{project_dir}/puppet/*/modules/*/secgen_test/*.rb") + + test_script_paths.each {|test_file_path| + output = `bundle exec ruby #{test_file_path}` + Print.info output + if output.include? "FAILED" + raise "Post provision failure!" + end + } + Print.info 'Running post-provision tests...' +end + # end of method declarations # start of program execution From 3279c506374fc75a59d3530f5d1d364c5354bd46 Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 02:31:20 +0000 Subject: [PATCH 06/47] Tests now working! Added for all ftp services and vulnerabilities. --- lib/objects/post_provision_test.rb | 22 ++++++------- lib/templates/Vagrantfile.erb | 2 ++ .../unix/ftp/proftpd/secgen_test/proftpd.rb | 24 ++++++++++++++ .../unix/ftp/vsftpd/secgen_test/vsftpd.rb | 24 ++++++++++++++ .../secgen_test/proftpd_133c_backdoor.rb | 12 ++----- .../secgen_test/vsftpd_234_backdoor.rb | 24 ++++++++++++++ secgen.rb | 31 ++++++++++--------- 7 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb create mode 100644 modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb create mode 100644 modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index b7bf537f7..b8c1252f2 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -5,7 +5,7 @@ # # Test classes must: require_relative '../../../../../lib/post_provision_test' -require_relative "../../../lib/helpers/print.rb" +require_relative '../../../lib/helpers/print.rb' require 'json' require 'base64' @@ -19,10 +19,6 @@ class PostProvisionTest attr_accessor :module_path attr_accessor :json_inputs - def initialize - # self.project_path = - end - def run Print.info "Running tests for #{self.module_name}" test_module @@ -32,18 +28,22 @@ class PostProvisionTest # Override me with testing details end - def get_system_ip(module_file_path) - # Get Vagrantfile - + def get_system_ip + vagrant_file_path = "#{get_project_path}/Vagrantfile" + vagrantfile = File.read(vagrant_file_path) + ip_line = vagrantfile.split("\n").delete_if { |line| !line.include? "# ip_address_for_#{get_system_name}"}[0] + ip_address = ip_line.split('=')[-1] + if ip_address == "DHCP" + "FAILED: Cannot test against dynamic IPs" # TODO: fix this so that we grab dynamic IP address (maybe from vagrant?) + else + ip_address + end end def get_json_inputs json_inputs_path = "#{File.expand_path('../', self.module_path)}/secgen_functions/files/json_inputs/*" - Print.info "json_inputs_path: #{json_inputs_path}" json_inputs_files = Dir.glob(json_inputs_path) - Print.info "json_input_files (pre delete): #{json_inputs_files}" json_inputs_files.delete_if { |path| !path.include?(self.module_name) } - Print.info "json_input_files (post delete): #{json_inputs_files}" JSON.parse(Base64.strict_decode64(File.read(json_inputs_files.first))) end diff --git a/lib/templates/Vagrantfile.erb b/lib/templates/Vagrantfile.erb index ede0f1522..6b3d4cb6f 100644 --- a/lib/templates/Vagrantfile.erb +++ b/lib/templates/Vagrantfile.erb @@ -136,6 +136,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| <% else %> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, type: "dhcp", auto_config: false <% end %> + # ip_address_for_<%= system.name %>=DHCP <% # Static networking -%> <% else -%> <% # Static oVirt networking -%> @@ -150,6 +151,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| <% # Static Virtualbox networking -%> <% else -%> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, ip: "<%= resolve_network(selected_module)%>" + # ip_address_for_<%= system.name %>=<%= resolve_network(selected_module)%> <% end -%> <% end -%> <% when 'vulnerability', 'service', 'utility', 'build' -%> diff --git a/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb b/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb new file mode 100644 index 000000000..169af55e4 --- /dev/null +++ b/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb @@ -0,0 +1,24 @@ +require_relative '../../../../../lib/post_provision_test' + +class ProftpdTest < PostProvisionTest + + attr_accessor :ftp_port + def initialize + super + self.module_name = 'proftpd' + self.module_path = get_module_path(__FILE__) + self.json_inputs = get_json_inputs + self.ftp_port = get_json_inputs['port'][0].to_i + self.system_ip = get_system_ip + end + + def test_module + if is_port_open? system_ip, ftp_port + Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" + else + Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" + end + end +end + +ProftpdTest.new.run \ No newline at end of file diff --git a/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb b/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb new file mode 100644 index 000000000..34a602bcc --- /dev/null +++ b/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb @@ -0,0 +1,24 @@ +require_relative '../../../../../lib/post_provision_test' + +class VsftpdTest < PostProvisionTest + + attr_accessor :ftp_port + def initialize + super + self.module_name = 'vsftpd' + self.module_path = get_module_path(__FILE__) + self.json_inputs = get_json_inputs + self.ftp_port = get_json_inputs['port'][0].to_i + self.system_ip = get_system_ip + end + + def test_module + if is_port_open? system_ip, ftp_port + Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" + else + Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" + end + end +end + +VsftpdTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb b/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb index 92bd87158..cc656ce45 100644 --- a/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb +++ b/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb @@ -8,18 +8,12 @@ class Proftpd133cBackdoorTest < PostProvisionTest self.module_name = 'proftpd_133c_backdoor' self.module_path = get_module_path(__FILE__) self.json_inputs = get_json_inputs - self.ftp_port = get_json_inputs['port'].to_i - # Print.info self.json_inputs - # Print.info "get_system_name: #{get_system_name}" - # Print.info "get_system_path: #{get_system_path}" - # Print.info "get_project_path: #{get_project_path}" + self.ftp_port = get_json_inputs['port'][0].to_i + self.system_ip = get_system_ip end def test_module - # TODO: Need to determine how to handle the output... see other Open3.capture3 module and stdout print pass/fail perhaps? - # TODO: Raise an exception? Return false? Print the PASSED / FAILED only? - - if is_port_open? "172.16.0.5", "21" + if is_port_open? system_ip, ftp_port Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" else Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" diff --git a/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb b/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb new file mode 100644 index 000000000..55e3a6a23 --- /dev/null +++ b/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb @@ -0,0 +1,24 @@ +require_relative '../../../../../lib/post_provision_test' + +class Vsftpd234BackdoorTest < PostProvisionTest + + attr_accessor :ftp_port + def initialize + super + self.module_name = 'vsftpd_234_backdoor' + self.module_path = get_module_path(__FILE__) + self.json_inputs = get_json_inputs + self.ftp_port = get_json_inputs['port'][0].to_i + self.system_ip = get_system_ip + end + + def test_module + if is_port_open? system_ip, ftp_port + Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" + else + Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" + end + end +end + +Vsftpd234BackdoorTest.new.run \ No newline at end of file diff --git a/secgen.rb b/secgen.rb index fb67ac42a..cedc3120d 100644 --- a/secgen.rb +++ b/secgen.rb @@ -119,13 +119,16 @@ def build_vms(scenario, project_dir, options) vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") if vagrant_output[:status] == 0 shutdown_cycle(project_dir) - post_provision_tests(project_dir) - Print.info 'VMs created.' - successful_creation = true - if options[:shutdown] or OVirtFunctions::provider_ovirt?(options) - Print.info 'Shutting down VMs.' - sleep(30) - GemExec.exe('vagrant', project_dir, 'halt') + if post_provision_tests(project_dir) + Print.info 'VMs created.' + successful_creation = true + if options[:shutdown] or OVirtFunctions::provider_ovirt?(options) + Print.info 'Shutting down VMs.' + sleep(30) + GemExec.exe('vagrant', project_dir, 'halt') + end + else + Print.err 'Tests failed!' end else if retry_count > 0 @@ -341,20 +344,18 @@ def shutdown_cycle(project_dir) end def post_provision_tests(project_dir) - # Get project files - Print.err "project_dir: #{project_dir}" + Print.info 'Running post-provision tests...' - # Get system names test_script_paths = Dir.glob("#{project_dir}/puppet/*/modules/*/secgen_test/*.rb") - - test_script_paths.each {|test_file_path| + test_script_paths.each do |test_file_path| output = `bundle exec ruby #{test_file_path}` Print.info output if output.include? "FAILED" - raise "Post provision failure!" + Print.err "ERROR: Post provision failure!" + return false end - } - Print.info 'Running post-provision tests...' + end + true end # end of method declarations From 17ed03a3274ebce23828e4223eef4bc11511d2b4 Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 17:22:50 +0000 Subject: [PATCH 07/47] Testing most service modules for open port [todo.. NTP and popa3d] --- lib/objects/post_provision_test.rb | 51 ++- lib/templates/Vagrantfile.erb | 4 +- .../unix/ftp/proftpd/secgen_test/proftpd.rb | 14 +- .../unix/ftp/vsftpd/secgen_test/vsftpd.rb | 14 +- .../secgen_test/parameterised_website.rb | 47 +++ .../unix/irc/unrealirc/secgen_metadata.xml | 4 - .../irc/unrealirc/secgen_test/unrealirc.rb | 16 + .../nfs/nfs_share/secgen_test/nfs_share.rb | 17 + .../unix/smb/samba/secgen_test/samba.rb | 17 + .../secgen_test/proftpd_133c_backdoor.rb | 14 +- .../secgen_test/vsftpd_234_backdoor.rb | 13 +- .../secgen_metadata.xml | 6 +- .../secgen_test/unrealirc_3281_backdoor.rb | 16 + .../nc_backdoor/secgen_test/nc_backdoor.rb | 16 + .../web_training/dvwa/secgen_test/dvwa.rb | 16 + .../gitlist_040/secgen_test/gitlist_040.rb | 16 + .../moinmoin_195/secgen_test/moinmoin_195.rb | 16 + .../onlinestore/secgen_test/onlinestore.rb | 16 + .../wordpress_1x/secgen_test/wordpress_1x.rb | 16 + .../wordpress_2x/secgen_test/wordpress_2x.rb | 16 + .../wordpress_3x/secgen_test/wordpress_3x.rb | 16 + .../wordpress_4x/secgen_test/wordpress_4x.rb | 16 + scenarios/tests/test_scenario.xml | 6 +- secgen.rb | 322 +++++++++--------- 24 files changed, 486 insertions(+), 219 deletions(-) create mode 100644 modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb create mode 100644 modules/services/unix/irc/unrealirc/secgen_test/unrealirc.rb create mode 100644 modules/services/unix/nfs/nfs_share/secgen_test/nfs_share.rb create mode 100644 modules/services/unix/smb/samba/secgen_test/samba.rb create mode 100644 modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_test/unrealirc_3281_backdoor.rb create mode 100644 modules/vulnerabilities/unix/misc/nc_backdoor/secgen_test/nc_backdoor.rb create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/secgen_test/dvwa.rb create mode 100644 modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb create mode 100644 modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb create mode 100644 modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb create mode 100644 modules/vulnerabilities/unix/webapp/wordpress_1x/secgen_test/wordpress_1x.rb create mode 100644 modules/vulnerabilities/unix/webapp/wordpress_2x/secgen_test/wordpress_2x.rb create mode 100644 modules/vulnerabilities/unix/webapp/wordpress_3x/secgen_test/wordpress_3x.rb create mode 100644 modules/vulnerabilities/unix/webapp/wordpress_4x/secgen_test/wordpress_4x.rb diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index b8c1252f2..47edaa25f 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -5,7 +5,6 @@ # # Test classes must: require_relative '../../../../../lib/post_provision_test' -require_relative '../../../lib/helpers/print.rb' require 'json' require 'base64' @@ -18,23 +17,50 @@ class PostProvisionTest attr_accessor :module_name attr_accessor :module_path attr_accessor :json_inputs + attr_accessor :port + attr_accessor :outputs + + def initialize + self.system_ip = get_system_ip + self.json_inputs = get_json_inputs + self.port = get_port + self.outputs = [] + end def run - Print.info "Running tests for #{self.module_name}" test_module + puts self.outputs end def test_module - # Override me with testing details + # Call super first in overriden methods + self.outputs << "Running tests for #{self.module_name}" end + ##################### + # Testing Functions # + ##################### + + def test_service_up + if is_port_open? system_ip, self.port + self.outputs << "PASSED: Port #{self.port} is open at #{get_system_ip} (#{get_system_name})!" + else + self.outputs << "FAILED: Port #{self.port} is closed at #{get_system_ip} (#{get_system_name})!" + end + end + + ################## + # Misc Functions # + ################## + def get_system_ip vagrant_file_path = "#{get_project_path}/Vagrantfile" vagrantfile = File.read(vagrant_file_path) ip_line = vagrantfile.split("\n").delete_if { |line| !line.include? "# ip_address_for_#{get_system_name}"}[0] ip_address = ip_line.split('=')[-1] if ip_address == "DHCP" - "FAILED: Cannot test against dynamic IPs" # TODO: fix this so that we grab dynamic IP address (maybe from vagrant?) + self.outputs << "FAILED: Cannot test against dynamic IPs" # TODO: fix this so that we grab dynamic IP address (maybe from vagrant?) + exit(1) else ip_address end @@ -44,7 +70,18 @@ class PostProvisionTest json_inputs_path = "#{File.expand_path('../', self.module_path)}/secgen_functions/files/json_inputs/*" json_inputs_files = Dir.glob(json_inputs_path) json_inputs_files.delete_if { |path| !path.include?(self.module_name) } - JSON.parse(Base64.strict_decode64(File.read(json_inputs_files.first))) + if json_inputs_files.size > 0 + return JSON.parse(Base64.strict_decode64(File.read(json_inputs_files.first))) + end + {} + end + + def get_port + if get_json_inputs != {} + get_json_inputs['port'][0].to_i + else + -1 + end end # Pass __FILE__ in from subclasses @@ -67,10 +104,6 @@ class PostProvisionTest "#{File.expand_path('../../../../', self.module_path)}" end - ############################## - ## Useful testing functions ## - ############################## - def is_port_open?(ip, port) begin Timeout::timeout(1) do diff --git a/lib/templates/Vagrantfile.erb b/lib/templates/Vagrantfile.erb index 6b3d4cb6f..1001829a0 100644 --- a/lib/templates/Vagrantfile.erb +++ b/lib/templates/Vagrantfile.erb @@ -136,7 +136,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| <% else %> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, type: "dhcp", auto_config: false <% end %> - # ip_address_for_<%= system.name %>=DHCP + # ip_address_for_<%= system.name %>=DHCP <% # Static networking -%> <% else -%> <% # Static oVirt networking -%> @@ -151,7 +151,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| <% # Static Virtualbox networking -%> <% else -%> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, ip: "<%= resolve_network(selected_module)%>" - # ip_address_for_<%= system.name %>=<%= resolve_network(selected_module)%> + # ip_address_for_<%= system.name %>=<%= resolve_network(selected_module)%> <% end -%> <% end -%> <% when 'vulnerability', 'service', 'utility', 'build' -%> diff --git a/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb b/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb index 169af55e4..01ad6df76 100644 --- a/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb +++ b/modules/services/unix/ftp/proftpd/secgen_test/proftpd.rb @@ -1,23 +1,15 @@ require_relative '../../../../../lib/post_provision_test' class ProftpdTest < PostProvisionTest - - attr_accessor :ftp_port def initialize - super self.module_name = 'proftpd' self.module_path = get_module_path(__FILE__) - self.json_inputs = get_json_inputs - self.ftp_port = get_json_inputs['port'][0].to_i - self.system_ip = get_system_ip + super end def test_module - if is_port_open? system_ip, ftp_port - Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" - else - Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" - end + super + test_service_up end end diff --git a/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb b/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb index 34a602bcc..13115198a 100644 --- a/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb +++ b/modules/services/unix/ftp/vsftpd/secgen_test/vsftpd.rb @@ -1,23 +1,15 @@ require_relative '../../../../../lib/post_provision_test' class VsftpdTest < PostProvisionTest - - attr_accessor :ftp_port def initialize - super self.module_name = 'vsftpd' self.module_path = get_module_path(__FILE__) - self.json_inputs = get_json_inputs - self.ftp_port = get_json_inputs['port'][0].to_i - self.system_ip = get_system_ip + super end def test_module - if is_port_open? system_ip, ftp_port - Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" - else - Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" - end + super + test_service_up end end diff --git a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb new file mode 100644 index 000000000..f4512644d --- /dev/null +++ b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb @@ -0,0 +1,47 @@ +require_relative '../../../../../lib/post_provision_test' +require 'json' +require 'net/http' + +class ParamWebsiteTest < PostProvisionTest + def initialize + self.module_name = 'parameterised_website' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + json_inputs = get_json_inputs + css_theme = json_inputs['theme'][0] + + if json_inputs['organisation'] + organisation = JSON.parse(json_inputs['organisation'][0]) + employee_1 = organisation['employees'][0] + + test_html_returned_content('/index.html', organisation['business_name']) + test_html_returned_content('/contact.html', organisation['business_moto']) + test_html_returned_content('/contact.html', employee_1['name']) + end + + test_html_returned_content("/css/#{css_theme}", 'Bootswatch v4.0.0') + + test_service_up + end + + def test_html_returned_content(page, match_string) + + begin + source = Net::HTTP.get(get_system_ip, page, self.port) + rescue SocketError + # do nothing + end + + if source.include? match_string + self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" + else + self.outputs << "FAILED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" + end + end +end + +ParamWebsiteTest.new.run \ No newline at end of file diff --git a/modules/services/unix/irc/unrealirc/secgen_metadata.xml b/modules/services/unix/irc/unrealirc/secgen_metadata.xml index 0e30d7480..77bf56ce5 100644 --- a/modules/services/unix/irc/unrealirc/secgen_metadata.xml +++ b/modules/services/unix/irc/unrealirc/secgen_metadata.xml @@ -32,10 +32,6 @@ Kali.* - - .*Stretch.* - - update diff --git a/modules/services/unix/irc/unrealirc/secgen_test/unrealirc.rb b/modules/services/unix/irc/unrealirc/secgen_test/unrealirc.rb new file mode 100644 index 000000000..511d0860d --- /dev/null +++ b/modules/services/unix/irc/unrealirc/secgen_test/unrealirc.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class UnrealircTest < PostProvisionTest + def initialize + self.module_name = 'unrealirc' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +UnrealircTest.new.run \ No newline at end of file diff --git a/modules/services/unix/nfs/nfs_share/secgen_test/nfs_share.rb b/modules/services/unix/nfs/nfs_share/secgen_test/nfs_share.rb new file mode 100644 index 000000000..a08e90b04 --- /dev/null +++ b/modules/services/unix/nfs/nfs_share/secgen_test/nfs_share.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class NFSShareTest < PostProvisionTest + def initialize + self.module_name = 'ntp' + self.module_path = get_module_path(__FILE__) + super + self.port = 2049 + end + + def test_module + super + test_service_up + end +end + +NFSShareTest.new.run \ No newline at end of file diff --git a/modules/services/unix/smb/samba/secgen_test/samba.rb b/modules/services/unix/smb/samba/secgen_test/samba.rb new file mode 100644 index 000000000..f406ebc26 --- /dev/null +++ b/modules/services/unix/smb/samba/secgen_test/samba.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class SambaTest < PostProvisionTest + def initialize + self.module_name = 'samba' + self.module_path = get_module_path(__FILE__) + super + self.port = 139 + end + + def test_module + super + test_service_up + end +end + +SambaTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb b/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb index cc656ce45..2d22e586d 100644 --- a/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb +++ b/modules/vulnerabilities/unix/ftp/proftpd_133c_backdoor/secgen_test/proftpd_133c_backdoor.rb @@ -1,23 +1,15 @@ require_relative '../../../../../lib/post_provision_test' class Proftpd133cBackdoorTest < PostProvisionTest - - attr_accessor :ftp_port def initialize - super self.module_name = 'proftpd_133c_backdoor' self.module_path = get_module_path(__FILE__) - self.json_inputs = get_json_inputs - self.ftp_port = get_json_inputs['port'][0].to_i - self.system_ip = get_system_ip + super end def test_module - if is_port_open? system_ip, ftp_port - Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" - else - Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" - end + super + test_service_up end end diff --git a/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb b/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb index 55e3a6a23..d5d7e85d4 100644 --- a/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb +++ b/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb @@ -1,23 +1,16 @@ require_relative '../../../../../lib/post_provision_test' class Vsftpd234BackdoorTest < PostProvisionTest - - attr_accessor :ftp_port def initialize super self.module_name = 'vsftpd_234_backdoor' self.module_path = get_module_path(__FILE__) - self.json_inputs = get_json_inputs - self.ftp_port = get_json_inputs['port'][0].to_i - self.system_ip = get_system_ip + super end def test_module - if is_port_open? system_ip, ftp_port - Print.info "PASSED: Port #{ftp_port} is open on #{get_system_name}!" - else - Print.err "FAILED: Port #{ftp_port} is closed on #{get_system_name}!" - end + super + test_service_up end end diff --git a/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_metadata.xml b/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_metadata.xml index c5ddf6fa2..fe04f8218 100644 --- a/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_metadata.xml +++ b/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_metadata.xml @@ -84,9 +84,9 @@ unrealircd MIT - - .*Stretch.* - + + + .*Kali.* diff --git a/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_test/unrealirc_3281_backdoor.rb b/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_test/unrealirc_3281_backdoor.rb new file mode 100644 index 000000000..f58b4c22e --- /dev/null +++ b/modules/vulnerabilities/unix/irc/unrealirc_3281_backdoor/secgen_test/unrealirc_3281_backdoor.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class Unrealirc3281BackdoorTest < PostProvisionTest + def initialize + self.module_name = 'unrealirc_3281_backdoor' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +Unrealirc3281BackdoorTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/misc/nc_backdoor/secgen_test/nc_backdoor.rb b/modules/vulnerabilities/unix/misc/nc_backdoor/secgen_test/nc_backdoor.rb new file mode 100644 index 000000000..ad8664095 --- /dev/null +++ b/modules/vulnerabilities/unix/misc/nc_backdoor/secgen_test/nc_backdoor.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class NcBackdoorTest < PostProvisionTest + def initialize + self.module_name = 'nc_backdoor' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +NcBackdoorTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/web_training/dvwa/secgen_test/dvwa.rb b/modules/vulnerabilities/unix/web_training/dvwa/secgen_test/dvwa.rb new file mode 100644 index 000000000..04cc12715 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/secgen_test/dvwa.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class DVWATest < PostProvisionTest + def initialize + self.module_name = 'dvwa' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +DVWATest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb b/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb new file mode 100644 index 000000000..b80f1599a --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class Gitlist040Test < PostProvisionTest + def initialize + self.module_name = 'gitlist_040' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +Gitlist040Test.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb b/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb new file mode 100644 index 000000000..4c6fcc9f7 --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class MoinMoin195Test < PostProvisionTest + def initialize + self.module_name = 'moinmoin_195' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +MoinMoin195Test.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb b/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb new file mode 100644 index 000000000..b242f6028 --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class OnlineStoreTest < PostProvisionTest + def initialize + self.module_name = 'onlinestore' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +OnlineStoreTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/wordpress_1x/secgen_test/wordpress_1x.rb b/modules/vulnerabilities/unix/webapp/wordpress_1x/secgen_test/wordpress_1x.rb new file mode 100644 index 000000000..c7d022bcd --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/wordpress_1x/secgen_test/wordpress_1x.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class Wordpress1xTest < PostProvisionTest + def initialize + self.module_name = 'wordpress_1x' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +Wordpress1xTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/wordpress_2x/secgen_test/wordpress_2x.rb b/modules/vulnerabilities/unix/webapp/wordpress_2x/secgen_test/wordpress_2x.rb new file mode 100644 index 000000000..15ec4cbba --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/wordpress_2x/secgen_test/wordpress_2x.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class Wordpress2xTest < PostProvisionTest + def initialize + self.module_name = 'wordpress_2x' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +Wordpress2xTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/wordpress_3x/secgen_test/wordpress_3x.rb b/modules/vulnerabilities/unix/webapp/wordpress_3x/secgen_test/wordpress_3x.rb new file mode 100644 index 000000000..fdc3ec350 --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/wordpress_3x/secgen_test/wordpress_3x.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class Wordpress3xTest < PostProvisionTest + def initialize + self.module_name = 'wordpress_3x' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +Wordpress3xTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/wordpress_4x/secgen_test/wordpress_4x.rb b/modules/vulnerabilities/unix/webapp/wordpress_4x/secgen_test/wordpress_4x.rb new file mode 100644 index 000000000..39fda4055 --- /dev/null +++ b/modules/vulnerabilities/unix/webapp/wordpress_4x/secgen_test/wordpress_4x.rb @@ -0,0 +1,16 @@ +require_relative '../../../../../lib/post_provision_test' + +class Wordpress4xTest < PostProvisionTest + def initialize + self.module_name = 'wordpress_4x' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_service_up + end +end + +Wordpress4xTest.new.run \ No newline at end of file diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index e3ef57c74..1f0c3a9bf 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -7,10 +7,12 @@ proftpd_testing - + + + - 172.16.0.5 + 172.16.0.17 diff --git a/secgen.rb b/secgen.rb index cedc3120d..9963ff87f 100644 --- a/secgen.rb +++ b/secgen.rb @@ -77,7 +77,7 @@ def build_config(scenario, out_dir, options) Print.info 'Resolving systems: randomising scenario...' # update systems with module selections - systems.map! { |system| + systems.map! {|system| system.module_selections = system.resolve_module_selection(all_available_modules, options) system } @@ -115,10 +115,11 @@ def build_vms(scenario, project_dir, options) retry_count = OVirtFunctions::provider_ovirt?(options) ? 2 : 0 successful_creation = false - while retry_count and !successful_creation + while retry_count >= 0 and !successful_creation vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") if vagrant_output[:status] == 0 - shutdown_cycle(project_dir) + # if true + reboot_cycle(project_dir) if post_provision_tests(project_dir) Print.info 'VMs created.' successful_creation = true @@ -127,8 +128,6 @@ def build_vms(scenario, project_dir, options) sleep(30) GemExec.exe('vagrant', project_dir, 'halt') end - else - Print.err 'Tests failed!' end else if retry_count > 0 @@ -146,7 +145,7 @@ def build_vms(scenario, project_dir, options) elsif match = line.match(/^([-a-zA-Z_0-9]+):[^:]+VM is not created/i) vm_not_to_destroy = match.captures[0] Print.err "Not going to destroy #{vm_not_to_destroy}, since it does not exist" - failures_to_destroy.delete_if {|x| x == vm_not_to_destroy } + failures_to_destroy.delete_if {|x| x == vm_not_to_destroy} # TODO: not sure if there is a need to remove_uncreated_vms() here too? (I don't think so?) end end @@ -173,7 +172,7 @@ def build_vms(scenario, project_dir, options) end sleep(10) end - else # TODO: elsif vagrant_output[:exception].type == ProcessHelper::TimeoutError >destroy individually broken vms as above? + else # TODO: elsif vagrant_output[:exception].type == ProcessHelper::TimeoutError >destroy individually broken vms as above? Print.err 'Vagrant up timeout, destroying VMs and retrying...' GemExec.exe('vagrant', project_dir, 'destroy -f') end @@ -263,14 +262,14 @@ def make_forensic_image(project_dir, image_output_location, image_type) system "cd '#{project_dir}' && vagrant halt" case image_type.downcase - when 'raw', 'dd' - create_dd_image(drive_path, image_output_location) + when 'raw', 'dd' + create_dd_image(drive_path, image_output_location) - when 'ewf', 'e01' - create_ewf_image(drive_path, image_output_location) + when 'ewf', 'e01' + create_ewf_image(drive_path, image_output_location) - else - Print.info "The image type [#{image_type}] is not recognised." + else + Print.info "The image type [#{image_type}] is not recognised." end end @@ -292,14 +291,14 @@ end def list_scenarios Print.std "Full paths to scenario files are displayed below" - Dir["#{ROOT_DIR}/scenarios/**/*"].select { |file| !File.directory? file }.each_with_index do |scenario_name, scenario_number| + Dir["#{ROOT_DIR}/scenarios/**/*"].select {|file| !File.directory? file}.each_with_index do |scenario_name, scenario_number| Print.std "#{scenario_number}) #{scenario_name}" end end def list_projects Print.std "Full paths to project directories are displayed below" - Dir["#{PROJECTS_DIR}/*"].select { |file| !File.file? file }.each_with_index do |scenario_name, scenario_number| + Dir["#{PROJECTS_DIR}/*"].select {|file| !File.file? file}.each_with_index do |scenario_name, scenario_number| Print.std "#{scenario_number}) #{scenario_name}" end end @@ -334,37 +333,48 @@ def get_vm_names(scenario) vm_names end -def shutdown_cycle(project_dir) +def reboot_cycle(project_dir) Print.info 'Shutting down VMs.' sleep(30) GemExec.exe('vagrant', project_dir, 'halt') sleep 5 - GemExec.exe('vagrant',project_dir,'up') + GemExec.exe('vagrant', project_dir, 'up --no-provision') sleep 30 end def post_provision_tests(project_dir) Print.info 'Running post-provision tests...' + tests_passed = true + test_module_outputs = [] test_script_paths = Dir.glob("#{project_dir}/puppet/*/modules/*/secgen_test/*.rb") test_script_paths.each do |test_file_path| - output = `bundle exec ruby #{test_file_path}` - Print.info output - if output.include? "FAILED" - Print.err "ERROR: Post provision failure!" - return false + test_script_output = `bundle exec ruby #{test_file_path}` + test_module_outputs << test_script_output.split("\n") + end + test_module_outputs.each do |output_lines| + output_lines.each do |line| + if line.include? "FAILED:" + tests_passed = false + Print.err line + Print.err "Post provision tests contained failures!" + elsif line.include? "PASSED:" + Print.info line + else + Print.std line + end end end - true + tests_passed end # end of method declarations # start of program execution -Print.std '~'*47 +Print.std '~' * 47 Print.std 'SecGen - Creates virtualised security scenarios' Print.std ' Licensed GPLv3 2014-18' -Print.std '~'*47 +Print.std '~' * 47 # Add read-options from config file (needs handling before options parsed by GetoptLong) if ARGV.include? '--read-options' @@ -416,94 +426,94 @@ options = {} opts.each do |opt, arg| case opt # Main options - when '--help' - usage - when '--scenario' - scenario = arg; - when '--project' - project_dir = arg; - when '--prefix' - options[:prefix] = arg - project_dir = project_dir(arg) + when '--help' + usage + when '--scenario' + scenario = arg; + when '--project' + project_dir = arg; + when '--prefix' + options[:prefix] = arg + project_dir = project_dir(arg) # Additional options - when '--system' - Print.info "VM control (Vagrant) commands will only apply to system #{arg} (must match a system defined in the scenario)" - options[:system] = arg - when '--reload' - Print.info "Will reload and re-provision the VMs" - options[:reload] = true - when '--gui-output' - Print.info "Gui output set (virtual machines will be spawned)" - options[:gui_output] = true - when '--nopae' - Print.info "no pae" - options[:nopae] = true - when '--hwvirtex' - Print.info "with HW virtualisation" - options[:hwvirtex] = true - when '--vtxvpid' - Print.info "with VT support" - options[:vtxvpid] = true - when '--memory-per-vm' - if options.has_key? :total_memory - Print.info 'Total memory option specified before memory per vm option, defaulting to total memory value' - else - Print.info "Memory per vm set to #{arg}" - options[:memory_per_vm] = arg - end - when '--total-memory' - if options.has_key? :memory_per_vm - Print.info 'Memory per vm option specified before total memory option, defaulting to memory per vm value' - else - Print.info "Total memory to be used set to #{arg}" - options[:total_memory] = arg - end - when '--cpu-cores' - Print.info "Number of cpus to be used set to #{arg}" - options[:cpu_cores] = arg - when '--max-cpu-usage' - Print.info "Max CPU usage set to #{arg}" - options[:max_cpu_usage] = arg - when '--shutdown' - Print.info 'Shutdown VMs after provisioning' - options[:shutdown] = true - when '--network-ranges' - Print.info 'Overriding Network Ranges' - options[:ip_ranges] = arg.split(',') - when '--forensic-image-type' - Print.info "Image output type set to #{arg}" - options[:forensic_image_type] = arg - - when '--ovirtuser' - Print.info "Ovirt Username : #{arg}" - options[:ovirtuser] = arg - when '--ovirtpass' - Print.info "Ovirt Password : ********" - options[:ovirtpass] = arg - when '--ovirt-url' - Print.info "Ovirt API url : #{arg}" - options[:ovirturl] = arg - when '--ovirtauthz' - Print.info "Ovirt Authz: #{arg}" - options[:ovirtauthz] = arg - when '--ovirt-cluster' - Print.info "Ovirt Cluster : #{arg}" - options[:ovirtcluster] = arg - when '--ovirt-network' - Print.info "Ovirt Network Name : #{arg}" - options[:ovirtnetwork] = arg - when '--ovirt-affinity-group' - Print.info "Ovirt Affinity Group : #{arg}" - options[:ovirtaffinitygroup] = arg - when '--snapshot' - Print.info "Taking snapshots when VMs are created" - options[:snapshot] = true - + when '--system' + Print.info "VM control (Vagrant) commands will only apply to system #{arg} (must match a system defined in the scenario)" + options[:system] = arg + when '--reload' + Print.info "Will reload and re-provision the VMs" + options[:reload] = true + when '--gui-output' + Print.info "Gui output set (virtual machines will be spawned)" + options[:gui_output] = true + when '--nopae' + Print.info "no pae" + options[:nopae] = true + when '--hwvirtex' + Print.info "with HW virtualisation" + options[:hwvirtex] = true + when '--vtxvpid' + Print.info "with VT support" + options[:vtxvpid] = true + when '--memory-per-vm' + if options.has_key? :total_memory + Print.info 'Total memory option specified before memory per vm option, defaulting to total memory value' else - Print.err "Argument not valid: #{arg}" - usage - exit 1 + Print.info "Memory per vm set to #{arg}" + options[:memory_per_vm] = arg + end + when '--total-memory' + if options.has_key? :memory_per_vm + Print.info 'Memory per vm option specified before total memory option, defaulting to memory per vm value' + else + Print.info "Total memory to be used set to #{arg}" + options[:total_memory] = arg + end + when '--cpu-cores' + Print.info "Number of cpus to be used set to #{arg}" + options[:cpu_cores] = arg + when '--max-cpu-usage' + Print.info "Max CPU usage set to #{arg}" + options[:max_cpu_usage] = arg + when '--shutdown' + Print.info 'Shutdown VMs after provisioning' + options[:shutdown] = true + when '--network-ranges' + Print.info 'Overriding Network Ranges' + options[:ip_ranges] = arg.split(',') + when '--forensic-image-type' + Print.info "Image output type set to #{arg}" + options[:forensic_image_type] = arg + + when '--ovirtuser' + Print.info "Ovirt Username : #{arg}" + options[:ovirtuser] = arg + when '--ovirtpass' + Print.info "Ovirt Password : ********" + options[:ovirtpass] = arg + when '--ovirt-url' + Print.info "Ovirt API url : #{arg}" + options[:ovirturl] = arg + when '--ovirtauthz' + Print.info "Ovirt Authz: #{arg}" + options[:ovirtauthz] = arg + when '--ovirt-cluster' + Print.info "Ovirt Cluster : #{arg}" + options[:ovirtcluster] = arg + when '--ovirt-network' + Print.info "Ovirt Network Name : #{arg}" + options[:ovirtnetwork] = arg + when '--ovirt-affinity-group' + Print.info "Ovirt Affinity Group : #{arg}" + options[:ovirtaffinitygroup] = arg + when '--snapshot' + Print.info "Taking snapshots when VMs are created" + options[:snapshot] = true + + else + Print.err "Argument not valid: #{arg}" + usage + exit 1 end end @@ -516,53 +526,53 @@ end # process command case ARGV[0] - when 'run', 'r' - project_dir = default_project_dir unless project_dir - run(scenario, project_dir, options) - when 'build-project', 'p' - project_dir = default_project_dir unless project_dir - build_config(scenario, project_dir, options) - when 'build-vms', 'v' - if project_dir - build_vms(scenario, project_dir, options) - else - Print.err 'Please specify project directory to read' - usage - exit 1 - end - - when 'create-forensic-image' - image_type = options.has_key?(:forensic_image_type) ? options[:forensic_image_type] : 'raw'; - - if project_dir - build_vms(scenario, project_dir, options) - make_forensic_image(project_dir, nil, image_type) - else - project_dir = default_project_dir unless project_dir - build_config(scenario, project_dir, options) - build_vms(scenario, project_dir, options) - make_forensic_image(project_dir, nil, image_type) - end - - when 'ovirt-post-build' - ovirt_post_build(options, scenario, project_dir) - exit 0 - - when 'list-scenarios' - list_scenarios - exit 0 - - when 'list-projects' - list_projects - exit 0 - - when 'delete-all-projects' - delete_all_projects - Print.std 'All projects deleted' - exit 0 - +when 'run', 'r' + project_dir = default_project_dir unless project_dir + run(scenario, project_dir, options) +when 'build-project', 'p' + project_dir = default_project_dir unless project_dir + build_config(scenario, project_dir, options) +when 'build-vms', 'v' + if project_dir + build_vms(scenario, project_dir, options) else - Print.err "Command not valid: #{ARGV[0]}" + Print.err 'Please specify project directory to read' usage exit 1 + end + +when 'create-forensic-image' + image_type = options.has_key?(:forensic_image_type) ? options[:forensic_image_type] : 'raw'; + + if project_dir + build_vms(scenario, project_dir, options) + make_forensic_image(project_dir, nil, image_type) + else + project_dir = default_project_dir unless project_dir + build_config(scenario, project_dir, options) + build_vms(scenario, project_dir, options) + make_forensic_image(project_dir, nil, image_type) + end + +when 'ovirt-post-build' + ovirt_post_build(options, scenario, project_dir) + exit 0 + +when 'list-scenarios' + list_scenarios + exit 0 + +when 'list-projects' + list_projects + exit 0 + +when 'delete-all-projects' + delete_all_projects + Print.std 'All projects deleted' + exit 0 + +else + Print.err "Command not valid: #{ARGV[0]}" + usage + exit 1 end From 606f267b2cec9b7d4f1a82e149ecd716bc03dec7 Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 17:23:42 +0000 Subject: [PATCH 08/47] more port check tests... --- .../secgen_test/mysql_stretch_compatible.rb | 17 +++++++++++++++++ .../secgen_test/mysql_wheezy_compatible.rb | 17 +++++++++++++++++ .../http/apache_bash_cgi/secgen_metadata.xml | 4 ++++ .../secgen_test/apache_bash_cgi.rb | 17 +++++++++++++++++ .../services/unix/irc/irc2/secgen_test/irc2.rb | 17 +++++++++++++++++ .../misc/distcc_exec/secgen_test/distcc_exec.rb | 17 +++++++++++++++++ 6 files changed, 89 insertions(+) create mode 100644 modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb create mode 100644 modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb create mode 100644 modules/services/unix/http/apache_bash_cgi/secgen_test/apache_bash_cgi.rb create mode 100644 modules/services/unix/irc/irc2/secgen_test/irc2.rb create mode 100644 modules/vulnerabilities/unix/misc/distcc_exec/secgen_test/distcc_exec.rb diff --git a/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb b/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb new file mode 100644 index 000000000..d95a30073 --- /dev/null +++ b/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class MySQLStretchTest < PostProvisionTest + def initialize + self.module_name = 'mysql_stretch_compatible' + self.module_path = get_module_path(__FILE__) + super + self.port = 3306 + end + + def test_module + super + test_service_up + end +end + +MySQLStretchTest.new.run \ No newline at end of file diff --git a/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb b/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb new file mode 100644 index 000000000..7a53abfd7 --- /dev/null +++ b/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class MySQLWheezyTest < PostProvisionTest + def initialize + self.module_name = 'mysql_wheezy_compatible' + self.module_path = get_module_path(__FILE__) + super + self.port = 3306 + end + + def test_module + super + test_service_up + end +end + +MySQLWheezyTest.new.run \ No newline at end of file diff --git a/modules/services/unix/http/apache_bash_cgi/secgen_metadata.xml b/modules/services/unix/http/apache_bash_cgi/secgen_metadata.xml index cbc588364..b1f2a0eaa 100644 --- a/modules/services/unix/http/apache_bash_cgi/secgen_metadata.xml +++ b/modules/services/unix/http/apache_bash_cgi/secgen_metadata.xml @@ -14,6 +14,10 @@ https://httpd.apache.org/ Apache v2 + + webapp + + .*apache httpd diff --git a/modules/services/unix/http/apache_bash_cgi/secgen_test/apache_bash_cgi.rb b/modules/services/unix/http/apache_bash_cgi/secgen_test/apache_bash_cgi.rb new file mode 100644 index 000000000..9343efa95 --- /dev/null +++ b/modules/services/unix/http/apache_bash_cgi/secgen_test/apache_bash_cgi.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class ApacheBashCGITest < PostProvisionTest + def initialize + self.module_name = 'apache_bash_cgi' + self.module_path = get_module_path(__FILE__) + super + self.port = 80 + end + + def test_module + super + test_service_up + end +end + +ApacheBashCGITest.new.run \ No newline at end of file diff --git a/modules/services/unix/irc/irc2/secgen_test/irc2.rb b/modules/services/unix/irc/irc2/secgen_test/irc2.rb new file mode 100644 index 000000000..7761fac90 --- /dev/null +++ b/modules/services/unix/irc/irc2/secgen_test/irc2.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class IRC2Test < PostProvisionTest + def initialize + self.module_name = 'irc2' + self.module_path = get_module_path(__FILE__) + super + self.port = 6667 + end + + def test_module + super + test_service_up + end +end + +IRC2Test.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/misc/distcc_exec/secgen_test/distcc_exec.rb b/modules/vulnerabilities/unix/misc/distcc_exec/secgen_test/distcc_exec.rb new file mode 100644 index 000000000..e3e3245e5 --- /dev/null +++ b/modules/vulnerabilities/unix/misc/distcc_exec/secgen_test/distcc_exec.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class DistCCExecTest < PostProvisionTest + def initialize + self.module_name = 'distcc_exec' + self.module_path = get_module_path(__FILE__) + super + self.port = 3632 + end + + def test_module + super + test_service_up + end +end + +DistCCExecTest.new.run \ No newline at end of file From db7a9daa8af7d542f40f366d48301f99996fb395 Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 17:50:23 +0000 Subject: [PATCH 09/47] popa3d and port check --- lib/objects/post_provision_test.rb | 2 +- .../unix/email/popa3d/secgen_test/popa3d.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 modules/services/unix/email/popa3d/secgen_test/popa3d.rb diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index 47edaa25f..ebcc7f63d 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -77,7 +77,7 @@ class PostProvisionTest end def get_port - if get_json_inputs != {} + if get_json_inputs != {} and get_json_inputs['port'] != nil get_json_inputs['port'][0].to_i else -1 diff --git a/modules/services/unix/email/popa3d/secgen_test/popa3d.rb b/modules/services/unix/email/popa3d/secgen_test/popa3d.rb new file mode 100644 index 000000000..b32aeec5a --- /dev/null +++ b/modules/services/unix/email/popa3d/secgen_test/popa3d.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class Popa3dTest < PostProvisionTest + def initialize + self.module_name = 'popa3d' + self.module_path = get_module_path(__FILE__) + super + self.port = 110 + end + + def test_module + super + test_service_up + end +end + +Popa3dTest.new.run \ No newline at end of file From fcb2dc0e9ba2562b3dd88bde8095f27e6d973ee2 Mon Sep 17 00:00:00 2001 From: ts Date: Mon, 4 Feb 2019 16:52:31 +0000 Subject: [PATCH 10/47] Added NTP test. Refactored html match from parameterised_website into the superclass --- Gemfile | 1 + Gemfile.lock | 4 ++- lib/objects/post_provision_test.rb | 21 +++++++++++++-- .../secgen_test/parameterised_website.rb | 14 ---------- .../services/unix/ntp/ntp/secgen_test/ntp.rb | 27 +++++++++++++++++++ scenarios/tests/test_scenario.xml | 11 ++++---- secgen.rb | 2 +- 7 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 modules/services/unix/ntp/ntp/secgen_test/ntp.rb diff --git a/Gemfile b/Gemfile index bc9ba0183..455954052 100644 --- a/Gemfile +++ b/Gemfile @@ -33,6 +33,7 @@ gem 'ruby-graphviz' gem 'rsa' gem 'gpgmeh' gem 'digest-sha3', :git => "http://github.com/izetex/digest-sha3-ruby" +gem 'net-ntp' #development only gems go here group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index 214c26f37..265befd94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -85,6 +85,7 @@ GEM minitest (5.11.3) multi_json (1.13.1) multipart-post (2.0.0) + net-ntp (2.1.3) nio4r (2.3.1) nokogiri (1.8.4) mini_portile2 (~> 2.3.0) @@ -159,6 +160,7 @@ DEPENDENCIES librarian-puppet mini_exiftool_vendored minitest + net-ntp nokogiri nori ovirt-engine-sdk @@ -182,4 +184,4 @@ DEPENDENCIES zipruby BUNDLED WITH - 1.16.1 + 2.0.0.pre.2 diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index ebcc7f63d..dea4e49d0 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -41,6 +41,7 @@ class PostProvisionTest # Testing Functions # ##################### + # Test service is up (tcp) def test_service_up if is_port_open? system_ip, self.port self.outputs << "PASSED: Port #{self.port} is open at #{get_system_ip} (#{get_system_name})!" @@ -49,6 +50,22 @@ class PostProvisionTest end end + # example usage for page: /index.html + def test_html_returned_content(page, match_string) + + begin + source = Net::HTTP.get(get_system_ip, page, self.port) + rescue SocketError + # do nothing + end + + if source.include? match_string + self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" + else + self.outputs << "FAILED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" + end + end + ################## # Misc Functions # ################## @@ -56,7 +73,7 @@ class PostProvisionTest def get_system_ip vagrant_file_path = "#{get_project_path}/Vagrantfile" vagrantfile = File.read(vagrant_file_path) - ip_line = vagrantfile.split("\n").delete_if { |line| !line.include? "# ip_address_for_#{get_system_name}"}[0] + ip_line = vagrantfile.split("\n").delete_if {|line| !line.include? "# ip_address_for_#{get_system_name}"}[0] ip_address = ip_line.split('=')[-1] if ip_address == "DHCP" self.outputs << "FAILED: Cannot test against dynamic IPs" # TODO: fix this so that we grab dynamic IP address (maybe from vagrant?) @@ -69,7 +86,7 @@ class PostProvisionTest def get_json_inputs json_inputs_path = "#{File.expand_path('../', self.module_path)}/secgen_functions/files/json_inputs/*" json_inputs_files = Dir.glob(json_inputs_path) - json_inputs_files.delete_if { |path| !path.include?(self.module_name) } + json_inputs_files.delete_if {|path| !path.include?(self.module_name)} if json_inputs_files.size > 0 return JSON.parse(Base64.strict_decode64(File.read(json_inputs_files.first))) end diff --git a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb index f4512644d..79b0f68b4 100644 --- a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb +++ b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb @@ -28,20 +28,6 @@ class ParamWebsiteTest < PostProvisionTest test_service_up end - def test_html_returned_content(page, match_string) - - begin - source = Net::HTTP.get(get_system_ip, page, self.port) - rescue SocketError - # do nothing - end - - if source.include? match_string - self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" - else - self.outputs << "FAILED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" - end - end end ParamWebsiteTest.new.run \ No newline at end of file diff --git a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb new file mode 100644 index 000000000..75a2a8c74 --- /dev/null +++ b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb @@ -0,0 +1,27 @@ +require_relative '../../../../../lib/post_provision_test' +require 'net/ntp' + +class NTPTest < PostProvisionTest + def initialize + self.module_name = 'ntp' + self.module_path = get_module_path(__FILE__) + super + self.port = 123 + end + + def test_module + super + test_ntp_query #TODO + end + + def test_ntp_query + begin + time_response = Net::NTP.get(system_ip, port).time + self.outputs << "PASSED: NTP responded on UDP port #{port} with #{time_response}" + rescue Errno::ECONNREFUSED + self.outputs << "FAILED: unable to connect to #{module_name} on UDP port #{port} " + end + end +end + +NTPTest.new.run \ No newline at end of file diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index 1f0c3a9bf..5d39e3819 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -4,15 +4,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario"> - proftpd_testing - + testing + - - - + + - 172.16.0.17 + 172.16.0.13 diff --git a/secgen.rb b/secgen.rb index 9963ff87f..65f329939 100644 --- a/secgen.rb +++ b/secgen.rb @@ -354,7 +354,7 @@ def post_provision_tests(project_dir) end test_module_outputs.each do |output_lines| output_lines.each do |line| - if line.include? "FAILED:" + if line.include? "FAILED:" # todo: read exit code instead tests_passed = false Print.err line Print.err "Post provision tests contained failures!" From 714b2c7b66107d4fffed06cd02be23fec25c45e7 Mon Sep 17 00:00:00 2001 From: ts Date: Mon, 4 Feb 2019 17:29:38 +0000 Subject: [PATCH 11/47] Test faiures read exit code instead of "FAILED" or "PASSED" strings --- lib/objects/post_provision_test.rb | 2 ++ .../services/unix/ntp/ntp/secgen_test/ntp.rb | 3 +- secgen.rb | 32 +++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index dea4e49d0..b45ff20b0 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -47,6 +47,7 @@ class PostProvisionTest self.outputs << "PASSED: Port #{self.port} is open at #{get_system_ip} (#{get_system_name})!" else self.outputs << "FAILED: Port #{self.port} is closed at #{get_system_ip} (#{get_system_name})!" + exit(1) end end @@ -63,6 +64,7 @@ class PostProvisionTest self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" else self.outputs << "FAILED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" + exit(1) end end diff --git a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb index 75a2a8c74..b48d8a80b 100644 --- a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb +++ b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb @@ -6,7 +6,7 @@ class NTPTest < PostProvisionTest self.module_name = 'ntp' self.module_path = get_module_path(__FILE__) super - self.port = 123 + self.port = 12 end def test_module @@ -20,6 +20,7 @@ class NTPTest < PostProvisionTest self.outputs << "PASSED: NTP responded on UDP port #{port} with #{time_response}" rescue Errno::ECONNREFUSED self.outputs << "FAILED: unable to connect to #{module_name} on UDP port #{port} " + exit(1) end end end diff --git a/secgen.rb b/secgen.rb index 65f329939..984213201 100644 --- a/secgen.rb +++ b/secgen.rb @@ -1,6 +1,7 @@ require 'getoptlong' require 'fileutils' require 'nori' +require 'open3' require_relative 'lib/helpers/constants.rb' require_relative 'lib/helpers/print.rb' @@ -116,10 +117,10 @@ def build_vms(scenario, project_dir, options) successful_creation = false while retry_count >= 0 and !successful_creation - vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") - if vagrant_output[:status] == 0 - # if true - reboot_cycle(project_dir) + # vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") + # if vagrant_output[:status] == 0 + if true + # reboot_cycle(project_dir) if post_provision_tests(project_dir) Print.info 'VMs created.' successful_creation = true @@ -349,20 +350,17 @@ def post_provision_tests(project_dir) test_module_outputs = [] test_script_paths = Dir.glob("#{project_dir}/puppet/*/modules/*/secgen_test/*.rb") test_script_paths.each do |test_file_path| - test_script_output = `bundle exec ruby #{test_file_path}` - test_module_outputs << test_script_output.split("\n") + test_stdout, test_stderr, test_status = Open3.capture3("bundle exec ruby #{test_file_path}") + test_module_outputs << {:stdout => test_stdout.split("\n"), :stderr => test_stderr, :exit_status => test_status} end - test_module_outputs.each do |output_lines| - output_lines.each do |line| - if line.include? "FAILED:" # todo: read exit code instead - tests_passed = false - Print.err line - Print.err "Post provision tests contained failures!" - elsif line.include? "PASSED:" - Print.info line - else - Print.std line - end + test_module_outputs.each do |test_output| + if test_output[:exit_status].exitstatus != 0 + tests_passed = false + Print.err test_output[:stdout].join("\n") + Print.err "Post provision tests contained failures!" + Print.err test_output[:stderr].join("\n") + else + Print.info test_output[:stdout].join("\n") end end tests_passed From 4c6718146601ac022b194e283c35ebcabed2b31f Mon Sep 17 00:00:00 2001 From: ts Date: Mon, 4 Feb 2019 17:38:00 +0000 Subject: [PATCH 12/47] Test faiures read exit code instead of "FAILED" or "PASSED" strings --- lib/objects/post_provision_test.rb | 5 ++++- modules/services/unix/ntp/ntp/secgen_test/ntp.rb | 8 ++++---- secgen.rb | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index b45ff20b0..e4659a2f6 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -19,17 +19,20 @@ class PostProvisionTest attr_accessor :json_inputs attr_accessor :port attr_accessor :outputs + attr_accessor :all_tests_passed def initialize self.system_ip = get_system_ip self.json_inputs = get_json_inputs self.port = get_port self.outputs = [] + self.all_tests_passed = true end def run test_module puts self.outputs + exit(1) unless all_tests_passed end def test_module @@ -47,7 +50,7 @@ class PostProvisionTest self.outputs << "PASSED: Port #{self.port} is open at #{get_system_ip} (#{get_system_name})!" else self.outputs << "FAILED: Port #{self.port} is closed at #{get_system_ip} (#{get_system_name})!" - exit(1) + self.all_tests_passed = false end end diff --git a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb index b48d8a80b..2f8bcf569 100644 --- a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb +++ b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb @@ -6,12 +6,12 @@ class NTPTest < PostProvisionTest self.module_name = 'ntp' self.module_path = get_module_path(__FILE__) super - self.port = 12 + self.port = 123 end def test_module super - test_ntp_query #TODO + test_ntp_query end def test_ntp_query @@ -19,8 +19,8 @@ class NTPTest < PostProvisionTest time_response = Net::NTP.get(system_ip, port).time self.outputs << "PASSED: NTP responded on UDP port #{port} with #{time_response}" rescue Errno::ECONNREFUSED - self.outputs << "FAILED: unable to connect to #{module_name} on UDP port #{port} " - exit(1) + self.outputs << "FAILED: unable to connect to #{module_name} on UDP port #{port}" + self.all_tests_passed = false end end end diff --git a/secgen.rb b/secgen.rb index 984213201..085c156fa 100644 --- a/secgen.rb +++ b/secgen.rb @@ -358,7 +358,7 @@ def post_provision_tests(project_dir) tests_passed = false Print.err test_output[:stdout].join("\n") Print.err "Post provision tests contained failures!" - Print.err test_output[:stderr].join("\n") + Print.err test_output[:stderr].join("\n") if test_output[:stderr].length > 0 else Print.info test_output[:stdout].join("\n") end From 9574ba5601402cdecd6775cd2b1a92a6ba35a4e6 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 11:46:14 +0000 Subject: [PATCH 13/47] Tests: local software modules (chkrootkit / nmap) --- lib/objects/post_provision_test.rb | 21 ++++++++++++++++++- lib/templates/Vagrantfile.erb | 6 ++++-- .../chkrootkit/secgen_test/chkrootkit.rb | 17 +++++++++++++++ .../setuid_nmap/secgen_test/setuid_nmap.rb | 19 +++++++++++++++++ scenarios/tests/test_scenario.xml | 5 ++--- secgen.rb | 9 ++++---- 6 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 modules/vulnerabilities/unix/local/chkrootkit/secgen_test/chkrootkit.rb create mode 100644 modules/vulnerabilities/unix/local/setuid_nmap/secgen_test/setuid_nmap.rb diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index e4659a2f6..533f9b08b 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -7,10 +7,11 @@ require 'json' require 'base64' - require 'socket' require 'timeout' +require_relative '../../../lib/helpers/gem_exec' + class PostProvisionTest attr_accessor :project_path attr_accessor :system_ip @@ -71,10 +72,28 @@ class PostProvisionTest end end + def test_local_command(test_output, local_command, match_string) + Dir.chdir(get_project_path) do + output = run_vagrant_ssh(local_command) + if output[:stdout].include? match_string or output[:stderr].include? match_string + self.outputs << "PASSED: #{test_output} local command (#{local_command}) matches with output (#{match_string}) on #{get_system_name}!" + else + self.outputs << "FAILED: #{test_output} local command (#{local_command}) matches with output (#{match_string}) on #{get_system_name}!" + self.outputs << output[:stderr] + self.all_tests_passed = false + end + end + end + ################## # Misc Functions # ################## + def run_vagrant_ssh(args) + stdout, stderr, status = Open3.capture3("/usr/bin/vagrant ssh -c '#{args}'") + {:stdout => stdout, :stderr => stderr, :exit_status => status} + end + def get_system_ip vagrant_file_path = "#{get_project_path}/Vagrantfile" vagrantfile = File.read(vagrant_file_path) diff --git a/lib/templates/Vagrantfile.erb b/lib/templates/Vagrantfile.erb index 1001829a0..fe2d02346 100644 --- a/lib/templates/Vagrantfile.erb +++ b/lib/templates/Vagrantfile.erb @@ -136,7 +136,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| <% else %> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, type: "dhcp", auto_config: false <% end %> - # ip_address_for_<%= system.name %>=DHCP + <% # Below string is used within testing, do not delete. -%> + # ip_address_for_<%= system.name %>=DHCP <% # Static networking -%> <% else -%> <% # Static oVirt networking -%> @@ -151,7 +152,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| <% # Static Virtualbox networking -%> <% else -%> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, ip: "<%= resolve_network(selected_module)%>" - # ip_address_for_<%= system.name %>=<%= resolve_network(selected_module)%> + <% # Below string is used within testing, do not delete. -%> + # ip_address_for_<%= system.name %>=<%= resolve_network(selected_module)%> <% end -%> <% end -%> <% when 'vulnerability', 'service', 'utility', 'build' -%> diff --git a/modules/vulnerabilities/unix/local/chkrootkit/secgen_test/chkrootkit.rb b/modules/vulnerabilities/unix/local/chkrootkit/secgen_test/chkrootkit.rb new file mode 100644 index 000000000..452d4aa6b --- /dev/null +++ b/modules/vulnerabilities/unix/local/chkrootkit/secgen_test/chkrootkit.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class ChkrootkitVulnTest < PostProvisionTest + def initialize + self.module_name = 'chkrootkit' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('Chkrootkit binary exists?', 'sudo ls -la /usr/sbin/chkrootkit', 'chkrootkit-0.49') + test_local_command('Chkrootkit runs?', 'sudo /usr/sbin/chkrootkit -V', 'chkrootkit version 0.49') + end + +end +ChkrootkitVulnTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/setuid_nmap/secgen_test/setuid_nmap.rb b/modules/vulnerabilities/unix/local/setuid_nmap/secgen_test/setuid_nmap.rb new file mode 100644 index 000000000..78e9506f0 --- /dev/null +++ b/modules/vulnerabilities/unix/local/setuid_nmap/secgen_test/setuid_nmap.rb @@ -0,0 +1,19 @@ +require_relative '../../../../../lib/post_provision_test' + + +class SetUIDNmapTest < PostProvisionTest + def initialize + self.module_name = 'setuid_nmap' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('nmap has setuid flag?', 'sudo ls -la /usr/bin/nmap', '-rwsr-xr-x') + test_local_command('nmap runs?', 'sudo /usr/bin/nmap --version', 'Nmap version') + end + +end + +SetUIDNmapTest.new.run \ No newline at end of file diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index 5d39e3819..0368e177e 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -7,11 +7,10 @@ testing - - + - 172.16.0.13 + 172.16.0.12 diff --git a/secgen.rb b/secgen.rb index 085c156fa..9a4d97575 100644 --- a/secgen.rb +++ b/secgen.rb @@ -117,10 +117,9 @@ def build_vms(scenario, project_dir, options) successful_creation = false while retry_count >= 0 and !successful_creation - # vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") - # if vagrant_output[:status] == 0 - if true - # reboot_cycle(project_dir) + vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") + if vagrant_output[:status] == 0 + reboot_cycle(project_dir) if post_provision_tests(project_dir) Print.info 'VMs created.' successful_creation = true @@ -358,7 +357,7 @@ def post_provision_tests(project_dir) tests_passed = false Print.err test_output[:stdout].join("\n") Print.err "Post provision tests contained failures!" - Print.err test_output[:stderr].join("\n") if test_output[:stderr].length > 0 + Print.err test_output[:stderr] else Print.info test_output[:stdout].join("\n") end From a8afae3569f225818668086bfb4ffc2978e69a7a Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 12:15:26 +0000 Subject: [PATCH 14/47] suid root bash tests + name update --- .../manifests/config.pp | 2 +- .../secgen_metadata.xml | 0 .../secgen_test/suid_root_bash.rb | 19 +++++++++++++++++++ .../suid_root_bash/suid_root_bash.pp | 1 + .../uid_bash_root/uid_bash_root.pp | 1 - .../uid_bash_root.xml | 4 ++-- 6 files changed, 23 insertions(+), 4 deletions(-) rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_bash_root => suid_root_bash}/manifests/config.pp (69%) rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_bash_root => suid_root_bash}/secgen_metadata.xml (100%) create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/suid_root_bash.pp delete mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/uid_bash_root.pp diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/manifests/config.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/manifests/config.pp similarity index 69% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/manifests/config.pp rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/manifests/config.pp index 1931fcfab..87063f48a 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/manifests/config.pp +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/manifests/config.pp @@ -1,4 +1,4 @@ -class uid_bash_root::config { +class suid_root_bash::config { file { '/bin/bash': ensure => present, mode => '4777', diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/secgen_metadata.xml b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_metadata.xml similarity index 100% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/secgen_metadata.xml rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_metadata.xml diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb new file mode 100644 index 000000000..e8f8c1589 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb @@ -0,0 +1,19 @@ +require_relative '../../../../../lib/post_provision_test' + + +class SUIDNanoTest < PostProvisionTest + def initialize + self.module_name = 'suid_root_nano' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('nano suid bit set?','sudo ls -la /bin/nano', '-rwsrwxrwx') + test_local_command('nano runs?','/bin/nano --version', 'GNU nano') + end + +end + +SUIDNanoTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/suid_root_bash.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/suid_root_bash.pp new file mode 100644 index 000000000..d16274345 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/suid_root_bash.pp @@ -0,0 +1 @@ +include suid_root_bash::config \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/uid_bash_root.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/uid_bash_root.pp deleted file mode 100644 index 5169dbf9b..000000000 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_bash_root/uid_bash_root.pp +++ /dev/null @@ -1 +0,0 @@ -include uid_bash_root::config \ No newline at end of file diff --git a/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_bash_root.xml b/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_bash_root.xml index 64357f8b5..03642ae78 100644 --- a/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_bash_root.xml +++ b/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_bash_root.xml @@ -6,10 +6,10 @@ - access_control_misconfigurations_uid_bash_root + access_control_misconfigurations_suid_root_bash - + From d27a0f8262427b4375f44f75b14969d46ef9b94c Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 12:16:11 +0000 Subject: [PATCH 15/47] readable shadow --- .../readable_shadow/manifests/config.pp | 2 +- .../readable_shadow/secgen_metadata.xml | 2 +- .../secgen_test/readable_shadow.rb | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_test/readable_shadow.rb diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/manifests/config.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/manifests/config.pp index 0639445c9..58fe907a0 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/manifests/config.pp +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/manifests/config.pp @@ -1,6 +1,6 @@ class readable_shadow::config { file { '/etc/shadow': ensure => present, - mode => '0622', + mode => '0644', } } diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_metadata.xml b/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_metadata.xml index 48ed6a44e..8f3cbeece 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_metadata.xml +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_metadata.xml @@ -6,7 +6,7 @@ Readable Shadow File Thomas Shaw MIT - Changes permissions on shadow file to 0622, reveals password hashes to local users. + Changes permissions on shadow file to 0611, reveals password hashes to local users. This is not a common misconfiguration, and not particularly subtle. access_control_misconfiguration diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_test/readable_shadow.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_test/readable_shadow.rb new file mode 100644 index 000000000..1bb66fc01 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/readable_shadow/secgen_test/readable_shadow.rb @@ -0,0 +1,18 @@ +require_relative '../../../../../lib/post_provision_test' + + +class ReadableShadowTest < PostProvisionTest + def initialize + self.module_name = 'readable_shadow' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('Shadow readable?','sudo ls -la /etc/shadow', '-rw-r--r--') + end + +end + +ReadableShadowTest.new.run \ No newline at end of file From 91f7d6398ed08f66a4a4194f867e84ad9724bb9f Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 12:17:44 +0000 Subject: [PATCH 16/47] suid_root_nano tests --- .../secgen_test/suid_root_nano.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_nano/secgen_test/suid_root_nano.rb diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_nano/secgen_test/suid_root_nano.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_nano/secgen_test/suid_root_nano.rb new file mode 100644 index 000000000..e8f8c1589 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_nano/secgen_test/suid_root_nano.rb @@ -0,0 +1,19 @@ +require_relative '../../../../../lib/post_provision_test' + + +class SUIDNanoTest < PostProvisionTest + def initialize + self.module_name = 'suid_root_nano' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('nano suid bit set?','sudo ls -la /bin/nano', '-rwsrwxrwx') + test_local_command('nano runs?','/bin/nano --version', 'GNU nano') + end + +end + +SUIDNanoTest.new.run \ No newline at end of file From c9fc118a69a5aa7cd7a9d011b574de9557258735 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 13:27:46 +0000 Subject: [PATCH 17/47] access_control_misconfigurations: added tests + updated module names + scenarios that referred to old names --- .../manifests/change_uid_permissions.pp | 2 +- .../secgen_metadata.xml | 0 .../secgen_test/suid_root_less.rb | 19 +++++++++++++++++++ .../suid_root_less.pp} | 2 +- .../manifests/change_uid_permissions.pp | 2 +- .../secgen_metadata.xml | 0 .../suid_root_vi/secgen_test/suid_root_vi.rb | 18 ++++++++++++++++++ .../suid_root_vi.pp} | 3 ++- .../secgen_test/writable_groups.rb | 18 ++++++++++++++++++ .../secgen_test/writable_passwd.rb | 18 ++++++++++++++++++ .../secgen_test/writable_shadow.rb | 18 ++++++++++++++++++ .../uid_less_root.xml | 2 +- .../uid_vi_root.xml | 2 +- ..._control_misconfigurations_uid_vi_root.xml | 2 +- 14 files changed, 99 insertions(+), 7 deletions(-) rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_less_root => suid_root_less}/manifests/change_uid_permissions.pp (69%) rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_less_root => suid_root_less}/secgen_metadata.xml (100%) create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/secgen_test/suid_root_less.rb rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_less_root/uid_less_root.pp => suid_root_less/suid_root_less.pp} (67%) rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_vi_root => suid_root_vi}/manifests/change_uid_permissions.pp (71%) rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_vi_root => suid_root_vi}/secgen_metadata.xml (100%) create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/secgen_test/suid_root_vi.rb rename modules/vulnerabilities/unix/access_control_misconfigurations/{uid_vi_root/uid_vi_root.pp => suid_root_vi/suid_root_vi.pp} (59%) create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/writable_groups/secgen_test/writable_groups.rb create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/writable_passwd/secgen_test/writable_passwd.rb create mode 100644 modules/vulnerabilities/unix/access_control_misconfigurations/writable_shadow/secgen_test/writable_shadow.rb diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/manifests/change_uid_permissions.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/manifests/change_uid_permissions.pp similarity index 69% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/manifests/change_uid_permissions.pp rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/manifests/change_uid_permissions.pp index 91e2c793d..ee920c929 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/manifests/change_uid_permissions.pp +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/manifests/change_uid_permissions.pp @@ -1,4 +1,4 @@ -class uid_less_root::change_uid_permissions ($file_input = [], $user = 'root') { +class suid_root_less::change_uid_permissions ($file_input = [], $user = 'root') { $file_input.each |$file, $permission_code| { file { $file: mode => $permission_code, diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/secgen_metadata.xml b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/secgen_metadata.xml similarity index 100% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/secgen_metadata.xml rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/secgen_metadata.xml diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/secgen_test/suid_root_less.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/secgen_test/suid_root_less.rb new file mode 100644 index 000000000..66c962058 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/secgen_test/suid_root_less.rb @@ -0,0 +1,19 @@ +require_relative '../../../../../lib/post_provision_test' + + +class SUIDLessTest < PostProvisionTest + def initialize + self.module_name = 'suid_root_less' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('less suid bit set?','sudo ls -la /bin/less', '-rwsrwxrwx') + test_local_command('less runs?','/bin/less --help', 'Commands marked with * may be preceded by a number') + end + +end + +SUIDLessTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/uid_less_root.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/suid_root_less.pp similarity index 67% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/uid_less_root.pp rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/suid_root_less.pp index 6ab2160da..5365f21a6 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_less_root/uid_less_root.pp +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_less/suid_root_less.pp @@ -1,4 +1,4 @@ -class {'uid_less_root::change_uid_permissions': +class {'suid_root_less::change_uid_permissions': user => 'root', file_input => { '/bin/less' => '4777', diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/manifests/change_uid_permissions.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/manifests/change_uid_permissions.pp similarity index 71% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/manifests/change_uid_permissions.pp rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/manifests/change_uid_permissions.pp index bd2ecc8a8..e41feba25 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/manifests/change_uid_permissions.pp +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/manifests/change_uid_permissions.pp @@ -1,4 +1,4 @@ -class uid_vi_root::change_uid_permissions ($file_input = [],$user = 'root') { +class suid_root_vi::change_uid_permissions ($file_input = [],$user = 'root') { $file_input.each |String $file, String $permission_code| { file { $file: mode => $permission_code, diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/secgen_metadata.xml b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/secgen_metadata.xml similarity index 100% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/secgen_metadata.xml rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/secgen_metadata.xml diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/secgen_test/suid_root_vi.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/secgen_test/suid_root_vi.rb new file mode 100644 index 000000000..31277d102 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/secgen_test/suid_root_vi.rb @@ -0,0 +1,18 @@ +require_relative '../../../../../lib/post_provision_test' + + +class SUIDviTest < PostProvisionTest + def initialize + self.module_name = 'suid_root_vi' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('vi suid bit set?','sudo ls -la $(readlink -f `whereis vim`)', 'rwsrwxrwx') + end + +end + +SUIDviTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/uid_vi_root.pp b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/suid_root_vi.pp similarity index 59% rename from modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/uid_vi_root.pp rename to modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/suid_root_vi.pp index 3fade5615..ca86b21fb 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/uid_vi_root/uid_vi_root.pp +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_vi/suid_root_vi.pp @@ -1,7 +1,8 @@ -class {'uid_vi_root::change_uid_permissions': +class {'suid_root_vi::change_uid_permissions': file_input => { '/usr/bin/vi' => '4777', '/etc/alternatives/vi' => '4777', '/usr/bin/vim.tiny' => '4777', + '/usr/bin/vim.basic' => '4777', } } \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/writable_groups/secgen_test/writable_groups.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/writable_groups/secgen_test/writable_groups.rb new file mode 100644 index 000000000..92f7b6f92 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/writable_groups/secgen_test/writable_groups.rb @@ -0,0 +1,18 @@ +require_relative '../../../../../lib/post_provision_test' + + +class WritableGroupsTest < PostProvisionTest + def initialize + self.module_name = 'writable_groups' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('writable groups?','sudo ls -la /etc/group', 'rwxrwxrwx') + end + +end + +WritableGroupsTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/writable_passwd/secgen_test/writable_passwd.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/writable_passwd/secgen_test/writable_passwd.rb new file mode 100644 index 000000000..0b2d12630 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/writable_passwd/secgen_test/writable_passwd.rb @@ -0,0 +1,18 @@ +require_relative '../../../../../lib/post_provision_test' + + +class WritablePasswdTest < PostProvisionTest + def initialize + self.module_name = 'writable_passwd' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('writable /etc/passwd?','sudo ls -la /etc/passwd', 'rwxrwxrwx') + end + +end + +WritablePasswdTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/writable_shadow/secgen_test/writable_shadow.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/writable_shadow/secgen_test/writable_shadow.rb new file mode 100644 index 000000000..d1d41d3f0 --- /dev/null +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/writable_shadow/secgen_test/writable_shadow.rb @@ -0,0 +1,18 @@ +require_relative '../../../../../lib/post_provision_test' + + +class WritableShadowTest < PostProvisionTest + def initialize + self.module_name = 'writable_shadow' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('writable /etc/shadow?','sudo ls -la /etc/shadow', 'rwxrwxrwx') + end + +end + +WritableShadowTest.new.run \ No newline at end of file diff --git a/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_less_root.xml b/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_less_root.xml index d9e6035d2..fecb5378c 100644 --- a/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_less_root.xml +++ b/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_less_root.xml @@ -9,7 +9,7 @@ access_control_misconfigurations_uid_less_root - + diff --git a/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_vi_root.xml b/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_vi_root.xml index e0b8030d0..672491336 100644 --- a/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_vi_root.xml +++ b/scenarios/examples/vulnerability_examples/access_control_misconfiguration_examples/uid_vi_root.xml @@ -9,7 +9,7 @@ access_control_misconfigurations_vi_root - + diff --git a/scenarios/examples/vulnerability_examples/access_control_misconfigurations_uid_vi_root.xml b/scenarios/examples/vulnerability_examples/access_control_misconfigurations_uid_vi_root.xml index 19bb7eadb..d0056cffa 100644 --- a/scenarios/examples/vulnerability_examples/access_control_misconfigurations_uid_vi_root.xml +++ b/scenarios/examples/vulnerability_examples/access_control_misconfigurations_uid_vi_root.xml @@ -9,7 +9,7 @@ access_control_misconfigurations_vi_root - + From b0881938f0ecf782ac6edbcc3c33c3e1308579d5 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 16:28:51 +0000 Subject: [PATCH 18/47] fixed mysql tests + update parameterised_website tests --- lib/objects/post_provision_test.rb | 5 ++-- .../secgen_test/mysql_stretch_compatible.rb | 3 +- .../secgen_test/mysql_wheezy_compatible.rb | 2 +- .../secgen_test/parameterised_website.rb | 29 ++++++++++++++++--- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index 533f9b08b..e1d167a4f 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -56,7 +56,7 @@ class PostProvisionTest end # example usage for page: /index.html - def test_html_returned_content(page, match_string) + def test_html_returned_content(page, match_string, hide_content=false) begin source = Net::HTTP.get(get_system_ip, page, self.port) @@ -65,6 +65,7 @@ class PostProvisionTest end if source.include? match_string + match_string = '' if hide_content self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" else self.outputs << "FAILED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" @@ -90,7 +91,7 @@ class PostProvisionTest ################## def run_vagrant_ssh(args) - stdout, stderr, status = Open3.capture3("/usr/bin/vagrant ssh -c '#{args}'") + stdout, stderr, status = Open3.capture3("/usr/bin/vagrant ssh #{get_system_name} -c '#{args}'") {:stdout => stdout, :stderr => stderr, :exit_status => status} end diff --git a/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb b/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb index d95a30073..8b821b377 100644 --- a/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb +++ b/modules/services/unix/database/mysql_stretch_compatible/mysql/secgen_test/mysql_stretch_compatible.rb @@ -5,12 +5,11 @@ class MySQLStretchTest < PostProvisionTest self.module_name = 'mysql_stretch_compatible' self.module_path = get_module_path(__FILE__) super - self.port = 3306 end def test_module super - test_service_up + test_local_command('mysqld process running?', 'ps -ef | grep mysqld', '/usr/sbin/mysqld') end end diff --git a/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb b/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb index 7a53abfd7..4e07fd320 100644 --- a/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb +++ b/modules/services/unix/database/mysql_wheezy_compatible/mysql/secgen_test/mysql_wheezy_compatible.rb @@ -10,7 +10,7 @@ class MySQLWheezyTest < PostProvisionTest def test_module super - test_service_up + test_local_command('mysqld process running?', 'ps -ef | grep mysqld', '/usr/bin/mysqld') end end diff --git a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb index 79b0f68b4..18b97ac40 100644 --- a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb +++ b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb @@ -12,9 +12,19 @@ class ParamWebsiteTest < PostProvisionTest def test_module super json_inputs = get_json_inputs - css_theme = json_inputs['theme'][0] - if json_inputs['organisation'] + test_organisation_functionality(json_inputs) + test_additional_page(json_inputs) + test_html_returned_content("/css/#{json_inputs['theme'][0]}", 'Bootswatch v4.0.0') + + test_service_up + end + + def test_organisation_functionality(json_inputs) + if json_inputs['organisation'] and + json_inputs['organisation'][0] and + json_inputs['organisation'][0] != '' + organisation = JSON.parse(json_inputs['organisation'][0]) employee_1 = organisation['employees'][0] @@ -22,10 +32,21 @@ class ParamWebsiteTest < PostProvisionTest test_html_returned_content('/contact.html', organisation['business_moto']) test_html_returned_content('/contact.html', employee_1['name']) end + end - test_html_returned_content("/css/#{css_theme}", 'Bootswatch v4.0.0') - test_service_up + def test_additional_page(json_inputs) + if json_inputs['additional_page_filenames'] and + json_inputs['additional_page_filenames'][0] and + json_inputs['additional_page_filenames'][0].include? 'html' and + json_inputs['additional_pages'] and + json_inputs['additional_pages'][0] + + page_name = json_inputs['additional_page_filenames'][0] + page_name = "/#{page_name}" if page_name.split[0] != '/' + + test_html_returned_content(page_name, json_inputs['additional_pages'][0], true) + end end end From 4dfd3e03eb52796754f73eb1597c2321a0a8fc47 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 16:29:39 +0000 Subject: [PATCH 19/47] parameterised_website/secgen_tests: more sensible test order --- .../secgen_test/parameterised_website.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb index 18b97ac40..2dfba2a0f 100644 --- a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb +++ b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb @@ -12,12 +12,10 @@ class ParamWebsiteTest < PostProvisionTest def test_module super json_inputs = get_json_inputs - + test_service_up test_organisation_functionality(json_inputs) test_additional_page(json_inputs) test_html_returned_content("/css/#{json_inputs['theme'][0]}", 'Bootswatch v4.0.0') - - test_service_up end def test_organisation_functionality(json_inputs) From 8704db35e981ac3646bb5cb5102209ccadf02557 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 17:26:40 +0000 Subject: [PATCH 20/47] basic_narrative.xml: added _server to prevent console access --- scenarios/ctf/basic_narrative.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenarios/ctf/basic_narrative.xml b/scenarios/ctf/basic_narrative.xml index c081e4b5c..e6a086379 100644 --- a/scenarios/ctf/basic_narrative.xml +++ b/scenarios/ctf/basic_narrative.xml @@ -15,7 +15,7 @@ intermediate - target + target_server From 1a61db5b1fb500b7e04d73c1322483c9125e3ca6 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 17:27:39 +0000 Subject: [PATCH 21/47] tests: net/http moved to superclass, updated website tests --- lib/objects/post_provision_test.rb | 5 +++-- .../secgen_test/parameterised_website.rb | 5 ++--- .../unix/webapp/onlinestore/secgen_test/onlinestore.rb | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index e1d167a4f..6d3f55ae1 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -9,6 +9,7 @@ require 'json' require 'base64' require 'socket' require 'timeout' +require 'net/http' require_relative '../../../lib/helpers/gem_exec' @@ -68,8 +69,8 @@ class PostProvisionTest match_string = '' if hide_content self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" else - self.outputs << "FAILED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" - exit(1) + self.outputs << "FAILED: Content #{match_string} is not contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" + self.all_tests_passed = false end end diff --git a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb index 2dfba2a0f..53de3efc7 100644 --- a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb +++ b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb @@ -1,6 +1,5 @@ require_relative '../../../../../lib/post_provision_test' require 'json' -require 'net/http' class ParamWebsiteTest < PostProvisionTest def initialize @@ -13,12 +12,12 @@ class ParamWebsiteTest < PostProvisionTest super json_inputs = get_json_inputs test_service_up - test_organisation_functionality(json_inputs) + test_org_functionality(json_inputs) test_additional_page(json_inputs) test_html_returned_content("/css/#{json_inputs['theme'][0]}", 'Bootswatch v4.0.0') end - def test_organisation_functionality(json_inputs) + def test_org_functionality(json_inputs) if json_inputs['organisation'] and json_inputs['organisation'][0] and json_inputs['organisation'][0] != '' diff --git a/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb b/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb index b242f6028..d20a08982 100644 --- a/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb +++ b/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb @@ -10,6 +10,7 @@ class OnlineStoreTest < PostProvisionTest def test_module super test_service_up + test_html_returned_content('/index.php', 'Welcome to furniture!') end end From 341cd0bdf6df9da71bf882fd6625cec7010f69a5 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 17:28:15 +0000 Subject: [PATCH 22/47] vulnerabilities/unix/local/dirtycow --- .../debian_puppet_32/secgen_metadata.xml | 5 +++ .../secgen_metadata.xml | 4 +++ .../unix/update/apt_upgrade/manifests/apt.pp | 35 ++++++++++++------- .../unix/local/dirtycow/dirtycow.pp | 1 + .../unix/local/dirtycow/manifests/config.pp | 3 ++ .../unix/local/dirtycow/secgen_metadata.xml | 33 +++++++++++++++++ .../local/dirtycow/secgen_test/dirtycow.rb | 17 +++++++++ 7 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp create mode 100644 modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp create mode 100644 modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml create mode 100644 modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb diff --git a/modules/bases/debian_puppet_32/secgen_metadata.xml b/modules/bases/debian_puppet_32/secgen_metadata.xml index 171d99ba9..fdda2be95 100644 --- a/modules/bases/debian_puppet_32/secgen_metadata.xml +++ b/modules/bases/debian_puppet_32/secgen_metadata.xml @@ -20,4 +20,9 @@ https://atlas.hashicorp.com/puppetlabs various + + + upgrade + + diff --git a/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml b/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml index a73992247..ec9597f9f 100644 --- a/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml +++ b/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml @@ -21,4 +21,8 @@ https://atlas.hashicorp.com/puppetlabs various + + upgrade + + diff --git a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp index 654d0c6f0..281d9a353 100644 --- a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp +++ b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp @@ -1,17 +1,28 @@ class apt_upgrade::apt { - case $operatingsystem { - 'Debian': { - exec { 'update': - command => "/usr/bin/apt-get upgrade", - tries => 5, - try_sleep => 30, + + notice("Running apt-upgrade module...") + + if defined('dirtycow::config') { + notice("vulnerabilities/unix/local/dirtycow included - skipping apt-get upgrade...") + } else { + case $operatingsystem { + 'Debian': { + exec { 'update': + command => "/usr/bin/apt-get -y upgrade", + tries => 5, + try_sleep => 30, + timeout => 0, + logoutput => true, + } } - } - 'Ubuntu': { - exec { 'update': - command => "/usr/bin/apt-get upgrade", - tries => 5, - try_sleep => 30, + 'Ubuntu': { + exec { 'update': + command => "/usr/bin/apt-get -y upgrade", + tries => 5, + try_sleep => 30, + timeout => 0, + logoutput => true, + } } } } diff --git a/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp b/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp new file mode 100644 index 000000000..f86b5785e --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp @@ -0,0 +1 @@ +include dirtycow::config \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp b/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp new file mode 100644 index 000000000..5a22e775d --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp @@ -0,0 +1,3 @@ +class dirtycow::config { + notice("dirtycow::config: Do nothing, the apt upgrade just checks if we're defined and blocks apt-get upgrade if so.") +} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml b/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml new file mode 100644 index 000000000..90d6aaac1 --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml @@ -0,0 +1,33 @@ + + + + DirtyCow privilege escalation + Thomas Shaw + MIT + DirtyCow local privilege escalation. Including this module prevents the default apt-get upgrade from + running which leaves the wheezy bases vulnerable. + + + unpatched_kernel + race_condition + root_rwx + local + linux + medium + + + .*Stretch.* + + + .*Kali.* + + + .*Windows.* + + + .*Ubuntu.* + + + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb b/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb new file mode 100644 index 000000000..1433b43a4 --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class DirtyCOWTest < PostProvisionTest + def initialize + self.module_name = 'dirtycow' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('apt-get upgrade not performed?', 'sudo apt-get -u upgrade --assume-no','linux-image-3.') + end + +end + +DirtyCOWTest.new.run \ No newline at end of file From b60f421d47a36d56b0f569802a8359685ba04456 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 17:30:40 +0000 Subject: [PATCH 23/47] scenarios/examples/vulnerability_examples/dirtycow.xml --- .../vulnerability_examples/dirtycow.xml | 24 +++++++++++++++++++ scenarios/tests/test_scenario.xml | 4 ++-- secgen.rb | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 scenarios/examples/vulnerability_examples/dirtycow.xml diff --git a/scenarios/examples/vulnerability_examples/dirtycow.xml b/scenarios/examples/vulnerability_examples/dirtycow.xml new file mode 100644 index 000000000..aba9df04f --- /dev/null +++ b/scenarios/examples/vulnerability_examples/dirtycow.xml @@ -0,0 +1,24 @@ + + + + + + dirtycow + + + + + + + 172.16.0.12 + + + + + IP_addresses + + + + diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index 0368e177e..7d5e7cc5d 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -5,9 +5,9 @@ xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario"> testing - + - + 172.16.0.12 diff --git a/secgen.rb b/secgen.rb index 9a4d97575..36bf0a8e7 100644 --- a/secgen.rb +++ b/secgen.rb @@ -147,7 +147,7 @@ def build_vms(scenario, project_dir, options) Print.err "Not going to destroy #{vm_not_to_destroy}, since it does not exist" failures_to_destroy.delete_if {|x| x == vm_not_to_destroy} # TODO: not sure if there is a need to remove_uncreated_vms() here too? (I don't think so?) - end + end # TODO: Add another elsif here to check if any tests have failed, edit the output of the tests so that it has a unique string that captures the vm name end failures_to_destroy = failures_to_destroy.uniq From 18948474997a401a6bc101f7627dc0c04f6a068b Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 18:15:59 +0000 Subject: [PATCH 24/47] post_provision_test, replaced gem_exec with open3 --- lib/objects/post_provision_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index 6d3f55ae1..d42787ef6 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -10,8 +10,7 @@ require 'base64' require 'socket' require 'timeout' require 'net/http' - -require_relative '../../../lib/helpers/gem_exec' +require 'open3' class PostProvisionTest attr_accessor :project_path From 1c6deeff94be7598801907c25ef9a9973658494c Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 18:16:25 +0000 Subject: [PATCH 25/47] gitlist_040: added content test --- .../unix/webapp/gitlist_040/secgen_test/gitlist_040.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb b/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb index b80f1599a..5dceede60 100644 --- a/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb +++ b/modules/vulnerabilities/unix/webapp/gitlist_040/secgen_test/gitlist_040.rb @@ -10,6 +10,7 @@ class Gitlist040Test < PostProvisionTest def test_module super test_service_up + test_html_returned_content('/', 'GitList') end end From d5adcf4ccac35d81e5c26a7dc8395ba5a5242fa1 Mon Sep 17 00:00:00 2001 From: ts Date: Tue, 5 Feb 2019 18:53:10 +0000 Subject: [PATCH 26/47] added retry loop for test_service_up? and increased sleep time as some web applications were failing. --- lib/objects/post_provision_test.rb | 30 +++++++++++++++++------------- secgen.rb | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/objects/post_provision_test.rb b/lib/objects/post_provision_test.rb index d42787ef6..f02030dae 100644 --- a/lib/objects/post_provision_test.rb +++ b/lib/objects/post_provision_test.rb @@ -56,15 +56,15 @@ class PostProvisionTest end # example usage for page: /index.html - def test_html_returned_content(page, match_string, hide_content=false) + def test_html_returned_content(page, match_string, hide_content = false) begin source = Net::HTTP.get(get_system_ip, page, self.port) - rescue SocketError + rescue SocketError, Errno::ECONNREFUSED # do nothing end - if source.include? match_string + if source and source.include? match_string match_string = '' if hide_content self.outputs << "PASSED: Content #{match_string} is contained within #{page} at #{get_system_ip}:#{self.port} (#{get_system_name})!" else @@ -147,18 +147,22 @@ class PostProvisionTest end def is_port_open?(ip, port) - begin - Timeout::timeout(1) do - begin - s = TCPSocket.new(ip, port) - s.close - return true - rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH - return false + retries = 5 + while retries > 0 + begin + Timeout::timeout(2) do + begin + s = TCPSocket.new(ip, port) + s.close + return true + rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH + # do nothing + end end + rescue Timeout::Error + # ignored end - rescue Timeout::Error - # ignored + retries -= 1 end false end diff --git a/secgen.rb b/secgen.rb index 36bf0a8e7..68e94e413 100644 --- a/secgen.rb +++ b/secgen.rb @@ -339,7 +339,7 @@ def reboot_cycle(project_dir) GemExec.exe('vagrant', project_dir, 'halt') sleep 5 GemExec.exe('vagrant', project_dir, 'up --no-provision') - sleep 30 + sleep 45 end def post_provision_tests(project_dir) From 0f8b41c3d0698a3ac653a687145441b516d6653c Mon Sep 17 00:00:00 2001 From: ts Date: Wed, 6 Feb 2019 17:45:11 +0000 Subject: [PATCH 27/47] delete bases/ubuntu_xenial_64 --- .../ubuntu_xenial_64/secgen_metadata.xml | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 modules/bases/ubuntu_xenial_64/secgen_metadata.xml diff --git a/modules/bases/ubuntu_xenial_64/secgen_metadata.xml b/modules/bases/ubuntu_xenial_64/secgen_metadata.xml deleted file mode 100644 index f013c4cfb..000000000 --- a/modules/bases/ubuntu_xenial_64/secgen_metadata.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - Ubuntu Xenial 16.04 LTS 64-bit Server by puppetlabs - Thomas Shaw - GPLv3 - TODO - 64-bit - server - cli - - linux - unix - Ubuntu Xenial 16.04 LTS - https://app.vagrantup.com/puppetlabs/boxes/ubuntu-16.04-64-puppet/versions/1.0.0/providers/virtualbox.box - debian_server - - https://atlas.hashicorp.com/puppetlabs - various - From d655b3d226ef276da6c01831d5ff3a01c23331cf Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 7 Feb 2019 11:11:50 +0000 Subject: [PATCH 28/47] updated tests + team project --- .../secgen_test/parameterised_website.rb | 42 +++++++++++++++---- .../services/unix/ntp/ntp/secgen_test/ntp.rb | 17 ++++++-- .../secgen_test/parameterised_accounts.rb | 24 +++++++++++ .../suid_root_bash/secgen_metadata.xml | 4 ++ .../secgen_test/suid_root_bash.rb | 10 ++--- .../bash/shellshock/secgen_test/shellshock.rb | 18 ++++++++ .../secgen_test/vsftpd_234_backdoor.rb | 1 - .../moinmoin_195/secgen_test/moinmoin_195.rb | 1 + scenarios/security_audit/team_project.xml | 2 +- scenarios/tests/test_scenario.xml | 2 +- 10 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 modules/utilities/unix/system/parameterised_accounts/secgen_test/parameterised_accounts.rb create mode 100644 modules/vulnerabilities/unix/bash/shellshock/secgen_test/shellshock.rb diff --git a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb index 53de3efc7..032c30b34 100644 --- a/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb +++ b/modules/services/unix/http/parameterised_website/secgen_test/parameterised_website.rb @@ -2,6 +2,8 @@ require_relative '../../../../../lib/post_provision_test' require 'json' class ParamWebsiteTest < PostProvisionTest + attr_accessor :organisation + def initialize self.module_name = 'parameterised_website' self.module_path = get_module_path(__FILE__) @@ -12,32 +14,54 @@ class ParamWebsiteTest < PostProvisionTest super json_inputs = get_json_inputs test_service_up + test_html_returned_content("/css/#{json_inputs['theme'][0]}", 'Bootswatch v4.0.0') test_org_functionality(json_inputs) test_additional_page(json_inputs) - test_html_returned_content("/css/#{json_inputs['theme'][0]}", 'Bootswatch v4.0.0') + test_security_audit_remit(json_inputs) + test_acceptable_use_policy(json_inputs) + end + + def get_organisation(json_inputs) + JSON.parse(json_inputs['organisation'][0]) end def test_org_functionality(json_inputs) if json_inputs['organisation'] and - json_inputs['organisation'][0] and - json_inputs['organisation'][0] != '' + json_inputs['organisation'][0] and + json_inputs['organisation'][0] != '' - organisation = JSON.parse(json_inputs['organisation'][0]) + organisation = get_organisation(json_inputs) employee_1 = organisation['employees'][0] test_html_returned_content('/index.html', organisation['business_name']) - test_html_returned_content('/contact.html', organisation['business_moto']) + test_html_returned_content('/contact.html', organisation['business_motto']) test_html_returned_content('/contact.html', employee_1['name']) end end + def test_security_audit_remit(json_inputs) + if json_inputs['security_audit'] and + json_inputs['security_audit'][0] and + json_inputs['security_audit'][0] != '' + test_html_returned_content('/security_audit_remit.html', "Security Audit Remit of #{get_organisation(json_inputs)['business_name']}") + end + end + + def test_acceptable_use_policy(json_inputs) + if json_inputs['host_acceptable_use_policy'] and + json_inputs['host_acceptable_use_policy'][0] and + json_inputs['host_acceptable_use_policy'][0] == 'true' + test_html_returned_content('/acceptable_use_policy.html', "Acceptable Use Policy") + test_html_returned_content('/acceptable_use_policy.html', get_organisation(json_inputs)['business_name']) + end + end def test_additional_page(json_inputs) if json_inputs['additional_page_filenames'] and - json_inputs['additional_page_filenames'][0] and - json_inputs['additional_page_filenames'][0].include? 'html' and - json_inputs['additional_pages'] and - json_inputs['additional_pages'][0] + json_inputs['additional_page_filenames'][0] and + json_inputs['additional_page_filenames'][0].include? 'html' and + json_inputs['additional_pages'] and + json_inputs['additional_pages'][0] page_name = json_inputs['additional_page_filenames'][0] page_name = "/#{page_name}" if page_name.split[0] != '/' diff --git a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb index 2f8bcf569..8a72f2117 100644 --- a/modules/services/unix/ntp/ntp/secgen_test/ntp.rb +++ b/modules/services/unix/ntp/ntp/secgen_test/ntp.rb @@ -15,10 +15,21 @@ class NTPTest < PostProvisionTest end def test_ntp_query - begin - time_response = Net::NTP.get(system_ip, port).time + time_response = '' + retries = 5 + while retries > 0 + begin + time_response = Net::NTP.get(system_ip, port).time + break + rescue Errno::ECONNREFUSED, Timeout::Error + # do nothing + end + sleep 2 + retries = -1 + end + if time_response != '' self.outputs << "PASSED: NTP responded on UDP port #{port} with #{time_response}" - rescue Errno::ECONNREFUSED + else self.outputs << "FAILED: unable to connect to #{module_name} on UDP port #{port}" self.all_tests_passed = false end diff --git a/modules/utilities/unix/system/parameterised_accounts/secgen_test/parameterised_accounts.rb b/modules/utilities/unix/system/parameterised_accounts/secgen_test/parameterised_accounts.rb new file mode 100644 index 000000000..b869febd9 --- /dev/null +++ b/modules/utilities/unix/system/parameterised_accounts/secgen_test/parameterised_accounts.rb @@ -0,0 +1,24 @@ +require_relative '../../../../../lib/post_provision_test' + +class ParameterisedAccountsTest < PostProvisionTest + def initialize + self.module_name = 'parameterised_accounts' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_accounts_exist + end + + def test_accounts_exist + get_json_inputs['accounts'].each do |account| + account = JSON.parse(account) + username = account['username'] + test_local_command("#{username} account exists?", 'cat /etc/passwd', username) + end + end +end + +ParameterisedAccountsTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_metadata.xml b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_metadata.xml index 8e4f18057..718b2a5a6 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_metadata.xml +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_metadata.xml @@ -15,4 +15,8 @@ Shell permission misconfiguration Bash shell running with root permissions due to suid bit set (try /bin/bash -cp "some_command") + + + .*shellshock.* + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb index e8f8c1589..df9d697cc 100644 --- a/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb +++ b/modules/vulnerabilities/unix/access_control_misconfigurations/suid_root_bash/secgen_test/suid_root_bash.rb @@ -1,19 +1,19 @@ require_relative '../../../../../lib/post_provision_test' -class SUIDNanoTest < PostProvisionTest +class SUIDBashTest < PostProvisionTest def initialize - self.module_name = 'suid_root_nano' + self.module_name = 'suid_root_bash' self.module_path = get_module_path(__FILE__) super end def test_module super - test_local_command('nano suid bit set?','sudo ls -la /bin/nano', '-rwsrwxrwx') - test_local_command('nano runs?','/bin/nano --version', 'GNU nano') + test_local_command('bash suid bit set?','sudo ls -la /bin/bash', '-rwsrwxrwx') + test_local_command('bash runs?','/bin/bash --version', 'GNU bash') end end -SUIDNanoTest.new.run \ No newline at end of file +SUIDBashTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/bash/shellshock/secgen_test/shellshock.rb b/modules/vulnerabilities/unix/bash/shellshock/secgen_test/shellshock.rb new file mode 100644 index 000000000..7f506e288 --- /dev/null +++ b/modules/vulnerabilities/unix/bash/shellshock/secgen_test/shellshock.rb @@ -0,0 +1,18 @@ +require_relative '../../../../../lib/post_provision_test' + + +class ShellshockTest < PostProvisionTest + def initialize + self.module_name = 'shellshock' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('correct /bin/bash version?','/bin/bash --version', 'version 4.1') + end + +end + +ShellshockTest.new.run \ No newline at end of file diff --git a/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb b/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb index d5d7e85d4..176bcfb8b 100644 --- a/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb +++ b/modules/vulnerabilities/unix/ftp/vsftpd_234_backdoor/secgen_test/vsftpd_234_backdoor.rb @@ -2,7 +2,6 @@ require_relative '../../../../../lib/post_provision_test' class Vsftpd234BackdoorTest < PostProvisionTest def initialize - super self.module_name = 'vsftpd_234_backdoor' self.module_path = get_module_path(__FILE__) super diff --git a/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb b/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb index 4c6fcc9f7..bd0de9206 100644 --- a/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb +++ b/modules/vulnerabilities/unix/webapp/moinmoin_195/secgen_test/moinmoin_195.rb @@ -10,6 +10,7 @@ class MoinMoin195Test < PostProvisionTest def test_module super test_service_up + test_html_returned_content('/index.html','') end end diff --git a/scenarios/security_audit/team_project.xml b/scenarios/security_audit/team_project.xml index b80365b6a..1cd951b2b 100644 --- a/scenarios/security_audit/team_project.xml +++ b/scenarios/security_audit/team_project.xml @@ -19,7 +19,7 @@ web - + 172.10.0.2 diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index 7d5e7cc5d..4b5bd5335 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -10,7 +10,7 @@ - 172.16.0.12 + 172.16.0.14 From 3e4123642c0fb0dc2acd65fe98b216ac9a5562b1 Mon Sep 17 00:00:00 2001 From: thomashaw Date: Thu, 7 Feb 2019 12:57:18 +0000 Subject: [PATCH 29/47] reverting dirtycow for now, need to exclude the puppet package from apt-get upgrade before inclusion --- Gemfile.lock | 41 ++++++++++--------- .../unix/local/dirtycow/dirtycow.pp | 1 - .../unix/local/dirtycow/manifests/config.pp | 3 -- .../unix/local/dirtycow/secgen_metadata.xml | 33 --------------- .../local/dirtycow/secgen_test/dirtycow.rb | 17 -------- scenarios/security_audit/team_project.xml | 25 +---------- 6 files changed, 23 insertions(+), 97 deletions(-) delete mode 100644 modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp delete mode 100644 modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp delete mode 100644 modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml delete mode 100644 modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb diff --git a/Gemfile.lock b/Gemfile.lock index 265befd94..e9a7c27b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,17 +19,18 @@ GIT GEM remote: https://rubygems.org/ specs: + CFPropertyList (2.3.6) PriorityQueue (0.1.2) - activesupport (5.2.1) + activesupport (5.2.2) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) bases (1.0.2) bcrypt (3.1.12) - chunky_png (1.3.10) + chunky_png (1.3.11) cinch (2.3.4) - concurrent-ruby (1.0.5) + concurrent-ruby (1.1.4) credy (0.2.1) thor (~> 0.19.1) digest-simple (1.1.0) @@ -38,6 +39,7 @@ GEM digest-whirlpool (1.0.3) duplicate (1.1.1) facter (2.5.1) + CFPropertyList (~> 2.2) faker (1.9.1) i18n (>= 0.7) faraday (0.13.1) @@ -45,7 +47,7 @@ GEM faraday_middleware (0.12.2) faraday (>= 0.7.4, < 1.0) fast_gettext (1.1.2) - ffi (1.9.25) + ffi (1.10.0) ffi-compiler (1.0.1) ffi (>= 1.0.0) rake @@ -60,14 +62,14 @@ GEM gpgmeh (0.1.6) activesupport (>= 2.3) nio4r (~> 2.2) - hiera (3.4.5) + hiera (3.5.0) hocon (1.2.5) httpclient (2.8.3) huffman (0.0.1) PriorityQueue activesupport ruby-graphviz - i18n (1.1.0) + i18n (1.5.3) concurrent-ruby (~> 1.0) json (2.1.0) librarian-puppet (3.0.0) @@ -80,21 +82,22 @@ GEM mini_exiftool (2.9.0) mini_exiftool_vendored (9.2.7.v1) mini_exiftool (>= 1.6.0) - mini_portile2 (2.3.0) - minitar (0.6.1) + mini_portile2 (2.4.0) + minitar (0.8) minitest (5.11.3) multi_json (1.13.1) multipart-post (2.0.0) net-ntp (2.1.3) nio4r (2.3.1) - nokogiri (1.8.4) - mini_portile2 (~> 2.3.0) + nokogiri (1.10.1) + mini_portile2 (~> 2.4.0) nori (2.6.0) - ovirt-engine-sdk (4.2.4) + ovirt-engine-sdk (4.3.0) json (>= 1, < 3) - pg (1.1.3) + pg (1.1.4) process_helper (0.1.2) - puppet (6.0.0) + puppet (6.2.0) + CFPropertyList (~> 2.2) facter (> 2.0.1, < 4) fast_gettext (~> 1.1.2) hiera (>= 3.2.1, < 4) @@ -103,7 +106,7 @@ GEM multi_json (~> 1.10) puppet-resource_api (~> 1.5) semantic_puppet (~> 1.0) - puppet-resource_api (1.5.0) + puppet-resource_api (1.6.2) hocon (>= 1.0) puppet_forge (2.2.9) faraday (>= 0.9.0, < 0.14.0) @@ -111,15 +114,15 @@ GEM gettext-setup (~> 0.11) minitar semantic_puppet (~> 1.0) - rake (12.3.1) - rdoc (6.0.4) + rake (12.3.2) + rdoc (6.1.1) redcarpet (3.4.0) rmagick (2.16.0) rqrcode (0.10.1) chunky_png (~> 1.0) rsa (0.1.4) rsync (1.0.9) - ruby-graphviz (1.2.3) + ruby-graphviz (1.2.4) rubyzip (1.2.2) scrypt (3.0.6) ffi-compiler (>= 1.0, < 2.0) @@ -135,7 +138,7 @@ GEM thread_safe (~> 0.1) wordlist (0.1.1) spidr (~> 0.2) - yard (0.9.16) + yard (0.9.18) zip-zip (0.3) rubyzip (>= 1.0.0) zipruby (0.3.6) @@ -184,4 +187,4 @@ DEPENDENCIES zipruby BUNDLED WITH - 2.0.0.pre.2 + 1.11.2 diff --git a/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp b/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp deleted file mode 100644 index f86b5785e..000000000 --- a/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp +++ /dev/null @@ -1 +0,0 @@ -include dirtycow::config \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp b/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp deleted file mode 100644 index 5a22e775d..000000000 --- a/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp +++ /dev/null @@ -1,3 +0,0 @@ -class dirtycow::config { - notice("dirtycow::config: Do nothing, the apt upgrade just checks if we're defined and blocks apt-get upgrade if so.") -} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml b/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml deleted file mode 100644 index 90d6aaac1..000000000 --- a/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - DirtyCow privilege escalation - Thomas Shaw - MIT - DirtyCow local privilege escalation. Including this module prevents the default apt-get upgrade from - running which leaves the wheezy bases vulnerable. - - - unpatched_kernel - race_condition - root_rwx - local - linux - medium - - - .*Stretch.* - - - .*Kali.* - - - .*Windows.* - - - .*Ubuntu.* - - - \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb b/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb deleted file mode 100644 index 1433b43a4..000000000 --- a/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb +++ /dev/null @@ -1,17 +0,0 @@ -require_relative '../../../../../lib/post_provision_test' - -class DirtyCOWTest < PostProvisionTest - def initialize - self.module_name = 'dirtycow' - self.module_path = get_module_path(__FILE__) - super - end - - def test_module - super - test_local_command('apt-get upgrade not performed?', 'sudo apt-get -u upgrade --assume-no','linux-image-3.') - end - -end - -DirtyCOWTest.new.run \ No newline at end of file diff --git a/scenarios/security_audit/team_project.xml b/scenarios/security_audit/team_project.xml index 1cd951b2b..0f45423a3 100644 --- a/scenarios/security_audit/team_project.xml +++ b/scenarios/security_audit/team_project.xml @@ -19,7 +19,7 @@ web - + 172.10.0.2 @@ -194,27 +194,4 @@ - - - attack_vm_1 - - - - IP_addresses - - - - - - - attack_vm_2 - - - - IP_addresses - - - - - From a0ced2520113cf72418403605c1b499ebaa6425f Mon Sep 17 00:00:00 2001 From: thomashaw Date: Thu, 7 Feb 2019 13:02:00 +0000 Subject: [PATCH 30/47] reverting upgrade on wheezy bases for now --- modules/bases/debian_puppet_32/secgen_metadata.xml | 4 ---- modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/modules/bases/debian_puppet_32/secgen_metadata.xml b/modules/bases/debian_puppet_32/secgen_metadata.xml index fdda2be95..b8bf6196e 100644 --- a/modules/bases/debian_puppet_32/secgen_metadata.xml +++ b/modules/bases/debian_puppet_32/secgen_metadata.xml @@ -21,8 +21,4 @@ https://atlas.hashicorp.com/puppetlabs various - - upgrade - - diff --git a/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml b/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml index ec9597f9f..a73992247 100644 --- a/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml +++ b/modules/bases/debian_wheezy_desktop_kde/secgen_metadata.xml @@ -21,8 +21,4 @@ https://atlas.hashicorp.com/puppetlabs various - - upgrade - - From 345e902ccacce26f6bbf498aad6c0d2d9b1fb6bc Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 7 Feb 2019 14:25:54 +0000 Subject: [PATCH 31/47] removed example ctf challenge stuff.. --- .../dc16_amadhj/manifests/install.pp | 39 ----------- .../manifests/install.pp | 45 ------------- .../python2_challenge_example.pp | 1 - .../secgen_metadata.xml | 63 ----------------- .../manifests/install.pp | 17 ----- .../ruby_challenge_example.pp | 1 - .../secgen_metadata.xml | 67 ------------------- 7 files changed, 233 deletions(-) delete mode 100644 modules/vulnerabilities/unix/ctf/defcon_quals_2016/dc16_amadhj/manifests/install.pp delete mode 100644 modules/vulnerabilities/unix/ctf/example/python2_challenge_example/manifests/install.pp delete mode 100644 modules/vulnerabilities/unix/ctf/example/python2_challenge_example/python2_challenge_example.pp delete mode 100644 modules/vulnerabilities/unix/ctf/example/python2_challenge_example/secgen_metadata.xml delete mode 100644 modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/manifests/install.pp delete mode 100644 modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/ruby_challenge_example.pp delete mode 100644 modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/secgen_metadata.xml diff --git a/modules/vulnerabilities/unix/ctf/defcon_quals_2016/dc16_amadhj/manifests/install.pp b/modules/vulnerabilities/unix/ctf/defcon_quals_2016/dc16_amadhj/manifests/install.pp deleted file mode 100644 index 5fb68ebc5..000000000 --- a/modules/vulnerabilities/unix/ctf/defcon_quals_2016/dc16_amadhj/manifests/install.pp +++ /dev/null @@ -1,39 +0,0 @@ -class dc16_amadhj::install { - $secgen_params = secgen_functions::get_parameters($::base64_inputs_file) - $group = $secgen_params['group'] - - if $secgen_params['account'][0] and $secgen_params['account'][0] != '' { - $account = parsejson($secgen_params['account'][0]) - } else { - $account = undef - } - - if $secgen_params['storage_directory'] and $secgen_params['storage_directory'][0] { - $storage_dir = $secgen_params['storage_directory'][0] - } else { - $storage_dir = undef - } - - if $group { - ::secgen_functions::install_setgid_binary { 'defcon16_amadhj_group': - source_module_name => $module_name, - challenge_name => $secgen_params['challenge_name'][0], - group => $group[0], - account => $account, - flag => $secgen_params['flag'][0], - flag_name => 'flag', - storage_dir => $storage_dir, - strings_to_leak => $secgen_params['strings_to_leak'], - } - } else { - ::secgen_functions::install_setuid_root_binary { 'defcon16_amadhj': - source_module_name => $module_name, - challenge_name => $secgen_params['challenge_name'][0], - account => $account, - flag => $secgen_params['flag'][0], - flag_name => 'flag', - storage_dir => $storage_dir, - strings_to_leak => $secgen_params['strings_to_leak'], - } - } -} diff --git a/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/manifests/install.pp b/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/manifests/install.pp deleted file mode 100644 index 747a9f5a8..000000000 --- a/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/manifests/install.pp +++ /dev/null @@ -1,45 +0,0 @@ -class python2_challenge_example::install { - $secgen_params = secgen_functions::get_parameters($::base64_inputs_file) - $group = $secgen_params['group'] - $script_data = $secgen_params['script_data'] - - if $secgen_params['account'][0] and $secgen_params['account'][0] != '' { - $account = parsejson($secgen_params['account'][0]) - } else { - $account = undef - } - - if $secgen_params['storage_directory'] and $secgen_params['storage_directory'][0] { - $storage_dir = $secgen_params['storage_directory'][0] - } else { - $storage_dir = undef - } - - if $group { - ::secgen_functions::install_setgid_script { 'python2_challenge_example': - source_module_name => $module_name, - challenge_name => $secgen_params['challenge_name'][0], - script_name => 'test.py', - script_data => $script_data[0], - group => $group[0], - account => $account, - flag => $secgen_params['flag'][0], - flag_name => 'flag', - storage_dir => $storage_dir, - strings_to_leak => $secgen_params['strings_to_leak'], - } - } else { - ::secgen_functions::install_setuid_root_script { 'python2_challenge_example': - source_module_name => $module_name, - challenge_name => $secgen_params['challenge_name'][0], - script_name => 'test.py', - script_data => $script_data[0], - account => $account, - flag => $secgen_params['flag'][0], - flag_name => 'flag', - storage_dir => $storage_dir, - strings_to_leak => $secgen_params['strings_to_leak'], - } - } - -} diff --git a/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/python2_challenge_example.pp b/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/python2_challenge_example.pp deleted file mode 100644 index 99d16c5df..000000000 --- a/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/python2_challenge_example.pp +++ /dev/null @@ -1 +0,0 @@ -include python2_challenge_example::install diff --git a/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/secgen_metadata.xml b/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/secgen_metadata.xml deleted file mode 100644 index 7f102f83e..000000000 --- a/modules/vulnerabilities/unix/ctf/example/python2_challenge_example/secgen_metadata.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - python2 Challenge Example - Thomas Shaw - MIT - python2 challenge example - - script_challenge - none - local - linux - - misc - example - - - challenge_name - script_data - account - flag - - storage_directory - - group - - python2_script_example - - - - - - - - challenges - - - password - - - - - - - - python2_script_example - - - - utilities/unix/system/accounts - - - - utilities/unix/system/binary_script_container - - - - utilities/unix/languages/python2/python - - - diff --git a/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/manifests/install.pp b/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/manifests/install.pp deleted file mode 100644 index f1bb96019..000000000 --- a/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/manifests/install.pp +++ /dev/null @@ -1,17 +0,0 @@ -class ruby_challenge_example::install { - $secgen_params = secgen_functions::get_parameters($::base64_inputs_file) - $challenge_name = $secgen_params['challenge_name'][0] - - ::secgen_functions::install_setgid_script { $challenge_name: - source_module_name => $module_name, - challenge_name => $challenge_name, - script_name => 'test.rb', - script_data => $secgen_params['script_data'][0], - group => $secgen_params['group'], - account => $secgen_params['account'], - flag => $secgen_params['flag'], - port => $secgen_params['port'], - storage_directory => $secgen_params['storage_directory'], - strings_to_leak => $secgen_params['strings_to_leak'], - } -} diff --git a/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/ruby_challenge_example.pp b/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/ruby_challenge_example.pp deleted file mode 100644 index 7bf010122..000000000 --- a/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/ruby_challenge_example.pp +++ /dev/null @@ -1 +0,0 @@ -include ruby_challenge_example::install diff --git a/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/secgen_metadata.xml b/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/secgen_metadata.xml deleted file mode 100644 index f64b75118..000000000 --- a/modules/vulnerabilities/unix/ctf/example/ruby_challenge_example/secgen_metadata.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - Ruby Challenge Example - Thomas Shaw - MIT - Ruby challenge example - - ctf_challenge - none - local - linux - - misc - example - - - challenge_name - script_data - account - flag - - group - - storage_directory - - port - - - ruby_challenge_example - - - - - - - - challenges - - - password - - - - - - - - - utilities/unix/system/accounts - - - - utilities/unix/system/binary_script_container - - - - utilities/unix/languages/ruby - - - - utilities/unix/system/xinetd - - - From 44fec02a322c2992127f1ae774cf0f923f48d550 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Wed, 6 Feb 2019 16:40:45 +0000 Subject: [PATCH 32/47] narrative update --- scenarios/ctf/basic_narrative.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/scenarios/ctf/basic_narrative.xml b/scenarios/ctf/basic_narrative.xml index e6a086379..2582204ec 100644 --- a/scenarios/ctf/basic_narrative.xml +++ b/scenarios/ctf/basic_narrative.xml @@ -453,6 +453,7 @@ attack_vm + IP_addresses From b5ae825f4d387aec99268ac9aee82cada44df0ae Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 14 Feb 2019 14:56:39 +0000 Subject: [PATCH 33/47] Added firefox auto-open to basic narrative --- scenarios/ctf/basic_narrative.xml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scenarios/ctf/basic_narrative.xml b/scenarios/ctf/basic_narrative.xml index 2582204ec..5d44ed5e6 100644 --- a/scenarios/ctf/basic_narrative.xml +++ b/scenarios/ctf/basic_narrative.xml @@ -439,7 +439,7 @@ - IP_addresses + IP_addresses @@ -454,9 +454,22 @@ attack_vm + + + + {"username":"root","password":"toor","super_user":"","strings_to_leak":[],"leaked_filenames":[]} + + + true + + + IP_addresses + + + - IP_addresses + IP_addresses From 4ee93f7e497e179ce137ad81481bfe54be3007ea Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 14 Feb 2019 14:58:33 +0000 Subject: [PATCH 34/47] added test string for Vagrantfile --- lib/templates/Vagrantfile.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/templates/Vagrantfile.erb b/lib/templates/Vagrantfile.erb index fe2d02346..05aea1512 100644 --- a/lib/templates/Vagrantfile.erb +++ b/lib/templates/Vagrantfile.erb @@ -149,7 +149,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # use some shell scripting to identify the name of the network interface (eth0/ens3/...), and set the IP address statically <%= system.name %>.vm.provision 'shell', inline: "echo -e \"auto lo\niface lo inet loopback\n\nauto <%= interface %>\niface <%= interface %> inet static\n\taddress <%= resolve_network(selected_module)%>\" > /etc/network/interfaces" <%= system.name %>.vm.provision 'shell', inline: "echo '' > /etc/environment" -<% # Static Virtualbox networking -%> + <% # Below string is used within testing, do not delete. -%> + # ip_address_for_<%= system.name %>=<%= resolve_network(selected_module)%> + <% # Static Virtualbox networking -%> <% else -%> <%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, ip: "<%= resolve_network(selected_module)%>" <% # Below string is used within testing, do not delete. -%> From 53bba1113365a4451a0af007176285fd49e14070 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Sat, 26 Jan 2019 20:11:17 +0000 Subject: [PATCH 35/47] lab updates (and related modules) (cherry picked from commit 665b0589c88feedbf6553322b1c485d32212b899) --- lib/objects/system.rb | 65 ++- .../hbauthentication/hbauthentication.pp | 0 .../hbauthentication/manifests/.no_puppet | 0 .../hbauthentication/secgen_local/local.rb | 35 ++ .../hbauthentication/secgen_metadata.xml | 39 ++ .../hbauthentication/shared/labsheet.html.erb | 29 + .../hbauthentication/shared/license.md.erb | 4 + .../hbauthentication/templates/intro.md.erb | 299 ++++++++++ .../hbauthentication/templates/lab.xml.erb | 161 ++++++ .../templates/labsheet.html.erb | 114 ++++ .../hbauthentication/templates/license.md.erb | 6 + .../templates/resources.md.erb | 0 .../integrity_protection/secgen_metadata.xml | 7 +- .../kali_forensic/kali_forensic.pp | 1 + .../kali_forensic/manifests/install.pp | 5 + .../kali_forensic/secgen_metadata.xml | 25 + .../kali_metapackages/kali_full/kali_full.pp | 1 + .../kali_full/manifests/install.pp | 5 + .../kali_full/secgen_metadata.xml | 25 + .../kali_pwtools/kali_pwtools.pp | 1 + .../kali_pwtools/manifests/install.pp | 5 + .../kali_pwtools/secgen_metadata.xml | 25 + .../kali_top10/kali_top10.pp | 1 + .../kali_top10/manifests/install.pp | 5 + .../kali_top10/secgen_metadata.xml | 25 + .../kali_metapackages/kali_web/kali_web.pp | 1 + .../kali_web/manifests/install.pp | 5 + .../kali_web/secgen_metadata.xml | 25 + .../setup_scripts/install-docker-debian.sh | 90 +++ .../unix/labtainers/manifests/config.pp | 12 + .../unix/labtainers/manifests/install.pp | 27 + .../dvwa/files/DVWA-master/.gitignore | 5 +- .../dvwa/files/DVWA-master/README.md | 60 +- .../DVWA-master/config/config.inc.php.dist | 2 +- .../DVWA-master/dvwa/includes/DBMS/MySQL.php | 15 +- .../dvwa/includes/dvwaPage.inc.php | 9 +- .../dvwa/js/add_event_listeners.js | 24 + .../files/DVWA-master/dvwa/js/dvwaPage.js | 3 +- .../external/recaptcha/recaptchalib.php | 290 +--------- .../vulnerabilities/brute/help/help.php | 2 +- .../brute/source/impossible.php | 2 +- .../vulnerabilities/captcha/help/help.php | 4 +- .../vulnerabilities/captcha/index.php | 2 +- .../vulnerabilities/captcha/source/high.php | 35 +- .../captcha/source/impossible.php | 10 +- .../vulnerabilities/captcha/source/low.php | 10 +- .../vulnerabilities/captcha/source/medium.php | 10 +- .../vulnerabilities/csp/help/help.php | 52 ++ .../DVWA-master/vulnerabilities/csp/index.php | 57 ++ .../vulnerabilities/csp/source/high.js | 19 + .../vulnerabilities/csp/source/high.php | 22 + .../vulnerabilities/csp/source/impossible.js | 19 + .../vulnerabilities/csp/source/impossible.php | 23 + .../vulnerabilities/csp/source/jsonp.php | 13 + .../csp/source/jsonp_impossible.php | 7 + .../vulnerabilities/csp/source/low.php | 22 + .../vulnerabilities/csp/source/medium.php | 25 + .../vulnerabilities/javascript/help/help.php | 52 ++ .../vulnerabilities/javascript/index.php | 123 ++++ .../vulnerabilities/javascript/source/high.js | 1 + .../javascript/source/high.php | 5 + .../javascript/source/high_unobfuscated.js | 540 ++++++++++++++++++ .../javascript/source/impossible.php | 0 .../vulnerabilities/javascript/source/low.php | 24 + .../javascript/source/medium.js | 1 + .../javascript/source/medium.php | 5 + .../vulnerabilities/upload/help/help.php | 2 +- .../vulnerabilities/view_source.php | 20 + .../vulnerabilities/view_source_all.php | 3 + .../web_training/dvwa/manifests/apache.pp | 39 +- .../web_training/dvwa/secgen_metadata.xml | 14 +- .../examples/vulnerability_examples/dvwa.xml | 21 +- scenarios/labs/ads_1_authentication.xml | 350 ++++++++++++ scenarios/labs/websec_lab_env.xml | 53 ++ 74 files changed, 2647 insertions(+), 391 deletions(-) create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/hbauthentication.pp create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/manifests/.no_puppet create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_local/local.rb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_metadata.xml create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/shared/labsheet.html.erb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/shared/license.md.erb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/templates/intro.md.erb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/templates/lab.xml.erb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/templates/labsheet.html.erb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/templates/license.md.erb create mode 100644 modules/generators/structured_content/hackerbot_config/hbauthentication/templates/resources.md.erb create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/kali_forensic.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/manifests/install.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/secgen_metadata.xml create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_full/kali_full.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_full/manifests/install.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_full/secgen_metadata.xml create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/kali_pwtools.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/manifests/install.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/secgen_metadata.xml create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/kali_top10.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/manifests/install.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/secgen_metadata.xml create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_web/kali_web.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_web/manifests/install.pp create mode 100644 modules/utilities/unix/attack_tools/kali_metapackages/kali_web/secgen_metadata.xml create mode 100755 modules/utilities/unix/labtainers/files/labtainer.files/trunk/setup_scripts/install-docker-debian.sh create mode 100644 modules/utilities/unix/labtainers/manifests/config.pp create mode 100644 modules/utilities/unix/labtainers/manifests/install.pp create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/add_event_listeners.js mode change 100755 => 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/external/recaptcha/recaptchalib.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/help/help.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/index.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.js create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.js create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp_impossible.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/low.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/medium.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/help/help.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/index.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.js create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high_unobfuscated.js create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/impossible.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/low.php create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.js create mode 100644 modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.php create mode 100644 scenarios/labs/ads_1_authentication.xml create mode 100644 scenarios/labs/websec_lab_env.xml diff --git a/lib/objects/system.rb b/lib/objects/system.rb index 30dbd4b2f..1012fe9eb 100644 --- a/lib/objects/system.rb +++ b/lib/objects/system.rb @@ -208,37 +208,42 @@ class System datastore_access = datastore_variablename_and_access_type['access'] datastore_variablename = datastore_variablename_and_access_type['variablename'] datastore_retrieved = [] - if datastore_access == 'first' - datastore_retrieved = [$datastore[datastore_variablename].first] - elsif datastore_access == 'next' - last_accessed = $datastore_iterators[datastore_variablename] - # first use? start at beginning - if last_accessed == nil - index_to_access = 0 + begin + if datastore_access == 'first' + datastore_retrieved = [$datastore[datastore_variablename].first] + elsif datastore_access == 'next' + last_accessed = $datastore_iterators[datastore_variablename] + # first use? start at beginning + if last_accessed == nil + index_to_access = 0 + else + index_to_access = last_accessed + 1 + end + $datastore_iterators[datastore_variablename] = index_to_access + datastore_retrieved = [$datastore[datastore_variablename][index_to_access]] + elsif datastore_access == 'previous' + last_accessed = $datastore_iterators[datastore_variablename] + # first use? start at end + if last_accessed == nil + index_to_access = $datastore[datastore_variablename].size - 1 + else + index_to_access = last_accessed - 1 + end + $datastore_iterators[datastore_variablename] = index_to_access + datastore_retrieved = [$datastore[datastore_variablename][index_to_access]] + elsif datastore_access.to_s == datastore_access.to_i.to_s + # Test for a valid element key (integer) + index_to_access = datastore_access.to_i + $datastore_iterators[datastore_variablename] = index_to_access + datastore_retrieved = [$datastore[datastore_variablename][index_to_access]] + elsif datastore_access == "all" + datastore_retrieved = $datastore[datastore_variablename] else - index_to_access = last_accessed + 1 + Print.err "Error: invalid access value (#{datastore_access})" + raise 'failed' end - $datastore_iterators[datastore_variablename] = index_to_access - datastore_retrieved = [$datastore[datastore_variablename][index_to_access]] - elsif datastore_access == 'previous' - last_accessed = $datastore_iterators[datastore_variablename] - # first use? start at end - if last_accessed == nil - index_to_access = $datastore[datastore_variablename].size - 1 - else - index_to_access = last_accessed - 1 - end - $datastore_iterators[datastore_variablename] = index_to_access - datastore_retrieved = [$datastore[datastore_variablename][index_to_access]] - elsif datastore_access.to_s == datastore_access.to_i.to_s - # Test for a valid element key (integer) - index_to_access = datastore_access.to_i - $datastore_iterators[datastore_variablename] = index_to_access - datastore_retrieved = [$datastore[datastore_variablename][index_to_access]] - elsif datastore_access == "all" - datastore_retrieved = $datastore[datastore_variablename] - else - Print.err "Error: invalid access value (#{datastore_access})" + rescue NoMethodError, SyntaxError => err + Print.err "Error accessing element (#{datastore_access}) from datastore (#{datastore_variablename}): #{err}" raise 'failed' end if datastore_retrieved && datastore_retrieved != [nil] @@ -457,4 +462,4 @@ class System modules_to_add end -end \ No newline at end of file +end diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/hbauthentication.pp b/modules/generators/structured_content/hackerbot_config/hbauthentication/hbauthentication.pp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/manifests/.no_puppet b/modules/generators/structured_content/hackerbot_config/hbauthentication/manifests/.no_puppet new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_local/local.rb b/modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_local/local.rb new file mode 100644 index 000000000..91be58494 --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_local/local.rb @@ -0,0 +1,35 @@ +#!/usr/bin/ruby +require_relative '../../../../../../lib/objects/local_hackerbot_config_generator.rb' + +class HB < HackerbotConfigGenerator + + attr_accessor :server_ip + + def initialize + super + self.module_name = 'Hackerbot Config Generator Authentication' + self.title = 'Authentication' + + self.local_dir = File.expand_path('../../',__FILE__) + self.templates_path = "#{self.local_dir}/templates/" + self.config_template_path = "#{self.local_dir}/templates/lab.xml.erb" + self.html_template_path = "#{self.local_dir}/templates/labsheet.html.erb" + + self.server_ip = [] + end + + def get_options_array + super + [['--server_ip', GetoptLong::REQUIRED_ARGUMENT]] + end + + def process_options(opt, arg) + super + case opt + when '--server_ip' + self.server_ip << arg; + end + end + +end + +HB.new.run diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_metadata.xml b/modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_metadata.xml new file mode 100644 index 000000000..59d09fa03 --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/secgen_metadata.xml @@ -0,0 +1,39 @@ + + + + Hackerbot config for a authentication lab + Z. Cliffe Schreuders + GPLv3 + Generates a config file for a hackerbot for an integrity lab. + Topics covered: . + + hackerbot_config + linux + + accounts + flags + root_password + + + + + + + vagrant + + + + + + + + + + puppet + + + hackerbot + + diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/shared/labsheet.html.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/shared/labsheet.html.erb new file mode 100644 index 000000000..72dab611a --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/shared/labsheet.html.erb @@ -0,0 +1,29 @@ + + + <%= self.title %> + + + + + +
+ + <%= self.html_rendered %> + +
+ + + diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/shared/license.md.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/shared/license.md.erb new file mode 100644 index 000000000..8e89ace31 --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/shared/license.md.erb @@ -0,0 +1,4 @@ +## License +This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB). + +Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version. diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/intro.md.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/intro.md.erb new file mode 100644 index 000000000..4fb95fc32 --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/intro.md.erb @@ -0,0 +1,299 @@ +# Authentication + +## Getting started +### VMs in this lab + +==Start these VMs== (if you haven't already): +- hackerbot_server (leave it running, you don't log into this) +- desktop (you can sudo to get superuser access) +- server (<%= $server_ip %>, you can ssh to this machine, but you don't have superuser access) +- kali_cracker (you will use this to crack the hashes you find) + +### Your login details for the "desktop" and "server" VMs +User: <%= $main_user %> +Password: tiaspbiqe2r (**t**his **i**s **a** **s**ecure **p**assword **b**ut **i**s **q**uite **e**asy **2** **r**emember) + +You won't login to the hackerbot_server, but the VM needs to be running to complete the lab. + +### For marks in the module +1. **You need to submit flags**. Note that the flags and the challenges in your VMs are different to other's in the class. Flags will be revealed to you as you complete challenges throughout the module. Flags look like this: ==flag{*somethingrandom*}==. Follow the link on the module page to submit your flags. +2. **You need to document the work and your solutions in a Log Book**. This needs to include screenshots (including the flags) of how you solved each Hackerbot challenge and a writeup describing your solution to each challenge, and answering any "Log Book Questions". The Log Book will be submitted later in the semester. + +## Meet Hackerbot! +![small-right](images/skullandusb.svg) + +This exercise involves interacting with Hackerbot, a chatbot who will attack your system. If you satisfy Hackerbot by completing the challenges she will reveal flags to you. + +**On the desktop VM:** + +==Open Pidgin and send some messages to Hackerbot:== + +- Try asking Hackerbot some questions +- Send "help" +- Send "list" +- Send "hello" + +> If Hackerbot seems to be waiting or halted, simply say 'hi' + +Work through the below exercises, completing the Hackerbot challenges as noted. + +--- + +## Introduction to authentication + +Authentication plays the important role of verifying an identity. For example, when someone gets into an airplane, sits down at a computer, picks up a mobile device, or uses a website, authentication is what is used to confirm that the person is who they claim to be. Authentication is an important first step *before* deciding how the system should act and what to allow. + +## Identity: users and groups + +Most computer systems have the concept of a user account. Although some devices such as mobile phones typically only have one user account, most modern computers can support having multiple users, each with their own identity. For example, a computer can have a separate account for each person that uses it, and if configured to do so may enable each user to have their own account preferences, and access to different resources. + +On Unix/Linux systems every user account is identified by a user ID number (UID), which is a 32-bit integer (whole number), and can have one or more user names, which are human readable strings of text. + +**On the desktop VM:** + +Open a terminal console. + +Assuming you have already logged in, you have already authenticated yourself on this system. + +==Log Book Question: When and how did you authenticate yourself?== + +Use these commands to find out about your current identity (or more accurately the identity of the software you are interacting with): + +```bash +whoami + +groups + +id +``` + +==Make a note of your UID and username.== + +Note that your account is also a member of one or more groups. A primary group, and a list of other groups. Some Linux systems, such as Debian, create a new seperate primary group for each user, others such as openSUSE have a shared group (named "users") that all normal users are a member of. Similar to the relationship between user names and UIDs, each group has a group name, and a group ID (GID). + +Information about user accounts is stored in the /etc/passwd file, which typically all users can read. + +==View the /etc/passwd file:== + +```bash +less /etc/passwd +``` + +==Find the line that describes your user account.== + +This line defines the username, password (well, it used to be stored here... we will come back to this), UID, primary group GID, full name, home directory, and shell for your account. + +Confirm this matches the information you recorded earlier. + +==Find the line that describes the root user account.== + +==Where is the root user's home directory?== + +> Press 'q' to quit less. + +==View the /etc/group file:== + +```bash +less /etc/group +``` + +Groups are defined in this file, along with which users are members. + +==Which users are members of the audio group?== + +Remember, primary groups do not appear in this file; for example, on openSUSE the "users" group, which all normal users are a member of, may not appear in the /etc/group file. + +The "su" program can be used to run a program (usually a shell; that is, a command prompt) as another user, effectively enabling users to switch between user accounts at the command prompt. + +==Change your identity to root==. Run: + +```bash +su - +``` + +Enter the root password. + +Use these commands to ==find out about your new identity:== + +```bash +whoami + +groups + +id +``` + +==What is the UID of root? What does this mean about this user?== + +==Lab Book Question: What gives this user special privileges: the name of the account, or the UID?== + +==Use the useradd command to create a new user account "fred"== + +> Hint: refer to the man page for useradd, by running "man useradd". + +==Set a password for the user fred.== + +> Hint: `sudo passwd fred` + +==Change identity to fred.== + +> Hint: `su - fred` + +==Run:(after su)== + +```bash +id +``` + +==Compare the result to the previous output.== + +==How does this compare to your other normal user account? What is different, and what about it is the same?== + +Run the single command "id" as root: + +```bash +sudo id +``` + +==Log Book Question: What is the difference between sudo and su? Which is most likely protect against accidental damage and also log the commands used?== + +## Users and SSH + +==Log in to the server via ssh:== + +```bash +ssh <%= $main_user %>@<%= $server_ip %> +``` + +==Display details of all users logged on to the system:== + +```bash +who +``` + +==List all the processes run by all users:== + +```bash +ps -eo user,comm +``` + +==List all the processes running as root:== + +```bash +ps -o user,comm -u root +``` + +==Run a command to list all the processes running as *your* normal user.== + +==Lab Book Question: How is this server authenticating users? What user accounts exist?== + +## Passwords, hashes and salt + +Given that important security decisions are made based on the user accounts, it is important to authenticate users, to ensure that the subjects are associated with the correct identity. + +==What are the kinds of factors that can be used to verify a user's identity? Hint: for example, "something they have".== + +==Which category of authentication factors is a password considered to be?== + +Originally passwords were stored "in the clear" (not enciphered). For example, Multics stored passwords in a file, and once at MIT a software bug caused the password file to be copied to the motd file (message of the day), which was printed every time anyone logged into the system. A solution is not to store the password in the clear. Instead a hash can be computed, using a one way hash function, and stored. When the user enters a password, a new hash is computed and compared to the original. + +On Linux, the command "shasum" can be used to check the integrity of files (hash functions have many uses), and works on the same principle. We can use it to generate a hash for any given string, for example a password: + +```bash +shasum +``` + +> Type "hello" without the quotes. Press Ctrl-D (which indicates "EOF"; that is, end of input). + +Repeat the above, with the same password ("hello"), and with a slight difference ("hello."). + +Are the outputs the same? + +Are the different hashes similar? + +Is this good? Why? + +Which one-way hash function does the shasum program use? Would this be a good option for hashing passwords? + +For password authentication, the hash still needs to be stored. On Unix, password hashes were once stored in the world-readable file /etc/passwd, now they are typically stored in /etc/shadow, which only root (the superuser) can access. + +==View the shadow file:== + +```bash +sudo less /etc/shadow +``` + +The format of the shadow file is: + +> username:**password**:last-changed(since 1-1-1970):days-until-may-change:days-until-must-change:days-warning-notice:days-since-expired-account-disabled:date-disable:reserved-field + +==Find the hash of your user account's password.== + +> Exit less ("q"). + +Use the passwd command to ==change your password:== + +```bash +passwd +``` + +> When prompted, enter a new password of your choosing. + +View the shadow file, and confirm that the stored password has changed. + +With reference to the shadow file, and the man page for crypt (Hint: "man crypt"), ==answer these Log Book questions==: + +- On Linux, the password hash stored in /etc/shadow has a prefix that specifies the hash function used.\ + > ==What hash function is used for your password?== + > Hint: the `hash-identifier` command line tool may also help. + +- ==When was the root password last changed?== + +- ==Do any accounts have a setting that will force a password change at a specific date?== + +A salt is a random string, used as further input into a one-way hash function (concatenated to the password). The salt is typically stored along with the hash. As a result the same password will have different hashes, so long as the salt is different. + +Why is that a good thing? + +What kind of attack does a salt defend against? + +What is the current salt for your account? Hint: it is stored after the second "\$". + +## Password weaknesses + +The strength of a password depends on its entropy: its degree of randomness. If a user chooses a word from a dictionary, it would not take long to attempt every dictionary word until finding one that results in the same hash. + +Try your hand at cracking passwords using the Kali virtual machine. + +**On your desktop VM:** +Add some new users with these passwords: +> Hello +> +> hellothere +> +> password1 + +**On your Kali VM:** +==Use John the Ripper (or Johnny a GUI for the John the Ripper) to crack the passwords.== +> Hint: `man john`, on the Kali Linux system. +> You will need to combine the passwd and shadow files (manually or with the kali `unshadow` command.) + +==Log Book Questions:== +- Which passwords are cracked the fastest? + +- How long did they take? + + +## Conclusion + +At this point you have: + +- Applied authentication concepts to Unix/Linux + +- Experimented with user accounts and identity + +- Experimented with one-way hash functions, salts, and password storage + +- Cracked passwords with low entropy using dictionary attacks + +Well done! diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/lab.xml.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/lab.xml.erb new file mode 100644 index 000000000..20053effd --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/lab.xml.erb @@ -0,0 +1,161 @@ +<% + require 'json' + require 'securerandom' + require 'digest/sha1' + require 'fileutils' + require 'erb' + + if self.accounts.empty? + abort('Sorry, you need to provide an account') + end + + $first_account = JSON.parse(self.accounts.first) + + $main_user = $first_account['username'].to_s + $main_user_pass = $first_account['password'].to_s + + $server_ip = self.server_ip.first + $root_password = self.root_password + $flags = self.flags + + REQUIRED_FLAGS = 1 + while $flags.length < REQUIRED_FLAGS + $flags << "flag{#{SecureRandom.hex}}" + Print.err "Warning: Not enough flags provided to hackerbot_config generator, some flags won't be tracked/marked!" + end + + def get_binding + binding + end +%> + + + + + + Hackerbot + + config/AIML + + + sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@{{chat_ip_address}} /bin/bash + + + + + Hi there. Today I'm your boss of sorts. I need you to test the security of our server. Help out and I'll give you some flags. + + + When you are ready, simply say 'ready'. + 'Ready'? + Ok, I'll do what I can to move things along... + Moving things along to the next one... + Ok, I'll do what I can to back things up... + Ok, backing up. + Ok, skipping it along. + Let me see what I can do to goto that attack. + That was the last one for now. You can rest easy, until next time... (End.) + That was the last one. Game over? + You are back to the beginning! + This is where it all began. + Doing my thing... + Here we go... + ... + .... + Let me know when you are 'ready', if you want to move on say 'next', or 'previous' and I'll move things along. + Say 'ready', 'next', or 'previous'. + + + I am waiting for you to say 'ready', 'next', 'previous', 'list', 'goto *X*', or 'answer *X*' + Say "The answer is *X*". + There is no question to answer + Correct + Incorrect + That's not possible. + Wouldn't you like to know. + + + Oh no. Failed to get shell... You need to let us in. + + + + Authentication + <%= ERB.new(File.read self.templates_path + 'intro.md.erb').result(self.get_binding) %> +
+<%= File.read self.templates_path + 'resources.md.erb' %> + +<%= File.read self.templates_path + 'license.md.erb' %> + +Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%= Time.new.to_s %>) +
+ + true + +
+ + + + <% $newuser = "user#{SecureRandom.hex(2)}" -%> + + Add a user to the system, named "<%= $newuser %>". + grep <%= $newuser %> /etc/shadow; echo $? + + + 0 + :) Well done! <%= $flags.pop %> + + + + 1 + :( It looks like you forgot to create the user? + + + :( User not found + + + + + + + Add the new <%= $newuser %> user to the 'users' group. + id <%= $newuser %> | grep users; echo $? + + + 0 + :) Well done! <%= $flags.pop %> + + + + 1 + :( It looks like you forgot to add the user to the group? + + + :( Group not found + + + + + + + Crack the passwords of the users on the desktop VM, and use those credentials to SSH to the server, where you will find flags (ssh username@<%= $server_ip %> for each username you crack the password for.) This is the end. + + + .* + :) + + + + .* + :) + + + + :) + + + + + +
diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/labsheet.html.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/labsheet.html.erb new file mode 100644 index 000000000..0bb7cc90a --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/labsheet.html.erb @@ -0,0 +1,114 @@ + + + <%= self.title %> + + + + + +
+ <%= self.html_TOC_rendered %> +
+ +
+ <%= self.html_rendered %> +
+ + + diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/license.md.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/license.md.erb new file mode 100644 index 000000000..c11478e8e --- /dev/null +++ b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/license.md.erb @@ -0,0 +1,6 @@ +## License +This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB). + +Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version. + +![small](images/leedsbeckett-logo.png) diff --git a/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/resources.md.erb b/modules/generators/structured_content/hackerbot_config/hbauthentication/templates/resources.md.erb new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/structured_content/hackerbot_config/integrity_protection/secgen_metadata.xml b/modules/generators/structured_content/hackerbot_config/integrity_protection/secgen_metadata.xml index a748298ff..bb040ff7e 100644 --- a/modules/generators/structured_content/hackerbot_config/integrity_protection/secgen_metadata.xml +++ b/modules/generators/structured_content/hackerbot_config/integrity_protection/secgen_metadata.xml @@ -29,10 +29,7 @@ - - - - + @@ -41,4 +38,4 @@ hackerbot - \ No newline at end of file + diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/kali_forensic.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/kali_forensic.pp new file mode 100644 index 000000000..b84aee99a --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/kali_forensic.pp @@ -0,0 +1 @@ +include kali_forensic::install diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/manifests/install.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/manifests/install.pp new file mode 100644 index 000000000..d7f7ed569 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/manifests/install.pp @@ -0,0 +1,5 @@ +class kali_forensic::install{ + package { ['kali-linux-forensic']: + ensure => 'installed', + } +} diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/secgen_metadata.xml b/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/secgen_metadata.xml new file mode 100644 index 000000000..c3ec2b3ff --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_forensic/secgen_metadata.xml @@ -0,0 +1,25 @@ + + + + Kali Linux Metapackage: kali-linux-forensic + Z. Cliffe Schreuders + GPLv3 + Installs a collection of software onto Kali. + kali-linux-forensic + If you are doing forensics work, you don’t want your analysis system to contain a bunch of unnecessary tools. To the rescue comes the kali-linux-forensic metapackage, which only contains the forensics tools in Kali. + Installation Size: 3.1 GB + + attack_tools + linux + + + Kali Light.* + attack + desktop + + + update + + diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/kali_full.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/kali_full.pp new file mode 100644 index 000000000..f21676bc1 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/kali_full.pp @@ -0,0 +1 @@ +include kali_full::install diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/manifests/install.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/manifests/install.pp new file mode 100644 index 000000000..dfb110de6 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/manifests/install.pp @@ -0,0 +1,5 @@ +class kali_full::install{ + package { ['kali-linux-full']: + ensure => 'installed', + } +} diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/secgen_metadata.xml b/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/secgen_metadata.xml new file mode 100644 index 000000000..aad49a1ea --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_full/secgen_metadata.xml @@ -0,0 +1,25 @@ + + + + Kali Linux Metapackage: kali-linux-full + Z. Cliffe Schreuders + GPLv3 + Installs a collection of software onto Kali. + kali-linux-full + When you download a Kali Linux ISO, you are essentially downloading an installation that has the kali-linux-full metapackage installed. This package includes all of the tools you are familiar with in Kali. + Installation Size: 9.0 GB + + attack_tools + linux + + + Kali Light.* + attack + desktop + + + update + + diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/kali_pwtools.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/kali_pwtools.pp new file mode 100644 index 000000000..9c6c591e5 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/kali_pwtools.pp @@ -0,0 +1 @@ +include kali_pwtools::install diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/manifests/install.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/manifests/install.pp new file mode 100644 index 000000000..cfdc535fa --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/manifests/install.pp @@ -0,0 +1,5 @@ +class kali_pwtools::install{ + package { ['kali-linux-pwtools']: + ensure => 'installed', + } +} diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/secgen_metadata.xml b/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/secgen_metadata.xml new file mode 100644 index 000000000..204aab2b0 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_pwtools/secgen_metadata.xml @@ -0,0 +1,25 @@ + + + + Kali Linux Metapackage: kali-linux-pwtools + Z. Cliffe Schreuders + GPLv3 + Installs a collection of software onto Kali. + kali-linux-pwtools + The kali-linux-pwtools metapackage contains over 40 different password cracking utilities as well as the GPU tools contained in kali-linux-gpu. + Installation Size: 6.0 GB + + attack_tools + linux + + + Kali Light.* + attack + desktop + + + update + + diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/kali_top10.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/kali_top10.pp new file mode 100644 index 000000000..2bf2404df --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/kali_top10.pp @@ -0,0 +1 @@ +include kali_top10::install diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/manifests/install.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/manifests/install.pp new file mode 100644 index 000000000..b45b4a3d4 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/manifests/install.pp @@ -0,0 +1,5 @@ +class kali_top10::install{ + package { ['kali-linux-top10']: + ensure => 'installed', + } +} diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/secgen_metadata.xml b/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/secgen_metadata.xml new file mode 100644 index 000000000..bac3c97b4 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_top10/secgen_metadata.xml @@ -0,0 +1,25 @@ + + + + Kali Linux Metapackage: kali-linux-top10 + Z. Cliffe Schreuders + GPLv3 + Installs a collection of software onto Kali. + kali-linux-top10 + In Kali Linux, we have a sub-menu called “Top 10 Security Tools”. The kali-linux-top10 metapackage will install all of these tools for you in one fell swoop. + Installation Size: 3.5 GB + + attack_tools + linux + + + Kali Light.* + attack + desktop + + + update + + diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/kali_web.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/kali_web.pp new file mode 100644 index 000000000..00df4deed --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/kali_web.pp @@ -0,0 +1 @@ +include kali_web::install diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/manifests/install.pp b/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/manifests/install.pp new file mode 100644 index 000000000..9b0c523c2 --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/manifests/install.pp @@ -0,0 +1,5 @@ +class kali_web::install{ + package { ['kali-linux-web']: + ensure => 'installed', + } +} diff --git a/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/secgen_metadata.xml b/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/secgen_metadata.xml new file mode 100644 index 000000000..62a788d0a --- /dev/null +++ b/modules/utilities/unix/attack_tools/kali_metapackages/kali_web/secgen_metadata.xml @@ -0,0 +1,25 @@ + + + + Kali Linux Metapackage: kali-linux-web + Z. Cliffe Schreuders + GPLv3 + Installs a collection of software onto Kali. + kali-linux-web + Web application assessments are very common in the field of penetration testing and for this reason, Kali includes the kali-linux-web metapackage containing dozens of tools related to web application hacking. + Installation Size: 4.9 GB + + attack_tools + linux + + + Kali Light.* + attack + desktop + + + update + + diff --git a/modules/utilities/unix/labtainers/files/labtainer.files/trunk/setup_scripts/install-docker-debian.sh b/modules/utilities/unix/labtainers/files/labtainer.files/trunk/setup_scripts/install-docker-debian.sh new file mode 100755 index 000000000..261e410ea --- /dev/null +++ b/modules/utilities/unix/labtainers/files/labtainer.files/trunk/setup_scripts/install-docker-debian.sh @@ -0,0 +1,90 @@ +#!/bin/bash +: <<'END' +This software was created by United States Government employees at +The Center for the Information Systems Studies and Research (CISR) +at the Naval Postgraduate School NPS. Please note that within the +United States, copyright protection is not available for any works +created by United States Government employees, pursuant to Title 17 +United States Code Section 105. This software is in the public +domain and is not subject to copyright. +END +# +#Install Docker on a Debian system, along with other packages required by Labtainers +# +type sudo >/dev/null 2>&1 || { echo >&2 "Please install sudo. Aborting."; exit 1; } +sudo -v || { echo >&2 "Please make sure user is sudoer. Aborting."; exit 1; } +#needed packages for Docker install +sudo apt-get update +sudo apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common + +#adds Docker�s official GPG Key +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - + +#used to verify matching Key ID (optional) +#sudo apt-key fingerprint 0EBFCD88 + +#sets up stable repository +sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" + +#installs Docker:Community Edition +sudo apt-get update +# SecGen change: repo is unauthenticated +sudo apt-get -y --allow-unauthenticated install docker-ce + +#gives user access to docker commands +sudo groupadd docker +sudo usermod -aG docker $USER + +#enables and starts docker +sudo systemctl start docker +sudo systemctl enable docker + +#additional packages needed for labtainers +sudo apt-get -y install python-pip +sudo pip install --upgrade pip +sudo pip install netaddr parse python-dateutil +sudo apt-get -y install openssh-server + +#---Checking if packages have been installed. If not, the system will not reboot and allow the user to investigate. +declare -a packagelist=("apt-transport-https" "ca-certificates" "curl" "gnupg2" "software-properties-common" "docker-ce" "python-pip" "openssh-server") +packagefail="false" + +for i in "${packagelist[@]}" +do +#echo $i +packagecheck=$(dpkg -s $i 2> /dev/null | grep Status) +#echo $packagecheck + if [ "$packagecheck" != "Status: install ok installed" ]; then + if [ $i = docker-ce ];then + echo "ERROR: '$i' package did not install properly. Please check the terminal output above for any errors related to the pacakge installation. Run the install script two more times. If the issue persists, go to docker docs and follow the instructions for installing docker. (Make sure the instructions is CE and is for your Linux distribution,e.g., Ubuntu and Fedora.)" + else + echo "ERROR: '$i' package did not install properly. Please check the terminal output above for any errors related to the pacakge installation. Try installing the '$i' package individually by executing this in the command line: 'sudo apt-get install $i" + fi + packagefail="true" + #echo $packagefail + fi +done + +pipcheck=$(pip list 2> /dev/null | grep -F netaddr) +#echo $pipcheck +if [ -z "$pipcheck" ]; then + echo "ERROR: 'netaddr' package did not install properly. Please check the terminal output for any errors related to the pacakge installation. Make sure 'python-pip' is installed and then try running this command: 'sudo -H pip install netaddr' " + packagefail="true" + #echo $packagefail +fi + +pipcheck=$(pip list 2> /dev/null | grep -F parse) +#echo $pipcheck +if [ -z "$pipcheck" ]; then + echo "ERROR: 'parse' package did not install properly. Please check the terminal output for any errors related to the package installation. Make sure 'python-pip' is installed and then try running this command: 'sudo -H pip install parse' " + packagefail="true" + #echo $packagefail +fi + +if [ $packagefail = "true" ]; then + exit 1 +fi + +exit 0 + +#Notes: The �-y� after each install means that the user doesn�t need to press �y� in between each package download. The install script is based on this page: https://docs.docker.com/engine/installation/linux/docker-ce/debian/ diff --git a/modules/utilities/unix/labtainers/manifests/config.pp b/modules/utilities/unix/labtainers/manifests/config.pp new file mode 100644 index 000000000..dfb24ddb1 --- /dev/null +++ b/modules/utilities/unix/labtainers/manifests/config.pp @@ -0,0 +1,12 @@ +class labtainers::config{ + require labtainers::install + + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + $lab = $secgen_parameters['lab'][0] + + exec { 'start lab': + command => "/opt/labtainers/labtainer-student/labtainer $lab", + provider => shell, + } + +} diff --git a/modules/utilities/unix/labtainers/manifests/install.pp b/modules/utilities/unix/labtainers/manifests/install.pp new file mode 100644 index 000000000..c140d6ea6 --- /dev/null +++ b/modules/utilities/unix/labtainers/manifests/install.pp @@ -0,0 +1,27 @@ +class labtainers::install{ + # $json_inputs = base64('decode', $::base64_inputs) + # $secgen_parameters = parsejson($json_inputs) + # $server_ip = $secgen_parameters['server_ip'][0] + # $port = $secgen_parameters['port'][0] + + + # these are also installed by the install script, but good to use puppet where possible + package { ['apt-transport-https', 'ca-certificates', 'curl', 'gnupg2', 'software-properties-common', 'python-pip', 'openssh-server']: + ensure => 'installed', + } -> + + file { '/opt/labtainers': + ensure => directory, + recurse => true, + source => 'puppet:///modules/labtainers/labtainer.files', + mode => '0766', + owner => 'root', + group => 'root', + } -> + + exec { 'install script': + command => '/opt/labtainers/install-labtainer.sh', + provider => shell, + } + +} diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/.gitignore b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/.gitignore index 319a2c383..723dba7b5 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/.gitignore +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/.gitignore @@ -1,2 +1,5 @@ config/config.inc.php -Dockerfile \ No newline at end of file +Dockerfile + +# Vim swap files +.*swp diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/README.md b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/README.md index 9c90823db..4908c787d 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/README.md +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/README.md @@ -12,7 +12,7 @@ Damn Vulnerable Web Application is damn vulnerable! **Do not upload it to your h ### Disclaimer -We do not take responsibility for the way in which any one uses this application (DVWA). We have made the purposes of the application clear and it should not be used maliciously. We have given warnings and taken measures to prevent users from installing DVWA on to live web servers. If your web server is compromised via an installation of DVWA it is not our responsibility it is the responsibility of the person/s who uploaded and installed it. +We do not take responsibility for the way in which any one uses this application (DVWA). We have made the purposes of the application clear and it should not be used maliciously. We have given warnings and taken measures to prevent users from installing DVWA on to live web servers. If your web server is compromised via an installation of DVWA, it is not our responsibility, it is the responsibility of the person/s who uploaded and installed it. - - - @@ -37,8 +37,8 @@ along with Damn Vulnerable Web Application (DVWA). If not, see http://www.gnu.o ## Download and install as a docker container - [dockerhub page](https://hub.docker.com/r/vulnerables/web-dvwa/) `docker run --rm -it -p 80:80 vulnerables/web-dvwa` - -Please ensure you are using aufs due to previous MySQL issues. Run `docker info` to check your storage driver. If it isn't aufs, please change it as such. There are guides for each operating system on how to do that, but they're quite different so we won't cover that here. + +Please ensure you are using aufs due to previous MySQL issues. Run `docker info` to check your storage driver. If it isn't aufs, please change it as such. There are guides for each operating system on how to do that, but they're quite different so we won't cover that here. ## Download @@ -74,7 +74,7 @@ Simply unzip dvwa.zip, place the unzipped files in your public html folder, then If you are using a Debian based Linux distribution, you will need to install the following packages _(or their equivalent)_: -`apt-get -y install apache2 mysql-server php php-mysqli php-gd libapache2-mod-php` +`apt-get -y install apache2 mysql-server php php-mysqli php-gd libapache2-mod-php` ### Database Setup @@ -84,30 +84,36 @@ If you receive an error while trying to create your database, make sure your dat The variables are set to the following by default: -```php +```php $_DVWA[ 'db_user' ] = 'root'; $_DVWA[ 'db_password' ] = 'p@ssw0rd'; $_DVWA[ 'db_database' ] = 'dvwa'; -``` - -Note, if you are using MariaDB rather than MySQL (MariaDB is default in Kali), then you can't use the database root user, you must create a new database user. To do this, connect to the database as the root user then use the following commands: - -```mysql -mysql> create database dvwa; -Query OK, 1 row affected (0.00 sec) - -mysql> grant all on dvwa.* to dvwa@localhost identified by 'xxx'; -Query OK, 0 rows affected, 1 warning (0.01 sec) - -mysql> flush privileges; -Query OK, 0 rows affected (0.00 sec) - - -``` - +``` + +Note, if you are using MariaDB rather than MySQL (MariaDB is default in Kali), then you can't use the database root user, you must create a new database user. To do this, connect to the database as the root user then use the following commands: + +```mysql +mysql> create database dvwa; +Query OK, 1 row affected (0.00 sec) + +mysql> grant all on dvwa.* to dvwa@localhost identified by 'SuperSecretPassword99'; +Query OK, 0 rows affected, 1 warning (0.01 sec) + +mysql> flush privileges; +Query OK, 0 rows affected (0.00 sec) +``` + +You will then need to update the config file, the new entries will look like this: + +```php +$_DVWA[ 'db_user' ] = 'dvwa'; +$_DVWA[ 'db_password' ] = 'SuperSecretPassword99'; +$_DVWA[ 'db_database' ] = 'dvwa'; +``` + ### Other Configuration -Depending on your Operating System as well as version of PHP, you may wish to alter the default configuration. The location of the files will be different on a per-machine basis. +Depending on your Operating System, as well as version of PHP, you may wish to alter the default configuration. The location of the files will be different on a per-machine basis. **Folder Permissions**: @@ -143,7 +149,7 @@ https://github.com/ethicalhack3r/DVWA/issues +Q. SQL Injection won't work on PHP v5.2.6. --A.If you are using PHP v5.2.6 or above you will need to do the following in order for SQL injection and other vulnerabilities to work. +-A.If you are using PHP v5.2.6 or above, you will need to do the following in order for SQL injection and other vulnerabilities to work. In `.htaccess`: @@ -171,6 +177,12 @@ With: -A. Apache may not have high enough privileges to run commands on the web server. If you are running DVWA under Linux make sure you are logged in as root. Under Windows log in as Administrator. ++Q. Why can't the database connect on CentOS? + +-A. You may be running into problems with SELinux. Either disable SELinux or run this command to allow the webserver to talk to the database: +``` +setsebool -P httpd_can_network_connect_db 1 +``` - - - diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/config/config.inc.php.dist b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/config/config.inc.php.dist index a03dd25fd..41d9ce582 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/config/config.inc.php.dist +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/config/config.inc.php.dist @@ -25,7 +25,7 @@ $_DVWA[ 'db_port '] = '5432'; # ReCAPTCHA settings # Used for the 'Insecure CAPTCHA' module -# You'll need to generate your own keys at: https://www.google.com/recaptcha/admin/create +# You'll need to generate your own keys at: https://www.google.com/recaptcha/admin $_DVWA[ 'recaptcha_public_key' ] = ''; $_DVWA[ 'recaptcha_private_key' ] = ''; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/DBMS/MySQL.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/DBMS/MySQL.php index 3af6617eb..c39061288 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/DBMS/MySQL.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/DBMS/MySQL.php @@ -47,17 +47,14 @@ dvwaMessagePush( "'users' table was created." ); // Insert some data into users -// Get the base directory for the avatar media... -$baseUrl = 'http://' . $_SERVER[ 'SERVER_NAME' ] . $_SERVER[ 'PHP_SELF' ]; -$stripPos = strpos( $baseUrl, 'setup.php' ); -$baseUrl = substr( $baseUrl, 0, $stripPos ) . 'hackable/users/'; +$avatarUrl = '/hackable/users/'; $insert = "INSERT INTO users VALUES - ('1','admin','admin','admin',MD5('password'),'{$baseUrl}admin.jpg', NOW(), '0'), - ('2','Gordon','Brown','gordonb',MD5('abc123'),'{$baseUrl}gordonb.jpg', NOW(), '0'), - ('3','Hack','Me','1337',MD5('charley'),'{$baseUrl}1337.jpg', NOW(), '0'), - ('4','Pablo','Picasso','pablo',MD5('letmein'),'{$baseUrl}pablo.jpg', NOW(), '0'), - ('5','Bob','Smith','smithy',MD5('password'),'{$baseUrl}smithy.jpg', NOW(), '0');"; + ('1','admin','admin','admin',MD5('password'),'{$avatarUrl}admin.jpg', NOW(), '0'), + ('2','Gordon','Brown','gordonb',MD5('abc123'),'{$avatarUrl}gordonb.jpg', NOW(), '0'), + ('3','Hack','Me','1337',MD5('charley'),'{$avatarUrl}1337.jpg', NOW(), '0'), + ('4','Pablo','Picasso','pablo',MD5('letmein'),'{$avatarUrl}pablo.jpg', NOW(), '0'), + ('5','Bob','Smith','smithy',MD5('password'),'{$avatarUrl}smithy.jpg', NOW(), '0');"; if( !mysqli_query($GLOBALS["___mysqli_ston"], $insert ) ) { dvwaMessagePush( "Data could not be inserted into 'users' table
SQL: " . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) ); dvwaPageReload(); diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/dvwaPage.inc.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/dvwaPage.inc.php index 114e7fd49..2ded275de 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/dvwaPage.inc.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/includes/dvwaPage.inc.php @@ -208,6 +208,8 @@ function dvwaHtmlEcho( $pPage ) { $menuBlocks[ 'vulnerabilities' ][] = array( 'id' => 'xss_d', 'name' => 'XSS (DOM)', 'url' => 'vulnerabilities/xss_d/' ); $menuBlocks[ 'vulnerabilities' ][] = array( 'id' => 'xss_r', 'name' => 'XSS (Reflected)', 'url' => 'vulnerabilities/xss_r/' ); $menuBlocks[ 'vulnerabilities' ][] = array( 'id' => 'xss_s', 'name' => 'XSS (Stored)', 'url' => 'vulnerabilities/xss_s/' ); + $menuBlocks[ 'vulnerabilities' ][] = array( 'id' => 'csp', 'name' => 'CSP Bypass', 'url' => 'vulnerabilities/csp/' ); + $menuBlocks[ 'vulnerabilities' ][] = array( 'id' => 'javascript', 'name' => 'JavaScript', 'url' => 'vulnerabilities/javascript/' ); } $menuBlocks[ 'meta' ] = array(); @@ -229,7 +231,7 @@ function dvwaHtmlEcho( $pPage ) { foreach( $menuBlock as $menuItem ) { $selectedClass = ( $menuItem[ 'id' ] == $pPage[ 'page_id' ] ) ? 'selected' : ''; $fixedUrl = DVWA_WEB_PAGE_TO_ROOT.$menuItem[ 'url' ]; - $menuBlockHtml .= "
  • {$menuItem[ 'name' ]}
  • \n"; + $menuBlockHtml .= "
  • {$menuItem[ 'name' ]}
  • \n"; } $menuHtml .= "
      {$menuBlockHtml}
    "; } @@ -328,6 +330,7 @@ function dvwaHtmlEcho( $pPage ) {

    Damn Vulnerable Web Application (DVWA) v" . dvwaVersionGet() . "

    +
    @@ -425,13 +428,13 @@ function dvwaExternalLinkUrlGet( $pLink,$text=null ) { function dvwaButtonHelpHtmlGet( $pId ) { $security = dvwaSecurityLevelGet(); - return ""; + return ""; } function dvwaButtonSourceHtmlGet( $pId ) { $security = dvwaSecurityLevelGet(); - return ""; + return ""; } diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/add_event_listeners.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/add_event_listeners.js new file mode 100644 index 000000000..5d9a82fd6 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/add_event_listeners.js @@ -0,0 +1,24 @@ +// These functions need to be called after the content they reference +// has been added to the page otherwise they will fail. + +function addEventListeners() { + var source_button = document.getElementById ("source_button"); + + if (source_button) { + source_button.addEventListener("click", function() { + var url=source_button.dataset.sourceUrl; + popUp (url); + }); + } + + var help_button = document.getElementById ("help_button"); + + if (help_button) { + help_button.addEventListener("click", function() { + var url=help_button.dataset.helpUrl; + popUp (url); + }); + } +} + +addEventListeners(); diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/dvwaPage.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/dvwaPage.js index 6be637c0b..0775a9db2 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/dvwaPage.js +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/dvwa/js/dvwaPage.js @@ -3,7 +3,8 @@ function popUp(URL) { day = new Date(); id = day.getTime(); - eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=500,height=300,left = 540,top = 250');"); + window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=800,height=300,left=540,top=250'); + //eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=800,height=300,left=540,top=250');"); } /* Form validation */ diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/external/recaptcha/recaptchalib.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/external/recaptcha/recaptchalib.php old mode 100755 new mode 100644 index 4fc5a9f61..eef481847 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/external/recaptcha/recaptchalib.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/external/recaptcha/recaptchalib.php @@ -1,279 +1,45 @@ $value ) - $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; - - // Cut the last '&' - $req=substr($req,0,strlen($req)-1); - return $req; +function recaptcha_check_answer($key, $response){ + return CheckCaptcha($key, $response); } +function CheckCaptcha($key, $response) { + try { + $url = 'https://www.google.com/recaptcha/api/siteverify'; + $dat = array( + 'secret' => $key, + 'response' => urlencode($response), + 'remoteip' => urlencode($_SERVER['REMOTE_ADDR']) + ); -/** - * Submits an HTTP POST to a reCAPTCHA server - * @param string $host - * @param string $path - * @param array $data - * @param int port - * @return array response - */ -function _recaptcha_http_post($host, $path, $data, $port = 80) { + $opt = array( + 'http' => array( + 'header' => "Content-type: application/x-www-form-urlencoded\r\n", + 'method' => 'POST', + 'content' => http_build_query($dat) + ) + ); - $req = _recaptcha_qsencode ($data); + $context = stream_context_create($opt); + $result = file_get_contents($url, false, $context); - $http_request = "POST $path HTTP/1.0\r\n"; - $http_request .= "Host: $host\r\n"; - $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; - $http_request .= "Content-Length: " . strlen($req) . "\r\n"; - $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; - $http_request .= "\r\n"; - $http_request .= $req; + return json_decode($result)->success; - $response = ''; - if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { - die ('Could not open socket'); - } - - fwrite($fs, $http_request); - - while ( !feof($fs) ) - $response .= fgets($fs, 1160); // One TCP-IP packet - fclose($fs); - $response = explode("\r\n\r\n", $response, 2); - - return $response; -} - - - -/** - * Gets the challenge HTML (javascript and non-javascript version). - * This is called from the browser, and the resulting reCAPTCHA HTML widget - * is embedded within the HTML form it was called from. - * @param string $pubkey A public key for reCAPTCHA - * @param string $error The error given by reCAPTCHA (optional, default is null) - * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) - - * @return string - The HTML to be embedded in the user's form. - */ -function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) -{ - - # commented out to deal with error in DVWA - ethicalhack3r - #if ($pubkey == null || $pubkey == '') { - # die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); - #} - - if ($use_ssl) { - $server = RECAPTCHA_API_SECURE_SERVER; - } else { - $server = RECAPTCHA_API_SERVER; - } - - $errorpart = ""; - if ($error) { - $errorpart = "&error=" . $error; - } - return ' - - '; -} - - - - -/** - * A ReCaptchaResponse is returned from recaptcha_check_answer() - */ -class ReCaptchaResponse { - var $is_valid; - var $error; -} - - -/** - * Calls an HTTP POST function to verify if the user's guess was correct - * @param string $privkey - * @param string $remoteip - * @param string $challenge - * @param string $response - * @param array $extra_params an array of extra variables to post to the server - * @return ReCaptchaResponse - */ -function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) -{ - if ($privkey == null || $privkey == '') { - die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } catch (Exception $e) { + return null; } - if ($remoteip == null || $remoteip == '') { - die ("For security reasons, you must pass the remote ip to reCAPTCHA"); - } - - - - //discard spam submissions - if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { - $recaptcha_response = new ReCaptchaResponse(); - $recaptcha_response->is_valid = false; - $recaptcha_response->error = 'incorrect-captcha-sol'; - return $recaptcha_response; - } - - $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", - array ( - 'privatekey' => $privkey, - 'remoteip' => $remoteip, - 'challenge' => $challenge, - 'response' => $response - ) + $extra_params - ); - - $answers = explode ("\n", $response [1]); - $recaptcha_response = new ReCaptchaResponse(); - - if (trim ($answers [0]) == 'true') { - $recaptcha_response->is_valid = true; - } - else { - $recaptcha_response->is_valid = false; - $recaptcha_response->error = $answers [1]; - } - return $recaptcha_response; - } -/** - * gets a URL where the user can sign up for reCAPTCHA. If your application - * has a configuration page where you enter a key, you should provide a link - * using this function. - * @param string $domain The domain where the page is hosted - * @param string $appname The name of your application - */ -function recaptcha_get_signup_url ($domain = null, $appname = null) { - return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); +function recaptcha_get_html($pubKey){ + return " + +
    + "; } -function _recaptcha_aes_pad($val) { - $block_size = 16; - $numpad = $block_size - (strlen ($val) % $block_size); - return str_pad($val, strlen ($val) + $numpad, chr($numpad)); -} - -/* Mailhide related code */ - -function _recaptcha_aes_encrypt($val,$ky) { - if (! function_exists ("mcrypt_encrypt")) { - die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); - } - $mode=MCRYPT_MODE_CBC; - $enc=MCRYPT_RIJNDAEL_128; - $val=_recaptcha_aes_pad($val); - return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); -} - - -function _recaptcha_mailhide_urlbase64 ($x) { - return strtr(base64_encode ($x), '+/', '-_'); -} - -/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ -function recaptcha_mailhide_url($pubkey, $privkey, $email) { - if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { - die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . - "you can do so at http://www.google.com/recaptcha/mailhide/apikey"); - } - - - $ky = pack('H*', $privkey); - $cryptmail = _recaptcha_aes_encrypt ($email, $ky); - - return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); -} - -/** - * gets the parts of the email to expose to the user. - * eg, given johndoe@example,com return ["john", "example.com"]. - * the email is then displayed as john...@example.com - */ -function _recaptcha_mailhide_email_parts ($email) { - $arr = preg_split("/@/", $email ); - - if (strlen ($arr[0]) <= 4) { - $arr[0] = substr ($arr[0], 0, 1); - } else if (strlen ($arr[0]) <= 6) { - $arr[0] = substr ($arr[0], 0, 3); - } else { - $arr[0] = substr ($arr[0], 0, 4); - } - return $arr; -} - -/** - * Gets html to display an email address given a public an private key. - * to get a key, go to: - * - * http://www.google.com/recaptcha/mailhide/apikey - */ -function recaptcha_mailhide_html($pubkey, $privkey, $email) { - $emailparts = _recaptcha_mailhide_email_parts ($email); - $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); - - return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); - -} - - ?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/help/help.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/help/help.php index ebe4c6821..11701dcd9 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/help/help.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/help/help.php @@ -44,7 +44,7 @@ This level also extends on the medium level, by waiting when there is a failed login but this time it is a random amount of time between two and four seconds. The idea of this is to try and confuse any timing predictions.

    -

    Using a form could have a similar effect as a CSRF token.

    +

    Using a form could have a similar effect as a CSRF token.


    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/source/impossible.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/source/impossible.php index fb245b7c3..0816216d6 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/source/impossible.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/brute/source/impossible.php @@ -1,6 +1,6 @@

    About

    -

    A is a program that can tell whether its user is a human or a computer. You've probably seen +

    A is a program that can tell whether its user is a human or a computer. You've probably seen them - colourful images with distorted text at the bottom of Web registration forms. CAPTCHAs are used by many websites to prevent abuse from "bots", or automated programs usually written to generate spam. No computer program can read distorted text as well as humans can, so bots cannot navigate sites protected by CAPTCHAs.

    @@ -58,5 +58,5 @@
    -

    Reference:

    +

    Reference:

    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/index.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/index.php index 3c7112fde..056e3c4c6 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/index.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/index.php @@ -87,7 +87,7 @@ $page[ 'body' ] .= "

    More Information

      -
    • " . dvwaExternalLinkUrlGet( 'http://www.captcha.net/' ) . "
    • +
    • " . dvwaExternalLinkUrlGet( 'https://en.wikipedia.org/wiki/CAPTCHA' ) . "
    • " . dvwaExternalLinkUrlGet( 'https://www.google.com/recaptcha/' ) . "
    • " . dvwaExternalLinkUrlGet( 'https://www.owasp.org/index.php/Testing_for_Captcha_(OWASP-AT-012)' ) . "
    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/high.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/high.php index ee48662ff..01f2787f5 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/high.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/high.php @@ -9,21 +9,20 @@ if( isset( $_POST[ 'Change' ] ) ) { $pass_conf = $_POST[ 'password_conf' ]; // Check CAPTCHA from 3rd party - $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ], - $_SERVER[ 'REMOTE_ADDR' ], - $_POST[ 'recaptcha_challenge_field' ], - $_POST[ 'recaptcha_response_field' ] ); + $resp = recaptcha_check_answer( + $_DVWA[ 'recaptcha_private_key' ], + $_POST['g-recaptcha-response'] + ); - // Did the CAPTCHA fail? - if( !$resp->is_valid && ( $_POST[ 'recaptcha_response_field' ] != 'hidd3n_valu3' || $_SERVER[ 'HTTP_USER_AGENT' ] != 'reCAPTCHA' ) ) { - // What happens when the CAPTCHA was entered incorrectly - $html .= "

    The CAPTCHA was incorrect. Please try again.
    "; - $hide_form = false; - return; - } - else { + if ( + $resp || + ( + $_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3' + && $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA' + ) + ){ // CAPTCHA was correct. Do both new passwords match? - if( $pass_new == $pass_conf ) { + if ($pass_new == $pass_conf) { $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); $pass_new = md5( $pass_new ); @@ -33,12 +32,18 @@ if( isset( $_POST[ 'Change' ] ) ) { // Feedback for user $html .= "
    Password Changed.
    "; - } - else { + + } else { // Ops. Password mismatch $html .= "
    Both passwords must match.
    "; $hide_form = false; } + + } else { + // What happens when the CAPTCHA was entered incorrectly + $html .= "

    The CAPTCHA was incorrect. Please try again.
    "; + $hide_form = false; + return; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/impossible.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/impossible.php index b16e8a1e8..8dcce3456 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/impossible.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/impossible.php @@ -24,13 +24,13 @@ if( isset( $_POST[ 'Change' ] ) ) { $pass_curr = md5( $pass_curr ); // Check CAPTCHA from 3rd party - $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ], - $_SERVER[ 'REMOTE_ADDR' ], - $_POST[ 'recaptcha_challenge_field' ], - $_POST[ 'recaptcha_response_field' ] ); + $resp = recaptcha_check_answer( + $_DVWA[ 'recaptcha_private_key' ], + $_POST['g-recaptcha-response'] + ); // Did the CAPTCHA fail? - if( !$resp->is_valid ) { + if( !$resp ) { // What happens when the CAPTCHA was entered incorrectly $html .= "

    The CAPTCHA was incorrect. Please try again.
    "; $hide_form = false; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/low.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/low.php index 71b9feef0..181297493 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/low.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/low.php @@ -9,13 +9,13 @@ if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) { $pass_conf = $_POST[ 'password_conf' ]; // Check CAPTCHA from 3rd party - $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ], - $_SERVER[ 'REMOTE_ADDR' ], - $_POST[ 'recaptcha_challenge_field' ], - $_POST[ 'recaptcha_response_field' ] ); + $resp = recaptcha_check_answer( + $_DVWA[ 'recaptcha_private_key'], + $_POST['g-recaptcha-response'] + ); // Did the CAPTCHA fail? - if( !$resp->is_valid ) { + if( !$resp ) { // What happens when the CAPTCHA was entered incorrectly $html .= "

    The CAPTCHA was incorrect. Please try again.
    "; $hide_form = false; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/medium.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/medium.php index d4bdc8113..d655b3649 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/medium.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/captcha/source/medium.php @@ -9,13 +9,13 @@ if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) { $pass_conf = $_POST[ 'password_conf' ]; // Check CAPTCHA from 3rd party - $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ], - $_SERVER[ 'REMOTE_ADDR' ], - $_POST[ 'recaptcha_challenge_field' ], - $_POST[ 'recaptcha_response_field' ] ); + $resp = recaptcha_check_answer( + $_DVWA[ 'recaptcha_private_key' ], + $_POST['g-recaptcha-response'] + ); // Did the CAPTCHA fail? - if( !$resp->is_valid ) { + if( !$resp ) { // What happens when the CAPTCHA was entered incorrectly $html .= "

    The CAPTCHA was incorrect. Please try again.
    "; $hide_form = false; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/help/help.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/help/help.php new file mode 100644 index 000000000..0d3797cad --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/help/help.php @@ -0,0 +1,52 @@ +
    +

    Help - Content Security Policy (CSP) Bypass

    + +
    + + + + +
    +

    About

    +

    Content Security Policy (CSP) is used to define where scripts and other resources can be loaded or executed from. This module will walk you through ways to bypass the policy based on common mistakes made by developers.

    +

    None of the vulnerabilities are actual vulnerabilities in CSP, they are vulnerabilities in the way it has been implemented.

    + +


    + +

    Objective

    +

    Bypass Content Security Policy (CSP) and execute JavaScript in the page.

    + +


    + +

    Low Level

    +

    Examine the policy to find all the sources that can be used to host external script files.

    +
    Spoiler: Scripts can be included from Pastebin, try storing some JavaScript on there and then loading it in.
    + +
    + +

    Medium Level

    +

    The CSP policy tries to use a nonce to prevent inline scripts from being added by attackers.

    +
    Spoiler: Examine the nonce and see how it varies (or doesn't).
    + +
    + +

    High Level

    +

    The page makes a JSONP call to source/jsonp.php passing the name of the function to callback to, you need to modify the jsonp.php script to change the callback function.

    +
    Spoiler: The JavaScript on the page will execute whatever is returned by the page, changing this to your own code will execute that instead
    + +
    + +

    Impossible Level

    +

    + This level is an update of the high level where the JSONP call has its callback function hardcoded and the CSP policy is locked down to only allow external scripts. +

    +
    + +
    + +
    + +

    Reference:

    +

    Reference:

    +

    Reference:

    +
    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/index.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/index.php new file mode 100644 index 000000000..aa189ff07 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/index.php @@ -0,0 +1,57 @@ + +

    Vulnerability: Content Security Policy (CSP) Bypass

    + +
    +EOF; + +require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/csp/source/{$vulnerabilityFile}"; + +$page[ 'body' ] .= << +EOF; + +$page[ 'body' ] .= " +

    More Information

    +
      +
    • " . dvwaExternalLinkUrlGet( 'https://content-security-policy.com/', "Content Security Policy Reference" ) . "
    • +
    • " . dvwaExternalLinkUrlGet( 'https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP', "Mozilla Developer Network - CSP: script-src") . "
    • +
    • " . dvwaExternalLinkUrlGet( 'https://blog.mozilla.org/security/2014/10/04/csp-for-the-web-we-have/', "Mozilla Security Blog - CSP for the web we have" ) . "
    • +
    +

    Module developed by Digininja.

    +
    \n"; + +dvwaHtmlEcho( $page ); + +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.js new file mode 100644 index 000000000..a4b10cfd4 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.js @@ -0,0 +1,19 @@ +function clickButton() { + var s = document.createElement("script"); + s.src = "source/jsonp.php?callback=solveSum"; + document.body.appendChild(s); +} + +function solveSum(obj) { + if ("answer" in obj) { + document.getElementById("answer").innerHTML = obj['answer']; + } +} + +var solve_button = document.getElementById ("solve"); + +if (solve_button) { + solve_button.addEventListener("click", function() { + clickButton(); + }); +} diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.php new file mode 100644 index 000000000..18e1bf0fa --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/high.php @@ -0,0 +1,22 @@ + + +

    The page makes a call to ' . DVWA_WEB_PAGE_TO_ROOT . '/vulnerabilities/csp/source/jsonp.php to load some code. Modify that page to run your own code.

    +

    1+2+3+4+5=

    + + + + +'; + diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.js new file mode 100644 index 000000000..11b56aa57 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.js @@ -0,0 +1,19 @@ +function clickButton() { + var s = document.createElement("script"); + s.src = "source/jsonp_impossible.php"; + document.body.appendChild(s); +} + +function solveSum(obj) { + if ("answer" in obj) { + document.getElementById("answer").innerHTML = obj['answer']; + } +} + +var solve_button = document.getElementById ("solve"); + +if (solve_button) { + solve_button.addEventListener("click", function() { + clickButton(); + }); +} diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.php new file mode 100644 index 000000000..320fd2f12 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/impossible.php @@ -0,0 +1,23 @@ + + +

    Unlike the high level, this does a JSONP call but does not use a callback, instead it hardcodes the function to call.

    The CSP settings only allow external JavaScript on the local server and no inline code.

    +

    1+2+3+4+5=

    + + + + +'; + diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp.php new file mode 100644 index 000000000..fcfc53522 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp.php @@ -0,0 +1,13 @@ + "15"); + +echo $callback . "(".json_encode($outp).")"; +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp_impossible.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp_impossible.php new file mode 100644 index 000000000..090a38b8b --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/jsonp_impossible.php @@ -0,0 +1,7 @@ + "15"); + +echo "solveSum (".json_encode($outp).")"; +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/low.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/low.php new file mode 100644 index 000000000..ea25c7213 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/low.php @@ -0,0 +1,22 @@ + + +"; +} +$page[ 'body' ] .= ' +
    +

    You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:

    + + +
    +'; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/medium.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/medium.php new file mode 100644 index 000000000..0fd03209e --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/csp/source/medium.php @@ -0,0 +1,25 @@ +alert(1) + +?> + +

    Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.

    + + + +'; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/help/help.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/help/help.php new file mode 100644 index 000000000..a679d2e41 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/help/help.php @@ -0,0 +1,52 @@ +
    +

    Help - Client Side JavaScript

    + +
    +

    About

    +

    The attacks in this section are designed to help you learn about how JavaScript is used in the browser and how it can be manipulated. The attacks could be carried out by just analysing network traffic, but that isn't the point and it would also probably be a lot harder.

    + +
    + +

    Objective

    +

    Simply submit the phrase "success" to win the level. Obviously, it isn't quite that easy, each level implements different protection mechanisms, the JavaScript included in the pages has to be analysed and then manipulated to bypass the protections.

    + +
    +

    Low Level

    +

    All the JavaScript is included in the page. Read the source and work out what function is being used to generate the token required to match with the phrase and then call the function manually.

    +
    Spoiler: Change the phrase to success and then use the function generate_token() to update the token.
    + +


    + +

    Medium Level

    +

    + The JavaScript has been broken out into its own file and then minimized. You need to view the source for the included file and then work out what it is doing. Both Firefox and Chrome have a Pretty Print feature which attempts to reverse the compression and display code in a readable way. +

    +
    Spoiler: The file uses the setTimeout function to run the do_elsesomething function which generates the token.
    + +


    + +

    High Level

    +

    + The JavaScript has been obfuscated by at least one engine. You are going to need to step through the code to work out what is useful, what is garbage and what is needed to complete the mission. +

    +
    Spoiler: If it helps, two packers have been used, the first is from Dan's Tools and the second is the JavaScript Obfuscator Tool.
    +
    Spoiler 2: This deobfuscation tool seems to work the best on this code deobfuscate javascript.
    +
    Spoiler 3: This is one way to do it... run the obfuscated JS through a deobfuscation app, intercept the response for the obfuscated JS and swap in the readable version. Work out the flow and you will see three functions that need to be called in order. Call the functions at the right time with the right parameters.
    + +


    + +

    Impossible Level

    +

    You can never trust the user and have to assume that any code sent to the user can be manipulated or bypassed and so there is no impossible level.

    + +
    + +
    + +

    Reference:

    +
      +
    • +
    • +
    • +
    • +
    +
    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/index.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/index.php new file mode 100644 index 000000000..1e5b5802c --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/index.php @@ -0,0 +1,123 @@ +Well done!

    "; + } else { + $message = "

    Invalid token.

    "; + } + break; + case 'medium': + if ($token == strrev("XXsuccessXX")) { + $message = "

    Well done!

    "; + } else { + $message = "

    Invalid token.

    "; + } + break; + case 'high': + if ($token == hash("sha256", hash("sha256", "XX" . strrev("success")) . "ZZ")) { + $message = "

    Well done!

    "; + } else { + $message = "

    Invalid token.

    "; + } + break; + default: + $vulnerabilityFile = 'impossible.php'; + break; + } + } else { + $message = "

    You got the phrase wrong.

    "; + } + } else { + $message = "

    Missing phrase or token.

    "; + } +} + +if ( $_COOKIE[ 'security' ] == "impossible" ) { +$page[ 'body' ] = << +

    Vulnerability: JavaScript Attacks

    + +
    +

    + You can never trust anything that comes from the user or prevent them from messing with it and so there is no impossible level. +

    +EOF; +} else { +$page[ 'body' ] = << +

    Vulnerability: JavaScript Attacks

    + +
    +

    + Submit the word "success" to win. +

    + + $message + +
    + + + +
    +EOF; +} + +require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/javascript/source/{$vulnerabilityFile}"; + +$page[ 'body' ] .= << +EOF; + +$page[ 'body' ] .= " +

    More Information

    +
      +
    • " . dvwaExternalLinkUrlGet( 'https://www.w3schools.com/js/' ) . "
    • +
    • " . dvwaExternalLinkUrlGet( 'https://www.youtube.com/watch?v=cs7EQdWO5o0&index=17&list=WL' ) . "
    • +
    • " . dvwaExternalLinkUrlGet( 'https://ponyfoo.com/articles/es6-proxies-in-depth' ) . "
    • +
    +

    Module developed by Digininja.

    +
    \n"; + +dvwaHtmlEcho( $page ); + +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.js new file mode 100644 index 000000000..30c3833ad --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.js @@ -0,0 +1 @@ +var a=['fromCharCode','toString','replace','BeJ','\x5cw+','Lyg','SuR','(w(){\x273M\x203L\x27;q\x201l=\x273K\x203I\x203J\x20T\x27;q\x201R=1c\x202I===\x271n\x27;q\x20Y=1R?2I:{};p(Y.3N){1R=1O}q\x202L=!1R&&1c\x202M===\x271n\x27;q\x202o=!Y.2S&&1c\x202d===\x271n\x27&&2d.2Q&&2d.2Q.3S;p(2o){Y=3R}z\x20p(2L){Y=2M}q\x202G=!Y.3Q&&1c\x202g===\x271n\x27&&2g.X;q\x202s=1c\x202l===\x27w\x27&&2l.3P;q\x201y=!Y.3H&&1c\x20Z!==\x272T\x27;q\x20m=\x273G\x27.3z(\x27\x27);q\x202w=[-3y,3x,3v,3w];q\x20U=[24,16,8,0];q\x20K=[3A,3B,3F,3E,3D,3C,3T,3U,4d,4c,4b,49,4a,4e,4f,4j,4i,4h,3u,48,47,3Z,3Y,3X,3V,3W,40,41,46,45,43,42,4k,3f,38,36,39,37,34,33,2Y,31,2Z,35,3t,3n,3m,3l,3o,3p,3s,3r,3q,3k,3j,3d,3a,3c,3b,3e,3h,3g,3i,4g];q\x201E=[\x271e\x27,\x2727\x27,\x271G\x27,\x272R\x27];q\x20l=[];p(Y.2S||!1z.1K){1z.1K=w(1x){A\x204C.Q.2U.1I(1x)===\x27[1n\x201z]\x27}}p(1y&&(Y.50||!Z.1N)){Z.1N=w(1x){A\x201c\x201x===\x271n\x27&&1x.1w&&1x.1w.1J===Z}}q\x202m=w(1X,x){A\x20w(s){A\x20O\x20N(x,1d).S(s)[1X]()}};q\x202a=w(x){q\x20P=2m(\x271e\x27,x);p(2o){P=2P(P,x)}P.1T=w(){A\x20O\x20N(x)};P.S=w(s){A\x20P.1T().S(s)};1g(q\x20i=0;i<1E.W;++i){q\x20T=1E[i];P[T]=2m(T,x)}A\x20P};q\x202P=w(P,x){q\x201S=2O(\x222N(\x271S\x27)\x22);q\x201Y=2O(\x222N(\x271w\x27).1Y\x22);q\x202n=x?\x271H\x27:\x271q\x27;q\x202z=w(s){p(1c\x20s===\x272p\x27){A\x201S.2x(2n).S(s,\x274S\x27).1G(\x271e\x27)}z{p(s===2q||s===2T){1u\x20O\x201t(1l)}z\x20p(s.1J===Z){s=O\x202r(s)}}p(1z.1K(s)||Z.1N(s)||s.1J===1Y){A\x201S.2x(2n).S(O\x201Y(s)).1G(\x271e\x27)}z{A\x20P(s)}};A\x202z};q\x202k=w(1X,x){A\x20w(G,s){A\x20O\x201P(G,x,1d).S(s)[1X]()}};q\x202f=w(x){q\x20P=2k(\x271e\x27,x);P.1T=w(G){A\x20O\x201P(G,x)};P.S=w(G,s){A\x20P.1T(G).S(s)};1g(q\x20i=0;i<1E.W;++i){q\x20T=1E[i];P[T]=2k(T,x)}A\x20P};w\x20N(x,1v){p(1v){l[0]=l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0;k.l=l}z{k.l=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}p(x){k.C=4I;k.B=4H;k.E=4l;k.F=4U;k.J=4J;k.I=4K;k.H=4L;k.D=4T}z{k.C=4X;k.B=4W;k.E=4Y;k.F=4Z;k.J=4V;k.I=4O;k.H=4F;k.D=4s}k.1C=k.1A=k.L=k.2i=0;k.1U=k.1L=1O;k.2j=1d;k.x=x}N.Q.S=w(s){p(k.1U){A}q\x202h,T=1c\x20s;p(T!==\x272p\x27){p(T===\x271n\x27){p(s===2q){1u\x20O\x201t(1l)}z\x20p(1y&&s.1J===Z){s=O\x202r(s)}z\x20p(!1z.1K(s)){p(!1y||!Z.1N(s)){1u\x20O\x201t(1l)}}}z{1u\x20O\x201t(1l)}2h=1d}q\x20r,M=0,i,W=s.W,l=k.l;4t(M>2]|=s[M]<>2]|=r<>2]|=(2t|(r>>6))<>2]|=(R|(r&V))<=2E){l[i>>2]|=(2D|(r>>12))<>2]|=(R|((r>>6)&V))<>2]|=(R|(r&V))<>2]|=(2X|(r>>18))<>2]|=(R|((r>>12)&V))<>2]|=(R|((r>>6)&V))<>2]|=(R|(r&V))<=1k){k.1C=l[16];k.1A=i-1k;k.1W();k.1L=1d}z{k.1A=i}}p(k.L>4r){k.2i+=k.L/2H<<0;k.L=k.L%2H}A\x20k};N.Q.1s=w(){p(k.1U){A}k.1U=1d;q\x20l=k.l,i=k.2u;l[16]=k.1C;l[i>>2]|=2w[i&3];k.1C=l[16];p(i>=4q){p(!k.1L){k.1W()}l[0]=k.1C;l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0}l[14]=k.2i<<3|k.L>>>29;l[15]=k.L<<3;k.1W()};N.Q.1W=w(){q\x20a=k.C,b=k.B,c=k.E,d=k.F,e=k.J,f=k.I,g=k.H,h=k.D,l=k.l,j,1a,1b,1j,v,1f,1h,1B,1Z,1V,1D;1g(j=16;j<1k;++j){v=l[j-15];1a=((v>>>7)|(v<<25))^((v>>>18)|(v<<14))^(v>>>3);v=l[j-2];1b=((v>>>17)|(v<<15))^((v>>>19)|(v<<13))^(v>>>10);l[j]=l[j-16]+1a+l[j-7]+1b<<0}1D=b&c;1g(j=0;j<1k;j+=4){p(k.2j){p(k.x){1B=4m;v=l[0]-4n;h=v-4o<<0;d=v+4p<<0}z{1B=4v;v=l[0]-4w;h=v-4G<<0;d=v+4D<<0}k.2j=1O}z{1a=((a>>>2)|(a<<30))^((a>>>13)|(a<<19))^((a>>>22)|(a<<10));1b=((e>>>6)|(e<<26))^((e>>>11)|(e<<21))^((e>>>25)|(e<<7));1B=a&b;1j=1B^(a&c)^1D;1h=(e&f)^(~e&g);v=h+1b+1h+K[j]+l[j];1f=1a+1j;h=d+v<<0;d=v+1f<<0}1a=((d>>>2)|(d<<30))^((d>>>13)|(d<<19))^((d>>>22)|(d<<10));1b=((h>>>6)|(h<<26))^((h>>>11)|(h<<21))^((h>>>25)|(h<<7));1Z=d&a;1j=1Z^(d&b)^1B;1h=(h&e)^(~h&f);v=g+1b+1h+K[j+1]+l[j+1];1f=1a+1j;g=c+v<<0;c=v+1f<<0;1a=((c>>>2)|(c<<30))^((c>>>13)|(c<<19))^((c>>>22)|(c<<10));1b=((g>>>6)|(g<<26))^((g>>>11)|(g<<21))^((g>>>25)|(g<<7));1V=c&d;1j=1V^(c&a)^1Z;1h=(g&h)^(~g&e);v=f+1b+1h+K[j+2]+l[j+2];1f=1a+1j;f=b+v<<0;b=v+1f<<0;1a=((b>>>2)|(b<<30))^((b>>>13)|(b<<19))^((b>>>22)|(b<<10));1b=((f>>>6)|(f<<26))^((f>>>11)|(f<<21))^((f>>>25)|(f<<7));1D=b&c;1j=1D^(b&d)^1V;1h=(f&g)^(~f&h);v=e+1b+1h+K[j+3]+l[j+3];1f=1a+1j;e=a+v<<0;a=v+1f<<0}k.C=k.C+a<<0;k.B=k.B+b<<0;k.E=k.E+c<<0;k.F=k.F+d<<0;k.J=k.J+e<<0;k.I=k.I+f<<0;k.H=k.H+g<<0;k.D=k.D+h<<0};N.Q.1e=w(){k.1s();q\x20C=k.C,B=k.B,E=k.E,F=k.F,J=k.J,I=k.I,H=k.H,D=k.D;q\x201e=m[(C>>28)&o]+m[(C>>24)&o]+m[(C>>20)&o]+m[(C>>16)&o]+m[(C>>12)&o]+m[(C>>8)&o]+m[(C>>4)&o]+m[C&o]+m[(B>>28)&o]+m[(B>>24)&o]+m[(B>>20)&o]+m[(B>>16)&o]+m[(B>>12)&o]+m[(B>>8)&o]+m[(B>>4)&o]+m[B&o]+m[(E>>28)&o]+m[(E>>24)&o]+m[(E>>20)&o]+m[(E>>16)&o]+m[(E>>12)&o]+m[(E>>8)&o]+m[(E>>4)&o]+m[E&o]+m[(F>>28)&o]+m[(F>>24)&o]+m[(F>>20)&o]+m[(F>>16)&o]+m[(F>>12)&o]+m[(F>>8)&o]+m[(F>>4)&o]+m[F&o]+m[(J>>28)&o]+m[(J>>24)&o]+m[(J>>20)&o]+m[(J>>16)&o]+m[(J>>12)&o]+m[(J>>8)&o]+m[(J>>4)&o]+m[J&o]+m[(I>>28)&o]+m[(I>>24)&o]+m[(I>>20)&o]+m[(I>>16)&o]+m[(I>>12)&o]+m[(I>>8)&o]+m[(I>>4)&o]+m[I&o]+m[(H>>28)&o]+m[(H>>24)&o]+m[(H>>20)&o]+m[(H>>16)&o]+m[(H>>12)&o]+m[(H>>8)&o]+m[(H>>4)&o]+m[H&o];p(!k.x){1e+=m[(D>>28)&o]+m[(D>>24)&o]+m[(D>>20)&o]+m[(D>>16)&o]+m[(D>>12)&o]+m[(D>>8)&o]+m[(D>>4)&o]+m[D&o]}A\x201e};N.Q.2U=N.Q.1e;N.Q.1G=w(){k.1s();q\x20C=k.C,B=k.B,E=k.E,F=k.F,J=k.J,I=k.I,H=k.H,D=k.D;q\x202b=[(C>>24)&u,(C>>16)&u,(C>>8)&u,C&u,(B>>24)&u,(B>>16)&u,(B>>8)&u,B&u,(E>>24)&u,(E>>16)&u,(E>>8)&u,E&u,(F>>24)&u,(F>>16)&u,(F>>8)&u,F&u,(J>>24)&u,(J>>16)&u,(J>>8)&u,J&u,(I>>24)&u,(I>>16)&u,(I>>8)&u,I&u,(H>>24)&u,(H>>16)&u,(H>>8)&u,H&u];p(!k.x){2b.4A((D>>24)&u,(D>>16)&u,(D>>8)&u,D&u)}A\x202b};N.Q.27=N.Q.1G;N.Q.2R=w(){k.1s();q\x201w=O\x20Z(k.x?28:32);q\x201i=O\x204x(1w);1i.1p(0,k.C);1i.1p(4,k.B);1i.1p(8,k.E);1i.1p(12,k.F);1i.1p(16,k.J);1i.1p(20,k.I);1i.1p(24,k.H);p(!k.x){1i.1p(28,k.D)}A\x201w};w\x201P(G,x,1v){q\x20i,T=1c\x20G;p(T===\x272p\x27){q\x20L=[],W=G.W,M=0,r;1g(i=0;i>6));L[M++]=(R|(r&V))}z\x20p(r<2A||r>=2E){L[M++]=(2D|(r>>12));L[M++]=(R|((r>>6)&V));L[M++]=(R|(r&V))}z{r=2C+(((r&23)<<10)|(G.1Q(++i)&23));L[M++]=(2X|(r>>18));L[M++]=(R|((r>>12)&V));L[M++]=(R|((r>>6)&V));L[M++]=(R|(r&V))}}G=L}z{p(T===\x271n\x27){p(G===2q){1u\x20O\x201t(1l)}z\x20p(1y&&G.1J===Z){G=O\x202r(G)}z\x20p(!1z.1K(G)){p(!1y||!Z.1N(G)){1u\x20O\x201t(1l)}}}z{1u\x20O\x201t(1l)}}p(G.W>1k){G=(O\x20N(x,1d)).S(G).27()}q\x201F=[],2e=[];1g(i=0;i<1k;++i){q\x20b=G[i]||0;1F[i]=4z^b;2e[i]=4y^b}N.1I(k,x,1v);k.S(2e);k.1F=1F;k.2c=1d;k.1v=1v}1P.Q=O\x20N();1P.Q.1s=w(){N.Q.1s.1I(k);p(k.2c){k.2c=1O;q\x202W=k.27();N.1I(k,k.x,k.1v);k.S(k.1F);k.S(2W);N.Q.1s.1I(k)}};q\x20X=2a();X.1q=X;X.1H=2a(1d);X.1q.2V=2f();X.1H.2V=2f(1d);p(2G){2g.X=X}z{Y.1q=X.1q;Y.1H=X.1H;p(2s){2l(w(){A\x20X})}}})();w\x202y(e){1g(q\x20t=\x22\x22,n=e.W-1;n>=0;n--)t+=e[n];A\x20t}w\x202J(t,y=\x224B\x22){1m.1o(\x221M\x22).1r=1q(1m.1o(\x221M\x22).1r+y)}w\x202B(e=\x224E\x22){1m.1o(\x221M\x22).1r=1q(e+1m.1o(\x221M\x22).1r)}w\x202K(a,b){1m.1o(\x221M\x22).1r=2y(1m.1o(\x222F\x22).1r)}1m.1o(\x222F\x22).1r=\x22\x22;4u(w(){2B(\x224M\x22)},4N);1m.1o(\x224P\x22).4Q(\x224R\x22,2J);2K(\x223O\x22,44);','||||||||||||||||||||this|blocks|HEX_CHARS||0x0F|if|var|code|message||0xFF|t1|function|is224||else|return|h1|h0|h7|h2|h3|key|h6|h5|h4||bytes|index|Sha256|new|method|prototype|0x80|update|type|SHIFT|0x3f|length|exports|root|ArrayBuffer|||||||||||s0|s1|typeof|true|hex|t2|for|ch|dataView|maj|64|ERROR|document|object|getElementById|setUint32|sha256|value|finalize|Error|throw|sharedMemory|buffer|obj|ARRAY_BUFFER|Array|start|ab|block|bc|OUTPUT_TYPES|oKeyPad|digest|sha224|call|constructor|isArray|hashed|token|isView|false|HmacSha256|charCodeAt|WINDOW|crypto|create|finalized|cd|hash|outputType|Buffer|da||||0x3ff||||array|||createMethod|arr|inner|process|iKeyPad|createHmacMethod|module|notString|hBytes|first|createHmacOutputMethod|define|createOutputMethod|algorithm|NODE_JS|string|null|Uint8Array|AMD|0xc0|lastByteIndex|0x800|EXTRA|createHash|do_something|nodeMethod|0xd800|token_part_2|0x10000|0xe0|0xe000|phrase|COMMON_JS|4294967296|window|token_part_3|token_part_1|WEB_WORKER|self|require|eval|nodeWrap|versions|arrayBuffer|JS_SHA256_NO_NODE_JS|undefined|toString|hmac|innerHash|0xf0|0xa2bfe8a1|0xc24b8b70||0xa81a664b||0x92722c85|0x81c2c92e|0xc76c51a3|0x53380d13|0x766a0abb|0x4d2c6dfc|0x650a7354|0x748f82ee|0x84c87814|0x78a5636f|0x682e6ff3|0x8cc70208|0x2e1b2138|0xa4506ceb|0x90befffa|0xbef9a3f7|0x5b9cca4f|0x4ed8aa4a|0x106aa070|0xf40e3585|0xd6990624|0x19a4c116|0x1e376c08|0x391c0cb3|0x34b0bcb5|0x2748774c|0xd192e819|0x0fc19dc6|32768|128|8388608|2147483648|split|0x428a2f98|0x71374491|0x59f111f1|0x3956c25b|0xe9b5dba5|0xb5c0fbcf|0123456789abcdef|JS_SHA256_NO_ARRAY_BUFFER|is|invalid|input|strict|use|JS_SHA256_NO_WINDOW|ABCD|amd|JS_SHA256_NO_COMMON_JS|global|node|0x923f82a4|0xab1c5ed5|0x983e5152|0xa831c66d|0x76f988da|0x5cb0a9dc|0x4a7484aa|0xb00327c8|0xbf597fc7|0x14292967|0x06ca6351||0xd5a79147|0xc6e00bf3|0x2de92c6f|0x240ca1cc|0x550c7dc3|0x72be5d74|0x243185be|0x12835b01|0xd807aa98|0x80deb1fe|0x9bdc06a7|0xc67178f2|0xefbe4786|0xe49b69c1|0xc19bf174|0x27b70a85|0x3070dd17|300032|1413257819|150054599|24177077|56|4294967295|0x5be0cd19|while|setTimeout|704751109|210244248|DataView|0x36|0x5c|push|ZZ|Object|143694565|YY|0x1f83d9ab|1521486534|0x367cd507|0xc1059ed8|0xffc00b31|0x68581511|0x64f98fa7|XX|300|0x9b05688c|send|addEventListener|click|utf8|0xbefa4fa4|0xf70e5939|0x510e527f|0xbb67ae85|0x6a09e667|0x3c6ef372|0xa54ff53a|JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW','split'];(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};e(++d);}(a,0x1f4));var b=function(c,d){c=c-0x0;var e=a[c];return e;};eval(function(d,e,f,g,h,i){h=function(j){return(j0x23?String[b('0x0')](j+0x1d):j[b('0x1')](0x24));};if(!''[b('0x2')](/^/,String)){while(f--){i[h(f)]=g[f]||h(f);}g=[function(k){if('wpA'!==b('0x3')){return i[k];}else{while(f--){i[k(f)]=g[f]||k(f);}g=[function(l){return i[l];}];k=function(){return b('0x4');};f=0x1;}}];h=function(){return b('0x4');};f=0x1;};while(f--){if(g[f]){if(b('0x5')===b('0x6')){return i[h];}else{d=d[b('0x2')](new RegExp('\x5cb'+h(f)+'\x5cb','g'),g[f]);}}}return d;}(b('0x7'),0x3e,0x137,b('0x8')[b('0x9')]('|'),0x0,{})); diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.php new file mode 100644 index 000000000..756058f33 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high.php @@ -0,0 +1,5 @@ + +EOF; +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high_unobfuscated.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high_unobfuscated.js new file mode 100644 index 000000000..3db08e8a5 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/high_unobfuscated.js @@ -0,0 +1,540 @@ +/** + * [js-sha256]{@link https://github.com/emn178/js-sha256} + * + * @version 0.9.0 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2017 + * @license MIT + */ +/*jslint bitwise: true */ +(function () { + 'use strict'; + + var ERROR = 'input is invalid type'; + var WINDOW = typeof window === 'object'; + var root = WINDOW ? window : {}; + if (root.JS_SHA256_NO_WINDOW) { + WINDOW = false; + } + var WEB_WORKER = !WINDOW && typeof self === 'object'; + var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; + if (NODE_JS) { + root = global; + } else if (WEB_WORKER) { + root = self; + } + var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; + var AMD = typeof define === 'function' && define.amd; + var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; + var HEX_CHARS = '0123456789abcdef'.split(''); + var EXTRA = [-2147483648, 8388608, 32768, 128]; + var SHIFT = [24, 16, 8, 0]; + var K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ]; + var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; + + var blocks = []; + + if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { + Array.isArray = function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; + } + + if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { + ArrayBuffer.isView = function (obj) { + return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; + }; + } + + var createOutputMethod = function (outputType, is224) { + return function (message) { + return new Sha256(is224, true).update(message)[outputType](); + }; + }; + + var createMethod = function (is224) { + var method = createOutputMethod('hex', is224); + if (NODE_JS) { + method = nodeWrap(method, is224); + } + method.create = function () { + return new Sha256(is224); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(type, is224); + } + return method; + }; + + var nodeWrap = function (method, is224) { + var crypto = eval("require('crypto')"); + var Buffer = eval("require('buffer').Buffer"); + var algorithm = is224 ? 'sha224' : 'sha256'; + var nodeMethod = function (message) { + if (typeof message === 'string') { + return crypto.createHash(algorithm).update(message, 'utf8').digest('hex'); + } else { + if (message === null || message === undefined) { + throw new Error(ERROR); + } else if (message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } + } + if (Array.isArray(message) || ArrayBuffer.isView(message) || + message.constructor === Buffer) { + return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex'); + } else { + return method(message); + } + }; + return nodeMethod; + }; + + var createHmacOutputMethod = function (outputType, is224) { + return function (key, message) { + return new HmacSha256(key, is224, true).update(message)[outputType](); + }; + }; + + var createHmacMethod = function (is224) { + var method = createHmacOutputMethod('hex', is224); + method.create = function (key) { + return new HmacSha256(key, is224); + }; + method.update = function (key, message) { + return method.create(key).update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createHmacOutputMethod(type, is224); + } + return method; + }; + + function Sha256(is224, sharedMemory) { + if (sharedMemory) { + blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + this.blocks = blocks; + } else { + this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + if (is224) { + this.h0 = 0xc1059ed8; + this.h1 = 0x367cd507; + this.h2 = 0x3070dd17; + this.h3 = 0xf70e5939; + this.h4 = 0xffc00b31; + this.h5 = 0x68581511; + this.h6 = 0x64f98fa7; + this.h7 = 0xbefa4fa4; + } else { // 256 + this.h0 = 0x6a09e667; + this.h1 = 0xbb67ae85; + this.h2 = 0x3c6ef372; + this.h3 = 0xa54ff53a; + this.h4 = 0x510e527f; + this.h5 = 0x9b05688c; + this.h6 = 0x1f83d9ab; + this.h7 = 0x5be0cd19; + } + + this.block = this.start = this.bytes = this.hBytes = 0; + this.finalized = this.hashed = false; + this.first = true; + this.is224 = is224; + } + + Sha256.prototype.update = function (message) { + if (this.finalized) { + return; + } + var notString, type = typeof message; + if (type !== 'string') { + if (type === 'object') { + if (message === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } else if (!Array.isArray(message)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + throw new Error(ERROR); + } + } + } else { + throw new Error(ERROR); + } + notString = true; + } + var code, index = 0, i, length = message.length, blocks = this.blocks; + + while (index < length) { + if (this.hashed) { + this.hashed = false; + blocks[0] = this.block; + blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + } + + if (notString) { + for (i = this.start; index < length && i < 64; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index < length && i < 64; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + + this.lastByteIndex = i; + this.bytes += i - this.start; + if (i >= 64) { + this.block = blocks[16]; + this.start = i - 64; + this.hash(); + this.hashed = true; + } else { + this.start = i; + } + } + if (this.bytes > 4294967295) { + this.hBytes += this.bytes / 4294967296 << 0; + this.bytes = this.bytes % 4294967296; + } + return this; + }; + + Sha256.prototype.finalize = function () { + if (this.finalized) { + return; + } + this.finalized = true; + var blocks = this.blocks, i = this.lastByteIndex; + blocks[16] = this.block; + blocks[i >> 2] |= EXTRA[i & 3]; + this.block = blocks[16]; + if (i >= 56) { + if (!this.hashed) { + this.hash(); + } + blocks[0] = this.block; + blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + } + blocks[14] = this.hBytes << 3 | this.bytes >>> 29; + blocks[15] = this.bytes << 3; + this.hash(); + }; + + Sha256.prototype.hash = function () { + var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, + h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; + + for (j = 16; j < 64; ++j) { + // rightrotate + t1 = blocks[j - 15]; + s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); + t1 = blocks[j - 2]; + s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); + blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0; + } + + bc = b & c; + for (j = 0; j < 64; j += 4) { + if (this.first) { + if (this.is224) { + ab = 300032; + t1 = blocks[0] - 1413257819; + h = t1 - 150054599 << 0; + d = t1 + 24177077 << 0; + } else { + ab = 704751109; + t1 = blocks[0] - 210244248; + h = t1 - 1521486534 << 0; + d = t1 + 143694565 << 0; + } + this.first = false; + } else { + s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); + s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); + ab = a & b; + maj = ab ^ (a & c) ^ bc; + ch = (e & f) ^ (~e & g); + t1 = h + s1 + ch + K[j] + blocks[j]; + t2 = s0 + maj; + h = d + t1 << 0; + d = t1 + t2 << 0; + } + s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); + s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); + da = d & a; + maj = da ^ (d & b) ^ ab; + ch = (h & e) ^ (~h & f); + t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; + t2 = s0 + maj; + g = c + t1 << 0; + c = t1 + t2 << 0; + s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); + s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); + cd = c & d; + maj = cd ^ (c & a) ^ da; + ch = (g & h) ^ (~g & e); + t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; + t2 = s0 + maj; + f = b + t1 << 0; + b = t1 + t2 << 0; + s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); + s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); + bc = b & c; + maj = bc ^ (b & d) ^ cd; + ch = (f & g) ^ (~f & h); + t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; + t2 = s0 + maj; + e = a + t1 << 0; + a = t1 + t2 << 0; + } + + this.h0 = this.h0 + a << 0; + this.h1 = this.h1 + b << 0; + this.h2 = this.h2 + c << 0; + this.h3 = this.h3 + d << 0; + this.h4 = this.h4 + e << 0; + this.h5 = this.h5 + f << 0; + this.h6 = this.h6 + g << 0; + this.h7 = this.h7 + h << 0; + }; + + Sha256.prototype.hex = function () { + this.finalize(); + + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, + h6 = this.h6, h7 = this.h7; + + var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] + + HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + + HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + + HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + + HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + + HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + + HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + + HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + + HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + + HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + + HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + + HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + + HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + + HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + + HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + + HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + + HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + + HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + + HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + + HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + + HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + + HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + + HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + + HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + + HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + + HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + + HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + + HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; + if (!this.is224) { + hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] + + HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + + HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + + HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; + } + return hex; + }; + + Sha256.prototype.toString = Sha256.prototype.hex; + + Sha256.prototype.digest = function () { + this.finalize(); + + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, + h6 = this.h6, h7 = this.h7; + + var arr = [ + (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, + (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, + (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, + (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, + (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF, + (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF, + (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF + ]; + if (!this.is224) { + arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF); + } + return arr; + }; + + Sha256.prototype.array = Sha256.prototype.digest; + + Sha256.prototype.arrayBuffer = function () { + this.finalize(); + + var buffer = new ArrayBuffer(this.is224 ? 28 : 32); + var dataView = new DataView(buffer); + dataView.setUint32(0, this.h0); + dataView.setUint32(4, this.h1); + dataView.setUint32(8, this.h2); + dataView.setUint32(12, this.h3); + dataView.setUint32(16, this.h4); + dataView.setUint32(20, this.h5); + dataView.setUint32(24, this.h6); + if (!this.is224) { + dataView.setUint32(28, this.h7); + } + return buffer; + }; + + function HmacSha256(key, is224, sharedMemory) { + var i, type = typeof key; + if (type === 'string') { + var bytes = [], length = key.length, index = 0, code; + for (i = 0; i < length; ++i) { + code = key.charCodeAt(i); + if (code < 0x80) { + bytes[index++] = code; + } else if (code < 0x800) { + bytes[index++] = (0xc0 | (code >> 6)); + bytes[index++] = (0x80 | (code & 0x3f)); + } else if (code < 0xd800 || code >= 0xe000) { + bytes[index++] = (0xe0 | (code >> 12)); + bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); + bytes[index++] = (0x80 | (code & 0x3f)); + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff)); + bytes[index++] = (0xf0 | (code >> 18)); + bytes[index++] = (0x80 | ((code >> 12) & 0x3f)); + bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); + bytes[index++] = (0x80 | (code & 0x3f)); + } + } + key = bytes; + } else { + if (type === 'object') { + if (key === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) { + key = new Uint8Array(key); + } else if (!Array.isArray(key)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) { + throw new Error(ERROR); + } + } + } else { + throw new Error(ERROR); + } + } + + if (key.length > 64) { + key = (new Sha256(is224, true)).update(key).array(); + } + + var oKeyPad = [], iKeyPad = []; + for (i = 0; i < 64; ++i) { + var b = key[i] || 0; + oKeyPad[i] = 0x5c ^ b; + iKeyPad[i] = 0x36 ^ b; + } + + Sha256.call(this, is224, sharedMemory); + + this.update(iKeyPad); + this.oKeyPad = oKeyPad; + this.inner = true; + this.sharedMemory = sharedMemory; + } + HmacSha256.prototype = new Sha256(); + + HmacSha256.prototype.finalize = function () { + Sha256.prototype.finalize.call(this); + if (this.inner) { + this.inner = false; + var innerHash = this.array(); + Sha256.call(this, this.is224, this.sharedMemory); + this.update(this.oKeyPad); + this.update(innerHash); + Sha256.prototype.finalize.call(this); + } + }; + + var exports = createMethod(); + exports.sha256 = exports; + exports.sha224 = createMethod(true); + exports.sha256.hmac = createHmacMethod(); + exports.sha224.hmac = createHmacMethod(true); + + if (COMMON_JS) { + module.exports = exports; + } else { + root.sha256 = exports.sha256; + root.sha224 = exports.sha224; + if (AMD) { + define(function () { + return exports; + }); + } + } +})(); + +function do_something(e){for(var t="",n=e.length-1;n>=0;n--)t+=e[n];return t} + +function token_part_3(t, y="ZZ") { + document.getElementById("token").value=sha256(document.getElementById("token").value+y) +} + +function token_part_2(e="YY") { + document.getElementById("token").value=sha256(e+document.getElementById("token").value) +} + +function token_part_1(a,b) { + document.getElementById("token").value=do_something(document.getElementById("phrase").value) +} + +document.getElementById("phrase").value=""; + +setTimeout(function(){token_part_2("XX")},300); + +document.getElementById("send").addEventListener("click", token_part_3); + +token_part_1("ABCD", 44); diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/impossible.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/impossible.php new file mode 100644 index 000000000..e69de29bb diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/low.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/low.php new file mode 100644 index 000000000..fc5542c9b --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/low.php @@ -0,0 +1,24 @@ + + +/* +MD5 code from here +https://github.com/blueimp/JavaScript-MD5 +*/ + +!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e>5]>>>t%32&255);return r}function d(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(d(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="";for(r=0;r>>4&15)+"0123456789abcdef".charAt(15&t);return e}function v(n){return unescape(encodeURIComponent(n))}function m(n){return h(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); + + function rot13(inp) { + return inp.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);}); + } + + function generate_token() { + var phrase = document.getElementById("phrase").value; + document.getElementById("token").value = md5(rot13(phrase)); + } + + generate_token(); + +EOF; +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.js b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.js new file mode 100644 index 000000000..f6c40a060 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.js @@ -0,0 +1 @@ +function do_something(e){for(var t="",n=e.length-1;n>=0;n--)t+=e[n];return t}setTimeout(function(){do_elsesomething("XX")},300);function do_elsesomething(e){document.getElementById("token").value=do_something(e+document.getElementById("phrase").value+"XX")} diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.php new file mode 100644 index 000000000..a0e707108 --- /dev/null +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/javascript/source/medium.php @@ -0,0 +1,5 @@ + +EOF; +?> diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/upload/help/help.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/upload/help/help.php index c4aee9884..997d947cd 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/upload/help/help.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/upload/help/help.php @@ -34,7 +34,7 @@

    High Level

    Once the file has been received from the client, the server will try to resize any image that was included in the request.

    -
    Spoiler: need to link in another vulnerability, such as file includion.
    +
    Spoiler: need to link in another vulnerability, such as file inclusion.

    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source.php index 090750f65..d0ef28445 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source.php @@ -43,6 +43,9 @@ switch ($id) { case "weak_id" : $vuln = 'Weak Session IDs'; break; + case "javascript" : + $vuln = 'JavaScript'; + break; default: $vuln = "Unknown Vulnerability"; } @@ -50,10 +53,26 @@ switch ($id) { $source = @file_get_contents( DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/{$id}/source/{$security}.php" ); $source = str_replace( array( '$html .=' ), array( 'echo' ), $source ); +$js_html = ""; +if (file_exists (DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/{$id}/source/{$security}.js")) { + $js_source = @file_get_contents( DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/{$id}/source/{$security}.js" ); + $js_html = " +

    vulnerabilities/{$id}/source/{$security}.js

    +
    + + + + +
    " . highlight_string( $js_source, true ) . "
    +
    + "; +} + $page[ 'body' ] .= "

    {$vuln} Source

    +

    vulnerabilities/{$id}/source/{$security}.php

    @@ -61,6 +80,7 @@ $page[ 'body' ] .= "
    + {$js_html}

    diff --git a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source_all.php b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source_all.php index 01d634b12..f1334704d 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source_all.php +++ b/modules/vulnerabilities/unix/web_training/dvwa/files/DVWA-master/vulnerabilities/view_source_all.php @@ -27,6 +27,9 @@ $impsrc = str_replace( array( '$html .=' ), array( 'echo' ), $impsrc); $impsrc = highlight_string( $impsrc, true ); switch ($id) { + case "javascript" : + $vuln = 'JavaScript'; + break; case "fi" : $vuln = 'File Inclusion'; break; diff --git a/modules/vulnerabilities/unix/web_training/dvwa/manifests/apache.pp b/modules/vulnerabilities/unix/web_training/dvwa/manifests/apache.pp index 066b3d7a8..9b7793571 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/manifests/apache.pp +++ b/modules/vulnerabilities/unix/web_training/dvwa/manifests/apache.pp @@ -4,33 +4,52 @@ class dvwa::apache { $db_password = $secgen_parameters['db_password'][0] $docroot = '/var/www/dvwa' - package { ['php5', 'php5-gd', 'php5-mysql']: + if ($operatingsystem == 'Debian') { + package { 'mysql-server': + ensure => installed, + } + case $operatingsystemrelease { + /^9.*/: { # do 9.x stretch stuff + $php_version = "php7.0" + } + /^7.*/: { #do 7.x wheezy stuff + $php_version = "php" + } + } + } else { + # kali + $php_version = "php7.3" + } + + package { ['php', 'php-mysqli', 'php-gd', 'libapache2-mod-php']: ensure => installed, } class { '::apache': default_vhost => false, - default_mods => 'php', + default_mods => $php_version, overwrite_ports => false, + mpm_module => 'prefork', } ::apache::vhost { 'dvwa': port => $port, docroot => $docroot, + + } + + mysql::db { 'dvwa_database': + user => 'dvwa_user', + password => $db_password, + host => 'localhost', + grant => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP'], } - -# mysql::db { 'dvwa_database': -# user => 'dvwa_user', -# password => $db_password, -# host => 'localhost', -# grant => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP'], -# } mysql_user{ 'dvwa_user@localhost': ensure => present, password_hash => mysql_password($db_password) } - + mysql_grant{'dvwa_user@localhost/dvwa_database.*': user => 'dvwa_user@localhost', table => 'dvwa_database.*', diff --git a/modules/vulnerabilities/unix/web_training/dvwa/secgen_metadata.xml b/modules/vulnerabilities/unix/web_training/dvwa/secgen_metadata.xml index eefe84168..ef192cfdb 100644 --- a/modules/vulnerabilities/unix/web_training/dvwa/secgen_metadata.xml +++ b/modules/vulnerabilities/unix/web_training/dvwa/secgen_metadata.xml @@ -15,11 +15,11 @@ port db_password - + 80 - + @@ -30,12 +30,12 @@ GPLv3 - + + .*/apache.* diff --git a/scenarios/examples/vulnerability_examples/dvwa.xml b/scenarios/examples/vulnerability_examples/dvwa.xml index 16b3cfc65..a68dba0e7 100644 --- a/scenarios/examples/vulnerability_examples/dvwa.xml +++ b/scenarios/examples/vulnerability_examples/dvwa.xml @@ -5,12 +5,29 @@ xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario"> - dvwa - + dvwa_stretch + + + dvwa_wheezy + + + + + + + + + dvwa_kali + + + + + + diff --git a/scenarios/labs/ads_1_authentication.xml b/scenarios/labs/ads_1_authentication.xml new file mode 100644 index 000000000..99ec73ab5 --- /dev/null +++ b/scenarios/labs/ads_1_authentication.xml @@ -0,0 +1,350 @@ + + + + + Authentication lab + Z. Cliffe Schreuders + A Hackerbot lab. Work through the labsheet, then when prompted interact with Hackerbot. Topics covered: Protecting integrity with file attributes; Protecting integrity with read-only filesystems. + + ctf-lab + hackerbot-lab + lab-sheet + intermediate + + + desktop + + + + + 172.16.0.2 + + 172.16.0.3 + + 172.16.0.4 + + 172.16.0.5 + + + + + + + + mythical_creatures + + + + + + mythical_creatures + + + + + mythical_creatures + + + + + mythical_creatures + + + + + mythical_creatures + + + + + + + + + + + + + + + + + + usernames + + + tiaspbiqe2r + + + true + + + + + + usernames + + + weak_passwords + + + + + usernames + + + weak_passwords + + + + + usernames + + + weak_passwords + + + + + usernames + + + weak_passwords + + + + + + + + + + + + user_accounts_desktop + + + + + + usernames + + + user_accounts_desktop + + + true + + + + + + + + user_accounts_desktop + + + true + + + IP_addresses + + + + + + IP_addresses + + + user_accounts_desktop + + + + + + desktop_root_password + + + + + + IP_addresses + + + + + + server + + + + + + + + usernames + + + tiaspbiqe2r + + + false + + + + + + usernames + + + weak_passwords + + + flag + + + + + + + + usernames + + + weak_passwords + + + flag + + + + + + + + usernames + + + weak_passwords + + + flag + + + + + + + + usernames + + + weak_passwords + + + flag + + + + + + + + + + + user_accounts_server + + + + + + + + desktop_root_password + + + + + + IP_addresses + + + + + + hackerbot_server + + + + + + + + + + + + + + + user_accounts_desktop + + + desktop_root_password + + + IP_addresses + + + + + + + + IP_addresses + + + + + + + + + + + + kali_cracker + + + + {"username":"root","password":"toor","super_user":"","strings_to_leak":[],"leaked_filenames":[]} + + + + + + + + + + kali_root_account + + + true + + + IP_addresses + + + + + + IP_addresses + + + + + diff --git a/scenarios/labs/websec_lab_env.xml b/scenarios/labs/websec_lab_env.xml new file mode 100644 index 000000000..6c2a19d39 --- /dev/null +++ b/scenarios/labs/websec_lab_env.xml @@ -0,0 +1,53 @@ + + + + + Web security lab environment + Z. Cliffe Schreuders + An environment for web security labs. Debian Stretch desktop with Damn Vulnerable Web App server, and Kali Linux. + + lab-environment + + + kali + + + + 172.16.0.2 + 172.16.0.3 + 172.16.0.4 + + + + {"username":"root","password":"toor","super_user":"","strings_to_leak":[],"leaked_filenames":[]} + + + + + + + + + + kali_root_account + + + true + + + IP_addresses + + + + + + + + IP_addresses + + + + + From 527c52eadb2098dd5c4bf2b900df17c867a77921 Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 14 Feb 2019 15:01:04 +0000 Subject: [PATCH 36/47] Basic Narrative on Stretch --- scenarios/ctf/basic_narrative.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenarios/ctf/basic_narrative.xml b/scenarios/ctf/basic_narrative.xml index 5d44ed5e6..179bf3bdd 100644 --- a/scenarios/ctf/basic_narrative.xml +++ b/scenarios/ctf/basic_narrative.xml @@ -16,7 +16,7 @@ target_server - + 172.10.0.2 From a280b45d23fb15a973f3770f5c9f9df789b1a93a Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 14 Feb 2019 15:27:52 +0000 Subject: [PATCH 37/47] Move post-provision tests outside the success block --- secgen.rb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/secgen.rb b/secgen.rb index 68e94e413..a249a89a6 100644 --- a/secgen.rb +++ b/secgen.rb @@ -118,16 +118,13 @@ def build_vms(scenario, project_dir, options) while retry_count >= 0 and !successful_creation vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") - if vagrant_output[:status] == 0 - reboot_cycle(project_dir) - if post_provision_tests(project_dir) - Print.info 'VMs created.' - successful_creation = true - if options[:shutdown] or OVirtFunctions::provider_ovirt?(options) - Print.info 'Shutting down VMs.' - sleep(30) - GemExec.exe('vagrant', project_dir, 'halt') - end + if vagrant_output[:status] == 0 and post_provision_tests(project_dir) + Print.info 'VMs created.' + successful_creation = true + if options[:shutdown] or OVirtFunctions::provider_ovirt?(options) + Print.info 'Shutting down VMs.' + sleep(30) + GemExec.exe('vagrant', project_dir, 'halt') end else if retry_count > 0 @@ -343,6 +340,7 @@ def reboot_cycle(project_dir) end def post_provision_tests(project_dir) + reboot_cycle(project_dir) Print.info 'Running post-provision tests...' tests_passed = true From a1c7ad10ede25ec1051f15dfe66f79d91fcac917 Mon Sep 17 00:00:00 2001 From: ts Date: Thu, 14 Feb 2019 16:08:33 +0000 Subject: [PATCH 38/47] remove kali top 10 for now --- Gemfile | 1 + Gemfile.lock | 3 ++- scenarios/ctf/basic_narrative.xml | 1 - scenarios/tests/test_scenario.xml | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 455954052..2fdcc1b75 100644 --- a/Gemfile +++ b/Gemfile @@ -34,6 +34,7 @@ gem 'rsa' gem 'gpgmeh' gem 'digest-sha3', :git => "http://github.com/izetex/digest-sha3-ruby" gem 'net-ntp' +gem 'CFPropertyList' #development only gems go here group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index e9a7c27b4..8b46ab9cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -147,6 +147,7 @@ PLATFORMS ruby DEPENDENCIES + CFPropertyList bases bcrypt braille! @@ -187,4 +188,4 @@ DEPENDENCIES zipruby BUNDLED WITH - 1.11.2 + 2.0.0.pre.2 diff --git a/scenarios/ctf/basic_narrative.xml b/scenarios/ctf/basic_narrative.xml index 179bf3bdd..e5de533c4 100644 --- a/scenarios/ctf/basic_narrative.xml +++ b/scenarios/ctf/basic_narrative.xml @@ -453,7 +453,6 @@ attack_vm - diff --git a/scenarios/tests/test_scenario.xml b/scenarios/tests/test_scenario.xml index 4b5bd5335..c68efee2c 100644 --- a/scenarios/tests/test_scenario.xml +++ b/scenarios/tests/test_scenario.xml @@ -7,7 +7,8 @@ testing - + + 172.16.0.14 From 8fb529da4925fd8f4a5e237f3ceb5ea2c647b702 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 16:51:02 +0000 Subject: [PATCH 39/47] (WiP) apt-upgrade: exclude puppet to prevent break at provision time --- scenarios/tests/test_scenario_apt_upgrade.xml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 scenarios/tests/test_scenario_apt_upgrade.xml diff --git a/scenarios/tests/test_scenario_apt_upgrade.xml b/scenarios/tests/test_scenario_apt_upgrade.xml new file mode 100644 index 000000000..208a0436e --- /dev/null +++ b/scenarios/tests/test_scenario_apt_upgrade.xml @@ -0,0 +1,34 @@ + + + + + Basic Narrative + Thomas Shaw + Single system narrative-based CTF challenge. + + + ctf + attack-ctf + web-hints + intermediate + + + target_server + + + + 172.12.0.2 + + + + + + + IP_addresses + + + + + From 47217d26e4966b06fa4a88d48a359c408ca3a9b3 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 17:19:30 +0000 Subject: [PATCH 40/47] onlinestore/secgen_tests: added check for populated db --- .../unix/webapp/onlinestore/secgen_test/onlinestore.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb b/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb index d20a08982..aea0a06a0 100644 --- a/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb +++ b/modules/vulnerabilities/unix/webapp/onlinestore/secgen_test/onlinestore.rb @@ -11,6 +11,7 @@ class OnlineStoreTest < PostProvisionTest super test_service_up test_html_returned_content('/index.php', 'Welcome to furniture!') + test_local_command('Users table populated?',"mysql -u csecvm --password=#{json_inputs['db_password'][0]} -D csecvm -e \"SELECT * FROM users;\"", JSON.parse(json_inputs['accounts'][1])['name']) end end From 9293aba51ffb0aebc5a37280c19bbf9bd1ca9d28 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 17:25:26 +0000 Subject: [PATCH 41/47] utilities/apt_upgrade: hold puppet-agent to prevent breaking on oVirt --- modules/utilities/unix/update/apt_upgrade/manifests/apt.pp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp index 281d9a353..e1417a85e 100644 --- a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp +++ b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp @@ -7,12 +7,17 @@ class apt_upgrade::apt { } else { case $operatingsystem { 'Debian': { + # can't upgrade puppet agent mid-provision or it breaks on oVirt. + exec { 'hold puppet-agent': + command => '/usr/bin/apt hold puppet-agent' + } exec { 'update': command => "/usr/bin/apt-get -y upgrade", tries => 5, try_sleep => 30, timeout => 0, logoutput => true, + require => Exec['hold puppet agent'], } } 'Ubuntu': { From b8865affb64faea7e9f0f099ea8b4abf6572ba7a Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 17:26:56 +0000 Subject: [PATCH 42/47] slight modification/fix for apt-upgrade --- modules/utilities/unix/update/apt_upgrade/manifests/apt.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp index e1417a85e..949602f41 100644 --- a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp +++ b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp @@ -9,7 +9,7 @@ class apt_upgrade::apt { 'Debian': { # can't upgrade puppet agent mid-provision or it breaks on oVirt. exec { 'hold puppet-agent': - command => '/usr/bin/apt hold puppet-agent' + command => '/usr/bin/apt-mark hold puppet-agent' } exec { 'update': command => "/usr/bin/apt-get -y upgrade", From 31a006f8c01496f452b9109ae6ad91b082a4e228 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 17:31:59 +0000 Subject: [PATCH 43/47] irc2 conflict with debian strech, not all stretch modules --- modules/services/unix/irc/irc2/secgen_metadata.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/unix/irc/irc2/secgen_metadata.xml b/modules/services/unix/irc/irc2/secgen_metadata.xml index a1900e1e6..f47a35173 100644 --- a/modules/services/unix/irc/irc2/secgen_metadata.xml +++ b/modules/services/unix/irc/irc2/secgen_metadata.xml @@ -20,7 +20,7 @@ ircd - .*Stretch.* + .*Debian.*Stretch.* update From c5cba350b4ecd0a20132572f99703e26d014f30a Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 17:41:46 +0000 Subject: [PATCH 44/47] missing hyphen in require --- modules/utilities/unix/update/apt_upgrade/manifests/apt.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp index 949602f41..3b406bb74 100644 --- a/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp +++ b/modules/utilities/unix/update/apt_upgrade/manifests/apt.pp @@ -17,7 +17,7 @@ class apt_upgrade::apt { try_sleep => 30, timeout => 0, logoutput => true, - require => Exec['hold puppet agent'], + require => Exec['hold puppet-agent'], } } 'Ubuntu': { From 930c0562344c6d999ced6c6aa65899c67fd03bf0 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 17:58:09 +0000 Subject: [PATCH 45/47] apache_stretch_compatible: now works with 2 vhosts like wheezy, enables stretch base for on basic_narrative.xml --- .../apache/manifests/init.pp | 30 ++++++----- .../apache/manifests/listen.pp | 26 ++++++++-- .../apache/manifests/mpm.pp | 51 ++++++++++--------- .../apache/manifests/namevirtualhost.pp | 32 ++++++++++-- .../apache/manifests/vhost.pp | 4 +- .../parameterised_website/manifests/apache.pp | 6 ++- .../webapp/onlinestore/manifests/apache.pp | 3 ++ 7 files changed, 102 insertions(+), 50 deletions(-) diff --git a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/init.pp b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/init.pp index e6349988c..1a6e6665d 100755 --- a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/init.pp +++ b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/init.pp @@ -34,7 +34,7 @@ class apache ( Boolean $service_manage = true, $service_ensure = 'running', $service_restart = undef, - $purge_configs = true, + $purge_configs = false, $purge_vhost_dir = undef, $purge_vdir = false, $serveradmin = 'root@localhost', @@ -90,7 +90,7 @@ class apache ( $error_log = $::apache::params::error_log, $scriptalias = $::apache::params::scriptalias, $access_log_file = $::apache::params::access_log_file, - $overwrite_ports = false, # TODO: Implement this as in wheezy apache + $overwrite_ports = true, # TODO: Implement this as in wheezy apache ) inherits ::apache::params { $valid_mpms_re = $apache_version ? { @@ -256,17 +256,19 @@ class apache ( $vhost_load_dir = $vhost_dir } - concat { $ports_file: - ensure => present, - owner => 'root', - group => $::apache::params::root_group, - mode => $::apache::file_mode, - notify => Class['Apache::Service'], - require => Package['httpd'], - } - concat::fragment { 'Apache ports header': - target => $ports_file, - content => template('apache/ports_header.erb'), + if $overwrite_ports { + concat { $ports_file: + ensure => present, + owner => 'root', + group => $::apache::params::root_group, + mode => $::apache::file_mode, + notify => Class['Apache::Service'], + require => Package['httpd'], + } + concat::fragment { 'Apache ports header': + target => $ports_file, + content => template('apache/ports_header.erb'), + } } if $::apache::conf_dir and $::apache::params::conf_file { @@ -332,7 +334,7 @@ class apache ( ensure => file, content => template($conf_template), notify => Class['Apache::Service'], - require => [Package['httpd'], Concat[$ports_file]], + require => [Package['httpd']], } # preserve back-wards compatibility to the times when default_mods was diff --git a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/listen.pp b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/listen.pp index 503ee8860..9730d3c75 100644 --- a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/listen.pp +++ b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/listen.pp @@ -1,9 +1,25 @@ -define apache::listen { +define apache::listen ($port='') { $listen_addr_port = $name - # Template uses: $listen_addr_port - concat::fragment { "Listen ${listen_addr_port}": - target => $::apache::ports_file, - content => template('apache/listen.erb'), + if defined(Concat[$::apache::ports_file]){ + # Template uses: $listen_addr_port + concat::fragment { "Listen ${listen_addr_port}": + target => $::apache::ports_file, + content => template('apache/listen.erb'), + } + } elsif $port != '80' { + # Create a temporary file + # join with cat $tmp_file >> $file + # remove tmp files + $ports_file = $::apache::ports_file + $tmp_file = "$ports_file-tmp_listen" + file { $tmp_file: + ensure => file, + content => template('apache/listen.erb'), + } + + exec { "apache::listen: cat $tmp_file with ports.conf": + command => "/bin/cat $tmp_file >> $ports_file;/bin/rm $tmp_file" + } } } diff --git a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/mpm.pp b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/mpm.pp index 119fedf57..ca342f3f0 100644 --- a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/mpm.pp +++ b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/mpm.pp @@ -29,20 +29,20 @@ define apache::mpm ( } } } else { - if versioncmp($apache_version, '2.4') >= 0 { - file { "${mod_dir}/${mpm}.load": - ensure => file, - path => "${mod_dir}/${mpm}.load", - content => "LoadModule ${_id} ${_path}\n", - require => [ - Package['httpd'], - Exec["mkdir ${mod_dir}"], - ], - before => File[$mod_dir], - notify => Class['apache::service'], - } + if versioncmp($apache_version, '2.4') >= 0 { + file { "${mod_dir}/${mpm}.load": + ensure => file, + path => "${mod_dir}/${mpm}.load", + content => "LoadModule ${_id} ${_path}\n", + require => [ + Package['httpd'], + Exec["mkdir ${mod_dir}"], + ], + before => File[$mod_dir], + notify => Class['apache::service'], } } + } case $::osfamily { 'debian': { @@ -73,22 +73,27 @@ define apache::mpm ( } } - if $mpm == 'itk' and $::operatingsystem == 'Ubuntu' and $::operatingsystemrelease == '14.04' { - # workaround https://bugs.launchpad.net/ubuntu/+source/mpm-itk/+bug/1286882 - exec { - '/usr/sbin/a2dismod mpm_event': - onlyif => '/usr/bin/test -e /etc/apache2/mods-enabled/mpm_event.load', - require => Package['httpd'], - before => Package['apache2-mpm-itk'], - } - } - - if $mpm == 'itk' and $::operatingsystem == 'Ubuntu' and $::operatingsystemrelease == '16.04' { + if $mpm == 'itk' and ( ( $::operatingsystem == 'Ubuntu' and $::operatingsystemrelease == '16.04' ) or ( $::operatingsystem == 'Debian' and versioncmp($::operatingsystemrelease, '9.0.0') >= 0 ) ) { $packagename = 'libapache2-mpm-itk' } else { $packagename = "apache2-mpm-${mpm}" } + $mod_enabled_dir = $::apache::mod_enable_dir + + if $mpm == 'prefork' and ( $::operatingsystem == 'Debian' and versioncmp($::operatingsystemrelease, '9.0.0') >= 0 ) { + exec { '/usr/sbin/a2dismod mpm_event': + onlyif => "/usr/bin/test -e ${mod_enabled_dir}/mpm_event.load", + } + } + + if $mpm == 'itk' and ( ( $::operatingsystem == 'Ubuntu' and $::operatingsystemrelease == '14.04' ) or ($::operatingsystem == 'Debian' and versioncmp($::operatingsystemrelease, '9.0.0') >= 0 ) ) { + # workaround https://bugs.launchpad.net/ubuntu/+source/mpm-itk/+bug/1286882 + exec { '/usr/sbin/a2dismod mpm_event': + onlyif => "/usr/bin/test -e ${mod_enabled_dir}/mpm_event.load", + } + } + if versioncmp($apache_version, '2.4') < 0 or $mpm == 'itk' { package { $packagename: ensure => present, diff --git a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/namevirtualhost.pp b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/namevirtualhost.pp index 4fa879518..d89cb0c5b 100644 --- a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/namevirtualhost.pp +++ b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/namevirtualhost.pp @@ -1,9 +1,31 @@ -define apache::namevirtualhost { +define apache::namevirtualhost ($port=''){ $addr_port = $name - # Template uses: $addr_port - concat::fragment { "NameVirtualHost ${addr_port}": - target => $::apache::ports_file, - content => template('apache/namevirtualhost.erb'), + if defined(Concat[$::apache::ports_file]){ + # Template uses: $addr_port + concat::fragment { "NameVirtualHost ${addr_port}": + target => $::apache::ports_file, + content => template('apache/namevirtualhost.erb'), + } + } elsif $port != '80' { # if a second vhost is declared off port 80 + # Create a temporary file + # join with cat $tmp_file >> $file + # remove tmp files + $ports_file = $::apache::ports_file + $tmp_file = "$ports_file-tmp_nvh" + file { $tmp_file: + ensure => file, + content => template('apache/namevirtualhost.erb'), + } + + exec { "apache::listen: cat $tmp_file with ports.conf": + command => "/bin/cat $tmp_file >> $ports_file;/bin/rm $tmp_file", + require => File[$tmp_file] + } + + } else { # if a second vhost is declared on port 80 + tidy { 'remove apache default site': + path =>'/etc/apache2/sites-enabled/000-default', + } } } diff --git a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/vhost.pp b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/vhost.pp index 0d58fa8a9..90912e92b 100644 --- a/modules/services/unix/http/apache_stretch_compatible/apache/manifests/vhost.pp +++ b/modules/services/unix/http/apache_stretch_compatible/apache/manifests/vhost.pp @@ -396,12 +396,12 @@ define apache::vhost( fail("Apache::Vhost[${name}]: Mixing IP and non-IP Listen directives is not possible; check the add_listen parameter of the apache::vhost define to disable this") } if $listen_addr_port and $ensure == 'present' { - ensure_resource('apache::listen', $listen_addr_port) + ensure_resource('apache::listen', $listen_addr_port, {'port'=> $port}) } } if ! $ip_based { if $ensure == 'present' and (versioncmp($apache_version, '2.4') < 0) { - ensure_resource('apache::namevirtualhost', $nvh_addr_port) + ensure_resource('::apache::namevirtualhost', $nvh_addr_port, {'port' => $port}) } } diff --git a/modules/services/unix/http/parameterised_website/manifests/apache.pp b/modules/services/unix/http/parameterised_website/manifests/apache.pp index 3235c139d..e5df7f40d 100644 --- a/modules/services/unix/http/parameterised_website/manifests/apache.pp +++ b/modules/services/unix/http/parameterised_website/manifests/apache.pp @@ -5,10 +5,14 @@ class parameterised_website::apache { class { '::apache': default_vhost => false, overwrite_ports => false, + mpm_module => 'prefork', } - apache::vhost { 'vhost.test.com': + apache::vhost { 'parameterised.website': port => $port, docroot => '/var/www/parameterised_website', + notify => Tidy['pws remove default site'], } + + ensure_resource('tidy','pws remove default site', {'path'=>'/etc/apache2/sites-enabled/000-default.conf'}) } \ No newline at end of file diff --git a/modules/vulnerabilities/unix/webapp/onlinestore/manifests/apache.pp b/modules/vulnerabilities/unix/webapp/onlinestore/manifests/apache.pp index 66137d77d..30389c6e7 100644 --- a/modules/vulnerabilities/unix/webapp/onlinestore/manifests/apache.pp +++ b/modules/vulnerabilities/unix/webapp/onlinestore/manifests/apache.pp @@ -12,8 +12,11 @@ class onlinestore::apache { ::apache::vhost { 'onlinestore': port => $port, docroot => $docroot, + notify => Tidy['os remove default site'], } + ensure_resource('tidy','os remove default site', {'path'=>'/etc/apache2/sites-enabled/000-default.conf'}) + case $operatingsystemrelease { /^9.*/: { # do 9.x stretch stuff exec { 'a2enmod php5.6': From df77d931f3002a88dba521dce5c414cf626c012e Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 18:00:26 +0000 Subject: [PATCH 46/47] reintroduce dirtycow as the apt-upgrade module works on oVirt with the puppet-agent package held --- .../unix/local/dirtycow/dirtycow.pp | 1 + .../unix/local/dirtycow/manifests/config.pp | 3 ++ .../unix/local/dirtycow/secgen_metadata.xml | 33 +++++++++++++++++++ .../local/dirtycow/secgen_test/dirtycow.rb | 17 ++++++++++ 4 files changed, 54 insertions(+) create mode 100644 modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp create mode 100644 modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp create mode 100644 modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml create mode 100644 modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb diff --git a/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp b/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp new file mode 100644 index 000000000..f86b5785e --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/dirtycow.pp @@ -0,0 +1 @@ +include dirtycow::config \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp b/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp new file mode 100644 index 000000000..5a22e775d --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/manifests/config.pp @@ -0,0 +1,3 @@ +class dirtycow::config { + notice("dirtycow::config: Do nothing, the apt upgrade just checks if we're defined and blocks apt-get upgrade if so.") +} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml b/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml new file mode 100644 index 000000000..90d6aaac1 --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/secgen_metadata.xml @@ -0,0 +1,33 @@ + + + + DirtyCow privilege escalation + Thomas Shaw + MIT + DirtyCow local privilege escalation. Including this module prevents the default apt-get upgrade from + running which leaves the wheezy bases vulnerable. + + + unpatched_kernel + race_condition + root_rwx + local + linux + medium + + + .*Stretch.* + + + .*Kali.* + + + .*Windows.* + + + .*Ubuntu.* + + + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb b/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb new file mode 100644 index 000000000..1433b43a4 --- /dev/null +++ b/modules/vulnerabilities/unix/local/dirtycow/secgen_test/dirtycow.rb @@ -0,0 +1,17 @@ +require_relative '../../../../../lib/post_provision_test' + +class DirtyCOWTest < PostProvisionTest + def initialize + self.module_name = 'dirtycow' + self.module_path = get_module_path(__FILE__) + super + end + + def test_module + super + test_local_command('apt-get upgrade not performed?', 'sudo apt-get -u upgrade --assume-no','linux-image-3.') + end + +end + +DirtyCOWTest.new.run \ No newline at end of file From 2f4703b19990137a0ceb6b04ca67f057679e9301 Mon Sep 17 00:00:00 2001 From: ts Date: Fri, 15 Feb 2019 18:01:30 +0000 Subject: [PATCH 47/47] --no-test flag --- lib/batch/batch_secgen.rb | 4 ++-- secgen.rb | 45 ++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/lib/batch/batch_secgen.rb b/lib/batch/batch_secgen.rb index 461173043..9766c7157 100644 --- a/lib/batch/batch_secgen.rb +++ b/lib/batch/batch_secgen.rb @@ -304,8 +304,8 @@ end # Database interactions def insert_row(db_conn, prepared_statements, statement_id, secgen_args) statement = "insert_row_#{statement_id}" - # Add --shutdown and strip trailing whitespace - secgen_args = '--shutdown ' + secgen_args.strip + # Add --shutdown and --no-tests and strip trailing whitespace + secgen_args = '--shutdown --no-tests ' + secgen_args.strip Print.info "Adding to queue: '#{statement}' '#{secgen_args}' 'todo'" unless prepared_statements.include? statement db_conn.prepare(statement, 'insert into queue (secgen_args, status) values ($1, $2) returning id') diff --git a/secgen.rb b/secgen.rb index a249a89a6..72996719b 100644 --- a/secgen.rb +++ b/secgen.rb @@ -31,6 +31,7 @@ def usage --help, -h: Shows this usage information --system, -y [system_name]: Only build this system_name from the scenario --snapshot: Creates a snapshot of VMs once built + --no-tests: Prevent post-provisioning tests from running. VIRTUALBOX OPTIONS: --gui-output, -g: Show the running VM (not headless) @@ -118,7 +119,7 @@ def build_vms(scenario, project_dir, options) while retry_count >= 0 and !successful_creation vagrant_output = GemExec.exe('vagrant', project_dir, "#{command} #{system}") - if vagrant_output[:status] == 0 and post_provision_tests(project_dir) + if vagrant_output[:status] == 0 and post_provision_tests(project_dir, options) Print.info 'VMs created.' successful_creation = true if options[:shutdown] or OVirtFunctions::provider_ovirt?(options) @@ -339,25 +340,27 @@ def reboot_cycle(project_dir) sleep 45 end -def post_provision_tests(project_dir) - reboot_cycle(project_dir) - Print.info 'Running post-provision tests...' - +def post_provision_tests(project_dir, options) tests_passed = true - test_module_outputs = [] - test_script_paths = Dir.glob("#{project_dir}/puppet/*/modules/*/secgen_test/*.rb") - test_script_paths.each do |test_file_path| - test_stdout, test_stderr, test_status = Open3.capture3("bundle exec ruby #{test_file_path}") - test_module_outputs << {:stdout => test_stdout.split("\n"), :stderr => test_stderr, :exit_status => test_status} - end - test_module_outputs.each do |test_output| - if test_output[:exit_status].exitstatus != 0 - tests_passed = false - Print.err test_output[:stdout].join("\n") - Print.err "Post provision tests contained failures!" - Print.err test_output[:stderr] - else - Print.info test_output[:stdout].join("\n") + unless options[:notests] + reboot_cycle(project_dir) + Print.info 'Running post-provision tests...' + + test_module_outputs = [] + test_script_paths = Dir.glob("#{project_dir}/puppet/*/modules/*/secgen_test/*.rb") + test_script_paths.each do |test_file_path| + test_stdout, test_stderr, test_status = Open3.capture3("bundle exec ruby #{test_file_path}") + test_module_outputs << {:stdout => test_stdout.split("\n"), :stderr => test_stderr, :exit_status => test_status} + end + test_module_outputs.each do |test_output| + if test_output[:exit_status].exitstatus != 0 + tests_passed = false + Print.err test_output[:stdout].join("\n") + Print.err "Post provision tests contained failures!" + Print.err test_output[:stderr] + else + Print.info test_output[:stdout].join("\n") + end end end tests_passed @@ -411,6 +414,7 @@ opts = GetoptLong.new( ['--ovirt-network', GetoptLong::REQUIRED_ARGUMENT], ['--ovirt-affinity-group', GetoptLong::REQUIRED_ARGUMENT], ['--snapshot', GetoptLong::NO_ARGUMENT], + ['--no-tests', GetoptLong::NO_ARGUMENT], ) scenario = SCENARIO_XML @@ -479,6 +483,9 @@ opts.each do |opt, arg| when '--forensic-image-type' Print.info "Image output type set to #{arg}" options[:forensic_image_type] = arg + when '--no-tests' + Print.info "Not running post-provision tests" + options[:notests] = true when '--ovirtuser' Print.info "Ovirt Username : #{arg}"