8.9 KiB
零基础学习AWS黑客技术直至成为专家 htARTE (HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您想在HackTricks中看到您的公司广告或下载HackTricks的PDF,请查看订阅计划!
- 获取官方PEASS & HackTricks商品
- 发现PEASS家族,我们独家的NFTs系列
- 加入 💬 Discord群组 或 telegram群组 或在 Twitter 🐦 上关注我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github仓库提交PR来分享您的黑客技巧。
NSCoding 和 NSSecureCoding
iOS为Objective-C或NSObject
提供了两个对象序列化协议:NSCoding
和 NSSecureCoding
。当一个类遵循这些协议中的任何一个时,数据会被序列化为**NSData
:一个字节缓冲区**的包装器。注意,在Swift中的Data
与NSData
或其可变对应物: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 的对象归档
NSKeyedArchiver
是 NSCoder
的一个具体子类,提供了一种编码对象并将它们存储在文件中的方法。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
它是 Decodable
和 Encodable
协议的组合。String
、Int
、Double
、Date
、Data
和 URL
本质上是 Codable
:这意味着它们可以轻松地进行编码和解码,无需任何额外工作。让我们看下面的例子:
struct CustomPointStruct:Codable {
var x: Double
var name: String
}
在示例中,通过将 Codable
添加到 CustomPointStruct
的继承列表中,自动支持了 init(from:)
和 encode(to:)
方法。有关 Codable
工作原理的更多详细信息,请查看苹果开发者文档。
您还可以使用 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
与 JSONEncoder
和 JSONDecoder
直接提供了对 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解析,有各种第三方库,例如:Fuzi、Ono、AEXML、RaptureXML、SwiftyXMLParser、SWXMLHash
它们在速度、内存使用、对象持久性方面各不相同,更重要的是:它们处理XML外部实体的方式不同。以XXE in the Apple iOS Office viewer为例。因此,如果可能的话,禁用外部实体解析是关键。有关更多详细信息,请参阅OWASP XXE预防备忘单。除了库,您还可以使用Apple的XMLParser
类
当不使用第三方库,而是使用Apple的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" %}
通过 htARTE (HackTricks AWS Red Team Expert)从零到英雄学习AWS黑客攻击!
支持HackTricks的其他方式:
- 如果您想在HackTricks中看到您的公司广告或下载HackTricks的PDF,请查看订阅计划!
- 获取官方PEASS & HackTricks商品
- 发现PEASS家族,我们独家的NFTs系列
- 加入 💬 Discord群组 或 telegram群组 或在 Twitter 🐦 上关注我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github仓库提交PR来分享您的黑客技巧。