Path: blob/master/tools/modules/update_payload_cached_sizes.rb
63036 views
#!/usr/bin/env ruby12##3# This module requires Metasploit: https://metasploit.com/download4# Current source: https://github.com/rapid7/metasploit-framework5##67#8# This script updates the CachedSize constants in payload modules9#1011msfbase = __FILE__12msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase)) while File.symlink?(msfbase)1314$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))15require 'msfenv'1617$LOAD_PATH.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']1819gem 'rex-text'20require 'rex'2122class StatusReporter23CLEAR_LINE = "\r\e[2K\r".freeze24private_constant :CLEAR_LINE2526def print_progress(s)27return if s.nil?2829@last_progress = s30print CLEAR_LINE31print info(s)32$stdout.flush33end3435def print_info(s)36print CLEAR_LINE37puts info(s)38print_progress(@last_progress)39end4041def print_error(s)42$stderr.print CLEAR_LINE43$stderr.puts error(s)44print_progress(@last_progress)45end4647def finish48print CLEAR_LINE49puts50end5152private5354def info(s)55"\e[1;36m[*]\e[0m #{s}"56end5758def error(s)59"\e[1;33m[!]\e[0m #{s}"60end61end6263# Initialize the simplified framework instance.64framework = Msf::Simple::Framework.create('DisableDatabase' => true)65exceptions = []66reporter = StatusReporter.new67current_payload = 06869# Currently the cached size is stored on stagers, but multiple stages can be associated with one stager70# Maps the stager to the available stages71stagers_to_stages = Hash.new { |hash, key| hash[key] = [] }7273modules = []74framework.payloads.each_module do |name, mod|75modules << [name, mod]76end7778total_payloads = modules.length79modules.each do |name, mod|80next if name =~ /generic/8182current_payload += 183reporter.print_progress "Updating single (#{current_payload}/#{total_payloads}) #{name}..."84mod_inst = framework.payloads.create(name)8586next if mod_inst.is_a?(Msf::Payload::Adapter)8788mod_dependencies = mod_inst.dependencies89missing_dependencies = mod_dependencies.reject(&:available?)90if missing_dependencies.any?91reporter.print_error "Cannot update payload size for #{name} - missing dependencies: #{missing_dependencies.join(',')}"92next93end9495if mod_inst.is_a?(Msf::Payload::Stager)96stagers_to_stages[mod_inst.file_path] << mod_inst97next98end99100current_size = mod.dynamic_size? ? ':dynamic' : mod.cached_size101new_size = Msf::Util::PayloadCachedSize.update_module_cached_size(framework, mod_inst)102if current_size != new_size103reporter.print_info "Single Updated: #{name} CacheSize on disk at #{mod.file_path} from #{current_size} to #{new_size}..."104end105rescue StandardError => e106reporter.print_error "Caught Error while updating #{name}:\n#{e}\n#{e.backtrace.map { |line| "\t#{line}" }.join("\n")}"107exceptions << [ e, name ]108end109110# Update the metadata on the stager module associated with stages111stager_count = 0112stagers_to_stages.each_value do |stages|113stager_count += 1114mod = stages.first115reporter.print_progress("Updating stager (#{stager_count}/#{stagers_to_stages.length}) #{stages.first.refname}...")116if mod.dynamic_size?117current_size = ':dynamic'118else119current_size = mod.class.const_defined?('CachedSize') ? mod.class.const_get('CachedSize') : nil120end121new_size = Msf::Util::PayloadCachedSize.update_stager_module_cached_size(framework, stages)122if current_size != new_size123reporter.print_info "Stager Updated: #{mod.refname} CacheSize on disk at #{mod.file_path} from #{current_size} to #{new_size}..."124end125rescue StandardError => e126reporter.print_error "Caught Error while updating #{mod.refname}:\n#{e}\n#{e.backtrace.map { |line| "\t#{line}" }.join("\n")}"127exceptions << [ e, name ]128end129130reporter.finish131132exit(1) unless exceptions.empty?133134135