A decade after the release of iPhone, our ways of communication changes significantly. Instead of talking face to face, we send message to each other and we identify where the message comes from by letting our phone tells us who the sender is. What if I told you that your trusted device can betray you and act on your behalf? What if anyone can be “you?”
The horror story of Apple’s product security continues. And today, on the land of “We just blindly trust IDS and now we are f**ked,” we have two new members. Remember that super convenient, magical feature that allows you to send SMS on your Mac through your phone? It turned out the “it just works” part is only possible because your phone will just process any command send to it asking it to send SMS from the current number. And our beloved personal assistant, Siri? It’s also a dummy that just processes command without checking the command is from you. Both daemons don’t verify message origin and process the request when IDS delivered the request to them.
I need to be clear that just because daemon doesn’t verify message origin doesn’t mean Apple is that dumb in security. By default, IDS is supposed to only allow the account owner (limited to devices signed into your iCloud account) to send message to those restricted services (SMS, and Siri iCloud). Those protection should be sufficient as long as Apple ensures no message can reach those restricted service unless it’s from account owner. But then, someone in the IDS team think it’s a good idea to allow message itself being able to override which service it suppose to be delivered to. What this means is that someone can tell IDS to send a message over iMessage service (which everyone can send message to other accounts since that’s how message works 😛), and inside the message, instead of the normal iMessage payload, the person can include instruction to say “actually this message is meant for SMS service” along with the payload for SMS service. Once IDS delivers the message to the identityservicesd on the target’s iOS device over iMessage service, the daemon sees the instruction to override target service and then pass the message to the new target service, which the involved daemon doesn’t check the sender. LOL we bypassed the wall that keeps your identity safe.
Personally I found this issue really interesting because it raised some fun questions: How are we suppose to separate individual identity away from the device that suppose to be your identity? Should individual be blamed for things their device did without the owner’s knowledge? I mean, with the SMS issue, one can literally put words in other’s mouth. All records will show the messages were sent by the owner of the device when the reality is that the device send those without the owner’s consent. The SMS is even logged on the victim’s device which cannot be achieved with traditional SMS spoofing techniques. There are quite a few creative ways to use this and I freaked out when seeing the bug actually worked 😅.
The Spaghetti Flavor of iOS 🍝
IDS (identityservicesd) is a huge spaghetti in iOS now. Based on the description in iOS Security white paper, the initial goal of IDS is to be something that allows iOS devices (and Mac) to exchange device identification (public key, push token) used to establish the end-to-end encrypted communication with each other. Somehow down the line, the IDS itself becomes a message transport for a lot of Apple’s daemons that need inter-device communication on iOS. Digging through the disassembly for a “suppose to be generic” message sending method on the daemon side, you can find a lot of service specific hack in there to disable or enable certain features on individual message 🤦♂️.
Somewhere in the spaghetti, identityservicesd will try to insert an “IDSAdHocServiceKey” with target service identifier if it believes the service that’s trying to send message is not capable of receiving message directly (AdHoc type 5), and then send the message using the primary service associated to the target service. I don’t know why this is there since there is no service actually uses this but maybe IDS engineers just want to better prepare for the future?
Anyway, the send part is not that interesting, what’s funny is the message handling part. Upon receiving the message from Apple Push Notification service, identityservicesd will try to find the service the message is for and then dispatch the message to clients that interested in the message. During this process, the daemon checks if the message contains the “IDSAdHocServiceKey” and override the target service if the key is present.
See the issue? One thing they missed is to check whether or not the overriding service is expecting to be delivered from primary service. The right way to do that would be check and see if target service has an AdHoc type of 5 before actually overriding it. All that’s left for an attacker to do is just to figure out which daemon doesn’t check message sender and craft message to have fun with them. Below is a video demo of SMS relay. It’s a little creepy to see the phone send out text without human touching it 😛 The strange string in the end is caused by a bug (or a feature?) in iOS 11.2 when it thinks the target is capable of receiving iMessage…
If you remember the HomeKit issue, you can see there are a lot similarities between these two. It felt like there is a common assumption inside Apple that clients using IDS don’t need to do extra work to ensure the message is delivered in the expected way… If that’s the assumption, maybe IDS should have a default behavior of not delivering message to clients from senders other than current account unless the client has a special entitlement. Then the product security team can conduct periodic security audit on IDS clients that have that special entitlement to ensure other daemons won’t have the similar issue again in the future.
The issue of IDS bypass was patched by Apple sometime between Dec 19th and Dec 20th by having IDS server strip of “IDSAdHocServiceKey” from individual messages. Maybe in the future iOS releases they will properly handle the message ¯\_(ツ)_/¯
Apple Security Bounty is a joke
Okay, I’m not sure if it’s just me not compatible with Apple’s product security team or if the product security team is always trying to be a jerk. My communication with them got a lot responsive after involving the press in the HomeKit issue. I found the IDS bypass issue on Dec 15th, then spent Dec 16th on scoping the affected daemons. Since I don’t want to do all the work free for Apple, I sent product-security an email asking about if I can get an invitation to join their security bounty program so I can report this one with some guarantee of the submission will be a bounty submission. Here is the reply I got from them.
All reported issues are evaluated against the Apple Security Bounty program’s criteria, however participation is by invitation only. Information about the Apple Security Bounty program is available in the iOS Security Guide at https://www.apple.com/business/docs/iOS_Security_Guide.pdf.
We would appreciate any additional information you are able to provide about the issue you mentioned. Submission of a qualifying issue is necessary but not sufficient to qualify for an invitation; Apple Security Bounty participation requires responsible disclosure: no public discussion of the issue until a fix is released and available.
For an issue to qualify, researchers must fully disclose details to Apple and coordinate with us so the issue can be fully addressed prior to any disclosure of details. Early disclosure disqualified your original issue.
“For an issue to qualify, researchers must fully disclose details to Apple and coordinate with us” did the first one, coordination was unfortunately not possible due to lack of communication from Apple’s side. Only after 9to5mac threatened publication of the article did Apple ever get back to me with something meaningful, and now they blame me for “early disclosure” ¯\_(ツ)_/¯ BTW do anyone know about this “requires responsible disclosure” part? It’s not documented in any place…
Then on Dec 19th had a call with them mostly talking about the HomeKit writeup revision and in the end I asked about bounty invitation again and basically the lady still blames me, but she said she will ask around and see if there is a solution. I tried to be nice and gave them some hints on where the IDS issue is at and wrapped up the call.
Then the next day they fixed the issue from server side and said nope again. After that it’s basically just me sending a long email expressing my frustration and refusing to play on their terms. Which I assume that email resulted them putting me back to the do-not-reply list since I haven’t hear back from them since then 🙃.
Thanks for reading through and I’d really like to get some feedback to calibrate my understanding of the world… Am I the one being unreasonable here? I was just asking for an invitation, not even say asking Apple to give bounty on the HomeKit issue. Should Apple just expect all security researchers work free for them?
That’s the horror story of Apple’s product security. Hope you won’t see a season 3 from me anytime soon.
Merry Christmas :)
PS: Someone should probably take a closer look from inside if “bad week” just keeps happening. It only took a new grad a Friday evening to find something like this, who knows what else is hidden under the imagination of “secure and private.”