hacktricks/mobile-pentesting/ios-pentesting/ios-serialisation-and-encoding.md

164 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<details>
<summary><strong>零基础学习AWS黑客技术直至成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong></strong></summary>
支持HackTricks的其他方式
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
* 获取[**官方PEASS & HackTricks商品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
</details>
### NSCoding 和 NSSecureCoding
iOS为Objective-C或`NSObject`提供了两个对象**序列化**协议:**`NSCoding`** 和 **`NSSecureCoding`**。当一个**类遵循**这些协议中的任何一个时,数据会被序列化为**`NSData`**:一个**字节缓冲区**的包装器。注意在Swift中的`Data`与`NSData`或其可变对应物:`NSMutableData`相同。`NSCoding`协议声明了必须实现的两个方法,以便对其实例变量进行编码/解码。**使用`NSCoding`的类需要实现`NSObject`或被标注为@objc类**。`NSCoding`协议要求实现编码和初始化,如下所示。
```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.
}
```
`NSCoding`的问题在于,对象通常在您能够评估类类型之前就已经**构建并插入**。这**允许攻击者轻松注入各种数据**。因此,引入了**`NSSecureCoding`**协议。当遵循[`NSSecureCoding`](https://developer.apple.com/documentation/foundation/NSSecureCoding)时,您需要包括:
```swift
static var supportsSecureCoding: Bool {
return true
}
```
`init(coder:)` 是类的一部分时。接下来,在解码对象时,应该进行检查,例如:
```swift
let obj = decoder.decodeObject(of:MyClass.self, forKey: "myKey")
```
遵守 `NSSecureCoding` 确保了被实例化的对象确实是预期的对象。然而,对数据**没有额外的完整性检查**,且数据未被加密。因此,任何需要保密的数据都需要额外的**加密**,而需要保护完整性的数据,应该增加一个额外的 HMAC。
### 使用 NSKeyedArchiver 的对象归档
`NSKeyedArchiver``NSCoder` 的一个具体子类,提供了一种编码对象并将它们存储在文件中的方法。`NSKeyedUnarchiver` 解码数据并重建原始数据。让我们以 `NSCoding` 部分的例子为例,现在对它们进行归档和解档:
```swift
// archiving:
NSKeyedArchiver.archiveRootObject(customPoint, toFile: "/path/to/archive")
// unarchiving:
guard let customPoint = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as?
CustomPoint else { return nil }
```
您还可以将信息保存在主要的 plist `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
它是 `Decodable``Encodable` 协议的组合。`String`、`Int`、`Double`、`Date`、`Data` 和 `URL` 本质上是 `Codable`:这意味着它们可以轻松地进行编码和解码,无需任何额外工作。让我们看下面的例子:
```swift
struct CustomPointStruct:Codable {
var x: Double
var name: String
}
```
在示例中,通过将 `Codable` 添加到 `CustomPointStruct` 的继承列表中,自动支持了 `init(from:)``encode(to:)` 方法。有关 `Codable` 工作原理的更多详细信息,请查看[苹果开发者文档](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types)。
您还可以使用 codable 将数据保存在主属性列表 `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)
}
```
### JSON 编码
有许多第三方库可以将数据编码为 JSON如[此处](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#json-and-codable)所示)。然而,苹果通过结合 `Codable``JSONEncoder``JSONDecoder` 直接提供了对 JSON 编码/解码的支持:
```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
有多种方式可以进行XML编码。类似于JSON解析有各种第三方库例如[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)
它们在速度、内存使用、对象持久性方面各不相同更重要的是它们处理XML外部实体的方式不同。以[XXE in the Apple iOS Office viewer](https://nvd.nist.gov/vuln/detail/CVE-2015-3784)为例。因此,如果可能的话,禁用外部实体解析是关键。有关更多详细信息,请参阅[OWASP XXE预防备忘单](https://cheatsheetseries.owasp.org/cheatsheets/XML\_External\_Entity\_Prevention\_Cheat\_Sheet.html)。除了库您还可以使用Apple的[`XMLParser`类](https://developer.apple.com/documentation/foundation/xmlparser)
当不使用第三方库而是使用Apple的`XMLParser`时,确保让`shouldResolveExternalEntities`返回`false`。
{% hint style="danger" %}
所有这些序列化/编码数据的方式都可以**用于在文件系统中存储数据**。在这些场景中,检查存储的数据是否包含任何类型的**敏感信息**。\
此外,在某些情况下,您可能能够**滥用一些序列化**的数据通过MitM捕获或在文件系统内修改它反序列化任意数据并**使应用程序执行意外的操作**(参见[反序列化页面](../../pentesting-web/deserialization/))。在这些情况下,建议加密并签名发送/保存序列化数据。
{% 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" %}
<details>
<summary><strong>通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>从零到英雄学习AWS黑客攻击</strong></summary>
支持HackTricks的其他方式
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
* 获取[**官方PEASS & HackTricks商品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
</details>