|August 20th, 2011|
AirPlay Mirroring was without a doubt one of the coolest iOS 5 features announced to the public at the 2011 WWDC Keynote. This amazing technology allows you to display the screen of your iOS device on an Apple TV 2. At the moment, the only supported mirroring device is the iPad 2 and the receiving device is limited to only the Apple TV 2. Airplay Mirroring is the latest in a pedigree of Apple media streaming technologies. The previous entry in the family was Airplay Video and is a slightly different technology that allows specific content to be broadcast from a variety of iOS devices and iTunes to an Apple TV 2. The precursor to that technology was originally called AirTunes and is used to broadcast audio content from iOS devices and iTunes to the AirPort Express and Apple TV (either 1 or 2). One peculiar thing that people noted about AirPlay Video was that it was wide open and unencrypted! This was surprising in light of the fact that AirTunes was most definitely not. Because of AirPlay Video’s relatively easy hackability, there quickly sprang up all manner of apps for both Mac OS X and iOS which would act as an AirPlay Video consumer.
So my thought process went like thus:
- AirTunes – Encrypted
- AirPlay Video – Unencrypted
- AirPlay Mirroring – ???
I thought it would be really awesome to whip up a AirPlay Mirroring consumer real quick and I thought the useful applications of such an app would be obvious. At the time I couldn’t find any technical information on the AirPlay Mirroring protocol so I made a guess that it was very similar to the AirPlay Video protocol, maybe even built right on top of it. One of the reasons for this dearth of information was that the setup to test the hypothesis is not a trivial one to get a hold of. First of all, hardware-wise you need:
- An iPad 2
- Apple TV 2
- An HDMI compatible TV along with an HDMI cable (My TV at the time was made in 1982. It did not have an HDMI input).
- A micro USB cable (not common).
Software-wise you need to install an iOS 5 beta on the iPad 2 and the corresponding iOS update for the Apple TV 2 (that is what you need the micro USB cable for). That setup will allow you to use AirPlay Mirroring but then you need the wherewithal to sniff the network packets and try talking on the right ports to find out the real story.
Say Hello, I mean, Bonjour
I acquired the all the necessary components and starting hacking. The first thing I did was to write a program that would appear on the network to be an AirPlay Mirroring capable device. Perusing the available services with Bonjour Browser made this easy enough. There it was clear as day, the AirPlay service (“
_airplay._tcp“). Looking in the TXT record fields there was a “features” section with a bit field of value
0x39f7. I didn’t know what the individual bitfield values indicated but I was sure that one of them was AirPlay Mirroring because the previously advertised value in that field on older versions of the OS was
0x7. So I wrote a program to register a similar looking Bonjour service and lo and behold, it showed up in the iPad 2′s AirPlay menu. Obviously nothing would happen if you selected it because I did not have the advertised AirPlay port (
7000) open and running. However, it did not show up as being a “Mirroring” capable device. After some head scratching I tried also registering an AirTunes service (“
_raop._tcp“). Now my laptop showed up as a device that could be mirrored to.
So now my program appears on the network to be a AirPlay Mirroring capable device. It was time to see what the iPad 2 was going to say to me on port
7000 after it connected. Interestingly enough, it didn’t say anything. It never even connected to it! This was odd because
7000 was the clearly advertised port in the Bonjour service. I decided that I should know what a real mirroring session is supposed to look like over the network.
It had been many years since I had done any significant packet sniffing (back when Wireshark was called Ethereal) and so I had to learn about all the new wireless specific quirks and issues (which was actually quite fun). After some flailing around with Wireshark I found out that the magical mode I needed to put my wireless card in is called “monitor mode” which is also known as “passive mode” (not even “promiscuous mode” would do the trick). Unfortunately Wireshark cannot enable monitor mode and so I turned to KisMAC. The interface was a bit confusing but I got the hang of it after a little bit. Our neighborhood is pretty 802.11 noisy and so I had to filter a lot of the other devices out by MAC address so that the capture log would only be my own wireless network. I also noticed that the interface was tuned to sniffing 2.4 GHz network channels as opposed to the 5 GHz ones that my network ran on. So I switched my network to 2.4 GHz and restricted it to only one channel so that KisMAC would not have to perform channel hopping and potentially lose a packet in the meantime (though I think this may have caused more transmission errors and re-transmissions by doing so).
I captured some packets into a dumplog and opened it up with Wireshark for examination. Unfortunately all I got were generic IEEE 802.11 packets with nothing but header and opaque data. It then occurred to me that the data obviously appeared opaque because it was encrypted (WPA2). I then took the security off of the network and captured another session. This time the higher level protocols were exposed and I could now observe a legitimate mirroring session in action.
The first thing I noticed was that the AirPlay session wasn’t even running on port
7000, instead it was running on port
7100! I couldn’t see this port number mentioned in any of the Bonjour advertisements or any of the earlier network traffic (it is possible that I just missed it). I am guessing that you might just have to know that mirroring sessions are conducted on port
7100 instead of the usual port
The second thing I noticed was that before the mirroring session started, an AirTunes stream was established and connected. I wasn’t sure that I would be required to do this and so I decided to leave that aspect alone for the time being.
“AIRP”!? That looks suspcious.
I also noticed some odd UDP communication between the iPad 2 and the Apple TV which appeared to possibly be related to the AirPlay session. The second one of which was particularly interesting because it contained the string “
AIRP“. In both exchanges each packet appeared to be sent twice. This is presumably because the reliability of the recipient receiving the message was important and UDP of course has no built-in mechanism to ensure delivery.
Getting Down To Business
Looking at the volume of traffic and where things spiked it was obvious that all the video was being shuttled over port
7100 and so it was time to examine the conversation over there. It starts easy enough with a “
GET /stream.xml” and a plist response containing version and screen size information. However, all my AirPlay Mirroring dreams were shot down when I arrived at “
POST /fp-setup“. This is a FairPlay DRM initiation which means that the mirroring video is indeed encrypted. I observed two back-and-forths between the consumer and producer most likely though an RSA keypair. This was to presumably to perform a challenge-response and for the iPad 2 to send the video’s encryption key over to the Apple TV (I would guess that would mostly likely be a 128-bit AES key used for CBC). At this point I was pretty much dead in the water. I sniffed a number of legitimate sessions and inspected the data fields for patterns and fields that remained constant. Just for kicks I tried having my program replay responses from legitimate sessions which were obviously rejected by the iPad 2 with a promptly closed port. At that point I was just grasping at straws.
The private key that I would need to create an AirPlay Mirroring consumer is hiding somewhere inside the Apple TV 2. I don’t have any idea whether it is in hardware or software (Perhaps present in the iOS restore images? Probably not though). I know that fairly recently someone cracked open an AirPort Express and extracted the AirTunes private key which allows people to now create AirTunes consumers (Hmm, could it be that the AirTunes and AirPlay Mirroring keys are the same?). Even if someone with more leet skills than me was able to retrieve the private key out of an Apple TV 2, I would still have to reverse-engineer the
fp-setup protocol and figure out what needs to be encrypted and where which would be no small feat.
I have decided to leave my AirPlay hacking for the time being in order to concentrate on other things. After my hacking session was finished I did later stumble upon some web pages that confirmed that AirPlay Mirroring is indeed encrypted. I had unfortunately missed that little nugget in my first research pass. It’s ok though. I had a ton of fun learning more about this hot new technology and was able to flex some minor reverse-engineering skills and keep them fresh.