iOS Penetration Testing- Cycript A Runtime Manipulation- Part 2

iOS Penetration Testing Part 2
iOS Penetration Testing Part 2

Previously we have posted iOS Penetration Testing App Decryption And Jailbreaking- Part 1

Now, this post is part 2 of a series giving an overview of the most useful iOS app pentesting tools. ‘Cycript’ is a runtime manipulation tool that is primarily useful for dynamic analysis and exploring the flow of the app you’re testing, research by Allyson O’Malley.

The series will be assuming that the user is using Electra jailbreak. I am specifically using iOS 11.1.2, but most of the tools in the series should work on any version of iOS 11.

1. Installing Cycript

For iOS 11, cycript is installed with ‘bfinject’, which we covered in Part 1. So, we already have cycript on our iPhone, but will need to install it on our computer too.

You can download it at

Extract the .zip to wherever you prefer, and cd into the directory.

2. Injecting Cycript into the App

Now we are ready to run cycript on our chosen target app with the following steps:

SSH into your phone and run:

bash bfinject -P AppName -L cycript

You should see something like this:

Cycript Injecting

Next you’ll need to start cycript on your computer. In a new terminal window, run:

cycript -r XX.X.X.XXX:1337

Where XX.X.X.XXX is your device’s IP address.

You’ll know if was successful when you see the cycript prompt appear:


NOTE: For user’s running Mojave/High Sierra, I have previously encountered an error running cycript that looks like this:

dyld: Library not loaded: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib

Referenced from: /Users/me/Downloads/cycript/Cycript.lib/cycript-apl
Reason: image not found
Abort trap: 6

If you get this issue, you’re having problems with your ruby versions/paths. A quick fix is to simply run:

brew install [email protected]

And then manually move the libruby.2.0.0.dylib file into your main cycript directory.

3. Runtime Exploration

Now we are ready to begin our analysis!

The first, most basic command that I usually run is to determine the current view I am looking at. You can do this by running:

cy# UIApp.keyWindow.rootViewController

And you should see it return the name of the current view controller. Sometimes, when there are more complex navigation controllers or tab bar controllers at play, to see the exact view you are looking at you may need to add onto ‘rootViewController’ with ‘visibleViewController’, ‘selectedViewController’, or ‘presentedViewController’.

Cycript Runtime Exploration

Next you will probably want to explore the current objects stored in memory. In Part 1, we went over an app’s dumped headers and took note of interesting classes/properties/methods. Now, the current view we are seeing is called ‘WelcomeViewController’. We can go back to our dumped header file, search for ‘WelcomeViewController’, and note that it has a property ‘loggedInUser’.

Now with cycript, we’re able to look at these properties.

cy# UIApp.keyWindow.rootViewController.loggedInUser
"<User: 0x104924e00>"

Now we see that the loggedInUser property is a reference to an instance of a class called ‘User’. We can also save objects as a variable to inspect them more easily:

cy# currentUser = UIApp.keyWindow.rootViewController.loggedInUser

Now we can go back to our class-dump file and see if there are any interesting properties on loggedInUser and so on.

We can also call methods! Say that the ‘loggedInUser’ class has a method:

- (_Bool)isEmailVerified;

We can call this method in cycript and see what it returns:

cy# [currentUser isEmailVerified]

We can also manipulate the method to return what we want:

cy# User.prototype.isEmailVerified = function () { return true; }

Just as we can manipulate properties:

cy# user.isLoggedIn = trueCopy

Another extremely useful command is ‘choose’ – used when you know of a class instance you want to inspect but aren’t sure exactly how to find it. This function will return an array of found instances, so you’ll usually want to go ahead and grab the first object in the array.

For example, say I want to inspect the instance of a class called ‘NetworkHandler’:

cy# choose(NetworkHandler)[0]
"<NetworkHandler: 0x103524e00>"

Now I can store that instance in a variable and begin to inspect it.

Part 3 will cover Frida/Objection, and

Part 4 will go over debugging/binary patching with Hopper and lldb.

This is just a very shallow introduction to all of the things cycript can do – for further reading, I would recommend going here. Thanks for reading.

Security Research by Allyson O’Malley, she is an iOS Software Engineer at Salesforce, with an interest in cyber security and a focus on iOS app security.

Join Our Club

Enter your Email address to receive notifications | Join over Million Followers

Leave a Reply
Previous Article
Facebook Privacy

Facebook Stored Passwords in Plain-Text Mistakenly

Next Article
Tesla Car Hacked

Hackers Hacked Tesla Model 3 in Pwn2Own

Related Posts