Module: Msf::Exploit::EXE

Included in:
CmdStager, PhpEXE, Post::Windows::Runas
Defined in:
lib/msf/core/exploit/exe.rb

Instance Method Summary collapse

Instance Method Details

#exe_init_options(opts) ⇒ Object (protected)


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/msf/core/exploit/exe.rb', line 179

def exe_init_options(opts)
  opts.merge!(
    {
      :template_path => datastore['EXE::Path'],
      :template => datastore['EXE::Template'],
      :inject => datastore['EXE::Inject'],
      :fallback => datastore['EXE::FallBack'],
      :sub_method => datastore['EXE::OldMethod']
    })

  # NOTE: If code and platform/arch are supplied, we use those values and skip initialization.
  #
  # This part is kind of tricky so we need to explain the logic behind the following load order.
  # First off, platform can be seen from different sources:
  #
  # 1. From the opts argument. For example: When you are using generate_payload_exe, and you want
  #    to set a specific platform. This is the most explicit. So we check first.
  #
  # 2. From the metadata of a payload module. Normally, a payload module should include the platform
  #    information, with the exception of some generic payloads. For example: generic/shell_reverse_tcp.
  #    This is the most trusted source.
  #
  # 3. From the exploit module's target.
  #
  # 4. From the exploit module's metadata.
  #
  # Architecture shares the same load order.

  unless opts[:code] && opts[:platform]
    if self.respond_to?(:payload_instance) && payload_instance.platform.platforms != [Msf::Module::Platform]
      opts[:platform] = payload_instance.platform
    elsif self.respond_to? :target_platform
      opts[:platform] = target_platform
    elsif self.respond_to? :platform
      opts[:platform] = platform
    end
  end

  unless opts[:code] && opts[:arch]
    if self.respond_to? :payload_instance
      opts[:arch] = payload_instance.arch
    elsif self.respond_to? :target_arch
      opts[:arch] = target_arch
    elsif self.respond_to? :arch
      opts[:arch] = arch
    end
  end
end

#exe_post_generation(opts) ⇒ Object (protected)


228
229
230
231
232
# File 'lib/msf/core/exploit/exe.rb', line 228

def exe_post_generation(opts)
  if opts[:fellback]
    print_status("Warning: Falling back to default template: #{opts[:fellback]}")
  end
end

#generate_payload_dccw_gdiplus_dll(opts = {}) ⇒ Object


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/msf/core/exploit/exe.rb', line 141

def generate_payload_dccw_gdiplus_dll(opts = {})
  return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
  return get_eicar_exe if datastore['EXE::EICAR']

  exe_init_options(opts)
  plat = opts[:platform]
  pl = opts[:code]

  pl ||= payload.encoded

  #Ensure opts[:arch] is an array
  opts[:arch] = [opts[:arch]] unless opts[:arch].kind_of? Array
  if opts[:arch] && opts[:arch].index(ARCH_X64)
    dll = Msf::Util::EXE.to_win64pe_dccw_gdiplus_dll(framework, pl, opts)
  else
    dll = Msf::Util::EXE.to_win32pe_dccw_gdiplus_dll(framework, pl, opts)
  end

  exe_post_generation(opts)
  dll
end

#generate_payload_dll(opts = {}) ⇒ Object


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/msf/core/exploit/exe.rb', line 112

def generate_payload_dll(opts = {})
  return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
  return get_eicar_exe if datastore['EXE::EICAR']

  exe_init_options(opts)
  plat = opts[:platform]
  pl = opts[:code]
  pl ||= payload.encoded

  #Ensure opts[:arch] is an array
  opts[:arch] = [opts[:arch]] unless opts[:arch].kind_of? Array

  # NOTE: Only x86_64 linux is supported here.
  if plat.index(Msf::Module::Platform::Linux)
    if opts[:arch] && opts[:arch].index(ARCH_X64)
      dll = Msf::Util::EXE.to_linux_x64_elf_dll(framework, pl,opts)
    end
  elsif plat.index(Msf::Module::Platform::Windows)
    if opts[:arch] && opts[:arch].index(ARCH_X64)
      dll = Msf::Util::EXE.to_win64pe_dll(framework, pl, opts)
    else
      dll = Msf::Util::EXE.to_win32pe_dll(framework, pl, opts)
    end
  end

  exe_post_generation(opts)
  dll
end

#generate_payload_exe(opts = {}) ⇒ String

Returns an executable.

Parameters:

  • opts (Hash) (defaults to: {})

Options Hash (opts):

Returns:

  • (String)

Raises:


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/msf/core/exploit/exe.rb', line 59

def generate_payload_exe(opts = {})
  return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
  return get_eicar_exe if datastore['EXE::EICAR']

  exe_init_options(opts)

  pl = opts[:code]
  pl ||= payload.encoded

  # Fall back to x86...
  opts[:arch] = [ARCH_X86] if !opts[:arch] || opts[:arch].length < 1

  # Ensure we have an array
  opts[:arch] = [opts[:arch]] unless opts[:arch].kind_of? Array

  # Transform the PlatformList
  if opts[:platform].kind_of? Msf::Module::PlatformList
    opts[:platform] = opts[:platform].platforms
  end

  exe = Msf::Util::EXE.to_executable(framework, opts[:arch], opts[:platform], pl, opts)

  unless exe
    raise Msf::NoCompatiblePayloadError, "Failed to generate an executable payload due to an invalid platform or arch."
  end

  exe_post_generation(opts)
  exe
end

#generate_payload_exe_service(opts = {}) ⇒ Object


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/msf/core/exploit/exe.rb', line 89

def generate_payload_exe_service(opts = {})
  return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
  return get_eicar_exe if datastore['EXE::EICAR']

  exe_init_options(opts)

  # NOTE: Only Windows is supported here.
  pl = opts[:code]
  pl ||= payload.encoded

  #Ensure opts[:arch] is an array
  opts[:arch] = [opts[:arch]] unless opts[:arch].kind_of? Array

  if opts[:arch] && opts[:arch].index(ARCH_X64)
    exe = Msf::Util::EXE.to_win64pe_service(framework, pl, opts)
  else
    exe = Msf::Util::EXE.to_win32pe_service(framework, pl, opts)
  end

  exe_post_generation(opts)
  exe
end

#generate_payload_msi(opts = {}) ⇒ Object


163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/msf/core/exploit/exe.rb', line 163

def generate_payload_msi(opts = {})
  return get_custom_exe(datastore['MSI::Custom']) unless datastore['MSI::Custom'].to_s.strip.empty?
  return get_eicar_exe if datastore['MSI::EICAR']

  exe = generate_payload_exe(opts)

  opts.merge! ({
      :msi_template => datastore['MSI::Template'],
      :msi_template_path => datastore['MSI::Path'],
      :uac => datastore['MSI::UAC']
  })

  Msf::Util::EXE.to_exe_msi(framework, exe, opts)
end

#get_custom_exe(path = nil) ⇒ Object


41
42
43
44
45
46
47
48
# File 'lib/msf/core/exploit/exe.rb', line 41

def get_custom_exe(path = nil)
  path ||= datastore['EXE::Custom']
  print_status("Using custom payload #{path}, no handler will be created!")
  datastore['DisablePayloadHandler'] = true
  exe = nil
  ::File.open(path,'rb') {|f| exe = f.read(f.stat.size)}
  exe
end

#get_eicar_exeObject

Avoid stating the string directly, don't want to get caught by local antivirus!


36
37
38
39
# File 'lib/msf/core/exploit/exe.rb', line 36

def get_eicar_exe
  obfus_eicar = ["x5o!p%@ap[4\\pzx54(p^)7cc)7}$eicar", "standard", "antivirus", "test", "file!$h+h*"]
  obfus_eicar.join("-").upcase
end

#initialize(info = {}) ⇒ Object


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/msf/core/exploit/exe.rb', line 12

def initialize(info = {})
  super

  # NOTE: Any new options here should also be dealt with in
  # EncodedPayload#encoded_exe in lib/msf/core/encoded_payload.rb
  register_advanced_options(
    [
      OptBool.new('EXE::EICAR',    [false, 'Generate an EICAR file instead of regular payload exe']),
      OptPath.new('EXE::Custom',   [false, 'Use custom exe instead of automatically generating a payload exe']),
      OptPath.new('EXE::Path',     [false, 'The directory in which to look for the executable template']),
      OptPath.new('EXE::Template', [false, 'The executable template file name.']),
      OptBool.new('EXE::Inject',   [false, 'Set to preserve the original EXE function']),
      OptBool.new('EXE::OldMethod',[false, 'Set to use the substitution EXE generation method.']),
      OptBool.new('EXE::FallBack', [false, 'Use the default template in case the specified one is missing']),
      OptBool.new('MSI::EICAR',    [false, 'Generate an EICAR file instead of regular payload msi']),
      OptPath.new('MSI::Custom',   [false, 'Use custom msi instead of automatically generating a payload msi']),
      OptPath.new('MSI::Path',     [false, 'The directory in which to look for the msi template']),
      OptPath.new('MSI::Template', [false, 'The msi template file name']),
      OptBool.new('MSI::UAC',      [false, 'Create an MSI with a UAC prompt (elevation to SYSTEM if accepted)'])
    ], self.class)
end