2010-11-12 18 views
21

Gli iPhone Jailbroken mi danno i nervi saldi mentre rilassa alcune API fondamentali su iOS, utilizzando MobileSubstrate.Rileva lo spoofing UDID sull'iPhone in fase di esecuzione

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

Credo che molte applicazioni usano UDID come mezzo per autenticare un dispositivo e/o di un utente dal momento che è semi-automatico e maneggevole, ma si deve essere consapevoli di questo problema: UIDevice non è così manomissione prova come dovrebbe essere. Esiste un'app chiamata UDID Faker, che ti consente facilmente di spoofare l'UDID di qualcun altro in fase di runtime.

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

Ecco il codice sorgente di esso:

// 
// 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]; 
} 

Come si può vedere, il metodo uniqueIdentifier nella classe UIDevice ora ritorna fakeUDID su eventuali applicazioni.

Sembra che Skype e altre app rilevi questo tipo di contaminazione, ma non so come farlo.

Quello che volevo fare è: quando UIDevice è macchiato all'avvio, avvisa e esce (0).

Idee?

+2

amico ... stai dando queste idee ad altre persone ... voglio dire che avresti potuto pubblicare solo la domanda senza il codice di esempio e le API/link esatti per lo spoofing. Ora tutti gli utenti SO sanno come falsificare un UDID. – lukya

+2

Le persone con tali intenzioni o non hanno la capacità di capire il codice di cui sopra, o hanno l'abilità e già lo sanno. –

+0

Avanti, ogni utente SO dovrebbe sapere come usare google. Solo perché i collegamenti non sono qui, non significa che qualcuno interessato non lo troverà. – JustSid

risposta

35

Non esiste un modo veramente sicuro per verificare se l'UDID è reale. L'UDID è ottenuto tramite liblockdown, che comunica lockdownd tramite un canale sicuro per ricevere l'UDID:

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

Quando il dispositivo è jailbroken, tutti e 4 i componenti possono essere sostituiti.


Un metodo per rilevare la presenza di UDID Faker è di controllare se alcune identificazioni (file, funzioni ecc) uniche ad esso esiste. Questo è un contrattacco molto specifico e fragile, come quando il metodo di rilevamento è esposto, lo spoofer potrebbe semplicemente cambiare l'identificazione per nascondere la loro esistenza.

Ad esempio, UDID Faker si basa su un file plist /var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist. Pertanto, si potrebbe verificare se il file esiste:

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

si definisce anche il metodo -[UIDevice orig_uniqueIdentifier] che potrebbe essere utilizzato per bypassare il falsario:

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

Naturalmente lo spoofer potrebbe semplicemente rinominare queste cose.


Un metodo più affidabile sta nel funzionamento del substrato mobile. Il codice inserito deve trovarsi in un dylib/bundle, che viene caricato in un'area di memoria diversa da da UIKit. Pertanto, è sufficiente verificare se il puntatore della funzione del metodo -uniqueIdentifier rientra nell'intervallo accettabile.

// 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 
} 

Comunque UDID Faker è un'incisione molto elevato (cioè esso può essere facilmente evitato). Esso dirotta il collegamento tra UIDevice e liblockdown fornendo un falso ID.

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

In questo modo è possibile spostare il codice chiedendo l'UDID in basso al livello di liblockdown. Questo può essere utilizzato per le app per piattaforme Jailbroken, ma questo non è possibile per le app di AppStore perché liblockdown è un'API privata. Inoltre, lo spoofer potrebbe dirottare liblockdown (è molto facile, spero che nessuno lo faccia), o addirittura sostituire lockdownd stesso.

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

(non ho intenzione di mostrare come utilizzare liblockdown qui. Si dovrebbe essere in grado di trovare informazioni sufficienti dal sito che hai collegato a.)

+0

Wow, grazie per la tua risposta elaborata, KennyTM! Perfezionare! – kenn

+0

Grazie mille per la tua risposta dettagliata! Uso parzialmente il tuo codice ma ricevo alcuni avvertimenti, forse puoi aiutarmi !? Ho incluso 'mach-o/dyld.h'. La riga 'uikit_loc = _dyld_get_image_header (i);' solleva l'avviso _Semantic Issue: assegnando a 'void *' da 'const struct mach_header *' scarta qualificers_ e 'if (funcptr Stefan

-3

La chiave sta rilevando un dispositivo JB e non correre su di esso.

+2

Questo è un po 'duro, quindi stai punendo tutti gli utenti JB. Non tutti gli utenti di JB sono pirati, basta guardare al successo di app e tweaks a pagamento sul negozio Cydia. – newenglander

Problemi correlati