Skip to content

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