Open ghost opened 9 years ago
what happened?
I just updated the first post.
It works, the problem was I wasn't keeping the event port open. But the decryption key seems incorrect.
As a sanity check I checked the challenge/response from a log of ios9 and an appleTV and fed the same into the existing airtunesd and the results are different. ios9 still seems to accept them and sends the video data though.
I can only guess the decryption key must have changed.
There also seems to be data of type 5 every 30 video packets. I'm guessing it may be audio info since everything is now being sent over this one connection.
Type is: 1 config record Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 5 wtf 194 5 0 0.0 Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 0 Encrypted Video Data Type is: 5 wtf 25194 5 0 0.0
Strangely ios7 works with the same protocol, AND the video data still doesn't decrypt.
Hmm looks like i've hit a dead :( It seems ios9 is using a different key/encryption which probably needs the library from the new apple tv firmware. I don't think decryption keys are available for the new apple tv firmware tho?
Any ideas on your end? It's also possible the video format has changed but i doubt it.
Maybe the sochi firmware can handle this type of encryption. I'll have to setup qemu and find the entry points tho. Any chance you have the entry points already?
No. I'm going to have a look at all this soon now that unicorn is released.
Oh i didn't know about unicorn! I'm attempting to decrypt an even newer firmware at the moment, will let you know how it goes. In the meantime here's a quick test vector for challenge 1 so you can check if it's generating with the new or old key.
46504c590301010000000004020003bb < 46504c5903010200000000820203d7ce93237c7d52efb40385eee64ed14616cad9dc49bdba930c1d8b359475f8d3da5a8356dbdd929eddb74e3a5e2b1e3c7e2587b9ba5a48f387484a4530f825d789440f15f9965d547d2bb51d45f1de0c58962bcbc0b8ca451793305a89aafbd60bf436272dd75fff777b2976112f8b373bac39e8175ac4a5b08e2f95cab6e47e
The current airtunesd returns this instead: 46504c5903010200000000820203879f7a3d3ce5a4c5db51176fa886babd9ca307a9626d8bbeee2ec31a2efdec3d9f5714833e2b3ffe6044b09a8c9946dfda0bceb86af01d27757f2f37ab366d138c0bd89b792d35695884089618460d4888ee0d09ed829b61a94f41e0f4cba1d49a2009130a64336ce44a030bca9960b9ba91511db91f4a3df46f246de2171f98
@kam187 which firmware do you use to pass negotiate?
It's a special set of attributes in the bonjour message to skip it. Let me get to my computer and I'll post it in about half an hour.
Here you go: The real device sends 0x507FFFF7,0x1E but the following is sufficient to make the device connect AND skip the initial verify stages:
'features': u'0x507FFFF7',
'model' : u'AppleTV3,2',
'srcvers': u'220.68',
@kam187 when I change the attributes as you said above , no video data comes and logs below AirTunes: 172.16.8.93 - - [22/Oct/2015 16:11:39] "POST /fp-setup HTTP/1.1" 200 - AirTunes: 172.16.8.93 - - [22/Oct/2015 16:11:39] code 501, message Unsupported method ('TEARDOWN')
on iOS 9.0.2
It's not as simple as that. The protocol is totally different. If you're just expecting it to work it won't, a lot more work needs to be done yet.
@kam187 ok , if you decode the video successfully, please let me know.
The encryption has changed so we need to find the decryption key for the new firmware and then reverse that firmware to find the decrypt function :/
What would be useful is a packet capture of the newer protocol. Can you help with that?
Yeah sure Ill upload it when I get to my computer
In the mean time there's one on here too:
https://github.com/juhovh/shairplay/issues/43
Although it doesn't show the actual image data
Hmm a bit of an update. I've managed to debug through a commercial solution (took forever) to get me a decrypt key for a logged session but the resulting data has no valid NALU format :/
Any ideas?
I wonder if it's switched to AES-GCM mode, but i wonder what the authenticated tag is...
Nope not AES-GCM :/
@kam187 leave me an email
My id at gmail dot com
Anyway I'll try to debug and double check the key when I have time. The only other thing I can thing to do is try to debug the decryption part but the whole thing is heavily obfuscated :/. Probably the original AirPlay library embedded in there.
I've got hold of a airtunesd from version 190.9, it looks to have updated init/challenge/decrypt functions which i've identified.
It contains thumb code though so we need a better emulator - espes drop me an email I can pass it over if you want to have a go.
One more experiment, i sent a fake bonjour with features 0x527FFFF7 but pointing to a commercial airplay receiver. I traced the traffic and there was no pair verify as expected but the whole thing worked fine.
So that means (for now at least) we can ignore the pair verify and use this feature ID and concentrate on the init/challenge/decrypt.
More progress. I'm now able to load the library and run it. But the fp_init function seems to have changed. There's a call to GetFairPlayHWInfo which stores something at a pointer which now has to be passed into fp_init. Unfortunately GetFairPlayHWInfo is an external symbol and I don't have access to the full firmware :(
I've tried the usual stuff of mallocing an buffer and passing it in but it doesn't work :(
omg decryption key is verified, sending the NALU directly to VLC displays some garbled parts of the screen until it crashes.
That means the old format of LEN
Edit false alarm, was deciding the wrong stream :/
Can you show a screenshot ?
发自我的 iPhone
在 2015年10月30日,下午11:30,kam187 notifications@github.com 写道:
omg decryption key is verified, sending the NALU directly to VLC displays some garbled parts of the screen until it crashes.
That means the old format of LEN , LEN, has now changed to something else.
— Reply to this email directly or view it on GitHub.
@kam187 int _GetFairPlayHWInfo(int arg0) { rbx = arg0; _GetPrimaryMACAddress(rbx + 0x4, var_C); rax = var_C; if (rax == 0x0) { (int32_t )rbx = 0x6; } return rax; }
Thanks. I've just discovered the airtunesd that was sent to me is from 7.0.1 firmware '11A470e' which has a decryption key available (https://ipsw.me/keys/AppleTV2,1)
int fp_init(int a1, int a2) @ 0x429B4 int fp_challenge(int a1, int a2, int a3, int a4, int a5, int a6, int a7, _BYTE a8 @ 0x7B67C int fp_decrypt(int a1, int a2, int a3, int a4, int a4) @ 0x34418
(fp_init is definitely correct, the other two are from a quick glance but looks correct, first step is to get init to work!)
SharpCode, which file is that from? I'll decrypt the firmware and take a closer look.
OSX 10.11.1 /System/Library/PrivateFrameworks/CoreUtils.framework
/System/Library/PrivateFrameworks/AirPlaySender.framework
Cool, thanks! I just found this:
https://github.com/foxsen/fairplay-server/blob/master/fairplay-server.c
anyone know the offset for 'airplay_load_hwinfo' in the old airtunesd? I'll just use that to grab the structure. Getting the AirPlaySender.framework to work may not be easy.
(of course that's his name for it, but the equivalent anyway)
nvm 0x1D754 :) <-- EDIT, nope that's not it.
In the old airtunesd it passes in a unsigned chat buf[24] memset to 0
Cool @kam187 Your information is very useful!
Ok so the old initsap gets passed in the unsigned char buf[24] memset to zero and when it returns it's full of 30 30 30 30 30 etc i.e. ascii 0's
This is running on an iphone though. Switching to the new airtunesd i now have unresolved symbols. I'm trying to add in coreutils now.
Finally extracted all 495 frameworks.. slowly slowly getting there!
So here's an update - There's 3 main methods i've tried and each one has failed for a different reason - but I thought an update here might be useful. (Here 'old library' means the current one in slave in the mirror that is the OLD protocol).
1) The first method which is probably the easiest to prove the library before going to too much effort is to use an iphone and dlopen the airtuned. An iphone because it's a bsd based system running on ARM and for the most part libraries are compatible because things like lockdownd etc exist on an iphone too. This isn't so great for the long term obviously because you can't use an iphone as a slave to decrypt :P Anyway....
With the old library this works fine. You can create a pointer to the function and call it directly - in the same way as slave in the mirror does now actually. This works because a) the init/start function of the airtunesd is self contained. i.e it doesn't call any external functions, so the library loads in without complaint. AND b) because the init function is self contained and doesn't need to call symbolic functions, it just branches around and calls fixed subroutines as part of its obfuscation.
With the new library, the start/init section calls some functions which are in an external library (CoreUtils), so the dlopen fails and airtunesd doesn't load in. To get around this I extracted the CoreUtils lib from the apple firmare and tried to link it. Codesign fails complaining it's the wrong format. So i used a jailbroken iphone and turned off codesign. Now the library links AND loads 'yay'!
However when i try to load airtunesd it's still looking for the library in the Private framework directory. This means that library's imports need to be changed - headache! (that's because the iphone uses a shared cache which has all the libraries in it and it's not as easy at pointing it to a local copy of that library :(
If i try to statically link airtunesd (where i have more control on where it gets it's symbols) it fails because after xcode 5 the arm executable overide no longer works
Dead end for now.
2) The second thing i tried was essentially 'copying' the assembly of the function and running it. I malloc some memory and mark it as executable. I load in the whole airtunes library, point to the correct memory address and run the function.
With the OLD library this works, with the new one i get a sigsys or signal 4. This means at some point it's calling a symbolised function or worse an imported function which obviously doesn't exist yet :( This clearly won't work for this new library.
[BTW this was with qemu in user mode and not with an iphone]
3) I extracted the AirPlayFramework from the latest firmware (sochi) we have a key for and disassembled it. I tried the same two methods above, but the same issues exist. The library imports functions from CoreUtils and directly running the function crashes.
i'm hearing stories that people have this running on qemu etc but i'm inclined to think that's either the previous library or they're importing a bunch of the private libraries from an apple tv and have got around the dependancy nightmare somehow.
Anyway now i've jailbroken the iPhone my next step is probably to install gdb on it and go back to the directly running the asm method to see where and why it's actually crashing.
Oh and one last thing, it seems the gethwaddress stuff was a mistake. The mac address IS passed into the initSAP function but that's not what is/was making it crash. I assume that's just to index the buffer against the incoming client or something like that - in any case it may be relevant to the key at a later stage but for now passing buf[24] full of 0's is enough.
Anyone with any other ideas or any help would be welcome!
slight update on 3)
I can statically link the AirPlayReceiver.framework AND confirm it's loaded in. BUT the fp_init function is no longer an exported function. Pointing to it's address gives me a EXEC_BAD_ACCESS or in the linux world i believe this is a SIGSEGV or bad memory access.
This could be happening because that memory is protected, OR because again an import is missing. I'll need to get gdb running to check it out i think
BTW if anyone has any ideas please let me know. I can share source code but you'll need to extract the firmware yourself for legal reasons.
Challenge phase 1: 46 50 4C 59 03 01 01 00 00 00 00 04 02 00 00 BB Response: 46 50 4C 59 03 01 02 00 00 00 00 82 02 00 3B 25 AC 1F 18 9A F1 19 18 56 65 64 D5 1D 76 53 57 A4 9F 7D 77 55 75 B2 A7 C4 CC 62 50 37 63 3E 35 4F F0 36 0B F9 BA 14 63 5A 90 BC BE 88 F7 0B 74 75 81 26 08 D8 A9 BC 8F E2 2A A1 6D F2 93 88 AB 54 29 E3 39 F8 36 00 3E 06 E2 B7 A7 2B 58 E4 82 A8 A6 6B 69 D1 F5 60 2D 16 0A 6B 7D D9 A0 5F 73 65 FE 8C 31 DA 11 97 0D B0 55 92 0E A1 1C 3B 5B 9B 11 27 81 95 48 06 F4 76 4D B3 8C ED 93 D4 Challenge phase 2: 46 50 4C 59 03 01 03 00 00 00 00 98 00 8F 1A 9C C0 42 CD F4 D1 16 A4 7F DC 6A E4 76 63 BB 48 D4 59 98 D8 FC 24 D9 98 BB C9 95 9E 28 04 92 D9 D5 C1 8A 63 DC 93 30 2B 9D 01 38 DA CF 02 ED 43 E9 26 29 0B E7 53 0D C6 1B A7 53 DC B4 96 0F FB D5 0A 86 B0 E9 18 E0 12 DA 63 90 23 C5 96 B8 A4 09 B5 19 39 A0 53 BC 4C FE 6F 52 35 C4 73 CC 89 DF 31 D9 66 7D C7 A2 F7 79 6B 67 A6 18 1B 7F 29 DF 08 E6 41 1F F7 2D 31 0C AD EF BC 60 20 55 D4 A6 48 97 F4 E9 52 C5 B1 59 11 E0 23 A9 67 6B 96 8D 96 A3 F2 F0 Response: 46 50 4C 59 03 01 04 00 00 00 00 14 48 97 F4 E9 52 C5 B1 59 11 E0 23 A9 67 6B 96 8D 96 A3 F2 F0 Decrypt:46 50 4C 59 01 02 01 00 00 00 00 3C 00 00 00 00 0F 30 DF E0 7D AB 9C 2F 04 A1 CF 05 2B F7 FF D0 00 00 00 10 B6 D4 3C E1 FB 16 DE B6 F3 9D 03 D2 D3 94 AF C5 8D 11 7E B2 DB A0 50 36 8C 10 14 14 0C D5 E2 F5 70 87 9C 28 Response: 47 BE 46 1F D2 46 91 AD 03 BD 4A 39 73 DE 91 81
Next problem, this key results in incorrect data :/
Nice!
You wouldn't happen to know if it is the same key pair used for the fairplay part used between iTunes-to-iTunes instance?
Unfortunately not because all i'm actually doing is forcing the library to load and calling its functions. It's heavily obfuscated.
Challenge 1 and 2 (and the responses) above come from a log between my phone and my appleTV. I've passed the same challenges to the airtunesd i have running and the responses match (YAY).
The encrypted key (Decrypt challenge) come from the same long, and the result comes from this airtunesd. I can't verify if it's correct or not because i have nothing to match it against.
Anyway i've tried decrypting the video traffic with this key and it doesn't give me any sensible NALU data. I even tried playing with endiness etc in case that was it, but nope nothing.
Not sure where to go from here :(
For whats its worth - I've been in contact with foxsen and he has pulled his server down. However you should check your mail right now ;)
Awesome! Thanks. Is that the new or old airtunesd tho? I'll find out in a second...
@kam187 , could you share the source? my email: gebenxiang at hotmail.com. Many thx.
I don't know if this helps you any, but apparently a Chinese developer was able to accomplish mirroring functionality in ios9. There a thread here discussing it http://forum.kodi.tv/showthread.php?tid=223465
So i've managed to get iOS9 to negotiate and start sending data. The config record looks correct (non encrypted). But the video data makes no sense once decrypted.
It appears that the key must have changed.
I tried to find a decrypted version of the newest formware for apple TV but I can't seem to find one. Emulating thumb is not a problem if i can find the firmware.
Any ideas