espes / Slave-in-the-Magic-Mirror

Open source implementation of AirPlay Mirroring. WIP.
610 stars 122 forks source link

iOS9 #12

Open ghost opened 8 years ago

ghost commented 8 years ago

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

anthonya1999 commented 8 years ago

To anyone who has it even partially working on iOS 9: could you share/update the project please? I really need it for a project. Much thanks!

JaxSJW commented 8 years ago

@omittchi I got an android demo from this guy. It works perfectly for iOS 9.

anthonya1999 commented 8 years ago

@JaxSJW Well that's a start, but I kinda need it for iOS...

greystar commented 8 years ago

Hi @kam187 , have you work it out? AFAIK, the FPLY decryption algorithm doesn't change, and It's fine to use the old airtunesd. So maybe Apple has changed the AES decryption method. I've tried several AES mode, but nothing yield sensible nalu.

jkiddo commented 8 years ago

@JaxSJW would you care to share your android demo?

ddejean commented 8 years ago

Any news ?

wgaylord commented 7 years ago

Any news on this?

wgaylord commented 7 years ago

iOS 9 is jail broken now so we can get code from it if needed.

shoc89 commented 7 years ago

Hello, i am trying to implement new airplay mirroring protocol. And i'am in a point of video decryption, but i can't find any information about this. Can you help me to find a way to do that? my email is mediata@abv.bg

adams79 commented 7 years ago

@kam187 Sorry to write here, however I'm trying contact you regarding a different airplay issue that is pairing between device and apple tv - that is now mandatory on tvOS 10.2. Since this has never changed since iOS 7.1 I think that you can help in understand how it works. If yes please contact me at ivan.dama at iCloud.com Many thanks

robertoandrade commented 7 years ago

Why do you say pairing is mandatory @adams79 ? if you advertise the endpoint with the features described on this thread, the fairplay handshake happens just fine without it and data can be decrypted without pairing at all.

cyshi commented 7 years ago

I have successfully cracked airplay protocol, and now IOS 10 mirror works fine. Thanks for discussion in this thread.

bbbang007 commented 7 years ago

@cyshi Genius, is there any chance that you can let me know more about how to make it work? And I completely understand, if the answer is no.

robertoandrade commented 7 years ago

@cyshi do you care to contribute with knowledge back then? I'm going thru the process of adjusting my implementation to work on iOS 10 as we speak and would benefit tremendously from the newly acquired knowledge you gained.

cyshi commented 7 years ago

I'm thinking of opening source of airplay handshake, only a little change in the decrypt phase and video decode phase.

The problem for opening source is I wonder how many peopel need help and whether they used it for commercial purpose.

robertoandrade commented 7 years ago

Even if you don't open source your implementation, can you at least provide the direction you took to get it working? Mine works all the way up to iOS 10.0.2 but fails from 10.2 and 10.3 forward, so something must have changed there.

On Mon, Apr 24, 2017 at 10:41 AM cyshi notifications@github.com wrote:

I'm thinking of opening source of airplay handshake, only a little change in the decrypt phase and video decode phase.

The problem for opening source is I wonder how many peopel need help and whether they used it for commercial purpose.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-296690057, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-dV1ZUaRXtLaZLO_jq1u4KL8bFldks5rzLSegaJpZM4GRiD8 .

bbbang007 commented 7 years ago

@cyshi Surely someone would use your work to make money, and that's not totally a bad thing.

cyshi commented 7 years ago

ios 10.3.1 works fine and i don't try to run on ios 10.0.2.

robertoandrade commented 7 years ago

Cool, can you please share just the overall concept of what you had to change in the Decryption/decoding phases to make it work? On Mon, Apr 24, 2017 at 3:50 PM cyshi notifications@github.com wrote:

ios 10.3.1 works fine and i don't try to run on ios 10.0.2.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-296802929, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-UtCQjQMDjWqou-A5nxT5u0yDJUpks5rzPzqgaJpZM4GRiD8 .

robertoandrade commented 7 years ago

@cyshi by:

only a little change in the decrypt phase

Do you refer to the fact that since iOS 8/9 you don't use the decrypted AES Key directly but instead feed it into a derivation algorithm that hashes it with a predefined set of strings (ie: AirPlayStreamKey/AirPlayStreamIV) as well as the streamConnectionID of each stream to come up with the final Key and IV to use for decryption of that particular feed? That has been working just fine since iOS8/9 all the way up to 10.0 but is producing garbled H264 frames when decrypting the same way on IOS 10.2+.

and video decode phase

The only thing I can think about here is the new payload type 0x1000 (4096) they introduced as well, which I currently ignore. is there anything in particular regarding the decoding of the decrypted H264 frames other than the conversion to Annex B format from AVCC for compatibility with most players?

robertoandrade commented 7 years ago

ping @cyshi

STL1te commented 7 years ago

ping @cyshi one more time

robertoandrade commented 7 years ago

It's kind of lame that the info we provided helped him and he is not willing to contribute the knowledge back (not the code)

robertoandrade commented 7 years ago

So no word whatsoever @cyshi ?

robertoandrade commented 7 years ago

@pengbin that's not all, there's something about the SHA512 key derivation logic that changed too and I can't figure out what, before you just hashed the fixed strings with the decrypted AES key to come up with the derived AES key and IV. Now it looks a bit different and from my reverse engineering of the various clients that cracked this successfully I still couldn't figure out what the new hash is composed of.

bobj1212 commented 7 years ago

Hi. Can someone please confirm that the aes method for decryption of the screen stream is still aes ctr? if not then which one is used now to decrypt the stream with the hashed aes key?

robertoandrade commented 7 years ago

That is still the case @bobj1212 the issue seems to be that since iOS 10.2 the hashing logic has changed for the derived aes key, I'm still trying to figure that one out. @cyshi seems to have a solution but has been pretty unresponsive for over a month now :(

robertoandrade commented 7 years ago

That is precisely what changed, the hashing algorithm, what is your source (ie: where is the stream coming from)

The derived AES key they now use to encrypt the content is hashed some other way starting with clients whose User-Agent matches AirPlay/320.20 (or above).

I'm still trying to figure out the new hashing done by those clients but it's gotta be something similar to the SHA512 process you just described with a small variance.

robertoandrade commented 7 years ago

The only thing I can think of is that when hashing the streamConnectionID you need to convert it to an unsigned long given it comes in as a signed one. Have you tried that?

robertoandrade commented 7 years ago

What does your 128 byte AVCC header looks like? You sure you're not sending Annex B formatted bitstream?

robertoandrade commented 7 years ago

Also make sure to send the codec data frames first unnencrypted, only the video bitstream frames need to be encrypted.

bobj1212 commented 7 years ago

is there any other change other then the fact that the bitstream is encrypted that is not the same in the protocol from how you send when stream is not encrypted? i.e at least for ios9, protocol is the same except from the fact that the bitstream is encrypted? all headers are the same ...

robertoandrade commented 7 years ago

Can you do an hexdump of the first few frames you send including the initial codec data (i.e.: pps and sps params) and the prefixing 128 byte header the avcc encoder must be giving you? Just want to make sure it's not using annex b notation. On Mon, Jun 5, 2017 at 8:58 AM bobj1212 notifications@github.com wrote:

is there any other change other then the fact that the bitstream is encrypted that is not the same in the protocol from how you send when stream is not encrypted? i.e at least for ios9, protocol is the same except from the fact that the bitstream is encrypted? all headers are the same ...

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306181162, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-WxWnZZOiwYVncFfG2rWw9_5SpKIks5sA_uPgaJpZM4GRiD8 .

msobiepanek-uz commented 7 years ago

@robertoandrade why are you so sure that hash algorithm has changed? It seems it's still the same string (as above) + connection id + key.

As you noticed there is this new payload in iOS 10.2 (4096), and you need to decrypt it first to keep aes order right. Then the first three video data chunks (with type 0) look like this:

000002fd21e00200225675afcd427c024a2995ace3a3c842f52a43bc480388727bf8205b4dc13a71387cc70e6bd8158fff2199c7cd1ab0a7a50da3d1b8ccbe66925410328f3e907b23194776f216e451f7a9a6ad837f6a5ab4ed53a3e7a704e3d47460bebf3a656b181dc5c6946ad484912f7b69eeeda6938210feacdb07958da76fae42b740cbdd22354257c7a28948b92154dce5088808b1ec5170b1c4df0c5073435aad9b29e8baf50fd1b3fadbc2438e93af3e163348a4f5d6384d690629279eda6326ce23702d28fc12fc87ceb8048d00383cbd060d74f86259a5d5ed5f534f1b40dbbd40da8800f75ada9cac663cc9a39894568cea11dcc505e83d10e08769a2be935cad0981acd1df64c5a28eae6cb40aeb996cb18cec1f434d907efb4cc771469a8d5226be60fd6ecd1fdabc557e87b44707b15190869ab08abc573e17859914fcecb9363ed99ffdd4612524606d8276ba078c2935091352e06892edfcec0d1cc6021c42a414468dff821c7df2817fb86b63f126c18ae6a77a1f72ad134b2907c690286480c85a2b39d9d0276ddea3187e36095467175f05dcf7dbbafd9e569adaf372a17a3f372fec83859db0c7d6d6bafe3425206d6581e3cd5648a307dffaeba3598f93cb83a1d6436f90cd170d358464892595156ebaad9df140b311a833c7221f209a414f1e6e6c1a872e8850de15208b8c8b2ad6d3611b8321b1028dfa8a01c4701648e199e700192b65d7064bb0a62f73cd6ecf3d696351f5453567e767653c2619f0be730e960efdf0189ca8a638b7fad2ce29d4e84a902b2e14c02af2bd6f7d5b733da9c31c1d3cc4584c31d21bb353b14dcc04b42c699a6f28ce4543efae229ac4b22b9b83110759e5a1fc0bbd6fc396417637c012352b7f354412bb147d237ecb3bad5212d0dd6f26416c1b7e1938e84f09713f9d90a13d8f2567454f46470ce6b0a1dc7607887ad76ae54c51bc74b00a5777759e42bc213039060a1ae98f30b60b3bf4f58ee90ba6fc8fa3b63659df648bdec17327c6a5a37aefae5e406e067498da986756948eb6e669a2273f4f07746f6fb755593520

0000011521e0040045a24a43bc57c51bfddac5d51c751c6f7d7169d677afe7d8cfc91ad427403872a78f3ad9f4402249f2cc0ca8630a38357ff0ae70eba321c21ecab1f4a3c1dc7dd400b9c2a7f079b97d0fff9e5f18316af37ef28723f2b2ec3442fd4e440b1f3a65c490dce999f19c7cea0ef280df1bb8ba988bf360e5064f32635e5ef3f2633f50c8edb52a800000a891f7691c9bab9f66ed5b6206f5dded4a0b3f512dedb627841b313505e90fd5745d9ece6334c81823008466872256df1b3fed33ba36563d91d845eefee02db8caeb44f83ec2aef3b6da0a7484f756bdf2e540431884bf5df63fa0a67ca4ebea99918c03674af4a1ff2eae28bec597232d376d42cd225aa78dc2135a33291eff0b8d06a95040005dc0

000002f821e0060065b24a53935fb2209fb177ad6414f0e22321c34564d81637310d9dc711dae882ff1b4e1272ae16578a7ac8db81578211fe26e86d4d05ca653466de2101270d78575b53735e63df54210ba372e488c1290e48ad279cdfa548c2afbfd21530d0aecb5ea3eef1721c5aeeb4420cf027eb31e30b7cc317b4c6525d7072c24c0f79adee8a5e2d9800161c91e15449954e248def843e8aad0086c10aed54671173c1d69d25772b1047193b71fa2fb0d7e111c337c91f21e2e181e4a5ca7cd442a79e7ff4d1c97d3cbcb007958eaaf8a1d7eff7e5b02b4d2a351d25745ef2a38e934ede3a7f97c3a38a4f58abee1dd340af0965615e4dfd47b6a9a005176ea7901953596a3832b9177877162fd38cd62fb63069a7cef4b05b1fce7c6692111675763c8a323f8445084919f375f793a57c6beb811a03fda194a52f21a3aab309133ffffd6fde1c08b9be7b743bd2e69dc020a267086500bbd19b6411f000b44b682f964432aa3ab3d911f24df6b6fcea9053e0863757b548e34b37f16ec7c852b9739d2ef19ba0bc0f350528aff6786e864774db744facce1454d559f2675d91a136249ab227bf5b3679a2d56e2869b5f18f2f2ed9742770b80d4eb6ccde959f124ce77371abc226dbaf86f9c7486a7857211b16a4385d597be03787efb2195793c8f32ac01b00a310c25b644bbbc491dd7d6f182e4a5db0541b7ee1e3d24302bac4dcf84f29a5f69c65a5fabe908ca0e96c9a79d2492eb83e9832c3b9048a4ec55647fed1145be9028cedf2b296eb4a771ec2b9684ff19f918b85b13b7faa265f6eea74e7e481f89ac122b9c6266c12e8ba58119350a8066d3e9d0e3271dea90db527b3796657f1274a8fc06a767ace6247f9f24dd1e44181079e3413603579cc71aa99ae19b41b08e4179a17c080ed269015de5cd8521e6bd8e344fc852e8be2258d80b560ec230f70330ef1950ba6671bb26ed4059ed05781e48b16774eaa744dfb854cfb12e5ce7de040e6f204ac3d579fe18f8bf185d3a5d62a7da1c0008eddfa5c948738371f8a6e6b92f84b1f98cb5f9d0f2f4ef8

It looks like valid AVCC data, first four bytes are the correct length of the NALU. However there is always only one NAL unit in the data. And until iOS 10.2 it was possible to replace length bytes with \x00\x00\x00\x01 to convert video from AVCC to Annex-B, now it doesn't work right away - I have no idea why. Maybe you'll be able to figure this out?

This data is coming from iphone 5, iOS 10.3.1, user-agent AirPlay/320.20

msobiepanek-uz commented 7 years ago

This 4096 payload looks like the first NALu and if I send it to the muxer I'm able to start actual screen sharing. But only the very first frame is clearly visible in VLC and so many artifacts later on...

robertoandrade commented 7 years ago

I noticed the same @maciej will try your suggestion for the key derivation and decryption but I thought I had tried that already. On Tue, Jun 6, 2017 at 4:47 AM maciej notifications@github.com wrote:

This 4096 payload looks like the first NALu and if I send it to the muxer I'm able to start actual screen sharing. But only the very first frame is clearly visible in VLC and so many artifacts later on...

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306422410, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-WH6jNXZvLHxcvgqGaHJmDph3aOmks5sBRIugaJpZM4GRiD8 .

robertoandrade commented 7 years ago

You're absolutely right @maciej maybe when I tested it I was ignoring the 4096 payload. Wondering where the artifacts come from. From my tests all the frames contain a single NALU but my logic is prepared to replace all AVCC 0001 prefix markers and replace them with length for annex b compatibility, I just never noticed it doing for more than one NALU in a given frame.

The other challenge I'm having is figuring out key derivation for the audio stream since it doesn't seem like the audio stream setup plist has a streamConnectionID and the negotiated key doesn't seem to decrypt the UDP/RTP packets I get.

robertoandrade commented 7 years ago

Correcting my statement from previously, the I'm replacing NALU length with the annex b 0001 prefix, not the other way around.

maciej commented 7 years ago

Hey @robertoandrade, I'd appreciate you stop mentioning me. I'm not involved in this issue.

robertoandrade commented 7 years ago

Sorry about that, I meant @maciejjj but for some reason it shows with a single j on my email notifications, my bad.

robertoandrade commented 7 years ago

Just to close the loop on the key derivation experimenta I had run before, it seems the derivation logic only changes between iOS 10.1 and 10.2 if you are doing pair-setup/verify to setup the context before decrypting the FP encrypted AES key and deriving it as you use information in the pairing context for the derivation. If I skip pairing altogether it works like before.

robertoandrade commented 7 years ago

The IV you send on eiv is the original IV it's ultimately discarded as the IV used to decrypt is derived from the ekey with the connectionId and the AirPlayStreamIV string. So make sure to encrypt with the derived IV but what you send on the eiv plist isn't really used anymore On Tue, Jun 6, 2017 at 8:10 AM bobj1212 notifications@github.com wrote:

I still have issue with the aes_ctr encryption for screen. Maybe i am doing something wrong with the IV. To get the IV, i hash the decrypted aes key with the (AirPlayStreamKey+connectionID). And i use this iv to encrypt. But what do i need to send to server in eIV? this hashed IV? It has no logic since server can generate it for it self from the encrypted key since i do not make random IV. my iv is just hash of key+strings. Hope you can help me with this.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306467012, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-SRTXyziEOTERMo3m5pH8mfpJXbJks5sBUG8gaJpZM4GRiD8 .

bobj1212 commented 7 years ago

Thanks! that made me crazy - i could not understand the logic. I will try to play with this more until i find why ATV show black screen. At least i can send audio not encrypted :). BTW does audio also being encrypted using aes_ctr? or another aes mode? and also, same logic for IV in the audio - sent the eiv as just 16 rand bytes that i generate (and not used anyplace else in my code) in blist as eIV and it is also ignored ? (Once i will passed these encryption issues i will be able to help with the issue you have with ios10.2...)

robertoandrade commented 7 years ago

I think I have it figured out for 10.2 now thanks to @maciejjj tips. My next challenge is audio decryption which it seems to be using CBC transformation but not sure yet about how it derives the key. On Tue, Jun 6, 2017 at 8:22 AM bobj1212 notifications@github.com wrote:

Thanks! that made me crazy - i could not understand the logic. I will try to play with this more until i find why ATV show black screen. At least i can send audio not encrypted :). BTW does audio also being encrypted using aes_ctr and also, same login for IV in the audio - sent it as just 16 rand bytes that i generate and not used anyplace in blist as eIV and it is also ignored ? (Once i will passed these encryption issues i will be able to help with the issue you have with ios10.2...)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306469544, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-SKvHmMDVBP6Jh8hanaOjPGW6Lxvks5sBUSMgaJpZM4GRiD8 .

msobiepanek-uz commented 7 years ago

@robertoandrade Were you able to get rid of artifacts from video? Or haven't you seen them at all? For now I'm putting video in the following way:

00000001 + sps + 00000001 + pps + 00000001 + NALU (from 4096 type) + 00000001 + NALU (type 0 from this point) + 00000001 + NALU + 00000001...

and so on. I write this data to a file (attached) and I'm able to play it, but video has many artifacts.

capture.mp4.zip

msobiepanek-uz commented 7 years ago

Hm do you use data with type 5 somehow?

robertoandrade commented 7 years ago

I haven't figured out a way around the artifacts yet and am currently ignoring type 5 payloads so maybe there's an answer there.

On Tue, Jun 6, 2017, 10:39 AM maciej notifications@github.com wrote:

Hm do you use data with type 5 somehow?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306506956, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-TqXnHfnAVykKGgJ23I_5yLCYjRPks5sBWSOgaJpZM4GRiD8 .

bobj1212 commented 7 years ago

so frustrating. i am still see black screen on tv. I am now trying to mirror to atv2. As far as i understand from you, in ATV2 where there is older ios (6.2..1) you use the original aes and iv. i.e no hashing on the key or iv. Is that correct? If this is correct then problem must me in my encryption function that cause me to see black screen even on atv2. Can you confirm that in older ios like 6.2.1 i need to use the original generated keys and iv with no hash into the aes_ctr? And another question, between calls to the aes_ctr, do i need to do something special with the IV? Thanks. Really hope you can help me to pass this step to find finally the problem.

robertoandrade commented 7 years ago

That is correct even though the version of tvOS is different than iOS, so not sure what you mean by 6.2.1 but that's how it used to work back iOS 8 days On Tue, Jun 6, 2017 at 6:22 PM bobj1212 notifications@github.com wrote:

so frustrating. i am still see black screen on tv. I am now trying to mirror to atv2. As far as i understand from you, in ATV2 where there is older ios (6.2..1) you use the original aes and iv. i.e no hashing on the key or iv. Is that correct? If this is correct then problem must me in my encryption function. Can you confirm that in older ios like 6.2.1 i need to use the original generated keys and iv with no hash into the aes_ctr? And another question, between calls to the aes_ctr, do i need to do something special with the IV? Thanks. Really hope you can help me to pass this step to find finally the problem.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306634309, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-TzDyAR9EozNwf143rVIDmcXhBG5ks5sBdEKgaJpZM4GRiD8 .

bobj1212 commented 7 years ago

i meant to the appletv software. on atv2 the latest one is 6.2.1 so now as said, i am checking on atv2. so i use the generated aes key and iv. This way at least i know that the issue is not with the hash since there is no hash on this old atv. Maybe it will help if you can let me know which lib you use for the aes_ctr encryption. and as said, if i need to do something special with the iv on each call to the encryption function.

Thanks.