Mittwoch, 18. Januar 2017

HALP! i get same nonce/100% nonce collision

Hello everybody,
once again there is an unsolved mystery, so there is once again time for a blogpost!

This time: The mysterious "always same nonce *bug*" or "100% collision with nocestatistics"

So after releasing futurerestore/noncestatistics (basically tools which *bruteforce* apnonces), i got lot's of tweets/emails telling me this is a bug in noncestatistics/futurerestore/calc.exe

So what's really up with this?
Well i can assure you this is neither a bug in noncestatistics, nor in futurerestore and also not a bug in calc.exe
You might be thinking: why is this apnonce thing, which is supposed to be random, always exactly the same?
I assume this is a bug introduced somewhere in 10.x

But let's take a look at what really happens...
If you've seen my talk at 33c3, you probably know what happens if you request an apnonce in normal mode.
Quick recap:
1) you request an apnonce with iTunes/idevicerestore/on device OTA updater
2)lockdownd (i think it's lockdownd, but don't quote me on that) is responsible for answering the request. So lockdownd asks the kernel "hey i need a nonce".
3) kernel does the following:
3.1) if a nonce hasn't been requested since the device booted, choose a random generator and write it to nvram.
3.2) read generator from nvram and derive a nonce from it
3.3) return that nonce to lockdownd

So here you see, that when you request a nonce twice without rebooting a device, you'll get the exact same nonce in normal mode. If you want it to change (in normal mode), you need to reboot.
So far, so good.
Now when you reboot into recovery (iBoot) two things can happen:
1) a generator does not exist in nvram, then *somehow* choose a random nonce (i'm not 100% sure but i think iBoot randomly chooses a generator and then derives a nonce from that, instead of directly deriving a nonce)
2) a generator does exist, then derive a nonce from that generator directly

When you go the second route, the generator is cleared from nvram, so if you reboot into recovery again, you can't get the same nonce twice.
This makes totally sense.
The problem is that for some reason apple fucked this up in iOS 10 (WTF APPLE!?!?! it worked perfectly fine in pre-iOS 10).
So the issue now is, that nvram doesn't get cleared so always the same nonce is derived in recovery.
So if this happens to you, you can verify this by changing the generator.
To do this you can reboot into normalmode and request a nonce. This should make the kernel write a different generator to nvram. If the generator still doesn't get cleared in recovery, then you should at least see a different nonce repeating over and over again.

Now i don't know what exactly causes this and i do know that it is possible to not have this problem, to launch the probabilistic attack exploiting bad randomness, however i don't know what exactly you need to do to clear that nonce from nvram without jailbreak.

Can you abuse that for prometheus?
Well, technically you can, because if you request an APTicket for that nonce and get the same on next reboot, you can use that ticket.
The issue here is, that once the nonce changes you'll probably never be able to generate that again (assuming the PRNG isn't horribly broken on post iPhone5s).
So you'd need to avoid requesting an APNonce in normal mode via iTunes (which shouldn't be too big of a problem if you never connect your phone to a computer), but you also need to block the on device OTA updater from requesting a nonce, which might be more of an issue.

This means if you somehow can keep the same generator forever in nvram, you can downgrade iPhone6/iPhone6s and iPhone7 with prometheus without jailbreak. So if you want to look into this, go ahead and share your results with us. (I'd love to see a page on theiphonewiki where people can actively work and share their results about all this)
I personally will not look into this particular bug right now.
Also don't forget that apple introduced this bug with an update and they can easily fix this with another update.

So that's the story with 100% noncecollision. You don't need to worry that noncestatistics, futurerestore or calc.exe might be broken.


Dienstag, 10. Januar 2017

BasebandGoldCertID not found, please spam tihmstar!

Hello everyone,
i've been writing a few blogposts lately, which were really fun and i think i can get used to this :D

Today's topic is tsschecker's BasebandGoldCertID (or short bbgcid).
You might have see this warning in tsschecker already:
Version: 211220dfa58e15d9f15c08a9185b53acadc489de - 182
[TSSC] opening firmware.json
[JSON] counting elements
[JSON] parsing elements
[TSSC] selecting latest iOS: 10.2
[TSSC] using cached Buildmanifest for iPad3,5_10.2
[Error] [TSSC] ERROR: device "iPad3,5" is not in bbgcid.json, which means it's BasebandGoldCertID isn't documented yet.
If you own such a device please consider contacting @tihmstar to get instructions how to contribute to this project.
[WARNING] [TSSR] there was an error getting BasebandGoldCertID, continuing without requesting Baseband ticket
[TSSR] Request URL set to
[TSSR] Sending TSS request attempt 1... success

iOS 10.2 for device iPad3,5 IS being signed!

ERROR: device is not in bbgcid.json, it's BasebandGoldCertID isn't documented yet.
So what exactly does this mean?
Again, tsschecker started as a project to analyse apple's tss server. You can send customized requests and see what it responds. Beside APTickets for the main iOS system you also have the baseband.
The baseband is a seperate processor, which has it's own OS. One of it's main tasks is to handle cellular communication like GSM, LTE and stuff like that (note i'm not an expert about baseband).
So basically you have basebands in phone and also in iPads which have 3G or LTE or whatever.
When restoring such a device you also need to restore the baseband, which has it's own seperate restore process. It also uses stuff like APTickets which need to be requested from apple while restoring (i really haven't looked into how this exactly works, these are just general observations).
So we note here: when restoring we also need a ticket for the baseband.

Tsschecker is able to request such tickets even though there are not many customizations yet.

Does that mean i can save a basebandticket?
Yes, you can save a baseband ticket if you want.
So it works as following:
When requesting a baseband ticket you need to send a bunch of values for apple. I figured out that most of these values can either be random, or omitted completely. All except the BasebandGoldCertID. This one has to be a device specifiy value matching the devicemodel.
For example if you want to get a ticket for the iPhone6,2 baseband you need to send the BasebandGoldCertID 3554301762. This is the same for all iPhone6,2 models. If you don't send this exact value for the iPhone6,2 you don't get a ticket.
Normally when you restore a device using iTunes or idevicerestore that value is read from device while restoring, that's why a central database was never needed.
But tsschecker aims to send requests to apple's server without the need of having a real device connected (thus the name "tss checker").
So this is the reason i started to collect BasebandGoldCertIDs.

Cool, does that mean i can downgrade basebande?
No, unlike iOS a downgrade is not possible. This is because the baseband all this ticket and restoring and signing stuff and i don't know of anybody actively looking into it and especially actively working on a downgrade. In theory you can find bugs or something like prometheus in the baseband but right now there isn't any public tool able to downgrade the baseband (correct me if i'm wrong) and also i don't know anyone working on that.

So what are the tickets even used for if i can't downgrade?
Literally nothing. I don't even know if the tickets we are saving right now can be used for downgrades in future or if there's something important i left out/didn't notice. Again, i haven't really looked into baseband.

So why even requesting tickets?
Well the initial idea of this is just to see if the baseband of a specific iOS verison is signed or not (remember "tss checker"? :P).
Right now this feature is used in futurerestore to see if a baseband is really signed before attempting to restore a baseband which was not shipped with the version being restored. (That cool iOS/baseband mismatch thing allowing to downgrade with prometheus)

When i started tsschecker i didn't know this tool would be that popular. I thought i should ask everybody who even cared using this tool to help me collecting bbgcids, but right now i get spammed with emails. This is why i decided to write this blogpost to exaplain what this is all about.

Ok i see. I have a device, which you don't have in your list, how can i help?
Finally the good part :P
Ok so basically you need to take your device and read out the BasebandGoldCertID and send me an email containig the devicemodel and the bbgcid. Then i can put that to tsschecker. You can even make a pullrequest on github with your bbgcid. If you can, please test if you get a ticket before submitting the bbgcid. If you run tsschecker with --no-baseband=2 then it will try to request only a baseband ticket.

How to find BasebandGoldCertID?
There are two easy ways of finding it. The first one is with ideviceinfo:

The second is with latest redsn0w, which you can get here:
Make sure to use the "normal" version, not the beta.
Then you click Extras->Even more->Identify

So let's go and collect all BasebandGoldCertIDs


Donnerstag, 5. Januar 2017

How to downgrade without jailbreak using prometheus

Hello everybody,
since the release of prometheus there has been a lot of confusion about what it can do and what it can't do. A lot of people asked me whether they should upgrade their 9.3.x device to iOS 10.2 to be able to downgrade to iOS 10.1.1. Every time i read this i was like NO DON'T DO THIS! But i can't stop everyone trying. I understand that this stuff is kinda complex, but i didn't think it would be *that hard* to understand. So far i've seen like 1 or 2 persons who kinda understood what they need to do, but even they fucked up in the end.
Let's clearify what prometheus can do and what it can't do.

Q: Can i downgrade without jailbreak?
A: No!

Q: But i saved shsh2 with tsschecker, why can't i downgrade without jailbreak?
A: Just saving shsh2 files is not enough! You need to do more. If you're asking this you surely didn't prepare properly and now it's too late.

Q: But i have iPhone5s/iPad Air and shsh2!
A: That's not a question. Also if you didn't prepare properly you still can't downgrade, even with shsh2!

Long version:
Doing crypto is hard. Doing crypto correctly is even harder!
Apple did a really great job with it's secure bootchain, the design is in theory really secure.
Of course there can always be bugs in the code, which might be exploitable, but that's not what we're gonna talk about in this blogpost. In my talk at 33c3 i described how the bootchain works, so if you haven't seen that i recommend doing so.
Apple uses crypto right in the first step of booting, they hash bootfiles and verify signatures. This makes it impossible to tamper with the data (assuming they did it right). But even when they did everything right, planned every step carefully, hashed every byte of data and verified every file's signature things still can go wrong. Like i said in the beginning, crypto is hard. Many things in cryptography depend on random numbers. When you design some cryptographic protocol you want to have a TRNG (True-Random-Number-Generator). Since those are really hard to make in practise the second best thing you want is a really really good PRNG (Pseudo-Random-Number-Generator).
I've seen many times people fucking this up, so i though "well, let's see if apple did it right".
Even if i didn't expect this to work at all (since 64bit device with SEP have a TRNG !?!??!) i still tried this, because well there's still the chance that apple fucked things up. For some reason iBoot doesn't use the TRNG from SEP but instead falls back to a PRNG (at least that's what i assume, i haven't really verified this). Since iBoot is the third thing to boot (Bootrom->iLLB->iBoot) there isn't really much happening in the device at this point and the entropy is very low. This makes it really hard to make a good PRNG.

So, why do we even need random numbers?
You've all probably heard about this "nonce" i keep talking. What exactly is a "nonce"?
Per definition a nonce is a "Number used ONCE". Often you just want a random number, you use it once and then you throw it away and never use it again.

Ok i see what a nonce is, but why do we need that?
Back in the iOS 4 day we didn't have nonces. We still had hashes and signatures, but no nonces.
This allowed us to do a pretty simple attack against the system, called "replay attack".
Back then you'd save an shsh blob (which was just a signed hash) with TinyUmbreall or something like that and when you'd try to restore you'd simple send the shsh blob you saved to iTunes which would give it to the device. Hash is fine, signature is fine let's restore!
So every time you restore a device you would give it the exact same sequence of bytes. Even if you in theory should ask the tss server on every restore, since the bytes never changed you can save and replay. You can't generate this sequence of bytes yourself, but you can just ask the tss server and save them. This would ultimately be the key to restoring iOS 4 devices. So when apple stops giving out the "keys" (Note: this is just a metaphor, you don't really get keys) you don't care, because you already have them.
Things changed with iOS 5 where apple introduces APTickets which have nonces.
So what does it mean?
When the device boots up it generates a nonce which is a random sequence of bytes.
What iTunes needs to do is to ask the device for the nonce it just generated. When iTunes requests an APTicket is send this nonce to the tss server too. The tss server generates an APTicket with the nonce it got and sends it back to iTunes. So now that ticket contains a bunch of hashes and this specific nonce. The device now verifies the APTicket and reads out the nonce inside. Then it compares the nonce in the APTicket with the one it just generated and if they match it boots the file. If they don't match however the file is rejected and the device doesn't boot up.
(Nonces are not checked on normal boot, but that's not the route we want to go)
The problem here is that even when you save the APTicket, the device would generate a completely different nonce on the next boot which makes that particular APTicket useless.
Since we can't do anthing to correct the nonce inside the APTicket we saved there is only one thing we can try: make the device generate the same nonce again!
Because if the device somehow generates the same nonce, we can again use the APTicket we saved and we win!

Remember i said crypto is hard? Well apple fucked up with random numbers in iPhone5s and iPad Air. Right now these are the only device i know to be vulnerable, but maybe they fuck up something else in future ;)

How exactly did they fuck up?
When generating random numbers it is possible that once in a while a number repeats. This is totally fine, since numbers are random and ideally every number has an equal chance of being generated.
Since nonces are 20bytes long, every nonce has the probability of 2^(-160) being generated.
If we assume that the device first randomly chooses a generator, which is 8byte in size, and then derives a nonce from that by hashing it with SHA1, you still have 2^64 different nonces, which are generated with the probability 2^(-64) each.
This is fine.
The issue here is that in reality for some reason nonces aren't generated with this probability.
I noticed that there are five nonces which together are generated with the probability of 1/5 which is 20% which means that on average every 5th nonce is one of those five nonces.
This is really bad!

To the attack!
Now if we save an APTicket for each of those 5 nonces we need an average of 5 reboots to make the device generate a nonce which is in one of our saved APTickets.
This is cool!

Now this was enough theory, let's get to the practical part!
First of all we need to figure out what nonces are generated the most. This theoretically can change in every iOS update so we need to do this for every new iOS version released!
It definetly changed from iOS 9 to iOS 10, so keep that in mind.

What we need to do is get noncestatistics and let it collect nonces for a few hours.
I'd say with about 500/1000 nonces you're good to go. Basically you just need to find those which are generated most likely.

By running "noncestatistics nonces.txt" it will collect nonces and save them to nonces.txt.
We let this run until we get like 500/1000 nonces and then we stop it with CTRL-C

This will stop collection, kick our device out of recovery mode and boot it back to normal.

Now having all the nonces we need to sort and count them, so let's run "noncestatistics -s nonces.txt".

So i let this run while taking a shit and collected about 400 nonces. Here we can see the ones generated the most. The ones which were generated like 2 or 3 or 4 times we can ignore, since this can always happen when dealing with random numbers, but those with a likelyhood of 12% and 8% are the interesting ones. In this example i figured that my iPhone5s on 10.1.1 generated these nonces quite a few times:

Note: you definetly need to make your own tests, as your device might generate different ones!

Now we save an APTicket for that particular nonce. (be sure to put your real ECID in there)

Repeat this step for all of the nonces up there. Also don't forget to change the filename or move the files into different directories so you don't overwrite them.

If you want to check what nonce is inside your APTicket you can use img4tool:

BNCH is the nonce inside the APTicket.

If you then decide to restore with futurerestore, you can specify all of your saved APTickes to increase the likelyhood of finding a match.
You'd run something like "futurerestore -w -t 1.shsh -t 2.shsh -t 3.shsh -t 4.shsh -t 5.shsh" and of course all the other parameters to futurerestore.
This will reboot your device until it generates a nonce which is in one of your APTickets.

I hope this clears the confusion about why your device never generates the correct nonce and what you need to do to be able to use the collision method in future.
If you still have questions or i forgot to mention something important, feel free to ask me on twitter or send me an email.
Keep in mind that i will ignore stuff like: "tsschecker crashes on windows when i doubleclick it".

Good luck saving APTickets for your colliding nonces


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:
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