Your home was not so secure after all
TL;DR — Apple built a super secure door, left the key on the door and forgot to build the wall around the door.
Ever since the existence of connected home accessories, security is always something people worried about. So many things that can go wrong with your fancy new BTLE lock with software running on it, compared to old mechanical locks. There was a period of time where the market of connected home accessories is really chaotic, manufacturer shipping poorly implemented accessories with terrible security. I was really happy when Apple announced HomeKit back in 2014, promising to offer a secure and private way to control connected home accessories.
The thing is, a lot of time there is really no way for people to check whether a thing is really secure or not. And for HomeKit, it turned out not to be so secure after all. HomeKit didn’t check the sender of remote message before processing the request, which ended up allowing potentially anyone to remotely control HomeKit accessories in the home.
HomeKit is actually an umbrella term covering both the software on your iOS device and a communication protocol. The software on your device provides a centralized place for you to manage home and accessories (daemon), and the communication protocol (HAP) used by the software on iOS to talk to your HomeKit accessories. The security issues with watchOS 4 and iOS 11.2 were on daemon side, the underlying HAP exchange is not breached.
So, what went wrong with HomeKit?
A not too technical version
Imagine HomeKit as the butler for your home, and when you are not at home, you can send iMessage to it asking it to do things for you. Say you want to unlock the front door, you would send a message to HomeKit asking it to unlock the front door. Once HomeKit receive the message, it should check that the message is sent by you and then unlock the door as you have asked. Except that in reality, HomeKit doesn’t check who sent the message and it will happily unlock the door whenever someone ask it to do so.
In order for HomeKit to do something, the message needs to contain a unique identifier that identifies the object (accessory, scene, or room) in the home. Normally it should be impossible for anyone to figure out the unique identifier for those objects unless you are actually authorized to access that home in HomeKit. However, there are two separate bugs, one in watchOS 4 - 4.1, and another in iOS 11.2 and watchOS 4.2, allow someone to figure out those unique identifiers without authorizing the person to access the home in first place. With those unique identifiers, remote attacker can ask HomeKit to do almost anything.
Apple disabled the ability for people to send HomeKit message to others on December 7th as a temporary solution while it works on a proper fix for future iOS release. As a result of that, sharing home to new users and remote access for existing shared users are not longer available for users on iOS before 11.2.1.
A more technical version
HomeKit daemon is built upon the request-response pattern. Each action you do in your favorite HomeKit app is being translated to a request, sent to daemon. The daemon processes the request, perform the operation, and then reply to the request. For HomeKit app running on iOS device, all of the communication is done over XPC and the access permission is enforced by TCC (the permission popup in iOS). All information discussed in this article are based on disassembling HomeKit daemon binary bundled with iOS SDK. Hopper is a great tool for this kind of task ;)
To allow you to securely access your accessories when you are not at home, and share your home with other users, Apple built a remote cloud messaging platform (same one behind iMessage). Messages across users, devices, and apps over multiple transports are processed by the HomeKit daemon with a centralized message dispatcher.
Fun things happen when someone try to design a system that’s too flexible. For XPC messages, HomeKit daemon doesn’t really need to perform extra validation for messages since TCC and iOS in general have already done all the hard work (Entitlements 😉). For normal daemon to daemon remote communication, the actual message is encrypted by HomeKit secure session, and the encrypted packet is then sent over the remote cloud messaging platform. The issue with HomeKit is how the daemon handles remote message without a secure session. Instead of having daemon discard the message that doesn’t make sense with the state machine, the daemon treat the message as a normal request and processed it anyway. Apple addressed the issue with iOS 11.2.1 and tvOS 11.2.1 by improving message handling on the daemon side.
Since HomeKit daemon handles request without secure session as a normal request, we can send messages to home manager and have it leak information about the home and its accessories. Those information could then be used to instruct HomeKit to perform actions it shouldn’t do in the normal situation. There are two ways we could gather the required information from home manager, one was available with watchOS 4 and 4.1, and the other one was introduced in iOS 11.2 and watchOS 4.2 🙃. Both are now patched as of iOS 11.2.1.
For watchOS 4 and 4.1
Of all the messages you can send to HomeKit daemon, there are some really interesting ones. There is one message that will let HomeKit on watchOS to reply with a list of home identifiers, along with the public and private key that used to encrypt home data and communicate with accessories to the sender. Once an attacker got the reply, it’s game over for HomeKit. With pairing identity and private key, the attacker can trick HomeKit into thinking him as the owner of the home, even after Apple fixed the messaging issue.
But yeah, now we have all the information we need to tell HomeKit daemon to do things, we can just send messages targeting the right home, and control every thing in user’s home (including IP cameras 😅).
Fortunately Apple deployed a temporary fix on the remote cloud platform sometime around mid November, disabling inter account messaging targeting an Apple Watch so only the iCloud account on the Apple Watch can send message to the watch. Apple properly addressed the vulnerability of sending full pairing identity with watchOS 4.2 by improving message origin validation and only replying with public key.
For iOS 11.2 and watchOS 4.2
I sent the report about HomeKit mishandling messages back in late October (more on communication with Apple’s product security team later), I’m surprised to see when iOS 11.2 officially released, they introduced new ways for remote attacker to control the home (and actually making it a lot easier). Before iOS 11.2, to control someone’s HomeKit accessories remotely, the target user needs to have an Apple Watch running watchOS 4 or 4.1 so the attacker can get the enough information about where to send the message. However, in iOS 11.2 (and watchOS 4.2), HomeKit introduced a new message on home manager which didn’t properly verify the message sender and will reply with sensitive home information. So now in order for the attacker to remotely control the home, the target just need to have an iOS device on iOS 11.2, which with the date issue happened a few days ago, a lot of people have updated. Thanks Apple! 🤦
That’s it, no fancy buffer overflow, just mishandling messages 😝. Level of ignorance on security? macOS root level.
Communicating with Apple
Honestly at this stage I think it’s safe to say marketing team at Apple can probably get whatever they want from engineering team with crazy deadline.
Those message mishandling issues were discovered back in late October, and was disclosed to Apple’s product security team the next day I found it (Oct 28). I got ONE email (on October 30) from Apple’s product security team saying they are investigating it through the entire November. During that time, I sent multiple emails (Oct 31, Nov 2, and Nov 16. Additionally there was one sent to Federighi on Nov 27.) to try to ensure the engineering team understood the issue but no reply at all. I observed that Apple deployed the watchOS server fix so I assumed they just being typical Apple not replying people (hello radar 🙃), so I thought the engineering team should have sufficient understanding of the issue and hoped they properly fixed the issue with iOS 11.2. But then iOS 11.2 officially released, while they did fix some issues in my report, they didn’t do a full security audit to ensure all messages are being handled properly, and instead they introduced a new message which makes the whole attack a lot easier 🤦.
It’s funny about how they prioritize the fix, in my initial report, I tried to list them by severity like this:
HomeKit daemon should differentiate messages from different transports
…Description of the issue…
— — —
Message for resetting home configuration
— — —
Message for getting home data and encryption key
— — —
Can remotely add/remove homes
— — —
And somehow the engineering team managed to fix almost everything expect the one on top about differentiate messages from different transports 🤷♂️.
Since they won’t reply to my emails and they made the situation worse in latest release, I wasn’t really sure what to do next. I asked around and lucky someone was able to poke a person they know working at product security team, and finally I was able to get a email reply from the team. I guess that’s how product security works now? I have to know someone to get my security issue handled properly?
The guy replying is really nice but cannot provide any useful information on when Apple can fix the new issues caused by their negligence of the original report…So I ended up reaching out to friend at 9to5mac and turned out Apple PR channel is much more responsive than product security, from them reaching out Apple PR to Apple come up with a temporary fix all happened with 48 hours. No wonder nowadays people just throw security issues on Twitter right? What a world we live in.
iOS 11.2.1 was released on December 13th which properly addressed all reported issues with HomeKit.
So yeah, be vigilant when someone make the promise that something is secure. And it’s really funny that the low level infrastructure in the codebase behaves differently than the rest of the components in a way that engineer is not expecting, which eventually resulted a completely security breakdown of the entire system. Hope Apple will be more careful in the future.
- Some information were removed from this post per the request of Apple Product Security.