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

150 lines
9.4 KiB
Markdown
Raw Normal View History

2023-06-03 01:46:23 +00:00
### NSCoding y NSSecureCoding
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
iOS cuenta con dos protocolos para la **serialización** de objetos para Objective-C o `NSObject`s: **`NSCoding`** y **`NSSecureCoding`**. Cuando una **clase se ajusta** a cualquiera de los protocolos, los datos se serializan a **`NSData`**: un envoltorio para **buffers de bytes**. Tenga en cuenta que `Data` en Swift es lo mismo que `NSData` o su contraparte mutable: `NSMutableData`. El protocolo `NSCoding` declara los dos métodos que deben implementarse para codificar/decodificar sus variables de instancia. **Una clase que utiliza `NSCoding` necesita implementar `NSObject` o estar anotada como una clase @objc**. El protocolo `NSCoding` requiere implementar encode e init como se muestra a continuación.
2021-05-21 16:38:18 +00:00
```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.
}
```
2023-06-03 01:46:23 +00:00
El problema con `NSCoding` es que el objeto a menudo ya está **construido e insertado antes de que puedas evaluar** el tipo de clase. Esto **permite a un atacante inyectar fácilmente todo tipo de datos**. Por lo tanto, se ha introducido el protocolo **`NSSecureCoding`**. Al conformarse con [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/NSSecureCoding), es necesario incluir:
2021-05-21 16:38:18 +00:00
```swift
static var supportsSecureCoding: Bool {
return true
}
```
2023-06-03 01:46:23 +00:00
Cuando `init(coder:)` es parte de la clase. A continuación, al decodificar el objeto, se debe realizar una comprobación, por ejemplo:
2021-05-21 16:38:18 +00:00
```swift
let obj = decoder.decodeObject(of:MyClass.self, forKey: "myKey")
```
2023-06-03 01:46:23 +00:00
La conformidad con `NSSecureCoding` asegura que los objetos que se están instanciando son realmente los que se esperaban. Sin embargo, **no se realizan controles adicionales de integridad** sobre los datos y los datos no están cifrados. Por lo tanto, cualquier dato secreto necesita **cifrado adicional** y los datos cuya integridad deba ser protegida, deben tener un HMAC adicional.
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
### Archivado de objetos con NSKeyedArchiver
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
`NSKeyedArchiver` es una subclase concreta de `NSCoder` y proporciona una forma de codificar objetos y almacenarlos en un archivo. El `NSKeyedUnarchiver` decodifica los datos y recrea los datos originales. Tomemos el ejemplo de la sección `NSCoding` y ahora los archivamos y desarchivamos:
2021-05-21 16:38:18 +00:00
```swift
// archiving:
NSKeyedArchiver.archiveRootObject(customPoint, toFile: "/path/to/archive")
// unarchiving:
guard let customPoint = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as?
CustomPoint else { return nil }
```
2023-06-03 01:46:23 +00:00
También puedes guardar la información en el plist primario `NSUserDefaults`:
2021-05-21 16:38:18 +00:00
```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)
}
```
2022-05-01 12:41:36 +00:00
### Codable
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
Es una combinación de los protocolos `Decodable` y `Encodable`. Un `String`, `Int`, `Double`, `Date`, `Data` y `URL` son `Codable` por naturaleza: lo que significa que pueden ser codificados y decodificados fácilmente sin ningún trabajo adicional. Tomemos el siguiente ejemplo:
2021-05-21 16:38:18 +00:00
```swift
struct CustomPointStruct:Codable {
var x: Double
var name: String
}
```
2023-06-03 01:46:23 +00:00
Al agregar `Codable` a la lista de herencia de `CustomPointStruct` en el ejemplo, los métodos `init(from:)` y `encode(to:)` son compatibles automáticamente. Para obtener más detalles sobre el funcionamiento de `Codable`, consulte [la documentación de desarrolladores de Apple](https://developer.apple.com/documentation/foundation/archives\_and\_serialization/encoding\_and\_decoding\_custom\_types).
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
También puede usar codable para guardar los datos en la lista de propiedades primarias `NSUserDefaults`:
2021-05-21 16:38:18 +00:00
```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)
}
```
2023-06-03 01:46:23 +00:00
### Codificación JSON
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
Existen muchas bibliotecas de terceros para codificar datos en JSON (como se explica [aquí](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#json-and-codable)). Sin embargo, Apple proporciona soporte para la codificación/decodificación de JSON directamente combinando `Codable` junto con un `JSONEncoder` y un `JSONDecoder`:
2021-05-21 16:38:18 +00:00
```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"
// })
```
2022-05-01 12:41:36 +00:00
### XML
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
Existen múltiples formas de codificar XML. Al igual que con el análisis de JSON, existen varias bibliotecas de terceros, como: [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)
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
Varían en términos de velocidad, uso de memoria, persistencia de objetos y lo más importante: difieren en cómo manejan las entidades XML externas. Vea [XXE en el visor de Office de Apple iOS](https://nvd.nist.gov/vuln/detail/CVE-2015-3784) como ejemplo. Por lo tanto, es clave deshabilitar el análisis de entidades externas XML si es posible. Consulte la [hoja de trucos de prevención de XXE de OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XML\_External\_Entity\_Prevention\_Cheat\_Sheet.html) para obtener más detalles. Además de las bibliotecas, se puede hacer uso de la clase [`XMLParser` de Apple](https://developer.apple.com/documentation/foundation/xmlparser)
2021-05-21 16:38:18 +00:00
2023-06-03 01:46:23 +00:00
Cuando no se utilizan bibliotecas de terceros, sino la clase `XMLParser` de Apple, asegúrese de que `shouldResolveExternalEntities` devuelva `false`.
2021-05-21 16:38:18 +00:00
{% hint style="danger" %}
2023-06-03 01:46:23 +00:00
Todas estas formas de serializar/codificar datos se pueden **utilizar para almacenar datos en el sistema de archivos**. En esos escenarios, verifique si los datos almacenados contienen algún tipo de **información sensible**.\
Además, en algunos casos puede ser posible **abusar de algunos datos serializados** (capturándolos a través de MitM o modificándolos dentro del sistema de archivos) deserializando datos arbitrarios y **haciendo que la aplicación realice acciones inesperadas** (ver la página de deserialización). En estos casos, se recomienda enviar/guardar los datos serializados cifrados y firmados.
2021-05-21 16:38:18 +00:00
{% endhint %}
2023-06-03 01:46:23 +00:00
## Referencias
2021-05-21 16:38:18 +00:00
{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %}
2021-05-21 16:38:18 +00:00
2022-04-28 16:01:33 +00:00
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? o ¿quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección de exclusivos [**NFTs**](https://opensea.io/collection/the-peass-family)
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- Consigue el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
2022-04-28 16:01:33 +00:00
2023-06-03 01:46:23 +00:00
- **Comparte tus trucos de hacking enviando PRs al [repositorio de hacktricks](https://github.com/carlospolop/hacktricks) y al [repositorio de hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>