#!/usr/bin/env ruby # frozen_string_literal: true require 'pwn' require 'optparse' require 'fileutils' require 'ruby-audio' require 'fftw3' require 'waveform' opts = {} OptionParser.new do |options| options.banner = "USAGE: #{File.basename($PROGRAM_NAME)} [opts] " options.on('-tPATH', '--target-file=PATH', '') do |t| opts[:target_file] = t end options.on('-sSEC', '--seconds-to-record=SEC', '') do |s| opts[:seconds_to_record] = s end options.on('-TTHREADS', '--max-threads=THREADS', '') do |t| opts[:max_threads] = t end options.on('-bPATH', '--baresip-binary=PATH', '') do |bs| opts[:baresip_bin] = bs end options.on('-SSOX', '--sox-path=SOX', '') do |sox| opts[:sox_bin] = sox end options.on('-rDIR', '--session-root=DIR', '') do |sr| opts[:session_root] = sr end options.on('-R', '--[no-]randomize', '') do |r| opts[:randomize] = r end options.on('-nREPORTNAME', '--report-name=REPORTNAME', '') do |n| opts[:report_name] = n end options.on('-H', '--[no-]start-reporting-server', '') do |s| opts[:start_reporting_server] = s end options.on('-X', '--[no-]speech-to-text', '') do |x| opts[:speech_to_text] = x end options.on('-xRULES', '--source-num-rules=RULES', '') do |x| opts[:src_num_rules] = x end # TODO: Add an hours of operation flag. # TODO: Add a resume feature to resume session following an interruption. # TODO: Append results to pwn_phone_results.json as things are running #save_memory. end.parse! if opts.empty? puts `#{File.basename($PROGRAM_NAME)} --help` exit 1 end begin pwn_provider = 'ruby-gem' # pwn_provider = ENV.fetch('PWN_PROVIDER') if ENV.keys.select { |s| s == 'PWN_PROVIDER' }.any? pwn_provider = ENV.fetch('PWN_PROVIDER') if ENV.keys.any? { |s| s == 'PWN_PROVIDER' } $stdout.sync = true # Required Flag Variables target_file = opts[:target_file] max_threads = opts[:max_threads] seconds_to_record = opts[:seconds_to_record] baresip_bin = opts[:baresip_bin] sox_bin = opts[:sox_bin] session_root = opts[:session_root] session_root ||= Dir.pwd # Optional Flag Variables randomize = opts[:randomize] report_name = opts[:report_name] report_name ||= File.basename(Dir.pwd) start_reporting_server = opts[:start_reporting_server] speech_to_text = opts[:speech_to_text] src_num_rules = opts[:src_num_rules] # Initiallize Phone Reconaissance results_hash = PWN::Plugins::BareSIP.recon( baresip_bin: baresip_bin, session_root: session_root, target_file: target_file, randomize: randomize, src_num_rules: src_num_rules, seconds_to_record: seconds_to_record, sox_bin: sox_bin, speech_to_text: speech_to_text, report_name: report_name ) # Generate HTML Report print "#{File.basename($PROGRAM_NAME)} Generating Report..." PWN::Reports::Phone.generate( dir_path: session_root, results_hash: results_hash ) puts 'complete.' # Start Simple HTTP Server (If Requested) if start_reporting_server listen_port = PWN::Plugins::Sock.get_random_unused_port.to_s if pwn_provider == 'docker' listen_ip = '0.0.0.0' else listen_ip = '127.0.0.1' end puts "For Scan Results Navigate to: http://127.0.0.1:#{listen_port}/#{report_name}.html" Dir.chdir(session_root) system( 'pwn_simple_http_server', '-i', listen_ip, '-p', listen_port ) end rescue StandardError => e raise e.message rescue SystemExit, Interrupt puts "\nGoodbye." end