For a long time, insecure iOS applications have been a major source of concern. As a result of the popularity of these apps, the number of insecurities has risen as well.
The technique of detecting and exploiting vulnerabilities in iOS applications is known as iOS penetration testing.
Decompiling the application to find any problems that could lead to bugs or utilizing an automated tool could be used as part of the procedure. It’s a set of tests covering everything from installation and configuration to discovering and exploiting software and hardware vulnerabilities in the iOS operating system and network security.
Basics of iOS:-
If you are like us, whenever you get your hands on a replacement device you wonder how secure it is. The iPhone was no exception. Here was a tool that had jumped across the edge from being a phone which may have a little browser to a tool that was more like your computer than your old phone.
Indeed, there have been similar security issues in these devices and the problems that were already occurring on desktop computers. What precautions and security mechanisms had Apple built into these devices to stop such compromises? Here was an opportunity to start an entirely new branch of computing from the beginning. How important was security going to be for these emerging smart devices?
Before diving right into the iOS application penetration testing, it’s important to know the iOS platform, the default security features to supply, and other important terminology.
In this article, I will try to explain these important terms in a simple and short way possible & provide further reading to explore them in-depth.
iOS Application Architecture:-
The iOS components that support iOS applications together with the application layer make up the architecture of an iOS application.
Figure no-1 : This image explain architecture of IOS in short.
Detailed Architecture of iOS:-
The below diagram explains and talks about the essential architecture of the iOS system where different layers are used between the Application and Hardware level to determine communication & perform different tasks.
Figure no-2 : This image explain architecture of IOS in depth.
Let’s discuss a number of these layers in brief:
Core OS: The Core OS layer provides various low-level features upon which different services are built. These include Accelerate Framework, Directory Services, System Configuration, OpenCL, etc.
- Core OS Layer
- A layer with which most applications interact.
- All the iOS technologies are built on the low-level features provided by the core OS layer.
- These technologies include core Bluetooth Framework, External Accessory Framework, Accelerate Framework, Security Services Framework, Local Authorization Framework, etc.
- The developer has limited access to the present layer. Still, the developer has the privileges to access the subsequent frameworks
- Accelerate – Big number and DSP calculations
- External Accessory – Communicate with hardware accessories.
- Security – Certificates and Cryptography
- System – Low-level OS method Core Services: The core services layer provides an abstraction over the services that are provided within the core OS layer. These services generally include address book, social, security, WebKit, etc.
- The core services layer provides an abstraction over the services provided within the core OS layer.
- It provides fundamental access to iPhone OS services.
- Following frameworks are available within the core services layer.
- Cloudkit Framework – The information is often moved between the app and the iCloud using the Cloudkit Framework.
- Core Foundation Framework – This provides data management and repair features for iOS apps.
- Core Data Framework – The information model of the model view controller app is handled using the Core Data Framework.
- Address Book Framework – The address book framework provides access to the contacts database of the user.
- Core Motion Framework – All the motion-based data on the device is accessed using the Core Motion Framework.
- Healthkit Framework – The health-related information of the user is often handled by this new framework.
- Core Location Framework – This framework provides the situation and heading information to the varied apps.
- Core Location – GPS, cellular or wi-fi based location services
Media: The media layer provides various media services which will be utilized within the device, i.e. it basically enables all the audio-visual technologies. It provides various functions like core image, core audio, core text, etc.
- The media layer provides multimedia services that you simply can use within your iPhone.
- The media layer enables all the graphics, audio, and video technology of the system.
- Allows the developer to figure with photos, videos, audios, animations, and graphics-like things.
- It contains the subsequent frameworks.
- AVFoundation – Advanced audio and video
- UIKit Graphics – Designing images and animating the view content.
- Core Graphics Framework – Support 2-D vector and image-based rendering and is the native drawing engine for iOS apps.
- Core Animation – The Core Animation technology optimizes the animation experience of the apps.
- Core Audio – Low-level audio
- Media Player – Supports audio, and video playback & enables the user to use their iTunes library.
- Core Text – Advanced text layouts and fonts
Cocoa Touch (Application): The Cocoa Touch layer is additionally referred to as the Application Layer. It is the topmost layer in the architecture and exposes various APIs for programming iPhone devices. The Cocoa Touch layer provides an abstraction layer to show the varied libraries for programming the iPhone and other iOS devices. As per the Apple documentation following are the frameworks presents.
The iOS Applications uses .IPA as their file extension.
You can read more about IPA file here: https://en.wikipedia.org/wiki/.ipa
- UIKit – UI element, life cycle management, etc
- Message Kit – Liable for Email, SMS
- Address Book – Contact, editing.
- Event Kit – Alarm, Calendar events, etc.
- Game Kit – Liable for gaming activity.
- iAd – Supports Apple’s advertisement platform
- Map Kit – Google map, Apple map.
- Message Kit – Liable for Email etc
Info.plist: The data .plist file describes the application to the OS employing a list of varied properties. This file is usually checked while performing security assessments because it may contain interesting information or help us find some misconfigurations.
Keychain: A keychain is mentioned as an encrypted container where an application can store sensitive information and only the authorized application can retrieve the information from it. Read More: https://developer.apple.com/documentation/security/keychain_services
IPA Build flow System:-
The main goal of Xcode Build System is to orchestrate execution of various tasks that will eventually produce an executable program.
Figure no-3 : This image explain IPA Build flow using Xcode.
Xcode runs a number of tools and passes dozens of arguments between them, handles their order of execution, parallelism and much much more. This is definitely not what you want to be dealing with manually when writing your next Swift project.
The majority of language processing systems, including Xcode Build Sytem, consist out of 5 parts:
These pieces play together in a way depicted on the diagram below:
Figure no-4 : This image explain Xcode Build System.
The purpose of preprocessing step is to transform your program in a way that it can be fed to a compiler. It replaces macros with their definitions, discovers dependencies and resolves preprocessor directives.
Considering that Swift compiler does not have a preprocessor, we are not allowed to define macros in our Swift projects. Nonetheless Xcode Build System partially compensates it and does preprocessing by means of Active Compilation Conditions that can be set in your project build settings.
Xcode resolves dependencies by means of lower-level build system llbuild. It is open source and you can find additional information on swift-llbuild Github page.
Compiler is a program that maps a source program in one language into a semantically equivalent target program in another language. In other words, it transforms Swift, Objective-C and C/C++ code into machine code without losing the former’s meaning.
Xcode uses two different compilers: one for Swift and the other for Objective-C, Objective-C++ and C/C++ files.
clang is Apple’s official compiler for the C languages family. It is open-sourced here: swift-clang.
swiftc is a Swift compiler executable which is used by Xcode to compile and run Swift source code. I’d venture to guess that you have already visited this link at least once: it is located in Swift language repository.
Assembler translates human-readable assembly code into relocatable machine code. It produces Mach-O files which are basically a collection of code and data.
The machine code and Mach-O file terms from the above definition require further explanation.
Machine code is a numeric language that represents a set of instructions that can be executed directly by CPU. It is named relocatable, because no matter where that object file is in the address space, the instructions will be executed relatively to that space.
Mach-O file is a special file format for iOS and macOS operating systems that is used for object files, executables and libraries. It is a stream of bytes grouped in some meaningful chunks that will run on the ARM processor of an iOS device or the Intel processor on a Mac.
Linker is a computer program that merges various object files and libraries together in order to make a single Mach-O executable file that can be run on iOS or macOS system. Linker takes two kinds of files as its input. These are object files that come out of assembler phase and libraries of several types (.dylib, .tbd and .a).
An attentive reader might have noticed that both assembler and linker produce Mach-O files as their outputs. There must be some difference between them, right?
The object files coming out of assembly phase are not finished yet. Some of them contain missing pieces that reference other object files or libraries. For example, if you were using printf in your code, it is the linker that glues this symbol together with libc library where printf function is implemented. It uses the symbol table created during the compiler phase to resolve references across different object files and libraries.
Lastly, loader which is a part of operating system, brings a program into memory and executes it. Loader allocates memory space required to run the program and initializes registers to initial state.
An IPA file is simply a zip file of an application. It contains the binary itself, an Info.plist, codesigning files, icons, and other resources.
When you download an app from the AppStore, the IPA file is downloaded to /var/mobile/Media/Downloads along with a meta file. After it is fully downloaded, an installation daemon (installd) is run which extracts the IPA to /var/mobile/Applications//. In this directory goes:
The .app folder which contains all of the app’s resources and the executable.
A Documents folder for storing any type of file (read/write privelages).
A Library folder for caching data and storing key/value data in plist format using NSUserDefaults
A tmp folder used to store temporary data. This folder’s contents are removed when the app is not running.
When SpringBoard (the homescreen app) is loaded, it reads the Info.plist of every app and caches it. From this, it gets the display name (name under icon), the icon itself, and the name of the executable, among other things.
When you click on the app’s icon, SpringBoard displays the app’s Default.png as a splash screen while the executable is loaded into memory. It is decrypted during this process, as every AppStore app is encrypted when it’s signed by Apple. As soon as the executable is loaded in memory, dyld (the dynamic linker) loads any frameworks or libraries that it is linked against (such as UIKit, libobjc, libSystem, etc.). Apps cannot include any libraries of its own; the executable must be standalone. Then, the app’s main() function is called, and the app’s code is run.
File Structure of an IPA:-
The IOS developers who are developing the apps using the Apple Xcode are well familiar with IPA files because they need to package their developed apps as IPA files either for testing of app store deployment purposes. Although, the IPA files are known to be installed as iOS apps, however, you can also decompress them to view the app data contained. Since an IPA file contains only one binary for the ARM architecture of mobile phones and it does not contain a binary for the x86 architecture, Many .ipa files cannot be installed on the iPhone Simulator.
To start, we need to examine the structure of the IPA file by renaming the IPA to .zip extension, so we can unzip it. After unzipping it, we will get the below contents.
- App binary: The executable file containing the compiled (unreadable) application source code.
- Info.plist: Configuration information, such as bundle ID, version number, and application display name.
- Frameworks: List of dynamic libraries.
- Embedded.mobileprovsion: These are certificates.
What is jailbreak?
Jailbreak is the method of lifting user restrictions in your device, set by the corporate. It’s important to understand that jailbreaking voids the warranty of your device. There are various jailbreaking methods for iOS – differing from version to version. Canijailbreak may be a great website for suggesting jailbreak tools supported by the iOS application. It’s worth mentioning, that jailbreaking is often done using Windows, Mac, or Linux. Furthermore, we have different classifications ofjailbreaking – that are defined below.
Untethered Jailbreak: Permanent Jailbreak, the device is going to be jailbroken even after a reboot.
Tethered Jailbreak: Temporary Jailbreak, after a reboot device is going to be back to its normal state.
Semi-tethered Jailbreak: A semi-tethered jailbreak is one where the device can begin on its own, but it’ll not have a patched kernel, and thus won’t be ready to run modified code.
Semi-untethered Jailbreak: A semi-untethered jailbreak is analogous to an untethered jailbreak wherein it allows the device else abreast of its own. The device’s start-up sequence is unaltered on each boot, and it boots into its original, non-jailbroken state. However, instead of employing a computer to jailbreak, as during a tethered or semi-tethered case, the users can re-jailbreak their devices using an app that runs on their device.
We looked at the fundamentals of iOS penetration testing in this post and learned a few strategies for application structure and application environment. Later we’ll go over more iOS pentesting basics and get into more advanced topics.