11 KiB
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
-
Découvrez The PEASS Family, notre collection exclusive de NFTs
-
Obtenez le swag officiel PEASS & HackTricks
-
Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
-
Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
NSCoding et NSSecureCoding
iOS est livré avec deux protocoles pour la sérialisation d'objets pour Objective-C ou les NSObject
s : NSCoding
et NSSecureCoding
. Lorsqu'une classe est conforme à l'un ou l'autre des protocoles, les données sont sérialisées en NSData
: un wrapper pour les tampons de bytes. Notez que Data
en Swift est identique à NSData
ou à son homologue mutable : NSMutableData
. Le protocole NSCoding
déclare les deux méthodes qui doivent être implémentées pour coder/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
nécessite de mettre en œuvre l'encodage et l'initialisation comme indiqué ci-dessous.
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
, vous devez inclure:
static var supportsSecureCoding: Bool {
return true
}
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 :
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, aucune vérification d'intégrité supplémentaire n'est effectuée sur les données et les données 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 supplémentaire.
Archivage d'objets avec NSKeyedArchiver
NSKeyedArchiver
est une sous-classe concrète de NSCoder
et permet de coder des objets et de les stocker dans un fichier. NSKeyedUnarchiver
décode les données et recrée les données d'origine. Prenons l'exemple de la section NSCoding
et archivons-les maintenant pour les désarchiver ensuite :
// 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
:
// 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
Il s'agit d'une combinaison des protocoles Decodable
et Encodable
. Une String
, Int
, Double
, Date
, Data
et URL
sont Codable
par nature: cela signifie qu'elles peuvent facilement être encodées et décodées sans aucun travail supplémentaire. Prenons l'exemple suivant:
struct CustomPointStruct:Codable {
var x: Double
var name: String
}
En ajoutant Codable
à la liste d'héritage pour 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 du développeur Apple.
Vous pouvez également utiliser Codable
pour enregistrer les données dans la liste de propriétés primaires NSUserDefaults
:
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). Cependant, Apple prend en charge l'encodage/décodage JSON directement en combinant Codable
avec un JSONEncoder
et un JSONDecoder
:
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 faire de l'encodage XML. Tout comme l'analyse JSON, il existe diverses bibliothèques tierces, telles que: Fuzi, Ono, AEXML, RaptureXML, SwiftyXMLParser, SWXMLHash
Ils varient en termes de vitesse, d'utilisation de la mémoire, de persistance des objets et plus important encore: diffèrent dans la façon dont ils gèrent les entités externes XML. Voir XXE dans le visualiseur de bureau Apple iOS 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 OWASP pour plus de détails. En plus des bibliothèques, vous pouvez utiliser la classe XMLParser
d'Apple
Lorsque vous n'utilisez pas de bibliothèques tierces, mais la XMLParser
d'Apple, assurez-vous de laisser shouldResolveExternalEntities
renvoyer false
.
{% hint style="danger" %}
Toutes ces façons de sérialiser/encoder des données 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 pouvez abuser de certaines données sérialisées (en les capturant via MitM ou en les modifiant à l'intérieur du système de fichiers) en désérialisant des données arbitraires et en faisant exécuter des actions inattendues à l'application (voir la page de désérialisation). Dans ces cas, il est recommandé d'envoyer/enregistrer 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" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
-
Découvrez The PEASS Family, notre collection exclusive de NFTs
-
Obtenez le swag officiel PEASS & HackTricks
-
Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
-
Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et hacktricks-cloud.