Private unique device identifier in iOS

前端 未结 8 1185
不知归路
不知归路 2021-01-30 01:57

We\'re working on a project with my colleagues which involves using a lot of private and non official code. This is not intended for AppStore use.

The f

8条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-30 02:30

    I'm sorry to say that apparently from iOS 8.3, to get any unique identifier you need a higher access level than normal user.

    Without exploiting anything, just with private frameworks, libraries and kernel requests, any request to unique identifiers returns null.

    Illustrating:

    Trying to use IOKit:

    void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_NOW);
    if (IOKit)
    {
        mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
        CFMutableDictionaryRef (*IOServiceMatching)(const char *name) = dlsym(IOKit, "IOServiceMatching");
        mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
        CFTypeRef (*IORegistryEntryCreateCFProperty)(mach_port_t entry, CFStringRef key, CFAllocatorRef allocator, uint32_t options) = dlsym(IOKit, "IORegistryEntryCreateCFProperty");
        kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
    
        if (kIOMasterPortDefault && IOServiceGetMatchingService && IORegistryEntryCreateCFProperty && IOObjectRelease)
        {
            mach_port_t platformExpertDevice = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
            if (platformExpertDevice)
            {
                CFTypeRef platformSerialNumber = IORegistryEntryCreateCFProperty(platformExpertDevice, CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0);
                if (platformSerialNumber && CFGetTypeID(platformSerialNumber) == CFStringGetTypeID())
                {
                    serialNumber = [NSString stringWithString:(__bridge NSString *)platformSerialNumber];
                    CFRelease(platformSerialNumber);
                }
                IOObjectRelease(platformExpertDevice);
            }
        }
        dlclose(IOKit);
    }
    

    Fails. Reason: IOPlatformSerialNumber is not accessible. Many other requests work fine.

    Trying to use Mach calls to get network adapters HW IDs:

    int         mib[6], len;
    char            *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        perror("if_nametoindex error");
        exit(2);
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        perror("sysctl 1 error");
        exit(3);
    }
    
    if ((buf = malloc(len)) == NULL) {
        perror("malloc error");
        exit(4);
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        perror("sysctl 2 error");
        exit(5);
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *ptr, *(ptr+1), *(ptr+2),
           *(ptr+3), *(ptr+4), *(ptr+5));
    

    Fails. Reason: Returns 02:00:00:00:00:00 for any network adapter.

    Trying to connect to lockdownd:

    void *libHandle = dlopen("/usr/lib/liblockdown.dylib", RTLD_LAZY);
    if (libHandle)
    {
        lockdown_connect = dlsym(libHandle, "lockdown_connect");
        lockdown_copy_value = dlsym(libHandle, "lockdown_copy_value");
    
        id connection = lockdown_connect();
        NSString *kLockdownDeviceColorKey
        NSString *color = lockdown_copy_value(connection, nil, kLockdownDeviceColorKey);
        NSLog(@"color = %@", color);
        lockdown_disconnect(connection);
    
        dlclose(libHandle);
    }
    else {
        printf("[%s] Unable to open liblockdown.dylib: %s\n",
               __FILE__, dlerror());
    }
    

    Fails. Reason: lockdown_connect() fails, returning null.

    Trying to use libMobileGestalt:

    void *libHandle = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_LAZY);
    if (libHandle)
    {
        MGCopyAnswer = dlsym(libHandle, "MGCopyAnswer");
    
        NSString* value = MGCopyAnswer(CFSTR("SerialNumber"));
        NSLog(@"Value: %@", value);
        CFRelease(value);
    }
    

    Fails. Reason: requests for unique identifiers return null. Any other request works fine.

    My suggestion is to use some privilege escalation technique to get superuser access, then run any of the methods listed here to get the property.

    Also, extend the study on liblockdown. If it's accessible at user-level (with something other than lockdown_connect), it might be possible to read these things.

提交回复
热议问题