mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-21 11:18:06 +00:00
(WiP) Created proftpd_133c_backdoor testing script - Needs testing!
This commit is contained in:
91
lib/objects/post_provision_test.rb
Normal file
91
lib/objects/post_provision_test.rb
Normal file
@@ -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
|
||||
@@ -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}"
|
||||
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
@@ -4,8 +4,10 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario">
|
||||
<system>
|
||||
<system_name>empty_stretch</system_name>
|
||||
<base platform="linux" distro="Debian 9" type="server"/>
|
||||
<system_name>proftpd_testing</system_name>
|
||||
<base platform="linux" distro="Debian 7.8" type="server"/>
|
||||
|
||||
<vulnerability module_path=".*proftpd_133c_backdoor"/>
|
||||
|
||||
<input into_datastore="IP_addresses">
|
||||
<value>172.16.0.5</value>
|
||||
|
||||
28
secgen.rb
28
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user