Como detecto que um aplicativo iOS está sendo executado em um telefone com jailbreak?

Respostas:

90

Depende do que você quer dizer com jailbreak. No caso simples, você poderá ver se o Cydia está instalado e seguir em frente - algo como

NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
   // do something useful
}

Para kernels hackeados, é um pouco (muito) mais envolvido.

wisequark
fonte
17
Não seria suficiente procurar qualquer arquivo / diretório fora da sua caixa de areia? Como / etc?
Rhythmic Fistman
58
Observe que nem todos os usuários têm o Cydia instalado - isso não é uma boa verificação, e você deve procurar algo como / bin / bash que / all / users / will / have.
Grant Paul
2
Onde o apt armazena suas informações? Ou eu poderia simplesmente chamar um comando system () e descobrir. Eu quero saber se eles têm certos aplicativos e se eles têm-los, em seguida, restringir o aplicativo
conradev
2
@RazorSharp Neste ponto, quase todos os usuários têm Cydia. Provavelmente é o suficiente para verificar isso agora. No entanto, se você deseja uma verificação 100% confiável, use uma verificação baseada no kernel, como abaixo.
9788 Paul
1
FWIW as verificações de arquivo são triviais para ignorar. Pode-se usar o mobilesubstrate para ligar fileExistsAtPath:e fazê-lo retornar NOpara o caminho específico que você verifica.
Toasted_flakes
55

Este é um código que combina algumas respostas que encontrei para essa necessidade e fornecerá uma taxa de sucesso muito maior:

BOOL isJailbroken()
{
#if !(TARGET_IPHONE_SIMULATOR)

   if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"] ||
       [[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"] ||
       [[NSFileManager defaultManager] fileExistsAtPath:@"/bin/bash"] ||
       [[NSFileManager defaultManager] fileExistsAtPath:@"/usr/sbin/sshd"] ||
       [[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt"] ||
       [[NSFileManager defaultManager] fileExistsAtPath:@"/private/var/lib/apt/"] ||
       [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]])  {
         return YES;
   }

   FILE *f = NULL ;
   if ((f = fopen("/bin/bash", "r")) ||
      (f = fopen("/Applications/Cydia.app", "r")) ||
      (f = fopen("/Library/MobileSubstrate/MobileSubstrate.dylib", "r")) ||
      (f = fopen("/usr/sbin/sshd", "r")) ||
      (f = fopen("/etc/apt", "r")))  {
         fclose(f);
         return YES;
   }
   fclose(f);

   NSError *error;
   NSString *stringToBeWritten = @"This is a test.";
   [stringToBeWritten writeToFile:@"/private/jailbreak.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
   [[NSFileManager defaultManager] removeItemAtPath:@"/private/jailbreak.txt" error:nil];
   if(error == nil)
   {
      return YES;
   }

#endif

   return NO;
}
Yossi
fonte
1
@ Porizm, esta é apenas uma combinação de algumas respostas que encontrei. Alguns deles não funcionaram para mim, mas para outros. Portanto, com este código, você não se arrisca. Se você usar isso, poderá ter 99% de certeza. Em relação ao desempenho, você pode executá-lo apenas uma vez em cada corrida e salvar a algum lugar resposta, você não tem que executá-lo cada vez ..
Yossi
3
@yossi e porizm apple aprovaram seu aplicativo que contém o código acima? responda
karthikPrabhu Alagu
4
Este método deve ser uma função C embutida, não Objective-C. É muito fácil de descobrir e desvio métodos Objective-C, especialmente se você chamá-loisJailbroken
progrmr
2
@Yossi isso cobre dispositivos jailbroken usando Taig?
Lakshay
3
@Lakshay Eu não sei .. Você está mais do que convidado para verificar e acrescentar aqui uma resposta :)
Yossi
54
+(BOOL)isJailbroken {
    NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
    return [[UIApplication sharedApplication] canOpenURL:url];
}

Verificar o caminho do arquivo /Applications/Cydia.appnão é permitido em um telefone normal? Nunca ouvi falar da Apple detectando isso e rejeitando um aplicativo, mas a Apple é imprevisível. O Cydia possui um esquema de URL cydia: // que pode ser verificado legalmente com o UIApplicationcanOpenURL:

Mark Johnson
fonte
1
Essa é uma ótima maneira de verificar e não sai da sua caixa de areia. Claro, se o jailbreaker não tiver o Cydia instalado, ele retornará NÃO, mas acho que a maioria dos Jailbreaks instala o Cydia.
Wim Haanstra
essa sequência não pode ser alterada quando o aplicativo está quebrado?
NSRover
8
Para o iOS9.0 +, você também precisa adicionar a chave LSApplicationQueriesSchemes no aplicativo. Caso contrário, canOpenURL sempre retornará false.
David V
1
Isso fornecerá um falso positivo se o usuário tiver um aplicativo instalado em conformidade com o esquema cydia: // como o InstantTV.
thattyson
@thattyson thanks! Eu estava olhando para verificar por que estava recebendo falsos positivos
rickrvo
52

Verificar se o kernel está quebrado não é MUITO mais envolvido.

O jailbreak faz com que a verificação de assinatura do kernel do código assinado sempre informe que o código foi assinado corretamente, os telefones não quebrados não podem executar o código com uma assinatura incorreta.

Portanto, inclua um executável separado no aplicativo com uma assinatura incorreta. Poderia ser apenas um programa de 3 linhas que possui main () e um valor de retorno. Compile o executável sem assinatura de código (desative-o em Configurações do Projeto-> Compilar) e assine-o com uma chave diferente usando o utilitário de linha de comando "codesign".

Faça com que seu aplicativo execute o executável separado. Se seu programa não pode obter o valor de retorno ao executar o executável separado com o sig ruim, ele definitivamente está preso. Se o executável separado retornar A-OK, o telefone será definitivamente desbloqueado.

GregH
fonte
13
Você pode obter um (sub) executável cuja assinatura é inválida assim através da App Store?
Fbrereto 6/04
34
Talvez as coisas tenham mudado, mas a execução de um executável separado não impediria sua aprovação na loja de aplicativos?
Peter Zich
4
Alguém pode responder antes dos comentários? Esta é uma pergunta importante.
Petr
Ninguém realmente vai impedi-lo de gravar um Mach-O em disco com uma assinatura inválida. No entanto, eu discordo da resposta de que verificar se o kernel está quebrado não está envolvido ou que essa é uma verificação definitiva por qualquer meio.
saagarjha
20
BOOL isJailbroken()
{
#if TARGET_IPHONE_SIMULATOR
    return NO;
#else
    FILE *f = fopen("/bin/bash", "r");

    if (errno == ENOENT)
    {
        // device is NOT jailbroken
        fclose(f);
        return NO;
    }
    else {
        // device IS jailbroken
        fclose(f);
        return YES;
    }
#endif
}
Richard J. Ross III
fonte
Essa é uma boa solução, mas o xCon e outras ferramentas como ele podem facilmente ignorar essa verificação. Então, estou procurando uma solução melhor.
precisa saber é o seguinte
7
@AlexeiRobsky não existe uma solução perfeita. Sempre haverá alguém que encontrará uma maneira de ignorar sua proteção, é apenas um fato.
Richard J. Ross III
14

Você pode detectar se um dispositivo é JailBroken ou não, verificando o seguinte:

  • Cydia está instalado
  • Verifique alguns dos caminhos do sistema
  • Executar uma verificação de integridade da sandbox
  • Executar verificação de link simbólico
  • Verifique se você cria e grava arquivos fora da sua Sandbox

Há uma biblioteca de código aberto que criei a partir de vários artigos e livros. Experimente no GitHub !

user3088680
fonte
14

Reescrevi no Swift 2.3 a solução fornecida pelo @Yossi

public static func jailbroken(application: UIApplication) -> Bool {
    guard let cydiaUrlScheme = NSURL(string: "cydia://package/com.example.package") else { return isJailbroken() }
    return application.canOpenURL(cydiaUrlScheme) || isJailbroken()
}


static func isJailbroken() -> Bool {

    if isSimulator {
        return false
    }

    let fileManager = NSFileManager.defaultManager()
    if fileManager.fileExistsAtPath("/Applications/Cydia.app") ||
        fileManager.fileExistsAtPath("/Library/MobileSubstrate/MobileSubstrate.dylib") ||
        fileManager.fileExistsAtPath("/bin/bash") ||
        fileManager.fileExistsAtPath("/usr/sbin/sshd") ||
        fileManager.fileExistsAtPath("/etc/apt") ||
        fileManager.fileExistsAtPath("/usr/bin/ssh") {
        return true
    }

    if canOpen("/Applications/Cydia.app") ||
        canOpen("/Library/MobileSubstrate/MobileSubstrate.dylib") ||
        canOpen("/bin/bash") ||
        canOpen("/usr/sbin/sshd") ||
        canOpen("/etc/apt") ||
        canOpen("/usr/bin/ssh") {
        return true
    }

    let path = "/private/" + NSUUID().UUIDString
    do {
        try "anyString".writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)
        try fileManager.removeItemAtPath(path)
        return true
    } catch {
        return false
    }
}

static func canOpen(path: String) -> Bool {
    let file = fopen(path, "r")
    guard file != nil else { return false }
    fclose(file)
    return true
}
Alex Peda
fonte
6

O método mais sofisticado que conheço é o uso da objc_copyImageNames()função. Ele retorna uma lista de bibliotecas atualmente carregadas e, como a maioria das pessoas tem o MobileSubstrate em dispositivos jailbroken e a maioria das ferramentas de crack do iAP depende disso, pelo menos algumas bibliotecas do MobileSubstrate serão exibidas.

Maxthon Chan
fonte
Você tem algum link sobre como são as bibliotecas do MobileSubstrate / CydiaSubstrate? Eu não tenho um telefone jailbroken para brincar, por isso estou dirigindo "cego" e as pesquisas do Google basicamente trazem seu comentário acima.
chadbag
@chadbag Eu também não tenho um, mas você pode procurar o debarquivo do MobileSubstrate, descompactá-lo e colocar na lista negra (quase) tudo .dylibo que está empacotado.
Maxthon Chan
Obrigado, descobri um código e posso adicionar mais algumas coisas com base no seu comentário. Muito Obrigado!
chadbag
4

Não conheço nenhuma "API" existente para isso. Se houvesse, um produto de mascaramento de jailbreak os encobriria rapidamente.

Como muitas pessoas apontam, é um jogo de gato e rato. E depois que os dois jogadores se tornam especialistas, tudo se resume a quem recebe o primeiro lance. (Pessoa segurando o dispositivo.)

Encontrei muitas boas sugestões para detectar jailbreak no novo livro de Zdziarski, "Hacking and Proturing iOS Apps". (Pessoalmente, paguei mais pelo O'Reilly eBook porque eles permitem copiar e colar.)

Não, eu não sou afiliado aos editores. Mas achei um bom livro. Não gosto de publicar apenas os erros dos hackers para que eles possam corrigi-los, então pensei em apontar para o livro.

Walt Sellers
fonte
4

Tente executar código não assinado através do seu aplicativo.

Um dispositivo jailbroken geralmente possui as seguintes características:

  • executar código não assinado
  • Cydia instalado
  • possui arquivos de jailbreak
  • acesso r / w completo a todo o sistema de arquivos
  • alguns arquivos do sistema foram modificados (conteúdo e, portanto, sha1 não corresponde aos arquivos originais)
  • preso a uma versão específica (versão jailbreakable)

Apenas verificar a existência de arquivos para detecção de jailbreak está fadado ao fracasso. Essas verificações são fáceis de ignorar.

kurapix
fonte
3
Tentando executar código não assinado faria sua aplicação ser rejeitado na AppStore
Frederic Yesid Peña Sánchez
4

Alguns arquivos comuns para verificar: /Library/MobileSubstrate/MobileSubstrate.dylib

/Applications/Cydia.app

/var/cache/apt

/var/lib/apt

/var/lib/cydia

/var/log/syslog

/var/tmp/cydia.log

/bin/bash

/bin/sh

/usr/sbin/sshd

/usr/libexec/ssh-keysign

/etc/ssh/sshd_config

/etc/apt

A maioria verifica arquivos relacionados ao Cydia.

DevC
fonte
3

Eu sugiro procurar arquivos que não estão presentes em um iPhone "baunilha". Todos os kits de jailbreak que eu vi instalar o ssh. Esse pode ser um bom indicador de um telefone com jailbreak.

Gordon Wilson
fonte
18
O ssh nunca é instalado automaticamente, os usuários devem instalá-lo eles mesmos.
Grant Paul
1
Eu realmente não acompanhei a cena do jailbreak. Porém, quando me lembro, quando escrevi isso (janeiro '09), o Ziphone e outros instalaram o ssh e o subsistema bsd por padrão. Talvez isso não seja mais verdade.
Gordon Wilson
12
confie em mim quando digo que o chpwn acompanhou a cena do jailbreak.
Winfield Trail
3

O que fizemos é que já temos um feed RSS para nos comunicar com nossos usuários ( Stocks Live ), colocamos uma notícia que diz algo como isto:

Alguns dispositivos jailbroken têm problemas bla bla bla, fizemos um hack para resolver esses problemas, mas precisamos saber se esse é um dispositivo jailbroken ou não, pressione aqui para que o aplicativo corrija o problema. Se você voltar ao normal, ou seja, removeu o jailbreak, pressione aqui.

Então você processa a interação do usuário e faz o que é apropriado, como se comportar de forma diferente, etc ...

Ilam
fonte
3

Tente encontrar um arquivo que o cydia ou o dispositivo jailbroken criam. Ou tente escrever em um arquivo fora da caixa preta do aplicativo. Se você conseguir fazer isso, o dispositivo será comprometido / desbloqueado :)

- (BOOL)jailbroken
{
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
karim
fonte
2
A Apple aprovou seu aplicativo que contém o código acima?
karthikPrabhu Alagu
3

Use o seguinte código para o Swift 4 e superior: Adicione o seguinte código no appdelegate:

private func getJailbrokenStatus() -> Bool {
    if TARGET_IPHONE_SIMULATOR != 1 {
        // Check 1 : existence of files that are common for jailbroken devices
        if FileManager.default.fileExists(atPath: "/Applications/Cydia.app")
            || FileManager.default.fileExists(atPath: "/Library/MobileSubstrate/MobileSubstrate.dylib")
            || FileManager.default.fileExists(atPath: "/bin/bash")
            || FileManager.default.fileExists(atPath: "/usr/sbin/sshd")
            || FileManager.default.fileExists(atPath: "/etc/apt")
            || FileManager.default.fileExists(atPath: "/private/var/lib/apt/")
            || UIApplication.shared.canOpenURL(URL(string:"cydia://package/com.example.package")!) {
            return true
        }
        // Check 2 : Reading and writing in system directories (sandbox violation)
        let stringToWrite = "Jailbreak Test"
        do {
            try stringToWrite.write(toFile:"/private/JailbreakTest.txt", atomically:true, encoding:String.Encoding.utf8)
            //Device is jailbroken
            return true
        } catch {
            return false
        }
    }
    else {
        return false
    }
}

func applicationDidBecomeActive (_ application: UIApplication) {

    if getJailbrokenStatus() {
        let alert = UIAlertController(title: LocalizedKeys.Errors.jailbreakError, message: LocalizedKeys.Errors.jailbreakErrorMessage, preferredStyle: UIAlertController.Style.alert)
        let jailBrokenView = UIViewController()

        jailBrokenView.view.frame = UIScreen.main.bounds
        jailBrokenView.view.backgroundColor = .white
        self.window?.rootViewController = jailBrokenView
        jailBrokenView.present(alert, animated: true, completion: nil)
    }

    if #available(iOS 11.0, *) {
        if !UIScreen.main.isCaptured {
            DispatchQueue.main.async {
                self.blockImageView.removeFromSuperview()
            }
        }
    }
}
Paritosh Pawar
fonte
1

Aqui estão as minhas soluções: Etapa 1

extension UIDevice {
    func isJailBroken() -> Bool {
        let cydiaPath = "/Applications/Cydia.app"
        let aptPath = "/private/var/lib/apt/"
        if FileManager.default.fileExists(atPath: cydiaPath) || FileManager.default.fileExists(atPath: aptPath) {
            return true
        }
        return false
    }
}

Etapa 2: Ligue para viewDidLoad()dentro do seu controlador de exibição da tela de inicialização (ou qualquer outro VC que você esteja chamando pela primeira vez):

       // show a blank screen or some other view controller
       let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
       self.navigationController?.present(viewController, animated: true, completion:nil)
Sanjeevcn
fonte
-2

Tente acessar /Application/Preferences.app/General.plist Você poderá fazê-lo em um iPhone com jailbreak No telefone não Jb, não poderá acessá-lo

aker
fonte
3
Esta resposta seria mais interessante com o código fonte. IMHO: Isso renderia a você um voto positivo.
Johan Karlsson
5
-1 = Os dispositivos não quebrados também podem abrir e ler este arquivo. (Testado)
frankish 17/04
@JohanKarlsson Suponho que os leitores aqui possam escrever seu próprio código-fonte. Se eles não podem - o que estão fazendo aqui?
precisa saber é o seguinte