hacktricks/mobile-pentesting/ios-pentesting/ios-serialisation-and-encoding.md
2023-08-03 19:12:22 +00:00

9.7 KiB
Raw Blame History

☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

NSCoding和NSSecureCoding

iOS提供了两个用于Objective-C或NSObject对象序列化的协议:NSCodingNSSecureCoding。当一个类符合这两个协议之一时,数据将被序列化为**NSData:一个字节缓冲区**的包装器。请注意Swift中的DataNSData或其可变对应物:NSMutableData是相同的。NSCoding协议声明了必须实现的两个方法,以便对其实例变量进行编码/解码。使用NSCoding的类需要实现NSObject或被注解为@objc类NSCoding协议要求实现如下的编码和初始化方法。

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

NSCoding存在的问题是对象通常在你能够评估类类型之前已经被构建和插入。这使得攻击者可以轻松地注入各种数据。因此,引入了NSSecureCoding协议。当遵循NSSecureCoding时,你需要包括:

static var supportsSecureCoding: Bool {
return true
}

init(coder:)是类的一部分时。接下来,在解码对象时,应进行检查,例如:

let obj = decoder.decodeObject(of:MyClass.self, forKey: "myKey")

遵循NSSecureCoding确保实例化的对象确实是预期的对象。然而对数据没有进行额外的完整性检查数据也没有加密。因此任何秘密数据都需要额外的加密需要保护完整性的数据应该获得额外的HMAC。

使用NSKeyedArchiver进行对象归档

NSKeyedArchiverNSCoder的具体子类,提供了一种编码对象并将其存储在文件中的方法。NSKeyedUnarchiver解码数据并重新创建原始数据。让我们以NSCoding部分的示例为例,现在对它们进行归档和解档:

// archiving:
NSKeyedArchiver.archiveRootObject(customPoint, toFile: "/path/to/archive")

// unarchiving:
guard let customPoint = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as?
CustomPoint else { return nil }

您还可以将信息保存在主要的plist 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

它是DecodableEncodable协议的组合。StringIntDoubleDateDataURL本质上是Codable的:这意味着它们可以很容易地进行编码和解码,无需额外的工作。让我们看下面的例子:

struct CustomPointStruct:Codable {
var x: Double
var name: String
}

通过在示例中将CustomPointStruct的继承列表中添加Codable,自动支持init(from:)encode(to:)方法。有关Codable的工作原理的更多详细信息,请参阅Apple开发者文档

您还可以使用Codable将数据保存在主属性列表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)
}

JSON 编码

有很多第三方库可以用来将数据编码为 JSON如此处所示链接)。然而,苹果提供了直接使用 Codable 结合 JSONEncoderJSONDecoder 来进行 JSON 编码/解码的支持:

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

有多种方法可以进行XML编码。与JSON解析类似有各种第三方库例如FuziOnoAEXMLRaptureXMLSwiftyXMLParserSWXMLHash

它们在速度、内存使用、对象持久性等方面有所不同更重要的是它们在处理XML外部实体时的方式也不同。例如参考苹果iOS办公查看器中的XXE。因此,如果可能的话,禁用外部实体解析是关键。请参阅OWASP XXE预防备忘单了解更多详细信息。除了这些库,您还可以使用苹果的XMLParser

当不使用第三方库而是使用苹果的XMLParser时,请确保让shouldResolveExternalEntities返回false

{% hint style="danger" %} 所有这些序列化/编码数据的方式都可以用于将数据存储在文件系统中。在这些情况下,检查存储的数据是否包含任何敏感信息。此外,在某些情况下,您可能能够滥用某些序列化数据通过MitM捕获它或在文件系统中修改它反序列化任意数据并使应用程序执行意外操作(参见反序列化页面)。在这些情况下,建议发送/保存加密和签名的序列化数据。 {% endhint %}

参考资料

{% 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 🎥