horrorho / InflatableDonkey

iOS9+ iCloud backup retrieval proof of concept
MIT License
262 stars 87 forks source link

Security update: Unauthorized #68

Open horrorho opened 7 years ago

horrorho commented 7 years ago

If you get an unauthorized exception using an existing mmeAuth token, you'll need to re-authenticate and use a fresh one.

:dragon:

There is a lot more to this issue and I suspect it revolves around a certain security flaw that Apple introduced in iOS9. However being the mean girl that I am, I would like to wait and confirm this before commenting further.

ajlyakhov commented 7 years ago

Thanks for the update. I've faced some issues with "Unauthorized" before because of obvious reasons and in most cases that also block Apple iD but not this time. It seems like mmeAuth token gets expired or blocked on Apple side, but apple id itself left active. So, I've re-authenticated and its fine now. Let's see how that goes further.

ghost commented 7 years ago

Just curious, when did these unauthorized exceptions start to appear? Also if we were to get this wouldn't that also mean that the account would sign out of all iCloud services on the device?

horrorho commented 7 years ago

@Yaldo425 In the last 24 hours or so. No it doesn't sign you out of other devices. I'm off to work now but I will make a more detailed post when I'm back this evening.

ghost commented 7 years ago

@horrorho Ok, thank you! This is pretty big and an explanation would be greatly appreciated. Would you know if there is a way around this error and has this become a permanent thing, meaning that I'll need to get a new AuthToken each time?

horrorho commented 7 years ago

Ok. InflatableDonkey, particularly in it's non-public modified forms, has the ability to bypass certain security mechanisms and for the most part I tend to keep quiet about it. Although I'm aware of numerous security concerns I've no interest in joining the magical kingdoms of iOS hackers/ security experts. This particular issue appears to have been patched so I'll make an exception.

iOS8 backups are only retrievable using mmeAuth tokens that are less than an hour old. It is not possible to take cached or old tokens and acquire backups with them. They can however be used for other iCloud activities (Photo Streams/ etc).

With the introduction of iOS9 Apple omitted this security layer. All valid tokens, regardless of age could acquire backups. This has now been patched and only new mmeAuth tokens (< 24 hours) can acquire backups. They can be still used for other CloudKit activities (iCloud photos/ documents/ etc). Modified versions of InflatableDonkey and it's unfinished replacement can still acquire iCloud photos/ WhatsApp archives/ etc. This is now more consistent with iOS8 behaviour.

This patches quite a nasty vulnerability where hackers/ law enforcement/ etc have had the ability to continually acquire backups using mmeAuth tokens, even in certain cases where the user has subsequently activated 2FA. I'm about 110% certain that NSA still has unfettered access to your data, although I won't provide any firm evidence to support my conclusion. We'll just say that I've seen and noted many things in my journey through countless hours reversing iOS/ iCloud assembly code/ protocols and leave it at that.

As of now you'll need to re-authenticate and acquire a new (< 24 hours old) mmeAuth token for backup retrieval. This should not impact legitimate users. Please be aware that the authentication mechanism has a much lower tolerance for suspicious activity (see #56) so please continue to use tokens as much as is possible. There has been a warning to this effect on the home page for the last two years or so but it still catches people out.

Astute users will be aware that there are still a few security mechanisms InflatableDonkey works around. My advice is not to rely on this.

:smirk_cat:

horrorho commented 7 years ago

Oh. I have spent the last few hours looking for a work around using unusual access patterns but it appears Apple have these covered. They have deliberately disabled other options with nice error messages to boot: Optional feature CHANGE_SET_TRACKING is disabled for this container, AppDefaultZone does not support getChanges call, etc.

There are a number of additional tricks that may work but to be honest I'll probably not bother as it's time consuming with no guarantee of success. If however it becomes clear that one of the other iOS backup retrieval companies finds a solution I'll look into it again. Those guys do this for a living, I do it as a hobby.

As usual I make no claims to be any sort of expert on anything and it's entirely possible I'm mistaken.

Feel free to feedback and to send me cake.

:cake:

michaljirman commented 7 years ago

Hi @horrorho, out of the curiosity and since the issue has been patched. Would you mind to clarify a little bit more on the way how the fixed unusual access pattern looked or was performed? I mean the one which returns now the error "Optional feature CHANGE_SET_TRACKING ...".

horrorho commented 7 years ago

@Jirmi I have a private tool that's based on an advanced CloudKit layer. It implements a lot of the low-level API that is missing in InflatableDonkey. I coded the core of InflatableDonkey's CloudKit API like two years ago now and it's light years behind what I know now.

There are a handful of ways to access CloudKit records. I was hoping that Apple had neglected to patch some of the non-direct calls. I admit I've not tried them all. There are also non-CloudKit approaches I've not had time to test. I understand this is somewhat vague but without releasing a lot of undocumented information on the internal API, it's going to be difficult to clarify.

As to releasing that private tool or undocumented information. It's problematic because it's exposes access to CloudKit in a manner that is not hardened, although Apple have been patching in holes. In comparison to the official CloudKit API it exposes a number of hidden calls and flat out bypasses certain security layers.

I've no intention of releasing a tool that could build an exploit toolkit. InflatableDonkey is already uncomfortably close even though it's only limited in scope to backup retrieval.

michaljirman commented 7 years ago

Hi @horrorho, thanks for the reply and no worries. I don't expect and I don't even wish you would release any private tool or information to the public which could be misused. I am just curious since you have mentioned that there were (or still are) some other ways how to access CloudKit records. I am happy to take on personal challenge to find some of them :-) since I know (thanks to you) there are some other approaches.

fongph commented 7 years ago

As of now you'll need to re-authenticate and acquire a new (< 24 hours old) mmeAuth token for backup retrieval

Is it the same story for mmeAuth token acquired from a 2FA-enabled account? I wonder if InflatableDonkey can be modified to be trusted so we don't need to do the 2FA workaround (tagging the fresh 6 digit code to the end of password) every time and simply just use user name / password to sign in.

horrorho commented 7 years ago

Hi @fongph. As far as I'm aware it does apply to 2FA for reasons stated above. Feel free to correct me if this is not the case.

In effect your second question concerns working around the tightened 2FA token requirements. As stated in earlier comments there are potential workarounds but I've not had the time to test them. Now that you've mentioned it, or at least alluded to it, I can confirm that trusted device spoofing is on that list.

Again I'm unlikely to work on this. It's a time/ ethical issue. There are other potential workarounds that I would like to test first. However some of these could legitimately be called exploits and at least one of them is severe.

horrorho commented 7 years ago

ElcomSoft commented on this issue a couple of weeks after this ticket with additional insight.

Of note: I only vaguely identified the expiration interval as being less than 24 hours, they've suggested it's closer to 12 hours.

I've been neglecting anything iCloud related in lieu of work for the past few weeks, so thank you @Jirmi for bringing it to my attention.

ajlyakhov commented 7 years ago

Hi @horrorho, in that article from ElcomSoft, I see the statement:

From now on, the following expiration time applies to iCloud tokens:

  • System backups (all versions of iOS): 12 hours
  • iCloud Drive data: unlimited, tokens unaffected
  • Synchronized data: unlimited, tokens unaffected
  • iCloud Photo Library (all versions): unlimited, tokens unaffected

Does that mean that theoretically we should be able to use tokens to retrieve files from CameraRollDomain and that would NOT be affected by current 12-hour rule?

I just give it a try with expired token:

java -jar ./InflatableDonkey.jar <expired_token> --domain CameraRollDomain

but still got "Unauthorized".

horrorho commented 7 years ago

@ajlyakhov Hi there. iCloud photos and the CameraRollDomain are not quite the same.

The iCloud photo library is stored in the com.apple.photos.cloud container. It remains accessible for the duration of a valid mmeAuthToken.

The CameraRollDomain exists within a snapshot that is stored in the com.apple.backup.ios container. It remains accessible to reads only for the first 12 hours of a valid mmeAuthToken's lifetime.

I've previously mentioned on other threads that there is a timestamp baked into the mmeAuthToken itself. Without elaborating on their structural details or behaviour and assuming that it's not been changed recently, I can push a gist to dump the mmeAuthToken timestamp if anyone cares for such a thing.

ajlyakhov commented 7 years ago

Thank you @horrorho! So, can we get access to com.apple.photos.cloud container using InflatableDonkey?

horrorho commented 7 years ago

@ajlyakhov #49

michaljirman commented 7 years ago

Hi @horrorho, since you are mentioning it ... I would be quite interested on the gist to dump the mmeAuthToken's timestamp.

horrorho commented 7 years ago

@Jirmi https://gist.github.com/horrorho/7207e7c2d13572532d1801d0d3b08cc8

Example token:

12345678:AQAAAABZkNzAEjRWeBI0VngSNFZ4EjRWeBI0Vng=

Timestamp:

AQAAAABZkNzAEjRWeBI0VngSNFZ4EjRWeBI0Vng= -> 2017-08-13T23:12:00Z

The timestamp is extracted from the mmeAuth component. It corresponds to the time the token was generated as opposed to any sort of expiration time.

The binary format also applies to other token types but the Base64 encoding scheme may differ depending on how the token was retrieved.

We're kind of poking around in Apple's private parts here so I'll just leave it at that.

marksims commented 7 years ago

hi @horrorho is it possible we download photo in the com.apple.photos.cloud container with inflatabledonkey? Thanks

QUOTE: "The iCloud photo library is stored in the com.apple.photos.cloud container. It remains accessible for the duration of a valid mmeAuthToken."

horrorho commented 7 years ago

@marksims Hi there. Kindly refer to #49

michaljirman commented 7 years ago

@horrorho thanks for the gist! It's probably worthy for me to have a look at the other tokens as you mentioned.

ajlyakhov commented 7 years ago

Hi @horrorho,

I'd like to experiment a bit with com.apple.photos.cloud container. My final goal is to get an ability to download photos, should that require:

In general, any guidance would be really helpful.

horrorho commented 7 years ago

@ajlyakhov #49