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¶
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¶
- Run
nic.pl
from the folder you want to make the Hook in - Select the iphone/tweak option
- Choose a project name (Example. "com.example.hook")
- Choose a Package name (Example. "com.example.hook")
- Choose a Mobile Substrate Bundle filter. This is what application you want to hook.
- 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 *))