Montag, 2. Januar 2017

Updates on prometheus / Stuck at Waiting for device... / Are my shsh file broken????

Hello everybody,
first of all i wish you a happy new year :D
In the past few days happened quite a bit, i held my talk at 33c3 about downgrading iOS, released futurerestore and img4tool and figured out tsschecker was broken.
Okay first things first. In case you haven't seen my presentation at 33c3 i really recommend doing so, as i'm explaining all downgrade related stuff starting from iOS (or iPhoneOS) 1.
Here's a link: https://media.ccc.de/v/33c3-7888-downgrading_ios_from_past_to_present
Right after the talk i released futurerestore and instantly got spammed with "it's not working i get segfault".
When i got home from 33c3 i figured it was related to build system i'm using for release builds (i'm automatically crosscompiling macos stuff on a linux box on every commit). The issue here was that futurerestore or better said even idevicerestore needs openssl. I've heard that was deprecated in macos a while ago and is not shipped by default (@p0sixninja suggested moving to CoreCrypto on macos).
Anyways, right now i'm simply linking the project to openssl's libcrypto.0.9.8.dylib which needs to be in  /opt/local/lib/ because the one shipped with macos in /usr/lib is missing a symbol. So until i changed stuff in my buildsystem (which is not first priority at the moment) you need to manually install openssl via homebrew or macports and make sure the library is there.
Having fixed that and a bunch of other stuff which i'm not gonna talk about because that's not too interesting, leaves us with one final problem: stuck at "Waiting for device...".
I need to say at this point that figuring out all these issues took a lot of effort, it "worked for me" and for some weird reason didn't work for everyone else. So after ruling out (hopefully) all the bugs in futurerestore which could have caused the "waiting for device" problem i finally realized the bug wasn't in futurerestore but in tsschecker.

When i started tsschecker it was a tool for me to analyze apple's tss server. It was really handy to send lots of different requests and see what response i'd get. The more and more i was working on tsschecker the more useful it became. At first i didn't even plan to use it to save shsh files, but at some point when i was working on prometheus i realized that tsschecker was the only tool which could do what i needed. At that time it was the --apnonce option and later the saving generator feature.
During development of prometheus i used tsschecker a lot and added more and more stuff to it, which in the end turned out to work perfectly with my test device (iPhone5s).
When iOS 10.1.1 jailbreak was announced and i told people that prometheus could upgrade them from one jailbroken iOS to another, everyone got hyped about saving shsh files.
While this would have been no problem with iOS 9, there is something apple changed in iOS10 i didn't notice, as i wasn't even using iOS10 on any of my devices.
Up to iOS 9 apple had a different IPSW for evey devicemodel (like iPhone6,1 iPhone6,2 ...).
With iOS 10 apple started packing lots of stuff into one IPSW making it usable for a lot of devices.
For example the iPad_64bit_10.2_14C92_Restore.ipsw is used for restoring 6 different devices!


As you can see in the image there are 12 different restore configurations (BuildIdentities) packed in one file!
This used to be 2 namely "Erase" and "Update" config, now there are 2 for every supported device.
Each of these configurations need a different APTicket.
What tsschecker would do in past versions is just take the first BuildIdentity and request a ticket for that. Which would have been fine is there was only one device supported per BuildManifest.
The first BuildIdentity in the manifest is often (always?) a config for "Erase", second is for "Update".
That didn't really matter in previous downgrades, as the only difference is the ramdisk hash (one for restore ramdisk, one for update ramdisk). However this does matter for prometheus. But even if tsschecker would pick the "Update" config instead of "Erase" you could simply use -u option in futurerestore and you would keep your data while upgrading (in case this doesn't fuck up the device ;P). The real problem here is that if the first BuildIdentity isn't for your device. For example you have iPad4,2 but the first BuildIdentity is the "Erase" config for iPad4,4.
In this case tsschecker would request a APTicket for iPad4,4 instead of iPad4,2 which renders the APTicket useless to you.
I didn't really notice this until now, as it *just worked* for my device.
This is fixed in latest tsschecker (which is 157 at the time of writing). Right now it properly searches for the correct config. What i noticed here is that there are some models like iPhone8,1 which have different boardconfig ("n71ap" and "n71map"). Those need to be correct too. Tsschecker now has a parameter -B or --boardconfig which lets you specify the boardconfig. It tires to automatically derive boardconfig from devicemodel and devicemodel from boardconfig, but in case there are ambiguities you need to specify the model/boardconfig manually.


So this hopefully save valid shsh files for future, but what about the ones we already saved?
How to verify they are good/bad?

Today i updated img4tool to version 82.
I added -v --verify parameter. This doesn't even comes close to what i plan to check inside IMG4/IM4M files, but today's update should be good enought for us right now.
What we need to do is to verify which of the BuildIdentities match the APTicket we have saved.
To do this we can do: img4tool -v BuildManifest.plist -s my_saved_file.shsh
IMPORTANT: you need to take the BuildManifest.plist from for IPSW your shsh file correcponds to.
If you saved your shsh file for 10.1.1_14B150 then you also need to use the BuildManifest.plist from the 10.1.1_14B150 IPSW.


When you run that command you'll see a bunch of warnings, which you can ignore. I need to figure out in future how to handle a few things but as of right now it works.
When the shsh file matches any of the restore configs in that BuildManifest you'll see something like in this image. What it would do is print you some information about the BuildIdentity which matched.

The important thing here is to check DeviceClass of that shsh file. The given file can only be used to restore ("Erase" install) an iPhone8,1 with boardconfig n61ap.
This is ok right?
Well the poor guy who sent me that shsh file also sent me his futurerestore log:

What you can see right in the very first line is that his phone actually is n71ap, which is not what the APTicket is for. Futurerestore tries to stich that APTicket to iBEC.n71.RELEASE.im4p which is correct for that device, but since the ticket is not for that file verification fails and the device rejects it.
This means the device fails to load iBEC, ramdisk, kernel and doesn't boot into restore mode.
You might be thinking: well let's just boot the other iBEC which the ticket is for.
But that won't work, as there are checks whether the firmware actually belongs to the device or not.
Unfortunally this person is just out of luck :(

Is there anything i can do when my ticket has wrong boardconfig?
Not really, all you can do is make sure that you save for correct boardconfig in future.
Even if that's not what you want to hear: make sure you save shsh for 10.2 while it's signed :/


So that's the story with with bad tickets, if you verified your tickets to be good and you still stuck at "waiting for device..." then just send me a tweet or an email and i'll see how i can help :)

At least there were some people who were able to use prometheus so the work was definetly worth it :D

Keep saving your shsh files
greets
tihmstar