Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)! Autres moyens de soutenir HackTricks : * Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)! * Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com) * Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez**-moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Partagez vos astuces de hacking en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
### NSCoding et NSSecureCoding iOS est équipé de deux protocoles pour la **sérialisation** d'objets pour Objective-C ou `NSObject`s : **`NSCoding`** et **`NSSecureCoding`**. Lorsqu'une **classe se conforme** à l'un de ces protocoles, les données sont sérialisées en **`NSData`** : un wrapper pour les **buffers d'octets**. Notez que `Data` en Swift est identique à `NSData` ou à son équivalent modifiable : `NSMutableData`. Le protocole `NSCoding` déclare les deux méthodes qui doivent être implémentées pour encoder/décoder ses variables d'instance. **Une classe utilisant `NSCoding` doit implémenter `NSObject` ou être annotée comme une classe @objc**. Le protocole `NSCoding` exige de mettre en œuvre encode et init comme indiqué ci-dessous. ```swift class CustomPoint: NSObject, NSCoding { //required by NSCoding: func encode(with aCoder: NSCoder) { aCoder.encode(x, forKey: "x") aCoder.encode(name, forKey: "name") } var x: Double = 0.0 var name: String = "" init(x: Double, name: String) { self.x = x self.name = name } // required by NSCoding: initialize members using a decoder. required convenience init?(coder aDecoder: NSCoder) { guard let name = aDecoder.decodeObject(forKey: "name") as? String else {return nil} self.init(x:aDecoder.decodeDouble(forKey:"x"), name:name) } //getters/setters/etc. } ``` Le problème avec `NSCoding` est que l'objet est souvent déjà **construit et inséré avant que vous puissiez évaluer** le type de classe. Cela **permet à un attaquant d'injecter facilement toutes sortes de données**. Par conséquent, le protocole **`NSSecureCoding`** a été introduit. Lorsque vous vous conformez à [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/NSSecureCoding), vous devez inclure : ```swift static var supportsSecureCoding: Bool { return true } ``` ```markdown lorsque `init(coder:)` fait partie de la classe. Ensuite, lors du décodage de l'objet, une vérification doit être effectuée, par exemple : ``` ```swift let obj = decoder.decodeObject(of:MyClass.self, forKey: "myKey") ``` La conformité à `NSSecureCoding` garantit que les objets instanciés sont bien ceux qui étaient attendus. Cependant, **aucun contrôle d'intégrité supplémentaire n'est effectué** sur les données et celles-ci ne sont pas chiffrées. Par conséquent, toute donnée secrète nécessite un **chiffrement** supplémentaire et les données dont l'intégrité doit être protégée doivent recevoir un HMAC additionnel. ### Archivage d'objets avec NSKeyedArchiver `NSKeyedArchiver` est une sous-classe concrète de `NSCoder` et offre un moyen de coder des objets et de les stocker dans un fichier. `NSKeyedUnarchiver` décode les données et recrée les données originales. Prenons l'exemple de la section `NSCoding` et archivons puis désarchivons-les : ```swift // archiving: NSKeyedArchiver.archiveRootObject(customPoint, toFile: "/path/to/archive") // unarchiving: guard let customPoint = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? CustomPoint else { return nil } ``` Vous pouvez également enregistrer les informations dans le plist principal `NSUserDefaults` : ```swift // archiving: let data = NSKeyedArchiver.archivedDataWithRootObject(customPoint) NSUserDefaults.standardUserDefaults().setObject(data, forKey: "customPoint") // unarchiving: if let data = NSUserDefaults.standardUserDefaults().objectForKey("customPoint") as? NSData { let customPoint = NSKeyedUnarchiver.unarchiveObjectWithData(data) } ``` ### Codable C'est une combinaison des protocoles `Decodable` et `Encodable`. Un `String`, `Int`, `Double`, `Date`, `Data` et `URL` sont naturellement `Codable` : cela signifie qu'ils peuvent être facilement encodés et décodés sans travail supplémentaire. Prenons l'exemple suivant : ```swift struct CustomPointStruct:Codable { var x: Double var name: String } ``` En ajoutant `Codable` à la liste d'héritage pour le `CustomPointStruct` dans l'exemple, les méthodes `init(from:)` et `encode(to:)` sont automatiquement prises en charge. Pour plus de détails sur le fonctionnement de `Codable`, consultez [la documentation pour développeurs d'Apple](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types). Vous pouvez également utiliser codable pour enregistrer les données dans la liste de propriétés principale `NSUserDefaults` : ```swift struct CustomPointStruct: Codable { var point: Double var name: String } var points: [CustomPointStruct] = [ CustomPointStruct(point: 1, name: "test"), CustomPointStruct(point: 2, name: "test"), CustomPointStruct(point: 3, name: "test"), ] UserDefaults.standard.set(try? PropertyListEncoder().encode(points), forKey: "points") if let data = UserDefaults.standard.value(forKey: "points") as? Data { let points2 = try? PropertyListDecoder().decode([CustomPointStruct].self, from: data) } ``` ### Encodage JSON Il existe de nombreuses bibliothèques tierces pour encoder des données en JSON (comme exposé [ici](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#json-and-codable)). Cependant, Apple offre un support pour l'encodage/décodage JSON directement en combinant `Codable` avec un `JSONEncoder` et un `JSONDecoder` : ```swift struct CustomPointStruct: Codable { var point: Double var name: String } let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted let test = CustomPointStruct(point: 10, name: "test") let data = try encoder.encode(test) let stringData = String(data: data, encoding: .utf8) // stringData = Optional ({ // "point" : 10, // "name" : "test" // }) ``` ### XML Il existe plusieurs façons de réaliser l'encodage XML. De manière similaire à l'analyse JSON, il existe diverses bibliothèques tierces, telles que : [Fuzi](https://github.com/cezheng/Fuzi), [Ono](https://github.com/mattt/Ono), [AEXML](https://github.com/tadija/AEXML), [RaptureXML](https://github.com/ZaBlanc/RaptureXML), [SwiftyXMLParser](https://github.com/yahoojapan/SwiftyXMLParser), [SWXMLHash](https://github.com/drmohundro/SWXMLHash) Elles varient en termes de vitesse, d'utilisation de la mémoire, de persistance des objets et plus important : elles diffèrent dans la manière dont elles gèrent les entités externes XML. Voir [XXE dans le visualiseur de documents Office iOS d'Apple](https://nvd.nist.gov/vuln/detail/CVE-2015-3784) comme exemple. Par conséquent, il est essentiel de désactiver l'analyse des entités externes si possible. Voir la [feuille de triche de prévention XXE de l'OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html) pour plus de détails. À côté des bibliothèques, vous pouvez utiliser la classe [`XMLParser` d'Apple](https://developer.apple.com/documentation/foundation/xmlparser) Lorsque vous n'utilisez pas de bibliothèques tierces, mais `XMLParser` d'Apple, assurez-vous que `shouldResolveExternalEntities` retourne `false`. {% hint style="danger" %} Toutes ces méthodes de sérialisation/encodage peuvent être **utilisées pour stocker des données dans le système de fichiers**. Dans ces scénarios, vérifiez si les données stockées contiennent des **informations sensibles**.\ De plus, dans certains cas, vous pourriez être en mesure d'**abuser de certaines données sérialisées** (les capturant via MitM ou les modifiant dans le système de fichiers) en désérialisant des données arbitraires et **en faisant exécuter à l'application des actions inattendues** (voir [page de Désérialisation](../../pentesting-web/deserialization/)). Dans ces cas, il est recommandé d'envoyer/de sauvegarder les données sérialisées chiffrées et signées. {% endhint %} ## Références {% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %}
Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)! Autres moyens de soutenir HackTricks : * Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)! * Obtenez le [**merchandising officiel PEASS & HackTricks**](https://peass.creator-spring.com) * Découvrez [**La Famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection d'[**NFTs**](https://opensea.io/collection/the-peass-family) exclusifs * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Partagez vos astuces de hacking en soumettant des PR aux dépôts github** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).