Files
metasploit-gs/lib/msf/core/reflective_dll_loader.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

81 lines
2.4 KiB
Ruby
Raw Normal View History

# -*- coding: binary -*-
###
#
# This mixin contains functionality which loads a Reflective
# DLL from disk into memory and finds the offset of the
# reflective loader's entry point.
#
###
2021-01-13 11:51:16 +00:00
require 'rex/peparsey'
module Msf::ReflectiveDLLLoader
2020-05-18 19:35:34 +10:00
# This is the ordinal of the reflective loader by default
# In new RDI DLLs that come with MSF
EXPORT_REFLECTIVELOADER = 1
# Load a reflectively-injectable DLL from disk and find the offset
# to the ReflectiveLoader function inside the DLL.
#
2017-03-27 01:17:23 -05:00
# @param [String] dll_path Path to the DLL to load.
#
# @return [Array] Tuple of DLL contents and offset to the
# +ReflectiveLoader+ function within the DLL.
2020-05-18 19:35:34 +10:00
def load_rdi_dll(dll_path, loader_name: 'ReflectiveLoader', loader_ordinal: EXPORT_REFLECTIVELOADER)
encrypted_dll = ::File.binread(dll_path)
dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_dll)
2020-05-18 19:35:34 +10:00
offset = parse_pe(dll, loader_name: loader_name, loader_ordinal: loader_ordinal)
2015-09-10 19:35:26 -05:00
2017-03-27 01:17:23 -05:00
unless offset
raise "Cannot find the ReflectiveLoader entry point in #{dll_path}"
end
2015-09-10 19:35:26 -05:00
return dll, offset
end
2017-03-27 01:17:23 -05:00
# Load a reflectively-injectable DLL from a string and find the offset
2015-09-10 19:35:26 -05:00
# to the ReflectiveLoader function inside the DLL.
#
2017-03-27 01:17:23 -05:00
# @param [String] dll_data the DLL data to load.
2015-09-10 19:35:26 -05:00
#
# @return [Integer] offset to the +ReflectiveLoader+ function within the DLL.
2020-05-18 19:35:34 +10:00
def load_rdi_dll_from_data(dll_data, loader_name: 'ReflectiveLoader', loader_ordinal: EXPORT_REFLECTIVELOADER)
decrypted_dll_data = ::MetasploitPayloads::Crypto.decrypt(ciphertext: dll_data)
offset = parse_pe(decrypted_dll_data, loader_name: loader_name, loader_ordinal: loader_ordinal)
2015-09-10 19:35:26 -05:00
2017-03-27 01:17:23 -05:00
unless offset
raise 'Cannot find the ReflectiveLoader entry point in DLL data'
end
2015-09-10 19:35:26 -05:00
offset
end
private
2020-05-18 19:35:34 +10:00
def parse_pe(dll, loader_name: 'ReflectiveLoader', loader_ordinal: EXPORT_REFLECTIVELOADER)
pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(dll))
2015-09-10 19:35:26 -05:00
offset = nil
2020-05-18 19:35:34 +10:00
unless loader_name.nil?
pe.exports.entries.each do |e|
if e.name =~ /^\S*#{loader_name}\S*/
2020-05-18 19:35:34 +10:00
offset = pe.rva_to_file_offset(e.rva)
break
end
end
end
2020-05-18 19:35:34 +10:00
# If we aren't able to find the ReflectiveLoader, we need to
2020-06-24 08:17:04 +10:00
# fallback to the known ordinal export for RDI DLLs?
2020-05-18 19:35:34 +10:00
if offset.nil? && !loader_ordinal.nil?
e = pe.exports.entries.find {|e| e.ordinal == loader_ordinal}
offset = pe.rva_to_file_offset(e.rva)
end
2015-09-10 19:35:26 -05:00
offset
end
end