Summary
Apple provides the following description about CFNetwork:
CFNetwork is a framework in the Core Services framework that provides a library of abstractions for network protocols.
CFNetwork fails to handle certain HTTP responses properly, causing the
_CFNetConnectionWillEnqueueRequests() function to dereference a NULL pointer, leading to
a denial of service condition exploitable by a server sending a crafted response to a
client application making use of this API.
Affected versions
This issue has been verified with CFNetwork 129.19 on Mac OS X 10.4.8 (8L2127).
Proof of concept, exploit or instructions to reproduce
The provided proof of concept will listen at the specified port for incoming connections and send back the response necessary to reproduce the denial of service condition on any default CFNetwork-based client.
$ gcc MOAB-25-01-2007.c -o cfnet-http -framework Carbon
$ ruby MOAB-25-01-2007.rb 8080
++ Starting HTTP server at port 8080.
(once ./cfnet-http runs or CFNetwork client connects...)
++ Connected: CFNetwork/129.19
Note: the provided MOAB-25-01-2007.c is just an example of a CFNetwork-based application
affected by the issue. Generally any application is affected unless it has implemented it's
own handling for the redirections (ex. Software Update fortunately does this).
Debugging information
The following debugging information shows the example CFNetwork client triggering the issue:
(gdb) r Starting program: .../cfnet-http Reading symbols for shared libraries ................................... done Requesting URL Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000008 0x910131ea in _CFNetConnectionWillEnqueueRequests () (gdb) i r eax 0x0 0 ecx 0x1800038 25165880 edx 0xbfff754c -1073777332 ebx 0x910127c3 -1862195261 esp 0xbfff7400 0xbfff7400 ebp 0xbfff7418 0xbfff7418 esi 0x12c 300 edi 0x0 0 eip 0x910131ea 0x910131ea <_CFNetConnectionWillEnqueueRequests+11> eflags 0x10286 66182 cs 0x17 23 ss 0x1f 31 ds 0x1f 31 es 0x1f 31 fs 0x0 0 gs 0x37 55 (gdb) back #0 0x910131ea in _CFNetConnectionWillEnqueueRequests () #1 0x910130f8 in addAuthenticationInfoToResponse1 () #2 0x91012a87 in checkHeaders () #3 0x91008c37 in httpRequestStateChanged () #4 0x9101022e in scheduleNewResponse () #5 0x91015386 in _CFNetConnectionResponseIsComplete () #6 0x9101469b in httpRequestRead () #7 0x9087875a in CFReadStreamRead () #8 0x910200c4 in _CFHTTPMessageSendRequest () #9 0x91020332 in _CFURLCreateDataAndPropertiesFromResource () #10 0x9082b5be in CFURLCreateDataAndPropertiesFromResource () #11 0x00001f28 in main () (gdb) disas _CFNetConnectionWillEnqueueRequests Dump of assembler code for function _CFNetConnectionWillEnqueueRequests: 0x910131df <_CFNetConnectionWillEnqueueRequests+0>: push %ebp 0x910131e0 <_CFNetConnectionWillEnqueueRequests+1>: mov %esp,%ebp 0x910131e2 <_CFNetConnectionWillEnqueueRequests+3>: push %edi 0x910131e3 <_CFNetConnectionWillEnqueueRequests+4>: push %esi 0x910131e4 <_CFNetConnectionWillEnqueueRequests+5>: sub $0x10,%esp 0x910131e7 <_CFNetConnectionWillEnqueueRequests+8>: mov 8(%ebp),%edi 0x910131ea <_CFNetConnectionWillEnqueueRequests+11>: mov 8(%edi),%edx 0x910131ed <_CFNetConnectionWillEnqueueRequests+14>: test $0x1,%dl 0x910131f0 <_CFNetConnectionWillEnqueueRequests+17>: je 0x91013200 0x910131f2 <_CFNetConnectionWillEnqueueRequests+19>: lea 12(%edi),%eax 0x910131f5 <_CFNetConnectionWillEnqueueRequests+22>: mov %eax,(%esp) 0x910131f8 <_CFNetConnectionWillEnqueueRequests+25>: call 0xa100649c 0x910131fd <_CFNetConnectionWillEnqueueRequests+30>: mov 8(%edi),%edx 0x91013200 <_CFNetConnectionWillEnqueueRequests+33>: mov %edx,%eax 0x91013202 <_CFNetConnectionWillEnqueueRequests+35>: shr %eax 0x91013204 <_CFNetConnectionWillEnqueueRequests+37>: and $0x1,%al 0x91013206 <_CFNetConnectionWillEnqueueRequests+39>: mov %eax,%esi 0x91013208 <_CFNetConnectionWillEnqueueRequests+41>: and $0x1,%dl 0x9101320b <_CFNetConnectionWillEnqueueRequests+44>: je 0x91013218 0x9101320d <_CFNetConnectionWillEnqueueRequests+46>: lea 12(%edi),%eax 0x91013210 <_CFNetConnectionWillEnqueueRequests+49>: mov %eax,(%esp) 0x91013213 <_CFNetConnectionWillEnqueueRequests+52>: call 0xa10064a6 0x91013218 <_CFNetConnectionWillEnqueueRequests+57>: mov %esi,%edx 0x9101321a <_CFNetConnectionWillEnqueueRequests+59>: movzbl %dl,%eax 0x9101321d <_CFNetConnectionWillEnqueueRequests+62>: add $0x10,%esp 0x91013220 <_CFNetConnectionWillEnqueueRequests+65>: pop %esi 0x91013221 <_CFNetConnectionWillEnqueueRequests+66>: pop %edi 0x91013222 <_CFNetConnectionWillEnqueueRequests+67>: pop %ebp 0x91013223 <_CFNetConnectionWillEnqueueRequests+68>: ret End of assembler dump. (gdb) p (void *)$edi $2 = (void *) 0x0 (gdb) p (void *)$edx $4 = (void *) 0xbfff754c (gdb) x/x $edx 0xbfff754c: 0x91009000 (gdb) x/i 0x91009000 0x91009000 <scheduleNewRequest+262>: pop %esi
Notes
Exploitation conditions
This issue will lead to a denial of service only. Arbitrary code execution isn't possible
at all, as it's simply dereferencing a NULL pointer. It's worth noting that apparently
CFNetwork doesn't perform any sanity checking over these responses and thus the application
must take care of verifying them at it's own. For instance, Software Update isn't affected.
Then again, this issue, in couple with MOAB-22-01-2007
gets you another shiny root shell. And unlike certain people who-miss-the-point say,
integrating it with a remote exploit is as simple as using a download+exec payload
(ex. via fork(), execve() curl, wait for pid, then
execve of downloaded file...).
Workaround or temporary solution
Perform sanity checking of HTTP responses received via CFNetwork API.
Wait for Apple to add further checks and fix the _CFNetConnectionWillEnqueueRequests() API.