Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/msf/util/payload_cached_size.rb
Views: 11779
# -*- coding: binary -*-1###2#3#4###56module Msf7module Util89#10# The class provides helper methods for verifying and updating the embedded CachedSize11# constant within payload modules.12#1314class PayloadCachedSize1516OPTS = {17'Format' => 'raw',18'Options' => {19'CPORT' => 4444,20'LPORT' => 4444,21'CMD' => '/bin/sh',22'URL' => 'http://a.com',23'PATH' => '/',24'BUNDLE' => 'data/isight.bundle',25'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',26'RC4PASSWORD' => 'Metasploit',27'DNSZONE' => 'corelan.eu',28'PEXEC' => '/bin/sh',29'HttpUserAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0',30'StagerURILength' => 531},32'Encoder' => nil,33'DisableNops' => true34}3536OPTS_ARCH_X64 = {37'DLL' => 'data/vncdll.x64.dll',38'PE' => 'data/vncdll.x64.dll'39}.freeze4041OPTS_ARCH_X86 = {42'DLL' => 'data/vncdll.x86.dll',43'PE' => 'data/vncdll.x86.dll'44}.freeze4546OPTS_IPV4 = {47'LHOST' => '255.255.255.255',48'KHOST' => '255.255.255.255',49'AHOST' => '255.255.255.255'50}.freeze5152OPTS_IPV6 = {53'LHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',54'KHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',55'AHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'56}.freeze5758# Insert a new CachedSize value into the text of a payload module59#60# @param data [String] The source code of a payload module61# @param cached_size [String] The new value for cached_size, which62# which should be either numeric or the string :dynamic63# @return [String]64def self.update_cache_constant(data, cached_size)65data.66gsub(/^\s*CachedSize\s*=\s*(\d+|:dynamic).*/, '').67gsub(/^(module MetasploitModule)\s*\n/) do |m|68"#{m.strip}\n\n CachedSize = #{cached_size}\n\n"69end70end7172# Insert a new CachedSize value into a payload module file73#74# @param mod [Msf::Payload] The class of the payload module to update75# @param cached_size [String] The new value for cached_size, which76# which should be either numeric or the string :dynamic77# @return [void]78def self.update_cached_size(mod, cached_size)79mod_data = ""8081::File.open(mod.file_path, 'rb') do |fd|82mod_data = fd.read(fd.stat.size)83end8485::File.open(mod.file_path, 'wb') do |fd|86fd.write update_cache_constant(mod_data, cached_size)87end88end8990# Updates the payload module specified with the current CachedSize91#92# @param mod [Msf::Payload] The class of the payload module to update93# @return [void]94def self.update_module_cached_size(mod)95update_cached_size(mod, compute_cached_size(mod))96end9798# Calculates the CachedSize value for a payload module99#100# @param mod [Msf::Payload] The class of the payload module to update101# @return [Integer]102def self.compute_cached_size(mod)103return ":dynamic" if is_dynamic?(mod)104105mod.generate_simple(module_options(mod)).size106end107108# Determines whether a payload generates a static sized output109#110# @param mod [Msf::Payload] The class of the payload module to update111# @param generation_count [Integer] The number of iterations to use to112# verify that the size is static.113# @return [Integer]114def self.is_dynamic?(mod, generation_count=5)115opts = module_options(mod)116[*(1..generation_count)].map do |x|117mod.generate_simple(opts).size118end.uniq.length != 1119end120121# Determines whether a payload's CachedSize is up to date122#123# @param mod [Msf::Payload] The class of the payload module to update124# @return [Boolean]125def self.is_cached_size_accurate?(mod)126return true if mod.dynamic_size? && is_dynamic?(mod)127return false if mod.cached_size.nil?128129mod.cached_size == mod.generate_simple(module_options(mod)).size130end131132# Get a set of sane default options for the module so it can generate a133# payload for size analysis.134#135# @param mod [Msf::Payload] The class of the payload module to get options for136# @return [Hash]137def self.module_options(mod)138opts = OPTS.clone139# Assign this way to overwrite the Options key of the newly cloned hash140opts['Options'] = opts['Options'].merge(mod.shortname =~ /6/ ? OPTS_IPV6 : OPTS_IPV4)141# Extract the AdaptedArch for adaptor payloads, note `mod.adapted_arch` is not part of the public API142# at this time, but could be in the future. The use of send is safe for now as it is an internal tool143# with automated tests if the API were to change in the future144adapted_arch = mod.send(:module_info)['AdaptedArch']145if adapted_arch == ARCH_X64 || mod.arch_to_s == ARCH_X64146opts['Options'].merge!(OPTS_ARCH_X64)147elsif adapted_arch == ARCH_X86 || mod.arch_to_s == ARCH_X86148opts['Options'].merge!(OPTS_ARCH_X86)149end150opts151end152end153154end155end156157158