mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 06:30:37 +00:00
164 lines
8.9 KiB
Markdown
164 lines
8.9 KiB
Markdown
<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>
|