Mecanismos de Detecção de Jailbreak¶
Mecanismos de detecção de jailbreak são adicionados às defesas contra engenharia reversa para dificultar a execução do aplicativo em um dispositivo com jailbreak. Isso bloqueia algumas das ferramentas e técnicas que os engenheiros reversos gostam de utilizar. Como a maioria dos outros tipos de defesa, a detecção de jailbreak não é muito eficaz por si só, mas espalhar verificações por todo o código-fonte do aplicativo pode melhorar a eficácia do esquema geral de anti-violentação.
Você pode aprender mais sobre Detecção de Jailbreak/Root no estudo de pesquisa "Estudo de Evasão de Detecção de Jailbreak/Root em iOS e Android" por Dana Geist e Marat Nigmatullin.
Verificações Comuns de Detecção de Jailbreak¶
Aqui apresentamos três técnicas típicas de detecção de jailbreak:
Verificações Baseadas em Arquivos:
O aplicativo pode estar verificando a existência de arquivos e diretórios normalmente associados a jailbreaks, como:
/Applications/Cydia.app
/Applications/FakeCarrier.app
/Applications/Icy.app
/Applications/IntelliScreen.app
/Applications/MxTube.app
/Applications/RockApp.app
/Applications/SBSettings.app
/Applications/WinterBoard.app
/Applications/blackra1n.app
/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist
/Library/MobileSubstrate/DynamicLibraries/Veency.plist
/Library/MobileSubstrate/MobileSubstrate.dylib
/System/Library/LaunchDaemons/com.ikey.bbot.plist
/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist
/bin/bash
/bin/sh
/etc/apt
/etc/ssh/sshd_config
/private/var/lib/apt
/private/var/lib/cydia
/private/var/mobile/Library/SBSettings/Themes
/private/var/stash
/private/var/tmp/cydia.log
/var/tmp/cydia.log
/usr/bin/sshd
/usr/libexec/sftp-server
/usr/libexec/ssh-keysign
/usr/sbin/sshd
/var/cache/apt
/var/lib/apt
/var/lib/cydia
/usr/sbin/frida-server
/usr/bin/cycript
/usr/local/bin/cycript
/usr/lib/libcycript.dylib
/var/log/syslog
Verificando Permissões de Arquivo:
O aplicativo pode estar tentando escrever em um local fora da sandbox do aplicativo. Por exemplo, pode tentar criar um arquivo no diretório /private. Se o arquivo for criado com sucesso, o aplicativo pode assumir que o dispositivo está com jailbreak.
do {
let pathToFileInRestrictedDirectory = "/private/jailbreak.txt"
try "This is a test.".write(toFile: pathToFileInRestrictedDirectory, atomically: true, encoding: String.Encoding.utf8)
try FileManager.default.removeItem(atPath: pathToFileInRestrictedDirectory)
// Dispositivo está com jailbreak
} catch {
// Dispositivo não está com jailbreak
}
Verificando Manipuladores de Protocolo:
O aplicativo pode estar tentando chamar manipuladores de protocolo conhecidos como cydia:// (disponível por padrão após a instalação do Cydia).
if let url = URL(string: "cydia://package/com.example.package"), UIApplication.shared.canOpenURL(url) {
// Dispositivo está com jailbreak
}
Bypass Automatizado de Detecção de Jailbreak¶
A maneira mais rápida de contornar mecanismos comuns de detecção de jailbreak é usando objection. Você pode encontrar a implementação do bypass de jailbreak no script jailbreak.ts.
Bypass Manual de Detecção de Jailbreak¶
Se os bypasses automatizados não forem eficazes, você precisará sujar as mãos e fazer engenharia reversa dos binários do aplicativo até encontrar os trechos de código responsáveis pela detecção e, em seguida, patchá-los estaticamente ou aplicar hooks em runtime para desativá-los.
Passo 1: Engenharia Reversa:
Quando você precisa fazer engenharia reversa de um binário procurando por detecção de jailbreak, a maneira mais óbvia é procurar por strings conhecidas, como "jail" ou "jailbreak". Observe que isso nem sempre será eficaz, especialmente quando há medidas de resiliência em vigor ou quando o desenvolvedor evitou termos tão óbvios.
Exemplo: Baixe DVIA-v2, descompacte-o, carregue o binário principal no radare2 para iOS e aguarde a conclusão da análise.
r2 -A ./DVIA-v2-swift/Payload/DVIA-v2.app/DVIA-v2
Agora você pode listar os símbolos do binário usando o comando is e aplicar um grep case-insensitive (~+) para a string "jail".
[0x1001a9790]> is~+jail
...
2230 0x001949a8 0x1001949a8 GLOBAL FUNC 0 DVIA_v2.JailbreakDetectionViewController.isJailbroken.allocator__Bool
7792 0x0016d2d8 0x10016d2d8 LOCAL FUNC 0 +[JailbreakDetection isJailbroken]
...
Como você pode ver, há um método de instância com a assinatura -[JailbreakDetectionVC isJailbroken].
Passo 2: Hooks Dinâmicos:
Agora você pode usar o Frida para contornar a detecção de jailbreak realizando a chamada instrumentação precoce, ou seja, substituindo a implementação da função logo na inicialização.
Use frida-trace no seu computador host:
frida-trace -U -f /Applications/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp -m "-[JailbreakDetectionVC isJailbroken]"
Isso iniciará o aplicativo, rastreará chamadas para -[JailbreakDetectionVC isJailbroken] e criará um hook em JavaScript para cada elemento correspondente.
Abra ./__handlers__/__JailbreakDetectionVC_isJailbroken_.js com seu editor favorito e edite a função de callback onLeave. Você pode simplesmente substituir o valor de retorno usando retval.replace() para sempre retornar 0:
onLeave: function (log, retval, state) {
console.log("Function [JailbreakDetectionVC isJailbroken] originally returned:"+ retval);
retval.replace(0);
console.log("Changing the return value to:"+retval);
}
Isso produzirá a seguinte saída:
$ frida-trace -U -f /Applications/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp -m "-[JailbreakDetectionVC isJailbroken]:"
Instrumenting functions... `...
-[JailbreakDetectionVC isJailbroken]: Loaded handler at "./__handlers__/__JailbreakDetectionVC_isJailbroken_.js"
Started tracing 1 function. Press Ctrl+C to stop.
Function [JailbreakDetectionVC isJailbroken] originally returned:0x1
Changing the return value to:0x0