In my previous blog, iOS Tutorial – Dumping the Application Heap from Memory, I covered how to dump sensitive information from the heap of an iOS application using GDB. This time we will be covering how to use Cycript to accomplish the same goal but using the class-dump-z output to specifically pull out properties or instance variables. This round will be in a more automated fashion by automatically parsing a class dump of the binary and generating the necessary Cycript scripts to pull the specific properties from memory. I will also be releasing another tool to do all of this for you in the near future. Keep an eye on our NetSPI GitHub repo for the latest tools and scripts for when we release it.
If we do not have access to the source code then we must first decrypt the binary. We do this first to dump the class information about the binary. There are several guides out there for decryption but Clutch is my go-to tool for ease of use as it also regenerates an IPA file with the decrypted binary in it so you can install it again on a different device if you have to. After we extract/install the new decrypted binary, we can now run class-dump-z to get the header information with all the classes, properties, class methods, instance methods, etc.
So you can see above that TestApp has a class called “CryptoManager” and has a property called “key”. This looks interesting as there could be an encryption key sitting there in memory. We will now use Cycript to grab that specific property from memory. Note during runtime, the “CryptoManager” class is instantiated before login but only after a valid user has successfully logged in once before on the device. Also, the class is never cleared out even when it is no longer needed, such as a user logged out, which is where the vulnerability lies. In this instance, we have already logged in successfully during a previous session and therefore the class is already in memory before the user logs in.
First we will hook into the running TestApp process from an SSH session so we can leave the application running on the iOS device.
MAPen-iPad-000314:~ root# cycript -p TestApp
Now that we are hooked in, let’s go ahead and talk about the “choose” method in cycript. The “choose” method scans the heap for the matching class name and returns an array of objects that match that class’ structure. So, if we type “choose(MyClass)”. It is going to contain an indexed array of all instantiated classes of MyClass that are currently in memory (or that match that structure). The below output is just calling out the first indexed object which is index “0” and storing it into a variable called “a”. If you like GDB more, we can also take the memory location returned and go back to GDB for dumping out everything from that sub-region in memory or set breakpoints and watch the registers. See my previous blog on how to scan the heap here (https://blog.netspi.com/ios-tutorial-dumping-the-application-heap-from-memory/). Note however, that there can be more than one class instantiated in this array and you will to go through each index to get the properties of that instantiated class.
Bingo! We now have the hexadecimal of the key we need to decrypt anything this application wants to keep encrypted.
Now let’s talk about how to automate this and go over what we know and what we have to figure out programmatically as we go. We know that the class-dump-z output contains the output of all the classes and their properties. What we don’t know is whether or not those classes are currently instantiated or not. We also don’t know how many times the classes are instantiated in memory. What we can do is parse the class-dump-z output and create a map of classes and their properties. Now that we have a map we can now create Cycript scripts to pull the information out for us. Note however, that this technique is for classes that are already instantiated and we won’t be covering how to make a new instance of an object in Cycript as there are many tutorials and books on how to do this.
Cool, now we know how many times to loop through the array to pull out all instantiated “CryptoManager” objects. Now let’s move on to cycript scripting.
Cycript can take a script as a parameter and a basic script just has to contain the commands we want to run like so:
PTaaS is NetSPI’s delivery model for penetration testing. It enables customers to simplify the scoping of new engagements, view their testing results in real time, orchestrate faster remediation, perform always-on continuous testing, and more - all through the Resolve™ vulnerability management and orchestration platform.
We help organizations defend against adversaries by being the best at simulating real-world, sophisticated adversaries with the products, services, and training we provide. We know how attackers think and operate, allowing us to help our customers better defend against the threats they face daily.
At NetSPI, we believe that there is simply no replacement for human-led manual deep dive testing. Our Resolve platform delivers automation to ensure our people spend time looking for the critical vulnerabilities that tools miss. We provide automated and manual testing of all aspects of an organization’s entire attack surface, including external and internal network, application, cloud, and physical security.
Our proven methodology ensures that the client experience and our findings aren’t only as good as the latest tester assigned to your project. That consistency gives our customers assurance that if vulnerabilities exist, we will find them.
Is your organization prepared for a ransomware attack? Explore our Ransomware Attack Simulation service.