Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Securing iOS applications

Max Bazaliy
February 06, 2015

Securing iOS applications

Mobile Central Europe, 2015

Max Bazaliy

February 06, 2015
Tweet

More Decks by Max Bazaliy

Other Decks in Programming

Transcript

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

    View Slide

  2. 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

    View Slide

  3. 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

    View Slide

  4. 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

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. 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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 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)

    View Slide

  15. 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)

    View Slide

  16. 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

    View Slide

  17. 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

    View Slide

  18. 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

    View Slide

  19. 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)

    View Slide

  20. 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

    View Slide

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

    View Slide

  22. 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

    View Slide

  23. 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

    View Slide

  24. 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!
    );

    View Slide

  25. 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

    View Slide

  26. 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);!

    View Slide

  27. 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);!
    !

    View Slide

  28. 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);!

    View Slide

  29. 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

    View Slide

  30. 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);

    View Slide

  31. 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!

    View Slide

  32. 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

    View Slide

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

    View Slide

  34. 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

    View Slide

  35. 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!
    }!

    View Slide

  36. 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);!
    }!

    View Slide

  37. 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;!
    }!

    View Slide

  38. 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;!
    }!

    View Slide

  39. 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;!
    }!

    View Slide

  40. 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;!
    }!

    View Slide

  41. 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;!
    }!

    View Slide

  42. 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;!
    }!

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. 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)!

    View Slide

  46. 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);!
    }!

    View Slide

  47. 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);!

    View Slide

  48. 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

    View Slide

  49. 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!

    View Slide

  50. 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

    View Slide

  51. 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

    View Slide

  52. 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

    View Slide

  53. 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

    View Slide

  54. 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 ?");!
    }!
    }!

    View Slide

  55. 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");!
    }!

    View Slide

  56. 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

    View Slide

  57. 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

    View Slide

  58. 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!

    View Slide

  59. 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);!

    View Slide

  60. 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,…);!
    !

    View Slide

  61. 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;!

    View Slide

  62. 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

    View Slide

  63. 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;"

    View Slide

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

    View Slide

  65. 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

    View Slide

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

    View Slide

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

    View Slide