hacktricks/mobile-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes.md

199 lines
15 KiB
Markdown
Raw Normal View History

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-06 18:56:34 +00:00
- Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **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-06 18:56:34 +00:00
- **Compartilhe suas técnicas de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>
2023-06-06 18:56:34 +00:00
Os esquemas de URL personalizados [permitem que os aplicativos se comuniquem por meio de um protocolo personalizado](https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple\_ref/doc/uid/TP40007072-CH6-SW1). Um aplicativo deve declarar suporte para os esquemas e lidar com URLs de entrada que usam esses esquemas.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
> Os esquemas de URL oferecem um vetor de ataque potencial para o seu aplicativo, portanto, certifique-se de **validar todos os parâmetros de URL** e **descartar URLs malformados**. Além disso, limite as **ações** disponíveis para aquelas que **não colocam em risco os dados do usuário**.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Por exemplo, a URI: `myapp://hostname?data=123876123` irá **invocar** o **aplicativo** mydata (aquele que **registrou** o esquema `mydata`) para a **ação** relacionada ao **hostname** `hostname` enviando o **parâmetro** `data` com valor `123876123`.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Um exemplo vulnerável é o seguinte [bug no aplicativo móvel do Skype](http://www.dhanjani.com/blog/2010/11/insecure-handling-of-url-schemes-in-apples-ios.html), descoberto em 2010: O aplicativo Skype registrou o manipulador de protocolo `skype://`, o que **permitiu que outros aplicativos acionassem chamadas para outros usuários do Skype e números de telefone**. Infelizmente, o Skype não pediu permissão aos usuários antes de fazer as chamadas, então qualquer aplicativo poderia ligar para números arbitrários sem o conhecimento do usuário. Os atacantes exploraram essa vulnerabilidade colocando um `<iframe src="skype://xxx?call"></iframe>` invisível (onde `xxx` foi substituído por um número premium), então qualquer usuário do Skype que inadvertidamente visitasse um site malicioso chamava o número premium.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Você pode encontrar os **esquemas registrados por um aplicativo** no arquivo **`Info.plist`** do aplicativo procurando por **`CFBundleURLTypes`** (exemplo do [iGoat-Swift](https://github.com/OWASP/iGoat-Swift)):
2021-05-21 16:38:18 +00:00
```markup
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.iGoat.myCompany</string>
<key>CFBundleURLSchemes</key>
<array>
<string>iGoat</string>
</array>
</dict>
</array>
```
2023-06-06 18:56:34 +00:00
No entanto, observe que **aplicativos maliciosos podem registrar novamente URIs** já registrados por outros aplicativos. Portanto, se você estiver enviando **informações confidenciais por meio de URIs** (myapp://hostname?password=123456), um aplicativo **malicioso** pode **interceptar** a URI com as **informações confidenciais**.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Além disso, a entrada dessas URIs **deve ser verificada e sanitizada**, pois pode estar vindo de **origens maliciosas** tentando explorar SQLInjections, XSS, CSRF, Traversals de Caminho ou outras possíveis vulnerabilidades.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
## Registro de Esquemas de Consulta do Aplicativo
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Os aplicativos podem chamar [`canOpenURL:`](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl?language=objc) para verificar se o **aplicativo de destino está disponível**. No entanto, como esse método estava sendo usado por aplicativos maliciosos como uma forma de **enumerar aplicativos instalados**, [a partir do iOS 9.0, os esquemas de URL passados para ele também devem ser declarados](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl?language=objc#discussion) adicionando a chave `LSApplicationQueriesSchemes` ao arquivo `Info.plist` do aplicativo e um array de **até 50 esquemas de URL**.
2021-05-21 16:38:18 +00:00
```markup
<key>LSApplicationQueriesSchemes</key>
<array>
<string>url_scheme1</string>
<string>url_scheme2</string>
</array>
```
2023-06-06 18:56:34 +00:00
`canOpenURL` sempre retornará `NO` para esquemas não declarados, independentemente de um aplicativo apropriado estar instalado ou não. No entanto, essa restrição se aplica apenas ao `canOpenURL`.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
## Testando o Manuseio e Validação de URLs
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Para determinar como um caminho de URL é construído e validado, se você tiver o código-fonte original, pode **procurar pelos seguintes métodos**:
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
* Método `application:didFinishLaunchingWithOptions:` ou `application:will-FinishLaunchingWithOptions:`: verifique como a decisão é tomada e como as informações sobre a URL são recuperadas.
* [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc): verifique como o recurso está sendo aberto, ou seja, como os dados estão sendo analisados, verifique as [opções](https://developer.apple.com/documentation/uikit/uiapplication/openurloptionskey), especialmente se o acesso pelo aplicativo chamador ([`sourceApplication`](https://developer.apple.com/documentation/uikit/uiapplication/openurloptionskey/1623128-sourceapplication)) deve ser permitido ou negado. O aplicativo também pode precisar da permissão do usuário ao usar o esquema de URL personalizado.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
No Telegram, você encontrará [quatro métodos diferentes sendo usados](https://github.com/peter-iakovlev/Telegram-iOS/blob/87e0a33ac438c1d702f2a0b75bf21f26866e346f/Telegram-iOS/AppDelegate.swift#L1250):
2021-05-21 16:38:18 +00:00
```swift
func application(_ application: UIApplication, open url: URL, sourceApplication: String?) -> Bool {
self.openUrl(url: url)
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?,
annotation: Any) -> Bool {
self.openUrl(url: url)
return true
}
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
self.openUrl(url: url)
return true
}
func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
self.openUrl(url: url)
return true
}
```
2023-06-06 18:56:34 +00:00
## Testando solicitações de URL para outros aplicativos
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
O método [`openURL:options:completionHandler:`](https://developer.apple.com/documentation/uikit/uiapplication/1648685-openurl?language=objc) e o método [obsoleto `openURL:` da `UIApplication`](https://developer.apple.com/documentation/uikit/uiapplication/1622961-openurl?language=objc) são responsáveis por **abrir URLs** (ou seja, enviar solicitações / fazer consultas para outros aplicativos) que podem ser locais para o aplicativo atual ou podem ser fornecidos por um aplicativo diferente. Se você tiver o código-fonte original, poderá procurar diretamente por usos desses métodos.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Além disso, se você estiver interessado em saber se o aplicativo está consultando serviços ou aplicativos específicos e se o aplicativo é bem conhecido, também pode pesquisar por esquemas de URL comuns online e incluí-los em seus **greps (lista de esquemas de aplicativos iOS)**.
2021-05-21 16:38:18 +00:00
```bash
egrep -nr "open.*options.*completionHandler" ./Telegram-iOS/
egrep -nr "openURL\(" ./Telegram-iOS/
egrep -nr "mt-encrypted-file://" ./Telegram-iOS/
egrep -nr "://" ./Telegram-iOS/
```
2023-06-06 18:56:34 +00:00
## Testando Métodos Obsoletos
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Procure por métodos obsoletos como:
2021-05-21 16:38:18 +00:00
* [`application:handleOpenURL:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622964-application?language=objc)
* [`openURL:`](https://developer.apple.com/documentation/uikit/uiapplication/1622961-openurl?language=objc)
* [`application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application)
2023-06-06 18:56:34 +00:00
Por exemplo, aqui encontramos esses três:
2021-05-21 16:38:18 +00:00
```bash
$ rabin2 -zzq Telegram\ X.app/Telegram\ X | grep -i "openurl"
0x1000d9e90 31 30 UIApplicationOpenURLOptionsKey
0x1000dee3f 50 49 application:openURL:sourceApplication:annotation:
0x1000dee71 29 28 application:openURL:options:
0x1000dee8e 27 26 application:handleOpenURL:
0x1000df2c9 9 8 openURL:
0x1000df766 12 11 canOpenURL:
0x1000df772 35 34 openURL:options:completionHandler:
...
```
2023-06-06 18:56:34 +00:00
## Chamando URLs arbitrárias
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
* **Safari**: Para testar rapidamente um esquema de URL, você pode abrir as URLs no Safari e observar como o aplicativo se comporta. Por exemplo, se você escrever `tel://123456789`, o Safari tentará iniciar a chamada para o número.
* **Notes App**: Pressione longamente os links que você escreveu para testar esquemas de URL personalizados. Lembre-se de sair do modo de edição para poder abri-los. Observe que você pode clicar ou pressionar links, incluindo esquemas de URL personalizados, somente se o aplicativo estiver instalado, caso contrário, eles não serão destacados como _links clicáveis_.
2021-05-21 16:38:18 +00:00
* [**IDB**](https://github.com/facebook/idb):
2023-06-06 18:56:34 +00:00
* Inicie o IDB, conecte-se ao seu dispositivo e selecione o aplicativo de destino. Você pode encontrar detalhes na [documentação do IDB](https://www.idbtool.com/documentation/setup.html).
* Vá para a seção **URL Handlers**. Em **URL schemes**, clique em **Refresh**, e à esquerda você encontrará uma lista de todos os esquemas personalizados definidos no aplicativo em teste. Você pode carregar esses esquemas clicando em **Open**, no lado direito. Ao simplesmente abrir um esquema de URI em branco (por exemplo, abrindo `myURLscheme://`), você pode descobrir funcionalidades ocultas (por exemplo, uma janela de depuração) e contornar a autenticação local.
2022-04-05 22:24:52 +00:00
* **Frida**:
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Se você simplesmente deseja abrir o esquema de URL, pode fazê-lo usando o Frida:
2021-05-21 16:38:18 +00:00
```javascript
$ frida -U iGoat-Swift
2021-05-21 16:38:18 +00:00
[iPhone::iGoat-Swift]-> function openURL(url) {
var UIApplication = ObjC.classes.UIApplication.sharedApplication();
var toOpen = ObjC.classes.NSURL.URLWithString_(url);
return UIApplication.openURL_(toOpen);
}
[iPhone::iGoat-Swift]-> openURL("tel://234234234")
true
```
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Neste exemplo do [Frida CodeShare](https://codeshare.frida.re/@dki/ios-url-scheme-fuzzing/), o autor usa a API não pública `LSApplicationWorkspace.openSensitiveURL:withOptions:` para abrir as URLs (do aplicativo SpringBoard):
2021-05-21 16:38:18 +00:00
```javascript
function openURL(url) {
var w = ObjC.classes.LSApplicationWorkspace.defaultWorkspace();
var toOpen = ObjC.classes.NSURL.URLWithString_(url);
return w.openSensitiveURL_withOptions_(toOpen, null);
}
```
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
> Observe que o uso de APIs não públicas não é permitido na App Store, é por isso que nem mesmo testamos essas APIs, mas podemos usá-las para nossa análise dinâmica.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
## Fuzzing de Esquemas de URL
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Se o aplicativo analisa partes da URL, você também pode realizar fuzzing de entrada para detectar bugs de corrupção de memória.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
O que aprendemos acima pode ser usado agora para construir seu próprio fuzzer na linguagem de sua escolha, por exemplo, em Python e chamar o `openURL` usando o [RPC do Frida](https://www.frida.re/docs/javascript-api/#rpc). Esse fuzzer deve fazer o seguinte:
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
* Gerar payloads.
* Para cada um deles, chame `openURL`.
* Verifique se o aplicativo gera um relatório de falha (`.ips`) em `/private/var/mobile/Library/Logs/CrashReporter`.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
O projeto [FuzzDB](https://github.com/fuzzdb-project/fuzzdb) oferece dicionários de fuzzing que você pode usar como payloads.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
## **Fuzzing Usando Frida**
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Fazer isso com o Frida é bastante fácil, você pode se referir a este [post de blog](https://grepharder.github.io/blog/0x03\_learning\_about\_universal\_links\_and\_fuzzing\_url\_schemes\_on\_ios\_with\_frida.html) para ver um exemplo que faz fuzzing do aplicativo iGoat-Swift (funcionando no iOS 11.1.2).
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Antes de executar o fuzzer, precisamos dos esquemas de URL como entradas. A partir da análise estática, sabemos que o aplicativo iGoat-Swift suporta o seguinte esquema de URL e parâmetros: `iGoat://?contactNumber={0}&message={0}`.
2021-05-21 16:38:18 +00:00
```bash
$ frida -U SpringBoard -l ios-url-scheme-fuzzing.js
[iPhone::SpringBoard]-> fuzz("iGoat", "iGoat://?contactNumber={0}&message={0}")
Watching for crashes from iGoat...
No logs were moved.
Opened URL: iGoat://?contactNumber=0&message=0
```
2023-06-06 18:56:34 +00:00
# Referências
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-06 18:56:34 +00:00
- Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **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-06 18:56:34 +00:00
- **Compartilhe suas técnicas de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [repositório hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>