Reverse engineering iOS apps: README

### Module 4 - Dynamic Analysis and Hacking
As you could see in the previous module, I personally _love_ to perform static analyses on iOS applications. But most of the security researchers and hackers prefer the dynamic analyses of systems. This is where you get to write code for exploits, run the applications and verify if they are vulnerable. This is a very interactive step and instead of seating down and reading assembly code or reading `.json`/`.plist` files, you get to inject code into the running application or send data to it and analyze how it parses and reacts to it.

One of the biggest differences between performing a dynamic analysis on an Android application vs an iOS application is the fact that in 99.9% of the time, on iOS, you need a physical device. This is because **all** the applications that you download from the App Store are compiled for an `ARM` architecture and the iOS simulators use your computer chip, meaning they have an `x86` or `x86_64` architecture.

The second obstacle you'll face is that, although it's not necessary, you probably will need that physical device to be jailbroken. This is because, as you learned in [Module 2](../Module-2/README.md), **all** applications downloaded from the App Store are encrypted. Meaning, if you are not able to get a _decrypted_ version of the application you want to analyze, you'll need to decrypt it yourself.

_Note: For the exercises in this module you need a device, but it doesn't need to be jailbroken for all the exercises because you'll be using the same [`CoinZa.ipa`](https://github.com/ivRodriguezCA/RE-iOS-Apps-Extras-Github/tree/master/Files) application which is already decrypted. You'll only need a jailbroken device for the Cycript and Frida exercises._

The exercises in this module are going to be different from the previous module. I'm going to present you a list of vulnerabilities, explaining you _what_ the vulnerability is and _how_ to exploit it, then you can test it on your own device.

#### Installing `CoinZa` on your device
To do the exercises in this module you'll need to first install the `CoinZa` application on your device. Luckily is super simple.
- If you haven't already, sign up for an `Apple Developer Account` [here](https://developer.apple.com/) (click on the `Account` tab), it's free.
- Connect your device to your computer.
- Open `Cydia Impactor` and drag-n-drop the `CoinZa.ipa`. **Important** it has to be the original `.ipa` you downloaded [here](https://github.com/ivRodriguezCA/RE-iOS-Apps-Extras-Github/tree/master/Files) and not the binary you extracted. (Cydia Impactor needs paid developer account($99), free account doesn't work).
- Enter your developer username and password and wait for `Impactor` to load install the application on your device.
- Troubleshooting:
    - If `Impactor` says your password is incorrect (_and you're 100% sure it's not_) or something about an "app-specific password". It probably means you need to generate an app-specific password, here's a [tutorial on how to do it](https://www.imore.com/how-generate-app-specific-passwords-iphone-ipad-mac).
    - If `Impactor` shows an error about a certificate request already in place:
        - On the top menu select `Xcode`.
        - Select `Revoke Certificates`.
        - **SUPER IMPORTANT:** This is probably not a new developer account, what this action will do is revoke the signing certificates for that account.
    - If after `Impactor` is done installing the application, you tap on its icon and iOS says something about the application not being _trusted_:
        - Open the `Settings` app.
        - Select `General`.
        - Scroll down and select `Profiles & Device Management`.
        - In the `Developer App` section, select your developer account.
        - Tap `Trust` and confirm.
    - file installer.cpp line 71 what _assert( teams.empty()), means need paid account, free account doesn't work.
     

##### URL Scheme injection
As you discovered in the static analysis step, the `CoinZa` application uses custom `Scheme URLs` and if you use what you learned in [Module 3](../Module-3/README.md) and open the application binary in `Hopper` (or `Ghidra`), search for the `AppDelegate` class, select the `application:openURL:options:` method and open it in the `pseudo-code` mode you can find:
```c
r2 = @"news";
if (objc_msgSend(r19, @selector(containsString:)) != 0x0) {
        r2 = @"news";
        r20 = [[r19 stringByReplacingOccurrencesOfString:@"news/" withString:@""] retain];
        r23 = [[NSBundle mainBundle] retain];
        r22 = [[UIStoryboard storyboardWithName:@"Main" bundle:r23] retain];
        r0 = [r22 instantiateViewControllerWithIdentifier:@"WebViewController"];
        r23 = r0;
        r0 = [r0 configureWithHTMLString:r20];
        r24 = [[UINavigationController alloc] initWithRootViewController:r23];
        r0 = [r21 window];
        r25 = [[r0 rootViewController] retain];
        r0 = [r25 topViewController];
        r0 = objc_msgSend(r0, @selector(presentViewController:animated:completion:));
}
```
- I cleaned up the code by removing some instructions. Most of the code is self-explanatory but if you're new to iOS and/or Objc, you might not know what a `UIStoryboard` or a `UINavigationController` are. That's okay, you can just read the documentation. But to save you time, I'll explain what's going on in this code snippet:
    - I didn't copy it here, but the register 19 (`r19`) is the URL passed as part of the `URL Type`. Basically a string looking like this `coinza://<something>`.
    - First there's a check if `r19` contains the string `"news"`.
    - If it doesn't, it just bypasses all this code.
    - If it does, it removes all the occurrences of the string `"news/"` from `r19` and assigns the result to `r20`.
    - Then it creates an instance of a view controller called `WebViewController`. Presumably, based on its name, it's a view controller that loads a WebView.
    - Then it calls a method named `configureWithHTMLString:`. We can assume this method is expecting a string that contains HTML code. The important thing to realize is that the HTML this class is expecting comes from `r20`, which we saw is the result of removing the string `"news/"` from the **original** passed in URL. This URL is controlled by the attacker!
    - Then performs a bunch of not so important instructions.
    - And finally it calls a method named `presentViewController:animated:completion:` which presents the `WebViewController`.
- **How:** Testing this vulnerability is very simple. With the `CoinZa` application installed on your device:
    - Open `Mobile Safari` and paste this string: `<html><body><script>document.location = 'https://google.com';</script></body></html>`.
    - You'll have to encode the URL first, the encoded version will look like this: `coinza://news/%3Chtml%3E%3Cbody%3E%3Cscript%3Edocument.location%20%3D%20%27https%3A%2F%2Fgoogle.com%27%3B%3C%2Fscript%3E%3C%2Fbody%3E%3C%2Fhtml%3E`