Top Level Namespace
Defined Under Namespace
Modules: NoradCli, SeedGenerator, TestServer Classes: ApplicationController, ApplicationRecord, BaseMachine, CreateResults, Manifest, Readme, Repo, Result, ResultsController, ResultsServer, Sectest
Constant Summary collapse
- AssessmentHelpers =
Module.new do MAX_SLEEP_TIME = 30 SLEEP_INTERVAL = 3 define_method :get_scans do %w(vulnerable secure) end define_method :assessment_name do name.split(/(?=[A-Z])|(?<=[a-z])(\d+)/).map { |e| e.downcase }.join('-') end define_method :manifest_file do assessment_path = @parent.nil? ? assessment_name : "#{@parent}/variants/#{assessment_name}" "./sectests/#{assessment_path}/manifest.yml" end define_method :options do @options ||= YAML.load(File.read(manifest_file)) end define_method :image_name do "#{['registry']}/#{['name']}:#{['version']}" end define_method :config_hash do return default_test_config if respond_to?(:default_test_config) ['default_config'].each_with_object({}) do |(k, v), h| h[k.to_sym] = v end end define_method :args do |target| ssh_vals = ['prog_args']['ssh_key'] ? load_ssh_args : {} format(['prog_args'], config_hash.merge({target: target}).merge(ssh_vals)).split(' ') end define_method :load_ssh_args do { ssh_user: 'testuser', ssh_key: Base64.strict_encode64(File.read(NoradCli.ssh_key_path)) } end define_method :machine_ready? do |machine, image_name| if @verify_machine_ready config_status = machine.exec(['cat', '/tmp/status']).to_s unless config_status.match(/ready_to_test/) puts "machine:#{image_name} not ready_to_test current status:#{config_status}" return false end end true end define_method :machine_running? do |machine, image_name| if !machine.json['State']['Running'] puts "Target machine: #{image_name} failed to start." return false end true end define_method :start_target_machine do |image_name| elapsed_time = 0 target = image_name.split('-')[-1].to_sym h_config = nil h_config = @host_config[target] if @host_config machine = Docker::Container.create(Image: image_name, HostConfig: h_config ) machine.start sleep SLEEP_INTERVAL until (machine_running?(machine, image_name) && machine_ready?(machine, image_name)) || elapsed_time > MAX_SLEEP_TIME sleep SLEEP_INTERVAL # sleep rather than wait since we are daemonizing a container elapsed_time += SLEEP_INTERVAL end machine end define_method :log_machine_not_running do |machine, image_name| puts '*' * 80 puts "* target docker container for #{image_name} not running" puts '*' * 80 pp machine.json puts "******************** logs #{image_name} *****************************" machine.streaming_logs(stdout: true, stderr: true) { |stream, chunk| puts "#{stream}: #{chunk}" } end define_method :stop_target_machine do |machine| machine.stop # Do not delete targets if debugging enabled if !ENV['ENABLE_NORAD_DEBUG'] machine.delete(force: true) end machine.id end define_method :scan_machine do |type| image_name = "#{assessment_name}-#{type}" machine = start_target_machine(image_name) target_name = type target_name = @target_host if @target_host scan(target_name, machine.id) if machine_running?(machine, image_name) && machine_ready?(machine, image_name) log_machine_not_running(machine, image_name) unless machine_running?(machine, image_name) stop_target_machine(machine) end define_method :scan_base do assessment_id = scan('base', base_machine.container.id) assessment_id end define_method :scan do |target, target_id| assessment_id = target == 'base' ? SecureRandom.hex(32) : target_id env = [ "NORAD_ROOT=http://results:3000", %Q{ASSESSMENT_PATHS=[{"id":"#{target}", "assessment": "/results/#{assessment_id}"}]}, "NORAD_SECRET=1234" ] c = Docker::Container.create({ Image: image_name, Cmd: args(target), Env: env, HostConfig: { Links: ["#{target_id}:#{target}", "#{results_server.container.id}:results"] }, }) c.start c.wait(60 * 10) # Output container logs for debugging if ENV['ENABLE_LOGS'] c.stop c_state = c.json['State'] # Print the entire state regardless of error or not to aid in debugging puts "[DEBUG] Container #{image_name}'s Final State" puts '-------------------------' c_state.each do |key, value| puts "#{key}: #{value}" end puts "\n[DEBUG] Logs for target \"#{image_name}\" run against #{target}:" # Print logs regardless of ExitCode puts c.logs(stdout: true, stderr: true) end c.delete(force: true) assessment_id end define_method :retrieve_results do |id| url = "http://localhost:#{results_server.host_port}/results?assessment_id=#{id}" uri = URI(url) JSON.parse(Net::HTTP.get(uri)) end end