```markdown ### NSCoding e NSSecureCoding O iOS vem com dois protocolos para **serialização** de objetos para Objective-C ou `NSObject`s: **`NSCoding`** e **`NSSecureCoding`**. Quando uma **classe está em conformidade** com qualquer um dos protocolos, os dados são serializados para **`NSData`**: um invólucro para **buffers de bytes**. Note que `Data` em Swift é o mesmo que `NSData` ou seu equivalente mutável: `NSMutableData`. O protocolo `NSCoding` declara os dois métodos que devem ser implementados para codificar/deodificar suas variáveis de instância. **Uma classe que usa `NSCoding` precisa implementar `NSObject` ou ser anotada como uma classe @objc**. O protocolo `NSCoding` exige a implementação de encode e init conforme mostrado abaixo. ``` ```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. } ``` O problema com `NSCoding` é que o objeto muitas vezes já está **construído e inserido antes de você poder avaliar** o tipo de classe. Isso **permite que um atacante injete facilmente todos os tipos de dados**. Portanto, o protocolo **`NSSecureCoding`** foi introduzido. Ao conformar-se com [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/NSSecureCoding), você precisa incluir: ```swift static var supportsSecureCoding: Bool { return true } ``` quando `init(coder:)` faz parte da classe. Em seguida, ao decodificar o objeto, deve ser feita uma verificação, por exemplo: ```swift let obj = decoder.decodeObject(of:MyClass.self, forKey: "myKey") ``` A conformidade com `NSSecureCoding` garante que os objetos sendo instanciados são de fato aqueles que eram esperados. No entanto, **não são realizadas verificações adicionais de integridade** sobre os dados e os dados não são criptografados. Portanto, qualquer dado secreto precisa de **criptografia** adicional e dados cuja integridade deve ser protegida devem receber um HMAC adicional. ### Arquivamento de Objetos com NSKeyedArchiver `NSKeyedArchiver` é uma subclasse concreta de `NSCoder` e oferece uma maneira de codificar objetos e armazená-los em um arquivo. O `NSKeyedUnarchiver` decodifica os dados e recria os dados originais. Vamos pegar o exemplo da seção `NSCoding` e agora arquivar e desarquivar eles: ```swift // archiving: NSKeyedArchiver.archiveRootObject(customPoint, toFile: "/path/to/archive") // unarchiving: guard let customPoint = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? CustomPoint else { return nil } ``` Você também pode salvar as informações no plist primário `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 É uma combinação dos protocolos `Decodable` e `Encodable`. Uma `String`, `Int`, `Double`, `Date`, `Data` e `URL` são naturalmente `Codable`: o que significa que podem ser codificados e decodificados facilmente sem nenhum trabalho adicional. Vamos ver o seguinte exemplo: ```swift struct CustomPointStruct:Codable { var x: Double var name: String } ``` Adicionando `Codable` à lista de herança para o `CustomPointStruct` no exemplo, os métodos `init(from:)` e `encode(to:)` são automaticamente suportados. Para mais detalhes sobre o funcionamento do `Codable`, consulte [a Documentação do Desenvolvedor Apple](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types). Você também pode usar codable para salvar os dados na lista de propriedades primária `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) } ``` ### Codificação JSON Existem muitas bibliotecas de terceiros para codificar dados em JSON (como exposto [aqui](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#json-and-codable)). No entanto, a Apple oferece suporte para codificação/decodificação de JSON diretamente combinando `Codable` com um `JSONEncoder` e um `JSONDecoder`: ```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 Existem várias maneiras de fazer codificação XML. Semelhante ao parsing de JSON, existem várias bibliotecas de terceiros, 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) Elas variam em termos de velocidade, uso de memória, persistência de objetos e mais importante: diferem na forma como lidam com entidades externas XML. Veja [XXE no visualizador de Office da Apple iOS](https://nvd.nist.gov/vuln/detail/CVE-2015-3784) como exemplo. Portanto, é fundamental desativar o parsing de entidades externas, se possível. Veja a [folha de dicas de prevenção de XXE da OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XML\_External\_Entity\_Prevention\_Cheat\_Sheet.html) para mais detalhes. Além das bibliotecas, você pode usar a classe [`XMLParser` da Apple](https://developer.apple.com/documentation/foundation/xmlparser) Quando não estiver usando bibliotecas de terceiros, mas sim o `XMLParser` da Apple, certifique-se de que `shouldResolveExternalEntities` retorne `false`. {% hint style="danger" %} Todas essas formas de serializar/codificar dados podem ser **usadas para armazenar dados no sistema de arquivos**. Nesses cenários, verifique se os dados armazenados contêm qualquer tipo de **informação sensível**.\ Além disso, em alguns casos, você pode ser capaz de **abusar de alguns dados serializados** (capturando-os via MitM ou modificando-os dentro do sistema de arquivos) desserializando dados arbitrários e **fazendo com que o aplicativo execute ações inesperadas** (veja a [página de Deserialization](../../pentesting-web/deserialization/)). Nestes casos, é recomendado enviar/salvar os dados serializados criptografados e assinados. {% endhint %} ## Referências {% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %}
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras maneiras de apoiar o HackTricks: * Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Obtenha o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Compartilhe suas dicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).