We left off last time trying to run the final, ultimate command:
And it failed with BANGing errors. Well, it took me some time to realize what the main problem was: in Python you need to first declare global variables, and only then can you use them in ‘functions’ or whatever you call them in Python (yeah, my Python knowledge is, um, somewhat ‘limited’ to say the least :D).
So all I had to do is copy the declarations of each global variable from all the ‘functions’ to the top of the file. After that it continued, but just to hit me again now with a “No such file or directory” error.
Turns out, that in the latest SDK gcc isn’t called gcc-4.2 anymore, but just simply gcc. So I needed to change that, then change the path because it wasn’t good either, then correct everything inside of the ‘functions’ too.
After that I needed to create a symbolic link named cur inside of config pointing to SOURCE/bs.
After that I just needed to add some more changes, because the regexp used to construct the current target device and build number didn’t work, so I harcoded in my values: (I know it is dirty, sorry…):
After all this, it seemed to be fine… but only for some seconds:
Assertion failed: (things[i].r_length == 2), function relocate_area, file mach-o/link.c, line 30.
fabricate: 'python' exited with status -6
I had a look at the file in question (SOURCE/data/mach-o/link.c), it is quite a simple one, but the function is quite complicated. As far as I know (right now) it gets (a) binary object(s) and some other parameters and it does some work with these: first of all it creates an array of relocation_info structures with the parameters loaded in, then it goes through all the array items with a for-loop. The first step of the for-loop is the assertion:
assert(things[i].r_length == 2);
So, the things array’s (that contains relocation_info structures) i-th item’s r_length needs to be 2. Looking at the header file it means “Long”. Well, for me (I put some printfs in the file to see what is going on) it works fine, but then it gets a 0 instead of 2. BANG, there is the error.
Sadly I don’t know yet how to continue, the error could be caused either by the input file (kernel cache) or the code itself. I am pretty sure it is the input file, but still not 100% sure about it, so I will keep digging.
See you in the next episode (I hope there will be a next one :)).
So, last time I was just about to do some compiling, getting down to real work, right? Well, let’s have a look at the README file of star_:
How to use:
- git submodule init -u
- ln -s /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk /var/sdk
- add binaries to bs, e.g.
cp decrypted_kernel iPhone2,1_4.3.3_8J2/kern
cp dyld_shared_cache_armv7 iPhone2,1_4.3.3_8J2/cache
OR import an ipsw:
install "xpwntool", "hfsplus", and "dmg" to ~/xpwnbin/
in here: cd config; python ipsw.py whatever.ipsw
- get t1utils and apply this patch: http://pastie.org/2251647
- get http://github.com/comex/xnu-env and point fs/xnu to it
- ./make.py pdf
As you can see it isn’t very long, but also not very detailed. Fortunately I was able to figure out that step 0 would be having a Mac OS X box up and running. Thanks to some guides I was able to do this pretty easily using VMware Player, and I have a Mac OS X 10.7.5 Lion machine up and running. I installed MacPorts, which is an essential component if you are planning on doing anything from the Terminal.
So, step 0 completed, let’s go on with step 1:
Cloning the GIT-repo and running the submodule init was pretty straightforward, except that the command in the README doesn’t work anymore, instead I did:
git submodule init
git submodule update
After that I had all the sources needed, let’s get to step 2 which is linking the SDK to /var/sdk. Well, it was kind of natural to me that I need to get the SDK from somewhere, which means going to the Mac AppStore, signing in with an Apple ID and install Xcode. If Xcode is installed you still need to find the SDK, here is what I have done:
You probably noticed, that I have a slightly different path and also iPhoneOS6.1.sdk, not 4.3. As far as I know this SDK still has support for iOS 4.3 in it (you can even select iOS 4.3 as your Build Target in Xcode), so this should not cause any problems.
All right, so far it hasn’t been very hard, let’s go to step 3, which is getting some required files from the IPSW file we need.
First of all I downloaded the IPSW file using idownloadblog.com. After that I tried to compile xpwn but I failed because somehow I wasn’t able to install CMake, so I searched the web and found some binaries of xpwntool which work great.
After that I thought I have everything to run the command, so why not give it a go?
mkdir bs #this is the output dir and it needs to be there
python ipsw.py iPod3,1_4.3.3_8J2_Restore.ipsw
And BANG! an error:
Couldn't get keys for iPod3,1_4.3.3
Okay, let’s have a look at the Python script. After some minutes it was obvious that the script uses a file – keyz.txt to get decryption keys for the files inside of the IPSW. So I only needed to go to iphonewikiÂ and get the keys for my iPod Touch. After I inserted the values to keyz.txt the script seemed to continue, but only after some seconds, it failed again:
lzssfile.c:createAbstractFileFromComp:112: mismatch: 4073636 7933935 7933952 ba 8a
error: cannot open infile
Well, that’s awkward, I mean what can I do with this? Fortunately there is one Google hit for this error message, which is from iphonewiki, this talk. According to the talk the solution is to give xpwntool the switch -decrypt and then later go on with manually processing the file (which is now decrypted but not decompressed).
So I did exactly that:
unzip iPod3,1_4.3.3_8J2_Restore.ipsw #Yeah, IPSW = ZIP :-)
~/xpwnbin/xpwntool kernelcache.n18 kernel_decrypted -k KEY -i IV -decrypt
Great, this finished without any errors, let’s get to the decompressing part. According to the book ‘iOS Internals’ (this part of it could als be read at Google Books for free) you need to open the file with ‘od’ find a specific pattern, then using the offset run the decompressor program which is called ‘lzssdec’. Well, od was easy to use since it is built into OS X as far as I know, so I only needed to get lzssdec. I found its source code easily with Google, so here is what I did:
g++ -o lzssdec lzssdec.cpp
od -A d -t x1 kern_decrypted | more
#Looking for a specific pattern: ce fa ed fe
lzssdec -o OFFSET < kern_decrypted > kern_final
If we were lucky in kern_final we have a decrypted and decompressed binary, let’s check it:
kern_final: Mach-O executable arm
Success, let’s move on!
Well, we have the kernel file, so now we need to get the other two files: cache and dyld. To do that the easiest way is to comment out the kernelcache stuff from ipsw.py and then just run it. This will create the missing two files in the directory SOURCE/bs. We need to copy kern to this folder too.
Awesome, we are almost there, right? What is next on the list?
Well, I finally started working with mobile-devices from the newer era, namely iOS (as you might know with older Windows Mobile devices I did some hacking back in 2010 at Hacktivity – a presentation that was a complete disaster, but I learned a lot from) , and my first finding is related to MobileSafari in some way, so I decided to have a look at the exploit code which is behind JailbreakMe.com 3.0.
Of course first of all I needed a device that is compatible with JailbreakMe.com, which isn’t as easy as it sounds. Why? Because of the way Apple deploys firmware to its devices.Every single time you would like to restore your iOS device to a certain iOS version iTunes (for beginners: the program you use to initiate and manage the restore process from your computer) makes a request to Apple’s server to ask for a cryptographic signature that is specific to your iOS device.
After it gets the signature it passes it to the device, together with the firmware image. The device checks the signature and if everything is OK it starts the restore process. There is also some encryption involved in the background, but to keep things simple I will say that without Apple’s signature you can not flash any firmware on the device. Many people tried to circumvent this, but it is not possible (yet), so what most people do is they save the signature for later use (the signature is not protected against replay-attacks and the request which needs to be sent to Apple is easy to understand) meaning that once you have a signature for a certain device and a certain iOS version you can always restore to that version (signature files are known as SHSH blobs).
This means that once Apple rolled out a new version of iOS it simply stops signing any requests that are for older versions, forcing anyone who tries to restore to an older version to upgrade. Since the last version of JailbreakMe.com (v3.0) works only on iOS 4.3-4.3.3 I needed a device with SHSH blobs saved for such iOS version.
Somehow I always have a little bit of fortune in these situations, because only after looking on the internet for some hours I found an iPod Touch 3G, which has been jailbroken and was running iOS 5.0.1. Good news, but I need something older, so I met the guy and had a look at the device. You can’t imagine my joy and happiness when I saw his Cydia homescreen: “SHSH blobs are available for: iOS 4.3.3, iOS 5.0, iOS 5.0.1”
I bought the iTouch immediately.
OK, having the device itself is great, I restored it to 4.3.3 and went to JailbreakMe.com, clicked “Install” and it worked. So far so good, but I want to do more, I want to customize the payload of the jailbreak. How can I do that? Well, let’s start with understanding what JailbreakMe.com is doing:
1. Based on your User Agent it decides which exploit you need (there is one main exploit which has been compiled for all the compatible devices and iOS versions)
2. When you hit install it hits you with a crafted PDF file that has a special font embedded in it, basically (as far as I understand) the font-parser engine has the vulnerability in it that allows comex (the creator of the exploit) to posix_spawn() a process with root privileges
3. posix_spawn() runs a binary that was extracted from the PDF to /tmp (it is called locutus) and that binary takes care of the rest: downloading necessary files, and installing them onto the device
4. Comex is a real Apple guy, so he worked some time on the eye-candy stuff: he hooks into the Springboard process of iOS (Springboard is responsible for the UI of iOS) to show a Cydia icon and a progress bar under it which imitates what you can see when you install something from the AppStore (that is quite funny to me, it truly looks like I am just installing something from the AppStore :D)
So, after knowing this I decided to go on and change locutus, since it is the process which can do anything, it has root privileges, so it is really a jackpot. I don’t even need to know what exactly the exploit does if I can change its payload, right? (kind of Metasploit idea :D).
So, first would be downloading all the code and make a trial-run to see if I can at all reproduce the same PDF-files comex is hosting @JailbreakMe. In the next episode I will show, why isn’t this so easy as ‘git clone && ./configure && make’ and profit.