class Aquatone::Commands::Gather
Public Instance Methods
execute!()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 4 def execute! if !options[:domain] output("Please specify a domain to assess\n") exit 1 end @assessment = Aquatone::Assessment.new(options[:domain]) banner("Gather") check_prerequisites prepare_tasks make_directories process_pages generate_report end
Private Instance Methods
check_prerequisites()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 22 def check_prerequisites if !has_executable?("node") output(red("node executable not found!\n\n")) output("Please make sure Node.js is installed on your system.\n") exit 1 end if !has_executable?("npm") output(red("npm executable not found!\n\n")) output("Please make sure NPM package manager is installed on your system.\n") exit 1 end if !Dir.exists?(File.join(Aquatone::AQUATONE_ROOT, "node_modules")) output("Installing Nightmare.js package, please wait...") Dir.chdir(Aquatone::AQUATONE_ROOT) do if system("npm install nightmare >/dev/null 2>&1") output(" Done\n\n") else output(red(" Failed\n")) exit 1 end end end end
generate_report()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 106 def generate_report output("Generating report...") report = Aquatone::Report.new(options[:domain], @visits) report.generate(File.join(@assessment.path, "report")) output("done\n") report_pages = Dir[File.join(@assessment.path, "report", "report_page_*.html")] output("Report pages generated:\n\n") sort_report_pages(report_pages).each do |report_page| output(" - file://#{report_page}\n") end output("\n") end
make_directories()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 130 def make_directories @assessment.make_directory("headers") @assessment.make_directory("html") @assessment.make_directory("report") @assessment.make_directory("screenshots") end
make_file_basename(host, port, domain)
click to toggle source
# File lib/aquatone/commands/gather.rb, line 137 def make_file_basename(host, port, domain) "#{domain}__#{host}__#{port}".downcase.gsub(".", "_") end
output_progress()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 141 def output_progress output("Stats: #{seconds_to_time(Time.now.to_i - @start_time)} elapsed; " \ "#{@task_count} out of #{@tasks.count} pages processed (#{@successful} successful, #{@failed} failed); " \ "#{(@task_count.to_f / @tasks.count.to_f * 100.00).round(1)}% done\n") end
parse_open_ports_file()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 119 def parse_open_ports_file contents = @assessment.read_file("open_ports.txt") result = {} lines = contents.split("\n").map(&:strip) lines.each do |line| values = line.split(",").map(&:strip) result[values[0]] = values[1..-1].map(&:to_i) end result end
prepare_tasks()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 48 def prepare_tasks if !@assessment.has_file?("hosts.json") output(red("#{@assessment.path} does not contain hosts.json file\n\n")) output("Did you run aquatone-discover first?\n") exit 1 end if !@assessment.has_file?("open_ports.txt") output(red("#{@assessment.path} does not contain open_ports.txt file\n\n")) output("Did you run aquatone-scan first?\n") exit 1 end @tasks = [] @hosts = JSON.parse(@assessment.read_file("hosts.json")) @open_ports = parse_open_ports_file @hosts.each_pair do |domain, host| next unless @open_ports.key?(host) @open_ports[host].each do |port| @tasks << [host, port, domain] end end end
process_pages()
click to toggle source
# File lib/aquatone/commands/gather.rb, line 70 def process_pages pool = thread_pool @task_count = 0 @successful = 0 @failed = 0 @start_time = Time.now.to_i @visits = [] output("Processing #{bold(@tasks.count)} pages...\n") @tasks.shuffle.each do |task| host, port, domain = task pool.schedule do begin output_progress if asked_for_progress? visit = visit_page(host, port, domain) if visit['success'] output("#{green('Processed:')} #{Aquatone::UrlMaker.make(host, port)} (#{domain}) - #{visit['status']}\n") @successful += 1 else output(" #{red('Failed:')} #{Aquatone::UrlMaker.make(host, port)} (#{domain}) - #{visit['error']} #{visit['details']}\n") @failed += 1 end jitter_sleep @task_count += 1 rescue Aquatone::Browser::Drivers::IncompatabilityError => e output("\n") output(red("Incompatability Error:") + " #{e.message}\n") exit 1 end end end pool.shutdown output("\nFinished processing pages:\n\n") output(" - Successful : #{bold(green(@successful))}\n") output(" - Failed : #{bold(red(@failed))}\n\n") end
sort_report_pages(pages)
click to toggle source
# File lib/aquatone/commands/gather.rb, line 147 def sort_report_pages(pages) pages.sort_by { |f| File.basename(f).split("_").last.split(".").first.to_i } end
visit_page(host, port, domain)
click to toggle source
# File lib/aquatone/commands/gather.rb, line 151 def visit_page(host, port, domain) file_basename = make_file_basename(host, port, domain) url = Aquatone::UrlMaker.make(host, port) html_destination = File.join(@assessment.path, "html", "#{file_basename}.html") headers_destination = File.join(@assessment.path, "headers", "#{file_basename}.txt") screenshot_destination = File.join(@assessment.path, "screenshots", "#{file_basename}.png") visit = Aquatone::Browser.visit(url, domain, html_destination, headers_destination, screenshot_destination, :timeout => options[:timeout]) if visit['success'] @visits.push({ :host => host, :port => port, :domain => domain, :url => url, :file_basename => file_basename, :headers => visit['headers'], :status => visit['status'] }) end visit end