Towards Discovering Remote Code Execution Vulnerabilities in Apple FaceTime Tao Huang and Tielei Wang About us
• Tao Huang
• Senior researcher at Pangu Lab
• Focusing on iOS/macOS vulnerability discovery
• Tielei Wang
• PhD, co-founder of Team Pangu, organizer of MOSEC
• Leading iOS/macOS security research at Pangu Lab
• Regularly present research at BlackHat, POC, etc Motivation
• Messaging apps are becoming a hot security research target • Google Project 0 released a series of blog posts about fuzzing messaging apps, including WhatsApp, FaceTime
• We decided to take a look at FaceTime Scope of the talk
• This talk will cover
• Code execution flows while making a FaceTime call
• Attack surfaces and vulnerabilities along with the code execution flows
• This talk will NOT cover
• FaceTime protocol families (e.g., SIP, STUN, RTP/SRTP, etc)
• Stream encryption, decryption, and storage
• https://blog.quarkslab.com/resources/2013-10-17_imessage-privacy/slides/ iMessage_privacy.pdf Outline
• Reverse-engineering FaceTime
• Attack surface and vulnerabilities analysis
• Conclusion 0 0 0 FaceTime
All Missed
Input
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
FaceTime is not a single application FaceTime
0 0 0 FaceTime
All Missed
Input
xxx-xxx-xxxx
xxx-xxx-xxxx FaceTime.app provides • xxx-xxx-xxxx the basic UI framework FaceTime.App
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx 0 0 0 FaceTime
All Missed
Input
• Manage the call status of xxx-xxx-xxxx FaceTime xxx-xxx-xxxx Respond to UI triggered • xxx-xxx-xxxx events callservicesd
xxx-xxx-xxxx • Communication bridge between avconferenced xxx-xxx-xxxx
and identityservicesd xxx-xxx-xxxx
xxx-xxx-xxxx 0 0 0 FaceTime
All Missed
Input
xxx-xxx-xxxx
xxx-xxx-xxxx Produce and handle avconferenced(macOS) • xxx-xxx-xxxx FaceTime video/audio mediaserverd(iOS) streams xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx 0 0 0 FaceTime
• We can consider that avconferenced(macOS) FaceTime consists of the callservicesd three major components mediaserverd(iOS) 0 0 0 FaceTime
All Missed
Input
xxx-xxx-xxxx
xxx-xxx-xxxx
• When a user tries to xxx-xxx-xxxx make a FaceTime call xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx 0 0 0 FaceTime UINotification-Call All Missed
Input
xxx-xxx-xxxx
xxx-xxx-xxxx
• FaceTime.app will xxx-xxx-xxxx generate a notification xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx
xxx-xxx-xxxx 0 0 0 FaceTime UINotification-Call callservicesd avconferenced(macOS) mediaserverd(iOS)
callservicesd will handle respond UI notification through - • [CSDFaceTimeProviderDelegate the notification provider: performStartCallAction:] 0 0 0 FaceTime callservicesd avconferenced(macOS) mediaserverd(iOS)
• callservicesd then invokes the corresponding handler to create a new invitation interact with avconferenced through xpc-message -[CSDAVConference “conferenceGetInviteData” • callservicesd sends an XPC prepareWithConfiguration:] message to avconferenced to get invitation data 0 0 0 FaceTime callservicesd avconferenced(macOS) mediaserverd(iOS) • MediaBlob contains configurations for audio and video streams interact with avconferenced through xpc-message -[CSDAVConference • SKEBlob contains prepareWithConfiguratio “conferenceGetInviteData” encryption and decryption n:] parameters for audio and video streams MediaBlob of A SKEBlob of A … 0 0 0 FaceTime callservicesd avconferenced(macOS) mediaserverd(iOS)
• avconferenced sends interact with avconferenced through xpc-message MediaBlob and SKEBlob -[CSDAVConference prepareWithConfiguratio “conferenceGetInviteData” back to callservicesd n:]
data from avconferenced 0 0 0 FaceTime callservicesd avconferenced(macOS) mediaserverd(iOS)
• callservicesd continues to send InviteData to Identityservicesd through encapsulate more -[CSDIDSChat conferenceFinishedPreparin information g:]
data from avconferenced
data from callservicesd • callservicesd passes the invitation data to identityservicesd for further encapsulation
identityservicesd
0 0 0 FaceTime avconferenced(macOS) data from avconferenced callservicesd mediaserverd(iOS) data from callservicesd • Identity Services Daemon is a system process that handles credentials for various services, including iCloud and iMessage. It also connects to computers and iOS devices on your local network to coordinate phone calls across multiple devices.
identityservicesd
0 0 0 FaceTime avconferenced(macOS) callservicesd mediaserverd(iOS) • identityservicesd continues to encapsulate more information, and then passes it to apsd
identityservicesd data from avconferenced data from callservicesd
0 0 0 FaceTime data from identityservicesd avconferenced(macOS) callservicesd mediaserverd(iOS) • The Apple Push Service Daemon (apsd) is responsible for sending and receiving Push Notifications. apsd
• apsd maintains a reliable and secure data from avconferenced connection with Apple server data from callservicesd data from identityservicesd
0 0 0 FaceTime identityservicesd avconferenced(macOS) callservicesd mediaserverd(iOS) • apsd serializes the whole invitation apsd data from avconferenced data into an APS Message data from callservicesd
0 0 0 data from identityservicesd FaceTime identityservicesd avconferenced(macOS) callservicesd data from apsd mediaserverd(iOS) • When an endpoint sends a notification to Apple, Apple does not simply forward it to the destination, instead Apple will modify payloads in the notification AppleServer • Comparing the notification sent out and the notification received, we can find what we can control
0 0 0 FaceTime apsd avconferenced(macOS) callservicesd mediaserverd(iOS) identityservicesd • AppleServer now forwards notifications to the callee endpoint, according to the content AppleServer of the APS Message
0 0 0 FaceTime apsd apsd avconferenced(macOS) callservicesd mediaserverd(iOS) identityservicesd AppleServer
0 0 0 FaceTime apsd apsd data from avconferenced avconferenced(macOS) callservicesd data from callservicesd mediaserverd(iOS) identityservicesd data from identityservicesd
data from apsd
• The callee apsd deserializes the APS message AppleServer
0 0 0 FaceTime apsd apsd data from avconferenced avconferenced(macOS) callservicesd data from callservicesd mediaserverd(iOS) identityservicesd data from identityservicesd
data from apsd
•We can set breakpoints in APSMessage deserialization functions in a debugger, and check the received notification •APSProtocolCommand = 10 •APSProtocolPayload = <…> •APSProtocolTopicHash = <…> AppleServer
0 0 0 FaceTime apsd apsd avconferenced(macOS) callservicesd mediaserverd(iOS) identityservicesd identityservicesd data from avconferenced data from callservicesd data from identityservicesd
•According to APSProtocolTopicHash and APSProtocolCommand, apsd delivers the payload of the notification to identityservicesd •We can set breakpoints in identityservicesd and check the received invitation
AppleServer
0 0 0 FaceTime apsd apsd avconferenced(macOS) callservicesd mediaserverd(iOS) identityservicesd identityservicesd data from avconferenced data from callservicesd data from identityservicesd •c=232 -> processIncomingInvitationWithPayload •c=233 -> processIncomingSessionAcceptMessage •c=234 -> processIncomingSessionDeclineMessage •c=235 -> processIncomingSessionCancelMessage •c=236 -> processIncomingSessionMessage •c=237 -> processIncomingSessionEndMessage •…
AppleServer
0 0 0 FaceTime apsd apsd avconferenced(macOS) callservicesd mediaserverd(iOS) identityservicesd identityservicesd data from avconferenced data from callservicesd data from identityservicesd AppleServer
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
data from avconferenced
data from callservicesd
•identityservicesd continues to forward data to callservicesd callservicesd parses binary payload through
-[CSDAbstractIDSProviderDelegate service:account:inviteReceivedForSession:fromID:withContext:]
AppleServer
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
data from avconferenced
data from callservicesd AppleServer
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
MediaBlob of A
SKEBlob of A …
•callservicesd continues to forward blobs to avconferenced/mediaserverd 0 0 0 FaceTime Accept xxx-xxx-xxx Decline 0 0 0 FaceTime Accept Accept xxx-xxx-xxx Decline UINotification-Accept
0 0 0 FaceTime Accept Accept xxx-xxx-xxx Decline AppleServer UINotification-Accept
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS) AppleServer
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
UINotification-Accept AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
respond UI notification through - [CSDFaceTimeProviderDelegate provider:performAnswerCallAc tion:] AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
interact with avconferenced through xpc-message -[CSDAVConference “conferenceGetInviteData” prepareWithConfiguration:]
MediaBlob of B
SKEBlob of B
… AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
interact with avconferenced through xpc-message -[CSDAVConference “conferenceGetInviteData” prepareWithConfiguration:]
data from avconferenced AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
Send InviteData to Identityservicesd through -[CSDIDSChat conferenceFinishedPreparing:]
data from avconferenced
data from callservicesd AppleServer
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd data from avconferenced callservicesd mediaserverd(iOS) mediaserverd(iOS) data from callservicesd
data from identityservicesd AppleServer
0 0 0 FaceTime apsd apsd data from avconferenced 0 0 0 FaceTime data from callservicesd
data from identityservicesd
data from apsd
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS) AppleServer
0 0 0 FaceTime apsd apsd 0 0 0 FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS) AppleServer
0 0 0 FaceTime 0 0 0 FaceTime data from avconferenced apsd apsd
data from callservicesd
data from identityservicesd
data from apsd
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS) •c=233 -> processIncomingSessionAcceptMessage
AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd data from avconferenced identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS) data from callservicesd
data from identityservicesd AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
data from avconferenceddata from avconferenced data from callservicesddata from callservicesd AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
MediaBlob of B
SKEBlob of B
… AppleServer
0 0 0 0 0 0 FaceTime apsd apsd FaceTime
socket socket avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
Meanwhile, identityservicesd creates sockets for session based connections 0 0 0 FaceTime 0 0 0 FaceTime AppleServer quickrelay
socket socket avconferenced(macOS) avconferenced(macOS) callservicesd identityservicesd identityservicesd callservicesd mediaserverd(iOS) mediaserverd(iOS)
Apple’s QuickRelay server coordinates caller and callee build a direct connection 0 0 0 FaceTime 0 0 0 FaceTime Now caller avconferenced(macOS) and callee can avconferenced(macOS) mediaserverd(iOS) see/hear each mediaserverd(iOS) other via FaceTime
socket socket socket identityservicesd identityservicesd
socketsocket socket identityservicesd is responsible for first layer packet handling and packet re-dispatching identityservicesd
-[IDSUDPLink _processIncomingPacket] recvmsg identityservicesd
-[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:]
-[IDSUDPLink _processIncomingPacket] recvmsg identityservicesd
-[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:]
-[IDSUDPLink _processIncomingPacket] recvmsg
In this function, identityservicesd identifies STUN messages according to magic number matching identityservicesd
-[IDSGlobalLink _processStunPacket:fromDeviceUniqueID:cbuuid:arrivalTime:headerOverhead:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSUDPLink _processIncomingPacket] recvmsg
identityservicesd passes STUN messages to a handler identityservicesd
-[IDSGlobalLink _processStunPacket:fromDeviceUniqueID:cbuuid:arrivalTime:headerOverhead:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSUDPLink _processIncomingPacket] recvmsg
-[IDSGlobalLink _processStunPacket:fromDeviceUniqueID:cbuuid:arrival Time:headerOverhead:] will further call different handlers according to different STUN message types. •Besides STUN messages, many other types of packets are also handled by identityservicesd itself •The rest of packets will be distributed to different processes such as avconferenced
identityservicesd identityservicesd
-[IDSGlobalLink _processStunPacket:fromDeviceUniqueID:cbuuid:arrivalTime:headerOverhead:] -[IDSGlobalLink _processStunPacket:fromDeviceUniqueID:cbuuid:arrivalTime:headerOverhead:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:]
-[IDSUDPLink _processIncomingPacket] recvmsg recvmsg -[IDSUDPLink _processIncomingPacket]
network RTP packets handler identityservicesd
-[IDSUDPLink _processIncomingPacket] recvmsg identityservicesd
-[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:]
-[IDSUDPLink _processIncomingPacket] recvmsg identityservicesd
-[IDSLinkManager link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSUDPLink _processIncomingPacket] recvmsg identityservicesd
-[IDSDSession link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSLinkManager link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSUDPLink _processIncomingPacket] recvmsg avconferenced(macOS) mediaserverd(iOS) Transfer data to avconferenced through a series of undocumented syscalls (os_channel_* identityservicesd os_nexus_*)
-[IDSDSession link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSLinkManager link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSUDPLink _processIncomingPacket] recvmsg avconferenced(macOS) avconferenced(macOS) mediaserverd(iOS) mediaserverd(iOS)
identityservicesd identityservicesd
-[IDSDSession link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSDSession link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSLinkManager link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSLinkManager link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:] -[IDSGlobalLink link:didReceivePacket: fromDeviceUniqueID: cbuuid:]
-[IDSUDPLink _processIncomingPacket] recvmsg recvmsg -[IDSUDPLink _processIncomingPacket]
network Attack Surfaces Attacker AppleServer
apsd
0 0 0 FaceTime
identityservicesd
avconferenced(macOS) callservicesd The code for notification mediaserverd(iOS) processing and delivering forms 0-click attack surfaces Attacker AppleServer
apsd
0 0 0 FaceTime
identityservicesd
avconferenced(macOS) callservicesd mediaserverd(iOS)
The code for socket packet processing and delivering forms 1-click attack surfaces, after a FaceTime call is connected Attacker AppleServer
apsd
0 0 0 FaceTime
identityservicesd
identityservicesd can further avconferenced(macOS) callservicesd dispatch messages to other mediaserverd(iOS) services according to topics and commands, and open new attack surfaces Attacker AppleServer
apsd
0 0 0 FaceTime
identityservicesd
avconferenced(macOS) other attack surfaces callservicesd mediaserverd(iOS)
iMessage
remoteDesktop
phonecontinuity
… Vulnerability Examples Attacker AppleServer Potential Info Leak apsd
0 0 0 FaceTime
identityservicesd
avconferenced(macOS) callservicesd mediaserverd(iOS)
iMessage
remoteDesktop
phonecontinuity
… Attacker AppleServer apsd
malicious invitation message identityservicesd c=232 U=
Invitation message contains a field indicating a UUID Attacker AppleServer apsd malicious invitation message c=232 identityservicesd U=
The victim’s identityservicesd will reply a message, using the same UUID Attacker AppleServer apsd
malicious invitation message identityservicesd c=233 U=
• Convert an NSData (presumed 16 bytes long) to UUID
• Stack variable uu is uninitialized
• Uninitialized memory leak Attacker AppleServer apsd malicious invitation message c=232 U=