From 17ed03a3274ebce23828e4223eef4bc11511d2b4 Mon Sep 17 00:00:00 2001 From: ts Date: Sat, 2 Feb 2019 17:22:50 +0000 Subject: [PATCH] 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