Skip to content

Runtime Hooking

Runtime Hooking

Frida

Frida Flags:
- -U: use frida over USB for use with
- -H 127.0.0.1: use frida to connect to a server on a port. This must be used with frida-server -H 0.0.0.0
- -f: run the application and pause the application. Use com.example.application.name
- --no-pause: with the -f parameter but don't pause the application
- -p: attach to running with process id
- -n Name: attach to process with name
- -l SCRIPT: add a JavaScript file to the application.
- -o Output_file: Specify log file

Launch Application through USB. Attach a script to be run on startup and log output to file:

>>> frida -U -f com.test.ios.dev -l /opt/Memory/Mobile/frida_iOS_helper_functions.js -o Keychain_test

Attach to running Application through USB. Attach a script to be run on startup and log output to file:

>>> frida -U -n "Test - Dev" -l /opt/Memory/Mobile/frida_iOS_helper_functions.js -o Keychain_test

Running frida on device

Use the update_frida.sh script

sudo /opt/Memory/Mobile/update_frida.sh iOS

Start the frida server on all interfaces:

frida-server -l 0.0.0.0:1337

Connecting through WIFI and not USB:

frida -H 192.168.88.29 -l ./ios-file-dataprotection.js Castlight

Frida Helper functions

https://github.com/vtky/Swizzler2
https://github.com/noobpk/frida-ios-hook

Objection

  • Biased off Frida

Attach to a Application:

objection --gadget="iGoat-Swift" explore

Run a single command:

objection --gadget="iGoat-Swift" explore --startup-command "ios jailbreak disable"

Run with a script:

objection --gadget="iGoat-Swift" explore --startup-script antiroot.js

List Classes:

OWASP.iGoat-Swift on (iPhone: 12.0) [usb] # ios hooking list classes

List Functions in a class:

OWASP.iGoat-Swift on (iPhone: 12.0) [usb] # ios hooking list class_methods <ClassName>

Disable iOS Pinning:

OWASP.iGoat-Swift on (iPhone: 12.0) [usb] # ios sslpinning disable

Dump the application key chain:

OWASP.iGoat-Swift on (iPhone: 12.0) [usb] # ios keychain dump

Application Folders:

OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env

Name               Path
-----------------  -------------------------------------------------------------------------------------------
BundlePath         /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
CachesDirectory    /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
DocumentDirectory  /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
LibraryDirectory   /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library

Theos

Installing Theos On Linux

Source

Get Code:

git clone --recursive https://github.com/theos/theos.git ~/theos

curl https://kabiroberai.com/toolchain/download.php?toolchain=ios-linux -Lo toolchain.tar.gz
tar xzf toolchain.tar.gz -C ~/theos/toolchain
rm toolchain.tar.gz

Get iOS SDK:

curl -LO https://github.com/theos/sdks/archive/master.zip
TMP=$(mktemp -d)
unzip master.zip -d $TMP
mv $TMP/sdks-master/*.sdk ~/theos/sdks
rm -r master.zip $TMP

Get Swift:

curl https://kabiroberai.com/toolchain/download.php?toolchain=swift-ubuntu-latest -Lo swift-toolchain.tar.gz
tar xzf swift-toolchain.tar.gz -C ~/theos/toolchain
rm swift-toolchain.tar.gz

Creating a Theos Project

  1. Run nic.pl from the folder you want to make the Hook in
  2. Select the iphone/tweak option
  3. Choose a project name (Example. "com.example.hook")
  4. Choose a Package name (Example. "com.example.hook")
  5. Choose a Mobile Substrate Bundle filter. This is what application you want to hook.
  6. Choose the Application you want to restart. This is the application you want to hook.

Example Makefile

ARCHS=arm64
TARGET := iphone:clang:latest:7.0
INSTALL_TARGET_PROCESSES = com.zellepay.zelle

THEOS=/opt/iOS/theos
THEOS_DEVICE_IP=iphone.usb 
THEOS_DEVICE_PORT=2222


include $(THEOS)/makefiles/common.mk

TWEAK_NAME = ZelleHook

ZelleHook_FILES = Tweak.x
ZelleHook_CFLAGS = -fobjc-arc

include $(THEOS_MAKE_PATH)/tweak.mk

Creating Objective C Hook

These hooks are pretty straight forward to construct. You will require the class name and function call details. "class-dump" tool can be used to retrieve such information.

e.g. $./class-dump {TargetAppBinary} > targetApp.classes.txt

Some example hooks:

    %hook ANSMetadata //Name of target class
    - (bool)computeIsJailbroken{ // name of the function we want to hook
    	NSLog(@" ## We hooked ANSMetadata - computIsJailbroken ! ## "); // this will be printed on the device console once it is called.
    	bool result = %orig;	// we call the "original" function that we are currently hooking. The return of the given function stored in "result".
    	NSLog(@" ## ANSMetadata - computIsJailbroken original return value is %d ## ", result); // Print the original result.
    	//Example console snippet:
    	//default	16:19:54.889467 -0400	DuoMobileApp	 ## ANSMetadata - computIsJailbroken original return value is 1 ##
    	//Now we return 0 as we want to bypass this jailbreak detection check.
    	return 0;
    }

    %hook AFSecurityPolicy //Name of target class
    + (id)policyWithPinningMode:(uint64_t)policyID{ // function which requires 1 parameter
    	id result = %orig(policyID);	//we call original function with original parameter.
    	//Print the result to device console and return the original result.
    	NSLog(@" ## AFSecurityPolicy - policyWithPinningMode is hit. PolicyID/Argument is %ld \nResult is %@ ## ", (long)policyID, result);
    	return result;
    }
    %end


    // In this example, given function returns a NSDictionary object (id is like void *).
    // Our hook gets the original output, changes the value of a parameter and returns the modified output.
    %hook DUODeviceInfo
    - (id)dictionaryRepresentation{
    	id result = %orig;
    	NSLog(@" ## DUODeviceInfo - dictionaryRepresentation original return value is: %@\n\n ## ", result);
    	/* Example console snippet:
    	default	16:03:51.008002 -0400	DuoMobileApp	## DUODeviceInfo - dictionaryRepresentation original return value is: {
    		"app_id" = "com.duosecurity.DuoMobile";
    		"app_version" = "3.27.0.4";
    		"device_name" = iPhone;
    		jailbroken = true; <-- our jailbreak is detected by the application.
    		language = en;
    		manufacturer = Apple;
    		model = "iPhone9,1";
    		pkpush = "rsa-sha512";
    		platform = iOS;
    		region = US;
    		version = "12.2";
    	}
    	*/

    	NSMutableDictionary *muteDict = [result mutableCopy]; //we cast it into a mutable form.
    	muteDict[@"jailbroken"] = @"false"; // setting the "jailbreak" flag to FALSE.
        NSLog(@"## DUODeviceInfo - dictionaryRepresentation after modification: %@", muteDict);
    	/* Example console snippet:
    	default	16:03:51.008002 -0400	DuoMobileApp	## DUODeviceInfo - dictionaryRepresentation after modification: {
    		"app_id" = "com.duosecurity.DuoMobile";
    		"app_version" = "3.27.0.4";
    		"device_name" = iPhone;
    		jailbroken = false; <-- now the value is false hence server will not flag the device as jailbroken.
    		language = en;
    		manufacturer = Apple;
    		model = "iPhone9,1";
    		pkpush = "rsa-sha512";
    		platform = iOS;
    		region = US;
    		version = "12.2";
    	}
    	*/

    	return (NSDictionary *) muteDict; // returning the modified dictionary to pass server-side validation.
    }	
    %end

Creating C Hook

Hooking a C function by Name:

static FILE * (*orig_fopen) ( const char * filename, const char * mode );
FILE * new_fopen ( const char * filename, const char * mode ) {
    if (strcmp(filename, "/bin/bash") == 0) {
        return NULL;
    }
    return orig_fopen(filename, mode);
}
 
%ctor {
    //Address of Function, Replacement Function, Backup Function address
    MSHookFunction((void *)fopen, (void *)new_fopen, (void **)&orig_fopen);
}

Hooking a C function by Address:

#include <mach-o/dyld.h>
#import "substrate.h"
 
int new_100037950(void)
{
    return 0;
}
 
int (*orig_100037950)();

%ctor
{
    @autoreleasepool
    {
        //Get Function Address from ASLR Offset and Function Address
        unsigned long function_address = _dyld_get_image_vmaddr_slide(0) + 0x100037950;

        //Replace the origination function address to the new Function
        //Address of Function, Replacement Function, Backup Function address
        MSHookFunction((void *)function_address, (void *)new_100037950, (void **)&orig_100037950);
    }
}

Creating Swift Hook

https://www.mbo42.com/2018/04/01/hooking-swift-methods/

Pushing the Hook to the device

Build and install the package to the iphone:

make clean
make
make package
make install

Cycrypt (Outdated)

Example:

Phone-7-1:~ root# cycript -p SpringBoard
cy# [UIApp description]
@"<SpringBoard: 0x10300c200>"
cy# @[0,1] instanceof Array
true
cy# [for (x of [1,2,3]) x+1]
[2,3,4]
cy# [2,3,4]
[2,3,4]
cy# choose(CALayer)[0]
#"<_UIBackdropViewLayer: 0x283d034c0>"
cy# [&](int a)->int{return a}
(extern "C" int 4411850752(int))
cy# ({m: 4, b: 5}).<TAB><TAB>
...................^
| syntax error, unexpected <
cy# fopen = (typedef void *(char *, char *))(fopen)
(extern "C" void *4411850768(char *, char *))