2010-11-12 120 views
21

通过使用MobileSubstrate,越狱后的iPhone在我的神经上感染了iOS的一些基本API。在运行时检测iPhone上的UDID欺骗

http://www.iphonedevwiki.net/index.php/MobileSubstrate

我相信很多应用程序使用UDID为平均数,因为它是半自动和方便来验证设备和/或用户,但你应该知道这个问题的:的UIDevice是不是篡改它应该是证明。有一个名为UDID Faker的应用程序,它很容易让你在运行时欺骗别人的UDID。

http://www.iphone-network.net/how-to-fake-udid-on-ios-4/

这里是它的源代码:

// 
// UDIDFaker.m 
// UDIDFaker 
// 

#include "substrate.h" 

#define ALog(...) NSLog(@"*** udidfaker: %@", [NSString stringWithFormat:__VA_ARGS__]); 
#define kConfigPath @"/var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist" 

@protocol Hook 
- (NSString *)orig_uniqueIdentifier; 
@end 

NSString *fakeUDID = nil; 

static NSString *$UIDevice$uniqueIdentifier(UIDevice<Hook> *self, SEL sel) { 

    if(fakeUDID != nil) { 
       ALog(@"fakeUDID %@", fakeUDID); 
     /* if it's a set value, make sure it's sane, and return it; else return the default one */ 
       return ([fakeUDID length] == 40) ? fakeUDID : [self orig_uniqueIdentifier]; 

    } 
    /* ... if it doesn't then return the original UDID */ 
    else { 
     return [self orig_uniqueIdentifier]; 
    } 
} 

__attribute__((constructor)) static void udidfakerInitialize() { 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     NSString *appsBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; 
     ALog(@"Loading UDID Faker into %@", appsBundleIdentifier); 


     NSDictionary *config = [NSDictionary dictionaryWithContentsOfFile: kConfigPath]; 
     fakeUDID = [config objectForKey: appsBundleIdentifier]; 
     [fakeUDID retain]; 

     if(fakeUDID != nil) { 

       ALog(@"Hooking UDID Faker into %@", appsBundleIdentifier); 
       MSHookMessage(objc_getClass("UIDevice"), @selector(uniqueIdentifier), (IMP)&$UIDevice$uniqueIdentifier, "orig_"); 
     } 

    [pool release]; 
} 

正如你所看到的,在的UIDevice类唯一标识符方法现在返回fakeUDID上的任何应用程序。

似乎Skype和其他一些应用程序检测到这种污点,但我不知道该怎么做。

我想要做的是:当启动时检测到受污染的UIDevice,警报并退出(0)。

想法?

+2

伙计..你给这些想法给其他人..我的意思是你可以只发布没有示例代码和确切的API /欺骗链接的问题。现在,所有SO用户都知道如何欺骗一个UDID .. – lukya 2010-11-12 13:48:17

+2

有这种意图的人要么没有理解上述代码的能力,要么有能力并且已经了解它。 – 2010-11-12 13:59:26

+0

来吧,每个SO用户都应该知道如何使用谷歌。仅仅因为链接不在这里,并不意味着对此感兴趣的人不会找到它。 – JustSid 2010-11-12 14:01:39

回答

35

没有一种真正安全的方法来检查UDID是否是真实的。

+-----------+ 
| your code | 
+-----------+ 
     | 
+----------+  +-------------+  +-----------+ 
| UIDevice |<----->| liblockdown |<=====>| lockdownd | (trusted data) 
+----------+  +-------------+  +-----------+ 
     untrusted user     trusted user 

当设备越狱,所有4个部件可以被替换:将UDID经由liblockdown,该通信经由安全信道来lockdownd以接收UDID得到。检测UDID法克尔的存在


的一种方法是,以检查是否一些独特标识(文件,函数等)来存在。这是一种非常特殊和脆弱的反击,当检测方法暴露时,欺骗者可以简单地改变识别以隐藏其存在。

例如,UDID Faker依赖plist文件/var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist。因此,你可以检查是否存在此文件:

NSString* fakerPrefPath = @"/var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist"; 
if ([[NSFileManager defaultManager] fileExistsAtPath:fakerPrefPath])) { 
    // UDID faker exists, tell user the uninstall etc. 
} 

它还定义方法-[UIDevice orig_uniqueIdentifier]它可以用来绕过摊贩:

UIDevice* device = [UIDevice currentDevice]; 
if ([device respondsToSelector:@selector(orig_uniqueIdentifier)]) 
    return [device orig_uniqueIdentifier]; 
else 
    return device.uniqueIdentifier; 

当然欺骗者可以简单地重命名这些东西。


更可靠的方法在于移动基板如何工作。注入的代码必须位于一个dylib/bundle中,它被加载到来自UIKit的不同的内存区域中。因此,您只需检查-uniqueIdentifier方法的函数指针是否在可接受的范围内。

// get range of code defined in UIKit 
uint32_t count = _dyld_image_count(); 
void* uikit_loc = 0; 
for (uint32_t i = 0; i < count; ++ i) { 
    if (!strcmp(_dyld_get_image_name(i), "/System/Library/Frameworks/UIKit.framework/UIKit")) { 
    uikit_loc = _dyld_get_image_header(i); 
    break; 
    } 
} 

.... 

IMP funcptr = [UIDevice instanceMethodForSelector:@selector(uniqueIdentifier)]; 
if (funcptr < uikit_loc) { 
    // tainted function 
} 

反正UDID法克尔是一个非常高的水平劈(即,它可以很容易地避免)。它通过提供伪造的ID来劫持UIDevice和liblockdown之间的链接。

+-----------+ 
| your code | 
+-----------+ 
     | 
+----------+  +-------------+  +-----------+ 
| UIDevice |<--. | liblockdown |<=====>| lockdownd | (trusted data) 
+----------+ | +-------------+  +-----------+ 
       | +------------+ 
       ‘-->| UDID Faker | 
        +------------+ 

因此,您可以将要求UDID降低的代码移动到liblockdown级别。这可以用于Jailbroken平台的应用程序,但这不适用于AppStore应用程序,因为liblockdown是一个私有API。此外,欺骗者可能会劫持liblockdown(这很容易,我希望没有人这样做),甚至可以取代lockdownd本身。

    +-----------+ 
        | your code | 
        +-----------+ 
         | 
+----------+  +-------------+  +-----------+ 
| UIDevice |<--. | liblockdown |<=====>| lockdownd | (trusted data) 
+----------+ | +-------------+  +-----------+ 
       | +------------+ 
       ‘-->| UDID Faker | 
        +------------+ 

(我不打算来展示如何在这里使用liblockdown,你应该能够找到你链接到该网站的足够信息。)

+0

哇,谢谢你的详细解答,KennyTM!完善! – kenn 2010-11-15 01:27:38

+0

非常感谢您的详细解答!我部分使用你的代码,但我收到一些警告,也许你可以帮助我!我已经包含'mach-o/dyld.h'。 'uikit_loc = _dyld_get_image_header(i)'引发警告_Semantic Issue:从'const struct mach_header *'分配给'void *'丢弃qualifiers_和'if(funcptr Stefan 2011-04-07 06:22:45

-3

的关键是检测JB设备而不是在其上运行。

+2

这有点苛刻,然后你惩罚所有的JB用户。并非所有的JB用户都是盗版者,只需看看付费应用程序的成功与Cydia商店的调整。 – newenglander 2013-05-02 09:24:30