Slide 1

Slide 1 text

February 6, 2015 Mobile Central Europe 1 2 3 4 5 6 7 8 9 10 11 12 Securing iOS apps Max Bazaliy

Slide 2

Slide 2 text

February 6, 2015 Mobile Central Europe About me 1 2 3 4 5 6 7 8 9 10 11 12 Bluebox Security CocoaHeads Ukraine mbazaliy

Slide 3

Slide 3 text

February 6, 2015 Mobile Central Europe Agenda 1 2 3 4 5 6 7 8 9 10 11 12 o  iOS security mechanisms o  Security from attacker’s perspective o  Reverse engineering tools detection o  Security coding practices o  Advanced practices

Slide 4

Slide 4 text

February 6, 2015 Mobile Central Europe o  Secured boot process o  Privilege separation o  Code signing o  Memory protection o  Sandbox o  Encryption 1 2 3 4 5 6 7 8 9 10 11 12 iOS security mechanisms

Slide 5

Slide 5 text

February 6, 2015 Mobile Central Europe 1 2 3 4 5 6 7 8 9 10 11 12 Secured boot process Bootrom LLB iBoot Kernel Application Signature check

Slide 6

Slide 6 text

February 6, 2015 Mobile Central Europe Privilege separation 1 2 3 4 5 6 7 8 9 10 11 12 o  Users (root, mobile, …) o  Groups o  File permissions o  Safari, Mail run as mobile o  Most important system processes as root

Slide 7

Slide 7 text

February 6, 2015 Mobile Central Europe Code signing 1 2 3 4 5 6 7 8 9 10 11 12 o  Implemented in kernel o  Every executable should be signed o  Stored in LC_CODE_SIGNATURE o  Superblob, entitlements, signature o  SHA1 check of memory pages o  Superblob is signed

Slide 8

Slide 8 text

February 6, 2015 Mobile Central Europe Memory protection 1 2 3 4 5 6 7 8 9 10 11 12 o  R ^ W policy o  Non executable stack and heap o  Implemented in kernel o  Vulnerable to ROP o  (K)ASLR o  No dynamic code generation

Slide 9

Slide 9 text

February 6, 2015 Mobile Central Europe Sandbox (Seatbelt) 1 2 3 4 5 6 7 8 9 10 11 12 o  Based upon TrustedBSD MAC framework o  Implemented in kernel o  Profiles (nointernet, container…) o  Operations (read, write, search…) o  System & user partition

Slide 10

Slide 10 text

February 6, 2015 Mobile Central Europe Encryption 1 2 3 4 5 6 7 8 9 10 11 12 o  Hardware AES and SHA modules o  7 derivative keys from UID and GID o  Everything is encrypted (iBoot, filesystem, …) o  Data protection API o  Passcode \ TouchID key o  Remote device wiping

Slide 11

Slide 11 text

February 6, 2015 Mobile Central Europe o  Code injection o  Function hooking o  ObjC logger o  Jailbreak detection o  Security checks 1 2 3 4 5 6 7 8 9 10 11 12 Security from attacker’s perspective

Slide 12

Slide 12 text

February 6, 2015 Mobile Central Europe Code injection 1 2 3 4 5 6 7 8 9 10 11 12 o  .dylib injection o  DYLD_INSERT_LIBRARIES o  LLDB o  Cycript o  LD_LOAD_DYLIB o  Mobile Substrate

Slide 13

Slide 13 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 DYLD_INSERT_LIBRARIES=dumper.dylib Scan.app/Scan Dynamic loader

Slide 14

Slide 14 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 LLDB Max-iPhone-5S:~ root# ./debugserver *:1234 -a ”Scan” $ lldb (lldb) platform select remote-ios (lldb) process connect connect://192.168.1.2:1234 (lldb) expr (void*)dlopen(“/Desktop/dumper.dylib”, 0x2)

Slide 15

Slide 15 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Cycript $ cycript -p Scan cy# dlopen(”/Desktop/dumper.dylib", RTLD_NOW)

Slide 16

Slide 16 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 New load command cmd LC_LOAD_DYLIB cmdsize 52 name @rpath/dumper.dylib time stamp 2 Thu Jan 1 03:00:02 1970 cur.ver. 1.0.0 compat.ver 1.0.0 otool -l –v binary | grep -A 5 LC_LOAD_DYLIB

Slide 17

Slide 17 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 New load command LC_LOAD_DYLIB or LC_LOAD_WEAK_DYLIB o  Wrap LC_LOAD, update sizeof commands o  optool o  insert_dylib o  yololib

Slide 18

Slide 18 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Mobile Substrate o  Most popular code patching framework o  Hook C, C++, Objective C, Java code o  Trampoline for C hooks o  Swizzling for Objective C o  Dynamic code injection o  Filter support

Slide 19

Slide 19 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Mobile Substrate hook API + Logos MSImageRef MSGetImageByName(const char *file) void *MSFindSymbol(MSImageRef image, const char *name) void MSHookFunction(void *symbol, void *hook, void **old) void MSHookMessageEx(Class _class, SEL message, IMP hook, IMP *old) void MSHookClassPair(Class _class, Class hook, Class old)

Slide 20

Slide 20 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Mobile Substrate Loader Filter = { Executables = ("mediaserverd"); Bundles = ( "com.apple.MobileSMS", "net.whatsapp.WhatsApp" ); CoreFoundationVersion = (550.32, 675.00); Classes = ("MMTrackingMgr"); Mode = "Any"; }; Load everything from /Library/MobileSubstrate/DynamicLibraries

Slide 21

Slide 21 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Function hooking main qsort No hooking

Slide 22

Slide 22 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Function hooking main qsort Hooking scenario hook

Slide 23

Slide 23 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Function hooking main qsort Hooking scenario 2 hook

Slide 24

Slide 24 text

February 6, 2015 Mobile Central Europe 13 14 15 16 17 18 19 20 21 22 23 24 Hooking [NSObject description] NSString *(*oldDescription)(id self, SEL _cmd);! ! NSString *newDescription(id self, SEL _cmd) {! NSString *description = (*oldDescription)(self, _cmd);! description = [description stringByAppendingString:@"!"];! return description;! }! ! MSHookMessageEx(! " [NSObject class], @selector(description),! " (IMP)&newDescription, (IMP*)&oldDescription! );

Slide 25

Slide 25 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 objc_msgSend[_[st|fp]ret] logging - [Pin password] +[PBKDF2 getKeyForPassphrase:], args: - [Pin initWithCoder:], args: <0x1f5a4320> - [Pin setPinValue:], args: - [Pin setNote:], args: - [Pin initWithCoder:], args: <0x1f5a4320> - [Pin setPinValue:], args: - [Pin setNote:], args: Aspective-C, Subjective-C, Inspective-C

Slide 26

Slide 26 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Bypassing shell check + (BOOL)shellCheck {! if (system(0))! return YES;! return NO;! } static int (*old_system)(char *) = NULL;! int hooked_system(char * cmd) {! if (!cmd) {! return 0;! }! return old_system(cmd);! }! MSHookFunction(system, hooked_system, &old_system);!

Slide 27

Slide 27 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Bypassing files check + (BOOL)cydiaCheck {! if ([[NSFileManager defaultManager] ! "fileExistsAtPath: @"/Applications/Cydia.app"])! return YES;! return NO;! } void* (*old_fileExistsAtPath)(void* self, SEL _cmd, NSString* path) = NULL;! void* hooked_fileExistsAtPath(void* self, SEL _cmd, NSString* path){! if ([path isEqualToString:@"/Applications/Cydia.app"]) {! return 0;! }! return old_fileExistsAtPath(self, _cmd, path);! }! MSHookMessageEx([NSFileManager class], @selector(fileExistsAtPath:),! (IMP)hooked_fileExistsAtPath, (IMP *)&old_fileExistsAtPath);! !

Slide 28

Slide 28 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Bypassing fork check + (BOOL)forkCheck {! pid_t result = fork();! if (!result)! exit(0);! if (result >= 0)! return YES;! return NO; } static pid_t (*old_fork)(void) = NULL;! pid_t hooked_fork() {! if (calledDirectlyFromApp()) {! return -1;! }! return old_fork();! }! MSHookFunction(fork, hooked_fork, &old_fork);!

Slide 29

Slide 29 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 const char* hook_dyld_get_image_name(uint32_t image_index) {! if (image_index >= dyld_skipimage)! return orig_get_image_name(image_index + 1);! else! return orig_get_image_name(image_index);! }! ! MSHookFunction(_dyld_image_count,hooked_image_count,&orig_image_count)! MSHookFunction(_dyld_get_image_name,hooked_get_image_name,&orig_get_image_name) uint32_t dyld_skipimage = 0;! ! uint32_t hooked_dyld_image_count(void) {! return orig_image_count() - 1;! }! “Calling functions like _dyld_image_count() and _dyld_get_image_name() to see which dylibs are currently loaded. Very difficult to patch, as patches are themselves part of dylibs.” – theiphonewiki.com

Slide 30

Slide 30 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Bypassing ptrace tricks static int (*orig_ptrace)(int request, pid_t pid, caddr_t addr, int data);! ! int hooked_ptrace(int request, pid_t pid, caddr_t addr, int data) {! int retVal;! if (request == PT_DENY_ATTACH || request == PT_TRACEME) {! return 0;! }! else {! retVal = orig_ptrace(request, pid, addr, data);! }! return retVal;! }! MSHookFunction(MSFindSymbol(0, "ptrace"),hooked_ptrace,(void **)&orig_ptrace);! ptrace(PT_DENY_ATTACH, 0, 0, 0);

Slide 31

Slide 31 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Bypassing SSL pinning - SSLKillSwitch OSStatus hooked_SSLHandshake(SSLContextRef context) {! OSStatus result = orig_SSLHandshake(context);! ! if (result == errSSLServerAuthCompleted) {! return orig_SSLHandshake(context);! }! else return result; }! … MSHookFunction(SSLHandshake,hooked_SSLHandshake, &orig_SSLHandshake) ! MSHookFunction(SSLCreateContext,hooked_SSLCreateContext,&orig_SSLCreateContext)! MSHookFunction(SSLSetSessionOption,hooked_SSLSetSessionOption,! " " " " " "&orig_SSLSetSessionOption)! SSLHandshake, SSLSetSessionOption, SSLCreateContext!

Slide 32

Slide 32 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Auto bypassing jailbreak checks o tsProtector X o xCon o Officer

Slide 33

Slide 33 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Tracing tweaks Introspy, Snoop-It, iSpy

Slide 34

Slide 34 text

February 6, 2015 Mobile Central Europe o  Debugger detection o  Hooks detection o  Code injection detection 25 26 27 28 29 30 31 32 33 34 35 36 Reverse engineering tools detection

Slide 35

Slide 35 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Debugger detection – process flags static int is_debugger_present(void) {! ! struct kinfo_proc info;! size_t info_size = sizeof(info);! ! name[0] = CTL_KERN;! " …! name[3] = getpid(); " " " " // Getting proccess pid! ! if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {! return 0;! }! return ((info.kp_proc.p_flag & P_TRACED) != 0); "// Checking P_TRACED flag! }!

Slide 36

Slide 36 text

February 6, 2015 Mobile Central Europe 25 26 27 28 29 30 31 32 33 34 35 36 Debugger detection – parent process static int is_debugserver_present(void) {! ! struct kinfo_proc info;! size_t info_size = sizeof(info);! ! name[0] = CTL_KERN;! " …! name[3] = getppid(); " " "// Getting parent proccess pid! ! if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {! return 0;! }! return (strncmp(info.kp_proc.p_comm, "launchd", sizeof("launchd")-1) != 0);! }!

Slide 37

Slide 37 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Breakpoint detection bool is_breakpoint_set(void* memory, size_t check_size) {! unsigned char *tmp_mem = (unsigned char*)memory;! for (size_t i = 0; i < check_size; i++)! {! if ((tmp_mem[i] == 0xFE) && (tmp_mem[i+1] == 0xDE))! return true;! }! return false;! }!

Slide 38

Slide 38 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Hook detection - pointer bool is_method_swizzled(Class clazz, SEL sel) {! ! Dl_info info;! if (dladdr(class_getMethodImplementation(clazz, sel), &info)) {! if (strstr(info.dli_fname, "/System/Library") || ! " " " "strstr(info.dli_fname, "/usr/lib”) {! return false;! }! }! return true;! }!

Slide 39

Slide 39 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Hook detection - trampoline bool is_function_hooked(void* function) {! ! uintptr_t* code = (uintptr_t*)(uintptr_t) function;! ! if (code[0] == 0xE5XXXXXX) {! return true;! }! return false;! }!

Slide 40

Slide 40 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 DYLD_INSERT_LIBRARIES detection extern char **environ;! ! bool is_dyld_insert_libraries_present(void) {! int i=0;! char *envp = *environ;! char *dyld_var = "DYLD_INSERT_LIBRARIES”;! while(envp) {! i++;! char *env_var = NULL, *env_val = NULL;! … ! if (strncmp(env_var, dyld_var , sizeof(dyld_var)-1) == 0) {! return true;! }! "envp = *(environ+i);! }! return false;! }!

Slide 41

Slide 41 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Mobile Substrate detection #import ! ! bool is_mobile_substrate_present(void) {! ! uint32_t count = _dyld_image_count();! char* substrate = "Library/MobileSubstrate/MobileSubstrate.dylib";! ! for (uint32_t i = 0; i < count; ++i) {! "if (strcmp(_dyld_get_image_name(i),substrate)==0) {! return true;! }! }! return false;! }!

Slide 42

Slide 42 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 ‘Bad’ symbols detection bool is_cycript_present(void) {! ! Class genericClass = objc_getClass("CYJSArray");! SEL genericSelector = sel_registerName("initWithJSObject:inContext:");! ! if (genericClass) {! Method method = class_getInstanceMethod(genericClass, genericSelector);! if (method) {! return true;! }! }! return false;! }!

Slide 43

Slide 43 text

February 6, 2015 Mobile Central Europe o  Anti-hooking o  Anti-patching o  Obfuscation 37 38 39 40 41 42 43 44 45 46 47 48 Security coding practices

Slide 44

Slide 44 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Anti-hooking __attribute__((always_inline))! static inline void my_secret_function(void)! o  Inline critical functions o  Symbol visibility __attribute__((visibility("hidden")))! static bool is_dyld_insert_libraries_present(void) o  Hook detection Dl_info info; if (dladdr(func_pointer, &info)) // Pointer! ! if (code[0] == 0xE5XXXXXX) " " // Trampoline

Slide 45

Slide 45 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Anti-patching – code checksum for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) {! if (cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {! segment_command_t* segment = (segment_command_t*)cmd;! if (!strcmp(segment->segname, SEG_TEXT)) {! section_t * section = (section_t *)(segment + 1);! for (uint32_t j = 0; section != NULL && j < segment->nsects; j++){! if (!strcmp(section->sectname, SECT_TEXT))! break;! section = (section_t *)(section + 1);! }! … if (!CC_SHA1(text_section, (CC_LONG)text_section_size, code_hash_buf))! if (memcmp(signature_buf, code_hash_buf, sizeof(code_hash_buf)) == 0)!

Slide 46

Slide 46 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Obfuscation – hide function calls uint32_t count = _dyld_image_count();! const char *image= NULL;! ! for(uint32_t i = 0; i < count; i++) {! dyld = _dyld_get_image_name(i);! }! static uint32_t (*orig_dyld_image_count)(void);! orig_dyld_image_count = dlsym(RTLD_DEFAULT, "_dyld_image_count");//To obfuscate! ! uint32_t count = orig_dyld_image_count();! const char *dyld = NULL;! ! for(uint32_t i = 0; i < count; i++) {! dyld = _dyld_get_image_name(i);! }!

Slide 47

Slide 47 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Obfuscation – hide method calls ! NSString *string = @"Hi im string";! string = [string uppercaseString];! ! ! // Obfuscate all strings! id string = @"Hi im string";! SEL genericSelector = sel_registerName("uppercaseString");! string = ((id(*)(id, SEL))objc_msgSend)(string,genericSelector);!

Slide 48

Slide 48 text

February 6, 2015 Mobile Central Europe 37 38 39 40 41 42 43 44 45 46 47 48 Obfuscation – strings obfuscation + (NSString*)xorString: (NSString*)first withString: (NSString*)second! {! …! for(int index = 0; index < [firstString length]; index++)! firstBytes[index] ^= secondBytes[index];! ! NSString *result = firstString;! return result;! }! o  Simple XOR o  Encoding \ Decoding table o  Crypto

Slide 49

Slide 49 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Obfuscation – numbers obfuscation __attribute__((noinline))! static volatile uint32_t get_obfuscated_num(uint32_t *seed){! *seed = ((*seed) * 214013 + 2531011) & 0x7fffffff;! return *seed >> 16;! }! ! int seed = 1802271524;! int number = get_obfuscated_num(&seed); //Return 2!

Slide 50

Slide 50 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 3rd party obfuscators o  Arxan o  LLVM Obfuscator o  iOS Class Guard

Slide 51

Slide 51 text

February 6, 2015 Mobile Central Europe o  Functions replacement o  System calls o  Device anomalies o  Assembler code obfuscation 49 50 51 52 53 54 55 56 57 58 59 60 Advanced practices

Slide 52

Slide 52 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Re-implement libc __attribute__((always_inline))! static inline int mb_memcmp(const void *s1, const void *s2, size_t n) {! if (n != 0) {! const unsigned char *p1 = s1, *p2 = s2;! ! do {! if (*p1++ != *p2++)! return (*--p1 - *--p2);! } while (--n != 0);! }! return (0);! }! memcmp, memcpy, strcmp, strncmp, strstr

Slide 53

Slide 53 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Re-implement dyld const void * dlladdr(mach_header *image, const char *symbol) {! " " " "… nlist_t *symbase = (nlist_t*)(image + (symtab->symoff + file_slide));! char *strings = (char*)(image + (symtab->stroff + file_slide));! nlist_t *sym;! ! for (i = 0, sym = symbase; i < symtab->nsyms; i += 1, sym += 1)! {! if (sym->n_un.n_strx != 0 && !strcmp(symbol, strings + sym->n_un.n_strx))! {! unsigned long address = vm_slide + sym->n_value;! if (sym->n_desc & N_ARM_THUMB_DEF)! return (const void*)(address | 1);! else! return (const void*)(address);! }! dlsym, dladdr, _dyld_get_image_xxx

Slide 54

Slide 54 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Device anomalies if (sysctl(myname, 4, &myinfo, &myinfo_size, NULL, 0) == -1) {! return;! }! ! // check for debugger trace flag set! if ((myinfo.kp_proc.p_flag & P_TRACED) != 0) ! "NSLog(@”Tracing detected");! } ! // check for aslr disabled flag! if ((myinfo.kp_proc.p_flag & P_DISABLE_ASLR) != 0) {! NSLog(@"PIE disabled");! } ! // check for debugger enabled flag! if ((myinfo.kp_proc.p_debugger) != 0) {! NSLog(@"Debugger enabled ?");! }! }!

Slide 55

Slide 55 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Device anomalies // check kproc for mobile's uid! if ( myinfo.kp_eproc.e_pcred.p_ruid != 501 ||! myinfo.kp_eproc.e_pcred.p_svuid != 501 ||! myinfo.kp_eproc.e_ucred.cr_uid != 501 )! {! NSLog(@"Mobile uid anomaly");! }! ! // check kproc for mobile's gid! if ( myinfo.kp_eproc.e_pcred.p_rgid != 501 ||! myinfo.kp_eproc.e_pcred.p_svgid != 501 )! {! NSLog(@"Mobile gid anomaly");! }!

Slide 56

Slide 56 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 System calls o  Syscall function as wrapper o  Implemented as svc 0x80 o  Syscall number in r12 or x16 o  Arguments in registers o  Listed in syscall.h

Slide 57

Slide 57 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Syscall ; ssize_t read(int, void *, size_t)! EXPORT _read! _read! MOV R12, #3 // SYS_read! SVC 0x80! BCC locret_2F756914! …! BX R12! #define "SYS_syscall 0! #define "SYS_exit 1! #define "SYS_fork 2! #define "SYS_read 3! #define "SYS_write 4! usr/include/sys/syscall.h

Slide 58

Slide 58 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Access to private stuff #include // opensource.apple.com! ! int csops(pid_t pid, unsigned int ops, void *addr, size_t size);! ! #define "SYS_csops 169! #include // opensource.apple.com! ! int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);! ! #define "SYS_ptrace 26!

Slide 59

Slide 59 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 CSOPS – getting code directory hash #include ! ! syscall(SYS_csops,! CS_OPS_CDHASH,! " (void*)BUFFER,! " CC_SHA1_DIGEST_LENGTH);!

Slide 60

Slide 60 text

February 6, 2015 Mobile Central Europe 49 50 51 52 53 54 55 56 57 58 59 60 Rewrite code using syscalls pid_t pid = getpid(); " " pid_t pid = syscall(SYS_getpid);! ! ! ! int st = sysctl(mib,…); " int st = syscall(SYS_sysctl,…);! ! ! ! pid_t pid = fork(); " " pid_t pid = syscall(SYS_fork);! ! ! ! int st = stat("/bin",…); " int st = syscall(SYS_stat,…);! !

Slide 61

Slide 61 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 Implement your own syscall int zyzcall(int num, uint32_t arg0, uint32_t arg1, uint32_t arg2) {! ! int result = 0;! asm volatile (! ".thumb;"! "mov r0, %[a0];"! " ""mov r1, %[a1];"! " ""mov r2, %[a2];“! " ""mov r12, %[num];"! " ""svc 0x80;"! "mov %[ret], r0;“! " " …! " ");! return result;!

Slide 62

Slide 62 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 How to obfuscate syscall ? o  ARM – 4 bytes o  Thumb - 2 bytes o  Thumb2 - 2/4 bytes o  ARM64 - 4 bytes

Slide 63

Slide 63 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 Instructions overlapping "add r11, r12, r4;"! "mov r4, %[a3];"! "mov r12, 0;“! "mov pc, r11;“! //overlaps with SVC instruction! ".byte 0x50, 0xf8;"! "svc 0x80;"! "mov %[ret], r0;"

Slide 64

Slide 64 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 Instructions overlapping No SVC instruction J

Slide 65

Slide 65 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 Summary o  Do not rely on iOS security and ObjC\Swift o  ‘Everything is hooked’ environment o  Detect hooks and code injection o  Detect debuggers and device anomalies o  Re implement standard functions o  Love and use syscalls o  Obfuscate your code

Slide 66

Slide 66 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 Cracking time == protection time

Slide 67

Slide 67 text

February 6, 2015 Mobile Central Europe 61 62 63 64 65 66 67 68 69 70 71 72 @mbazaliy